Serializing
This commit is contained in:
parent
818941460f
commit
398b655f3d
@ -1,25 +1,16 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Tools/Memory.h"
|
||||
#include "DeerCore/Tools/Path.h"
|
||||
|
||||
namespace Deer {
|
||||
class World;
|
||||
class WorldSettings;
|
||||
|
||||
namespace Universe {
|
||||
struct WorldHandle {
|
||||
uint32_t worldId = 0;
|
||||
uint32_t generation = 0;
|
||||
World* createWorld(const WorldSettings&);
|
||||
|
||||
WorldHandle() {}
|
||||
WorldHandle(uint32_t _worldId, uint32_t _generation) : worldId(_worldId), generation(_generation) {}
|
||||
};
|
||||
void saveWorldInJson(World*, const Path& path);
|
||||
|
||||
WorldHandle createWorld(const WorldSettings&);
|
||||
World& getWorld(WorldHandle);
|
||||
|
||||
void destroyWorld(WorldHandle);
|
||||
void destroyAllWorlds();
|
||||
|
||||
void flushDestroyedWorlds();
|
||||
} // namespace Universe
|
||||
} // namespace Deer
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Tools/Memory.h"
|
||||
#include "DeerCore/Tools/TypeDefs.h"
|
||||
#include "DeerCore/Universe.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
@ -33,7 +34,6 @@ namespace Deer {
|
||||
|
||||
class World {
|
||||
public:
|
||||
World(const WorldSettings&);
|
||||
~World();
|
||||
|
||||
void execute();
|
||||
@ -49,11 +49,14 @@ namespace Deer {
|
||||
void setRenderFrequency(int);
|
||||
#endif
|
||||
private:
|
||||
World(const WorldSettings&);
|
||||
|
||||
std::atomic<WorldState> executingState;
|
||||
WorldSettings worldSettings;
|
||||
|
||||
#ifdef DEER_RENDER
|
||||
float renderDeltaTime;
|
||||
#endif
|
||||
friend World* Universe::createWorld(const WorldSettings& worldSettings);
|
||||
}; // namespace World
|
||||
} // namespace Deer
|
||||
|
||||
@ -12,7 +12,7 @@ namespace Deer {
|
||||
unsigned int height;
|
||||
|
||||
WindowProps(const std::string& _title = "Deer Engine",
|
||||
unsigned int _width = 1280,
|
||||
unsigned int _width = 900,
|
||||
unsigned int _height = 720)
|
||||
: title(_title), width(_width), height(_height) {
|
||||
}
|
||||
|
||||
@ -1,30 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "DeerCore/Components.h"
|
||||
#include "DeerCore/EntityEnviroment.h"
|
||||
#include "DeerCore/World/Serialization/SerializationGlobalVars.h"
|
||||
|
||||
#include "EntitySerializationStruct.h"
|
||||
|
||||
namespace Deer {
|
||||
template <class Archive, typename T>
|
||||
void saveComponent(Archive& archive, const std::string& componentName, Entity const& m_entity) {
|
||||
void saveComponent(Archive& archive, Entity const& m_entity) {
|
||||
bool hasComponent = m_entity.hasComponent<T>();
|
||||
archive(cereal::make_nvp(("has_" + componentName).c_str(), hasComponent));
|
||||
archive(cereal::make_nvp(("contains_" + typedef(T).get_name()).c_str(), hasComponent));
|
||||
if (hasComponent) {
|
||||
const T& component = m_entity.getComponent<T>();
|
||||
archive(cereal::make_nvp(componentName.c_str(), component));
|
||||
archive(cereal::make_nvp(typedef(T).get_name(), component));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Archive, typename T>
|
||||
void loadComponent(Archive& archive, const std::string& componentName, Entity const& m_entity) {
|
||||
void loadComponent(Archive& archive, Entity const& m_entity) {
|
||||
bool hasComponent;
|
||||
archive(cereal::make_nvp(("has_" + componentName).c_str(), hasComponent));
|
||||
archive(cereal::make_nvp(("contains_" + typedef(T).get_name()).c_str(), hasComponent));
|
||||
if (hasComponent) {
|
||||
T& component = m_entity.addComponent<T>();
|
||||
archive(cereal::make_nvp(componentName.c_str(), component));
|
||||
archive(cereal::make_nvp(typedef(T).get_name(), component));
|
||||
}
|
||||
}
|
||||
|
||||
// ENTITY
|
||||
template <class Archive>
|
||||
void save(Archive& archive, EntitySerializationStruct const& m_entity) {
|
||||
@ -4,7 +4,7 @@
|
||||
namespace Deer {
|
||||
class EntityEnvironment;
|
||||
struct EntitySerializationStruct {
|
||||
uint16_t entityID;
|
||||
uint32_t entityID;
|
||||
EntityEnvironment* env;
|
||||
};
|
||||
} // namespace Deer
|
||||
9
Deer/src/DeerCore/Universe/Serialization/Settings.h
Normal file
9
Deer/src/DeerCore/Universe/Serialization/Settings.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
namespace Deer {
|
||||
namespace Serialization {
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
12
Deer/src/DeerCore/Universe/Serialization/World.h
Normal file
12
Deer/src/DeerCore/Universe/Serialization/World.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "DeerCore/World.h"
|
||||
#include "DeerCore/EntityEnviroment.h"
|
||||
|
||||
namespace Deer {
|
||||
namespace Universe {
|
||||
template <class Archive>
|
||||
void save(Archive& archive, World const& world) {
|
||||
World
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,82 +9,44 @@
|
||||
|
||||
namespace Deer {
|
||||
namespace Universe {
|
||||
struct WorldSlot {
|
||||
Scope<World> world = nullptr;
|
||||
uint32_t generation = 1;
|
||||
};
|
||||
|
||||
std::vector<WorldSlot> universeWorldSlots;
|
||||
std::vector<Scope<World>> universeWorlds;
|
||||
std::mutex universeMutex;
|
||||
|
||||
int getFreeWorldSlot();
|
||||
void unlockedFlushDestroyedWorlds();
|
||||
bool unlockedFlushDestroyedWorlds();
|
||||
} // namespace Universe
|
||||
|
||||
int Universe::getFreeWorldSlot() {
|
||||
for (int i = 0; i < universeWorldSlots.size(); i++) {
|
||||
if (universeWorldSlots[i].world == nullptr)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Universe::WorldHandle Universe::createWorld(const WorldSettings& worldSettings) {
|
||||
World* Universe::createWorld(const WorldSettings& worldSettings) {
|
||||
std::lock_guard<std::mutex> lock(universeMutex);
|
||||
unlockedFlushDestroyedWorlds();
|
||||
|
||||
int universeSlot = getFreeWorldSlot();
|
||||
if (universeSlot == -1) {
|
||||
universeSlot = universeWorldSlots.size();
|
||||
universeWorldSlots.push_back({});
|
||||
}
|
||||
|
||||
WorldSlot& worldSlot = universeWorldSlots[universeSlot];
|
||||
worldSlot.world = MakeScope<World>(worldSettings);
|
||||
|
||||
return WorldHandle(universeSlot, worldSlot.generation);
|
||||
}
|
||||
|
||||
World& Universe::getWorld(WorldHandle handle) {
|
||||
std::lock_guard<std::mutex> lock(universeMutex);
|
||||
|
||||
DEER_CORE_ASSERT(handle.worldId < universeWorldSlots.size(), "Invalid world handle");
|
||||
DEER_CORE_ASSERT(handle.generation == universeWorldSlots[handle.worldId].generation, "Invalid world generation");
|
||||
DEER_CORE_ASSERT(universeWorldSlots[handle.worldId].world, "World no longer exists");
|
||||
|
||||
return *universeWorldSlots[handle.worldId].world;
|
||||
}
|
||||
|
||||
void Universe::destroyWorld(WorldHandle handle) {
|
||||
std::lock_guard<std::mutex> lock(universeMutex);
|
||||
|
||||
DEER_CORE_ASSERT(handle.worldId < universeWorldSlots.size(), "Invalid world handle");
|
||||
DEER_CORE_ASSERT(handle.generation == universeWorldSlots[handle.worldId].generation, "Invalid world generation");
|
||||
DEER_CORE_ASSERT(universeWorldSlots[handle.worldId].world, "World no longer exists");
|
||||
|
||||
universeWorldSlots[handle.worldId].world->destroy();
|
||||
unlockedFlushDestroyedWorlds();
|
||||
while (unlockedFlushDestroyedWorlds());;
|
||||
|
||||
universeWorlds.push_back(Scope<World>(new World(worldSettings)));
|
||||
return universeWorlds.back().get();
|
||||
}
|
||||
|
||||
void Universe::destroyAllWorlds() {
|
||||
std::lock_guard<std::mutex> lock(universeMutex);
|
||||
for (WorldSlot& slot : universeWorldSlots)
|
||||
slot.world->destroy();
|
||||
unlockedFlushDestroyedWorlds();
|
||||
for (Scope<World>& world : universeWorlds)
|
||||
world->destroy();
|
||||
while (unlockedFlushDestroyedWorlds());;
|
||||
}
|
||||
|
||||
void Universe::unlockedFlushDestroyedWorlds() {
|
||||
for (WorldSlot& slot : universeWorldSlots) {
|
||||
if (slot.world != nullptr && slot.world->getExecutionState() == WorldState::ReadyToDestroy) {
|
||||
slot.world.release();
|
||||
slot.world = nullptr;
|
||||
slot.generation++;
|
||||
bool Universe::unlockedFlushDestroyedWorlds() {
|
||||
for (size_t i = 0; i < universeWorlds.size(); i++) {
|
||||
Scope<World>& world = universeWorlds[i];
|
||||
if (world->getExecutionState() == WorldState::ReadyToDestroy) {
|
||||
world.reset();
|
||||
world = Scope<World>(universeWorlds.back().release());
|
||||
universeWorlds.back() = nullptr;
|
||||
universeWorlds.pop_back();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Universe::flushDestroyedWorlds() {
|
||||
std::lock_guard<std::mutex> lock(universeMutex);
|
||||
unlockedFlushDestroyedWorlds();
|
||||
while (unlockedFlushDestroyedWorlds());;
|
||||
}
|
||||
} // namespace Deer
|
||||
12
Deer/src/DeerCore/Universe/UniverseSerialization.cpp
Normal file
12
Deer/src/DeerCore/Universe/UniverseSerialization.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "DeerCore/Universe.h"
|
||||
#include "DeerCore/World.h"
|
||||
#include "DeerCore/Log.h"
|
||||
|
||||
#include "cereal/cereal.hpp"
|
||||
#include "cereal/archives/json.hpp"
|
||||
|
||||
namespace Deer {
|
||||
|
||||
|
||||
|
||||
} // namespace Deer
|
||||
@ -9,6 +9,15 @@
|
||||
#include "scriptarray.h"
|
||||
#include "scriptstdstring.h"
|
||||
|
||||
#include "DeerRender/Shader.h"
|
||||
#include "DeerRender/Mesh.h"
|
||||
#include "DeerRender/Render/Render.h"
|
||||
#include "DeerRender/Render/RenderUtils.h"
|
||||
#include "DeerRender/Components.h"
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
#include "glm/matrix.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Deer {
|
||||
@ -89,6 +98,7 @@ namespace Deer {
|
||||
}
|
||||
void frameBuffer_clearRGBA(int r, int g, int b, int a, Resource<FrameBuffer>& frameBuffer) {
|
||||
int data[] = {r, g, b, a};
|
||||
frameBuffer.getData().clear();
|
||||
frameBuffer.getData().clearBuffer(0, data);
|
||||
}
|
||||
bool frameBuffer_isValid(Resource<FrameBuffer>& frameBuffer) {
|
||||
@ -97,5 +107,26 @@ namespace Deer {
|
||||
void frameBuffer_resize(int x, int y, Resource<FrameBuffer>& frameBuffer) {
|
||||
frameBuffer.getData().resize(x, y);
|
||||
}
|
||||
void frameBuffer_drawMesh(Resource<GPUMesh> mesh, Resource<Shader> shaderResource, TransformComponent transform, WorldCamera camera, Resource<FrameBuffer>& frameBuffer) {
|
||||
frameBuffer.getData().bind();
|
||||
|
||||
glm::mat4 camMatrix = glm::inverse(camera.transform.getMatrix());
|
||||
glm::mat4 projectionMatrix = camera.camera.getMatrix();
|
||||
glm::mat4 invertZ = glm::scale(glm::mat4(1.0f), glm::vec3(1, 1, -1));
|
||||
|
||||
// Lets invert the z axis for engine convenience
|
||||
glm::mat4 cameraProjectionMatrix = projectionMatrix * invertZ * camMatrix;
|
||||
glm::mat4 matrix = transform.getMatrix();
|
||||
|
||||
Shader& shader = shaderResource.getData();
|
||||
|
||||
shader.bind();
|
||||
shader.uploadUniformMat4("u_viewMatrix", cameraProjectionMatrix);
|
||||
shader.uploadUniformMat4("u_worldMatrix", matrix);
|
||||
|
||||
mesh.getData().vertexArray->bind();
|
||||
Render::submit(*mesh.getData().vertexArray);
|
||||
frameBuffer.getData().unbind();
|
||||
}
|
||||
} // namespace Scripting
|
||||
} // namespace Deer
|
||||
@ -1,16 +1,16 @@
|
||||
#pragma once
|
||||
#include "DeerRender/Resource.h"
|
||||
#include "DeerRender/World.h"
|
||||
#include "scriptarray.h"
|
||||
#include "scriptdictionary.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#include "DeerRender/Resource.h"
|
||||
|
||||
namespace Deer {
|
||||
class FrameBuffer;
|
||||
class GPUMesh;
|
||||
class Shader;
|
||||
|
||||
namespace Scripting {
|
||||
template <typename T>
|
||||
@ -47,6 +47,8 @@ namespace Deer {
|
||||
void frameBuffer_clearRGBA(int, int, int, int, Resource<FrameBuffer>&);
|
||||
bool frameBuffer_isValid(Resource<FrameBuffer>&);
|
||||
void frameBuffer_resize(int, int, Resource<FrameBuffer>&);
|
||||
void frameBuffer_drawMesh(Resource<GPUMesh>, Resource<Shader>, TransformComponent, WorldCamera, Resource<FrameBuffer>&);
|
||||
|
||||
Resource<FrameBuffer> createFrameBuffer(std::string& name, int sixeX, int sizeY);
|
||||
} // namespace Scripting
|
||||
} // namespace Deer
|
||||
@ -32,12 +32,9 @@ namespace Deer {
|
||||
AS_CHECK(scriptEngine->RegisterObjectType("Texture", sizeof(Resource<Texture>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<Texture>>()));
|
||||
AS_CHECK(scriptEngine->RegisterObjectType("FrameBuffer", sizeof(Resource<FrameBuffer>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<FrameBuffer>>()));
|
||||
}
|
||||
int frameBuffer_getWidth(Resource<FrameBuffer>&);
|
||||
int frameBuffer_getHeight(Resource<FrameBuffer>&);
|
||||
void frameBuffer_clearRGBA(int, int, int, int, Resource<FrameBuffer>&);
|
||||
bool frameBuffer_isValid(Resource<FrameBuffer>&);
|
||||
void frameBuffer_resize(int, int, Resource<FrameBuffer>&);
|
||||
|
||||
|
||||
|
||||
Resource<FrameBuffer> createFrameBuffer(const std::string name, int sixeX, int sizeY);
|
||||
|
||||
void Scripting::registerResourceFunctions() {
|
||||
@ -46,6 +43,7 @@ namespace Deer {
|
||||
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "bool isValid()", frameBuffer_isValid);
|
||||
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "void resize(int, int)", frameBuffer_resize);
|
||||
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "void clearRGBA(int, int, int, int)", frameBuffer_clearRGBA);
|
||||
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "void drawMesh(GPUMesh, Shader, Transform, WorldCamera)", frameBuffer_drawMesh);
|
||||
|
||||
scriptEngine->SetDefaultNamespace("Resource");
|
||||
REGISTER_GLOBAL_FUNC(scriptEngine, "FrameBuffer createFrameBuffer(string&in name, int sizeX, int sizeY)", createFrameBuffer);
|
||||
|
||||
@ -1,89 +0,0 @@
|
||||
[Window][DockSpace Demo]
|
||||
Pos=0,0
|
||||
Size=2560,1371
|
||||
Collapsed=0
|
||||
|
||||
[Window][Debug##Default]
|
||||
Pos=60,60
|
||||
Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Terrain Editor]
|
||||
Pos=925,24
|
||||
Size=355,434
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
[Window][Viewport]
|
||||
Pos=369,24
|
||||
Size=554,434
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
[Window][ViewportPanel]
|
||||
Pos=389,28
|
||||
Size=1689,1008
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
[Window][ShaderExplorer]
|
||||
Pos=0,413
|
||||
Size=1280,307
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
[Window][TreePanel]
|
||||
Pos=0,28
|
||||
Size=387,1008
|
||||
Collapsed=0
|
||||
DockId=0x00000001,0
|
||||
|
||||
[Window][MeshExplorer]
|
||||
Pos=0,439
|
||||
Size=1280,281
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
[Window][PropertiesPanel]
|
||||
Pos=2080,28
|
||||
Size=480,1008
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][CameraPanel]
|
||||
Pos=265,24
|
||||
Size=702,477
|
||||
Collapsed=0
|
||||
DockId=0x00000005,1
|
||||
|
||||
[Window][MU]
|
||||
Pos=60,60
|
||||
Size=40,64
|
||||
Collapsed=0
|
||||
|
||||
[Window][Rename entity]
|
||||
Pos=398,235
|
||||
Size=643,74
|
||||
Collapsed=0
|
||||
|
||||
[Window][Test]
|
||||
Pos=423,24
|
||||
Size=1682,1012
|
||||
Collapsed=0
|
||||
DockId=0x00000005,2
|
||||
|
||||
[Window][AssetExplorer]
|
||||
Pos=0,1038
|
||||
Size=2560,333
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,28 Size=2560,1343 Split=Y Selected=0x34A4C10F
|
||||
DockNode ID=0x00000003 Parent=0xA1672E74 SizeRef=1280,1008 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=387,696 Selected=0xE45B9F93
|
||||
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=2171,696 Split=X Selected=0x34A4C10F
|
||||
DockNode ID=0x00000005 Parent=0x00000002 SizeRef=1689,1078 CentralNode=1 Selected=0x34A4C10F
|
||||
DockNode ID=0x00000006 Parent=0x00000002 SizeRef=480,1078 Selected=0xA35A27E3
|
||||
DockNode ID=0x00000004 Parent=0xA1672E74 SizeRef=1280,333 Selected=0x21191D0B
|
||||
|
||||
32
Editor/Scripts/Previewer/Previewer.as
Normal file
32
Editor/Scripts/Previewer/Previewer.as
Normal file
@ -0,0 +1,32 @@
|
||||
namespace Previewer {
|
||||
FrameBuffer getMeshPreview(GPUMesh mesh) {
|
||||
FrameBuffer frame = Resource::createFrameBuffer(mesh.path, 128, 128);
|
||||
frame.clearRGBA(0, 0, 0, 255);
|
||||
|
||||
WorldCamera wcamera;
|
||||
wcamera.transform.position = vec3(0, 1, -3.5);
|
||||
|
||||
Transform transform;
|
||||
transform.rotation.setEuler(vec3(0, 135, 0));
|
||||
|
||||
Shader shader = Builtin::simpleShader();
|
||||
|
||||
frame.drawMesh(mesh, shader, transform, wcamera);
|
||||
return frame;
|
||||
}
|
||||
|
||||
FrameBuffer getShaderPreview(Shader shader) {
|
||||
FrameBuffer frame = Resource::createFrameBuffer(shader.path, 128, 128);
|
||||
frame.clearRGBA(0, 0, 0, 0);
|
||||
|
||||
WorldCamera wcamera;
|
||||
wcamera.transform.rotation.setEuler(vec3(0, 0, 0));
|
||||
wcamera.transform.position = vec3(0, 0, -1.55);
|
||||
|
||||
Transform transform;
|
||||
GPUMesh mesh = Builtin::sphere();
|
||||
|
||||
frame.drawMesh(mesh, shader, transform, wcamera);
|
||||
return frame;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,73 @@
|
||||
bool allowRender = false;
|
||||
|
||||
class MeshResource {
|
||||
string displayName;
|
||||
string path;
|
||||
GPUMesh meshResource;
|
||||
FrameBuffer frameBuffer;
|
||||
|
||||
bool loaded = false;
|
||||
|
||||
MeshResource(string _meshPath) {
|
||||
path = _meshPath;
|
||||
}
|
||||
|
||||
void render() {
|
||||
if (!loaded) {
|
||||
if (allowRender) {
|
||||
meshResource = StudioAPI::loadGPUMesh(path);
|
||||
frameBuffer = Previewer::getMeshPreview(meshResource);
|
||||
displayName = meshResource.name;
|
||||
allowRender = false;
|
||||
loaded = true;
|
||||
} else {
|
||||
ImGui::text("Loading");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::cartIconButton(displayName, frameBuffer, 128, ImGui::getAvailableSizeX());
|
||||
ImGui::dragDropSource("MESH", any(meshResource), displayName);
|
||||
}
|
||||
}
|
||||
|
||||
class ShaderResource {
|
||||
string displayName;
|
||||
string path;
|
||||
Shader shaderResource;
|
||||
FrameBuffer frameBuffer;
|
||||
|
||||
bool loaded = false;
|
||||
|
||||
ShaderResource(string _path) {
|
||||
path = _path;
|
||||
}
|
||||
|
||||
void render() {
|
||||
if (!loaded) {
|
||||
if (allowRender) {
|
||||
shaderResource = StudioAPI::loadShader(path);
|
||||
frameBuffer = Previewer::getShaderPreview(shaderResource);
|
||||
displayName = shaderResource.name;
|
||||
allowRender = false;
|
||||
loaded = true;
|
||||
} else {
|
||||
ImGui::text("Loading");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::cartIconButton(displayName, frameBuffer, 128, ImGui::getAvailableSizeX());
|
||||
ImGui::dragDropSource("SHADER", any(shaderResource), displayName);
|
||||
}
|
||||
}
|
||||
|
||||
class ResourceExplorer : Panel {
|
||||
string selectedResource = "";
|
||||
string currentPath = "";
|
||||
array<string> subFolders;
|
||||
array<MeshResource@> meshes;
|
||||
array<ShaderResource@> shaders;
|
||||
array<string> subFiles;
|
||||
bool alreadyRendered = false;
|
||||
float fase = 0;
|
||||
@ -9,7 +75,6 @@ class ResourceExplorer : Panel {
|
||||
dictionary meshFrameBuffer;
|
||||
|
||||
void onInit() {
|
||||
print("hy");
|
||||
setPath("");
|
||||
}
|
||||
|
||||
@ -18,11 +83,23 @@ class ResourceExplorer : Panel {
|
||||
currentPath = path;
|
||||
subFolders = StudioAPI::getResourceFolders(path);
|
||||
subFiles = StudioAPI::getResourceFiles(path);
|
||||
fase = 0;
|
||||
meshes = array<MeshResource@>(0);
|
||||
shaders = array<ShaderResource@>(0);
|
||||
|
||||
for ( uint i = 0; i < subFiles.length(); i++) {
|
||||
ResourceType resType = StudioAPI::getResourceType(subFiles[i]);
|
||||
if (resType == ResourceType::Mesh) {
|
||||
MeshResource@ meshRes = @MeshResource(subFiles[i]);
|
||||
meshes.insertLast(@meshRes);
|
||||
}
|
||||
if (resType == ResourceType::Shader) {
|
||||
ShaderResource@ shaderRes = @ShaderResource(subFiles[i]);
|
||||
shaders.insertLast(@shaderRes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onImGui() {
|
||||
alreadyRendered = false;
|
||||
renderMenuBar();
|
||||
ImGui::space();
|
||||
fase += 0.3;
|
||||
@ -39,36 +116,27 @@ class ResourceExplorer : Panel {
|
||||
ImGui::nextColumn();
|
||||
}
|
||||
|
||||
for ( uint i = 0; i < subFiles.length(); i++) {
|
||||
drawResource(subFiles[i]);
|
||||
allowRender = true;
|
||||
for ( uint i = 0; i < meshes.length(); i++) {
|
||||
meshes[i].render();
|
||||
ImGui::nextColumn();
|
||||
}
|
||||
for ( uint i = 0; i < shaders.length(); i++) {
|
||||
shaders[i].render();
|
||||
ImGui::nextColumn();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void drawResource(string&in filename) {
|
||||
ResourceType resType = StudioAPI::getResourceType(filename);
|
||||
bool selected = filename == selectedResource;
|
||||
|
||||
if (resType == ResourceType::Mesh) {
|
||||
FrameBuffer frameBuffer;
|
||||
GPUMesh mesh = StudioAPI::loadGPUMesh(filename);
|
||||
//frameBuffer = Previewer::renderMeshPreview_fase(mesh, fase);
|
||||
meshFrameBuffer[filename] = frameBuffer;
|
||||
alreadyRendered = true;
|
||||
|
||||
Texture mesTexture = StudioAPI::loadIcon("mesh.png");
|
||||
if (ImGui::cartIconButton(Path::getName(filename), mesTexture, 128, ImGui::getAvailableSizeX())) {
|
||||
selectedResource = filename;
|
||||
}
|
||||
|
||||
ImGui::dragDropSource("MESH", any(mesh), filename);
|
||||
ImGui::nextColumn();
|
||||
return;
|
||||
}
|
||||
|
||||
if (resType == ResourceType::Shader) {
|
||||
Texture shaderTexture = StudioAPI::loadIcon("shader.png");
|
||||
Shader shader = StudioAPI::loadShader(filename);
|
||||
if (ImGui::cartIconButton(Path::getName(filename), shaderTexture, 128, ImGui::getAvailableSizeX())) {
|
||||
FrameBuffer frame = Previewer::getShaderPreview(shader);
|
||||
if (ImGui::cartIconButton(Path::getName(filename), frame, 128, ImGui::getAvailableSizeX())) {
|
||||
selectedResource = filename;
|
||||
}
|
||||
ImGui::dragDropSource("SHADER", any(shader), filename);
|
||||
@ -92,7 +160,7 @@ class ResourceExplorer : Panel {
|
||||
}
|
||||
|
||||
void renderMenuBar() {
|
||||
// If we select that path
|
||||
// If we select that path
|
||||
if (ImGui::button("Resources")) {
|
||||
setPath("");
|
||||
}
|
||||
|
||||
@ -184,6 +184,10 @@ class TreePanel : Panel {
|
||||
}
|
||||
|
||||
void onMenuBar() {
|
||||
if (!(rootNode is null)) {
|
||||
ImGui::subMenu("Entiy", SimpleFunction(rootNode.renderContextMenu));
|
||||
}
|
||||
|
||||
if (ImGui::menuItem("Refresh")) {
|
||||
infoChanged = true;
|
||||
networkBehaviourFilter = EntityNetworkBehaviour::Parent;
|
||||
|
||||
@ -30,14 +30,14 @@ class ViewportPanel : Panel {
|
||||
if (!ImGui::isPanelActive())
|
||||
return;
|
||||
|
||||
if (ImGui::isMouseDragging(key::MouseRight) && !ImGui::isKeyDown(key::MouseMiddle)) {
|
||||
if (ImGui::isMouseDragging(key::MouseLeft) && !ImGui::isKeyDown(key::MouseMiddle)) {
|
||||
pitch += ImGui::getMouseDeltaY() * 0.1;
|
||||
yaw += ImGui::getMouseDeltaX() * 0.1;
|
||||
|
||||
sceneCamera.transform.rotation.setEuler(vec3(pitch, yaw, 0));
|
||||
}
|
||||
|
||||
if (ImGui::isMouseDragging(key::MouseMiddle) && !ImGui::isKeyDown(key::MouseRight)) {
|
||||
if (ImGui::isMouseDragging(key::MouseMiddle) && !ImGui::isKeyDown(key::MouseLeft)) {
|
||||
vec3 panDir = vec3();
|
||||
|
||||
panDir.x -= ImGui::getMouseDeltaX();
|
||||
|
||||
83
Resources/shader_blue.glsl
Normal file
83
Resources/shader_blue.glsl
Normal file
@ -0,0 +1,83 @@
|
||||
#type vertex
|
||||
#version 410 core
|
||||
|
||||
// Vertex attributes
|
||||
layout(location = 0) in vec3 v_position;
|
||||
layout(location = 1) in vec3 v_normal;
|
||||
layout(location = 2) in vec2 v_UV;
|
||||
|
||||
// Outputs to fragment shader
|
||||
out vec3 normalWS;
|
||||
out vec3 normalVS;
|
||||
out vec3 positionVS;
|
||||
|
||||
// Uniforms
|
||||
uniform mat4 u_worldMatrix;
|
||||
uniform mat4 u_viewMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_viewMatrix * u_worldMatrix * vec4(v_position, 1.0);
|
||||
positionVS = gl_Position.xyz;
|
||||
|
||||
mat3 normalMatrix = transpose(inverse(mat3(u_worldMatrix)));
|
||||
normalWS = normalize(normalMatrix * v_normal);
|
||||
|
||||
mat3 normalMatrixView = transpose(inverse(mat3(u_viewMatrix * u_worldMatrix)));
|
||||
normalVS = normalize(normalMatrixView * v_normal);
|
||||
|
||||
}
|
||||
|
||||
#type fragment
|
||||
#version 410 core
|
||||
|
||||
// Fragment outputs
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
layout(location = 1) out int objectID;
|
||||
|
||||
// Inputs from vertex shader
|
||||
in vec3 normalWS;
|
||||
in vec3 normalVS;
|
||||
in vec3 positionVS;
|
||||
|
||||
// Uniforms
|
||||
uniform int u_objectID;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Directional light
|
||||
vec3 lightDir = normalize(vec3(1.0, 7.0, 3.0));
|
||||
|
||||
// Base light intensity
|
||||
float light = clamp(dot(normalWS, lightDir) * 0.8 + 0.2, 0.0, 1.0);
|
||||
|
||||
// Gradient from purple (dark) to cyan (lit)
|
||||
vec3 gradientColor = mix(
|
||||
vec3(0.7137, 0.4471, 0.9412),
|
||||
vec3(0.5255, 0.9725, 1.0),
|
||||
light
|
||||
);
|
||||
|
||||
// Rim/fresnel effect
|
||||
float rim = 0.5 - dot(normalWS, normalize(lightDir)) * 0.5;
|
||||
float rimValue = rim * rim * rim * rim;
|
||||
vec3 rimColor = vec3(1.0, 0.8, 0.5) * (rim * rim * rim * rim);
|
||||
|
||||
vec3 mixedColor = mix(
|
||||
gradientColor,
|
||||
vec3(1, 1, 1) ,
|
||||
rimValue
|
||||
);
|
||||
|
||||
//float fresnel = dot(, vec3(0, 0, -1));
|
||||
//fresnel = fresnel * fresnel;
|
||||
|
||||
float fresnel = 1 + dot(normalize(positionVS), normalize(normalVS));
|
||||
fresnel = fresnel * fresnel * fresnel * fresnel;
|
||||
|
||||
// Combine everything
|
||||
fragColor = vec4(mixedColor + vec3(fresnel, fresnel, fresnel), 1.0);
|
||||
|
||||
// Object ID output
|
||||
objectID = u_objectID;
|
||||
}
|
||||
83
Resources/shader_darkBlue.glsl
Normal file
83
Resources/shader_darkBlue.glsl
Normal file
@ -0,0 +1,83 @@
|
||||
#type vertex
|
||||
#version 410 core
|
||||
|
||||
// Vertex attributes
|
||||
layout(location = 0) in vec3 v_position;
|
||||
layout(location = 1) in vec3 v_normal;
|
||||
layout(location = 2) in vec2 v_UV;
|
||||
|
||||
// Outputs to fragment shader
|
||||
out vec3 normalWS;
|
||||
out vec3 normalVS;
|
||||
out vec3 positionVS;
|
||||
|
||||
// Uniforms
|
||||
uniform mat4 u_worldMatrix;
|
||||
uniform mat4 u_viewMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_viewMatrix * u_worldMatrix * vec4(v_position, 1.0);
|
||||
positionVS = gl_Position.xyz;
|
||||
|
||||
mat3 normalMatrix = transpose(inverse(mat3(u_worldMatrix)));
|
||||
normalWS = normalize(normalMatrix * v_normal);
|
||||
|
||||
mat3 normalMatrixView = transpose(inverse(mat3(u_viewMatrix * u_worldMatrix)));
|
||||
normalVS = normalize(normalMatrixView * v_normal);
|
||||
|
||||
}
|
||||
|
||||
#type fragment
|
||||
#version 410 core
|
||||
|
||||
// Fragment outputs
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
layout(location = 1) out int objectID;
|
||||
|
||||
// Inputs from vertex shader
|
||||
in vec3 normalWS;
|
||||
in vec3 normalVS;
|
||||
in vec3 positionVS;
|
||||
|
||||
// Uniforms
|
||||
uniform int u_objectID;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Directional light
|
||||
vec3 lightDir = normalize(vec3(1.0, 7.0, 3.0));
|
||||
|
||||
// Base light intensity
|
||||
float light = clamp(dot(normalWS, lightDir) * 0.8 + 0.2, 0.0, 1.0);
|
||||
|
||||
// Gradient from purple (dark) to cyan (lit)
|
||||
vec3 gradientColor = mix(
|
||||
vec3(0.3137, 0.2471, 0.5412),
|
||||
vec3(0.5255, 0.9725, 1.0),
|
||||
light
|
||||
);
|
||||
|
||||
// Rim/fresnel effect
|
||||
float rim = 0.5 - dot(normalWS, normalize(lightDir)) * 0.5;
|
||||
float rimValue = rim * rim * rim * rim;
|
||||
vec3 rimColor = vec3(1.0, 0.8, 0.5) * (rim * rim * rim * rim);
|
||||
|
||||
vec3 mixedColor = mix(
|
||||
gradientColor,
|
||||
vec3(1, 1, 1) ,
|
||||
rimValue
|
||||
);
|
||||
|
||||
//float fresnel = dot(, vec3(0, 0, -1));
|
||||
//fresnel = fresnel * fresnel;
|
||||
|
||||
float fresnel = 1 + dot(normalize(positionVS), normalize(normalVS));
|
||||
fresnel = fresnel * fresnel * fresnel * fresnel;
|
||||
|
||||
// Combine everything
|
||||
fragColor = vec4(mixedColor + vec3(fresnel, fresnel, fresnel), 1.0);
|
||||
|
||||
// Object ID output
|
||||
objectID = u_objectID;
|
||||
}
|
||||
72
imgui.ini
72
imgui.ini
@ -1,6 +1,6 @@
|
||||
[Window][DockSpace Demo]
|
||||
Pos=0,0
|
||||
Size=2560,1371
|
||||
Size=1920,1011
|
||||
Collapsed=0
|
||||
|
||||
[Window][Debug##Default]
|
||||
@ -8,66 +8,36 @@ Pos=60,60
|
||||
Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][TreePanel]
|
||||
Pos=0,26
|
||||
Size=569,925
|
||||
[Window][ViewportPanel]
|
||||
Pos=561,26
|
||||
Size=934,493
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
[Window][PropertiesPanel]
|
||||
Pos=1872,26
|
||||
Size=688,925
|
||||
Collapsed=0
|
||||
DockId=0x00000002,0
|
||||
|
||||
[Window][ResourceExplorer]
|
||||
Pos=0,953
|
||||
Size=2560,418
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
[Window][ViewportPanel]
|
||||
Pos=571,26
|
||||
Size=1299,925
|
||||
Pos=1497,26
|
||||
Size=423,493
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Rename entity]
|
||||
Pos=848,548
|
||||
Size=306,133
|
||||
[Window][ResourceExplorer]
|
||||
Pos=0,521
|
||||
Size=1920,490
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
[Window][RENAME_ENTITY_1]
|
||||
Pos=755,542
|
||||
Size=380,90
|
||||
[Window][TreePanel]
|
||||
Pos=0,26
|
||||
Size=559,493
|
||||
Collapsed=0
|
||||
|
||||
[Window][Dear ImGui Demo]
|
||||
Pos=571,26
|
||||
Size=1299,925
|
||||
Collapsed=0
|
||||
DockId=0x00000006,1
|
||||
|
||||
[Window][Dear ImGui Demo/ResizableChild_478B81A3]
|
||||
IsChild=1
|
||||
Size=1167,176
|
||||
|
||||
[Window][Dear ImGui Demo/Red_BEEF922B]
|
||||
IsChild=1
|
||||
Size=200,100
|
||||
|
||||
[Window][Dear ImGui Style Editor]
|
||||
Pos=544,26
|
||||
Size=1262,926
|
||||
Collapsed=0
|
||||
DockId=0x00000006,2
|
||||
DockId=0x00000001,0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x0AC2E849 Window=0xD0388BC8 Pos=0,26 Size=2560,1345 Split=Y Selected=0x16E3C1E7
|
||||
DockNode ID=0x00000003 Parent=0x0AC2E849 SizeRef=2560,926 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=1230,1336 Split=X Selected=0x16E3C1E7
|
||||
DockNode ID=0x00000005 Parent=0x00000001 SizeRef=569,572 CentralNode=1 Selected=0x16E3C1E7
|
||||
DockNode ID=0x00000006 Parent=0x00000001 SizeRef=1299,572 Selected=0x0F5FFC8C
|
||||
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=688,1336 Selected=0x9876A79B
|
||||
DockNode ID=0x00000004 Parent=0x0AC2E849 SizeRef=2560,418 Selected=0x018A0F9B
|
||||
DockSpace ID=0x0AC2E849 Window=0xD0388BC8 Pos=0,26 Size=1920,985 Split=Y
|
||||
DockNode ID=0x00000003 Parent=0x0AC2E849 SizeRef=1920,493 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=559,985 Selected=0x16E3C1E7
|
||||
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=1359,985 Split=X
|
||||
DockNode ID=0x00000005 Parent=0x00000002 SizeRef=934,493 CentralNode=1 Selected=0x0F5FFC8C
|
||||
DockNode ID=0x00000006 Parent=0x00000002 SizeRef=423,493 Selected=0x9876A79B
|
||||
DockNode ID=0x00000004 Parent=0x0AC2E849 SizeRef=1920,490 Selected=0x018A0F9B
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user