diff --git a/Deer/Include/DeerCore/Universe.h b/Deer/Include/DeerCore/Universe.h index 8274558..7ab53f9 100644 --- a/Deer/Include/DeerCore/Universe.h +++ b/Deer/Include/DeerCore/Universe.h @@ -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 \ No newline at end of file diff --git a/Deer/Include/DeerCore/World.h b/Deer/Include/DeerCore/World.h index e4fa4ba..bd93b68 100755 --- a/Deer/Include/DeerCore/World.h +++ b/Deer/Include/DeerCore/World.h @@ -1,6 +1,7 @@ #pragma once #include "DeerCore/Tools/Memory.h" #include "DeerCore/Tools/TypeDefs.h" +#include "DeerCore/Universe.h" #include #include @@ -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 executingState; WorldSettings worldSettings; #ifdef DEER_RENDER float renderDeltaTime; #endif + friend World* Universe::createWorld(const WorldSettings& worldSettings); }; // namespace World } // namespace Deer diff --git a/Deer/Include/DeerRender/Window.h b/Deer/Include/DeerRender/Window.h index f794666..e2db1db 100755 --- a/Deer/Include/DeerRender/Window.h +++ b/Deer/Include/DeerRender/Window.h @@ -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) { } diff --git a/Deer/src/DeerCore/World/Serialization/Components/RelationshipComponentSerialization.h b/Deer/src/DeerCore/Universe/Serialization/Components/RelationshipComponentSerialization.h similarity index 100% rename from Deer/src/DeerCore/World/Serialization/Components/RelationshipComponentSerialization.h rename to Deer/src/DeerCore/Universe/Serialization/Components/RelationshipComponentSerialization.h diff --git a/Deer/src/DeerCore/World/Serialization/Components/TransformComponentSerialization.h b/Deer/src/DeerCore/Universe/Serialization/Components/TransformComponentSerialization.h similarity index 100% rename from Deer/src/DeerCore/World/Serialization/Components/TransformComponentSerialization.h rename to Deer/src/DeerCore/Universe/Serialization/Components/TransformComponentSerialization.h diff --git a/Deer/src/DeerCore/World/Serialization/QuatSerialization.h b/Deer/src/DeerCore/Universe/Serialization/Core/QuatSerialization.h similarity index 100% rename from Deer/src/DeerCore/World/Serialization/QuatSerialization.h rename to Deer/src/DeerCore/Universe/Serialization/Core/QuatSerialization.h diff --git a/Deer/src/DeerCore/World/Serialization/Vec3Serialization.h b/Deer/src/DeerCore/Universe/Serialization/Core/Vec3Serialization.h similarity index 100% rename from Deer/src/DeerCore/World/Serialization/Vec3Serialization.h rename to Deer/src/DeerCore/Universe/Serialization/Core/Vec3Serialization.h diff --git a/Deer/src/DeerCore/World/Serialization/EntitySerialization.h b/Deer/src/DeerCore/Universe/Serialization/Entity/EntitySerialization.h similarity index 79% rename from Deer/src/DeerCore/World/Serialization/EntitySerialization.h rename to Deer/src/DeerCore/Universe/Serialization/Entity/EntitySerialization.h index d1844f4..47a89e0 100755 --- a/Deer/src/DeerCore/World/Serialization/EntitySerialization.h +++ b/Deer/src/DeerCore/Universe/Serialization/Entity/EntitySerialization.h @@ -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 - 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(); - 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(); - archive(cereal::make_nvp(componentName.c_str(), component)); + archive(cereal::make_nvp(typedef(T).get_name(), component)); } } template - 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(); - archive(cereal::make_nvp(componentName.c_str(), component)); + archive(cereal::make_nvp(typedef(T).get_name(), component)); } } + // ENTITY template void save(Archive& archive, EntitySerializationStruct const& m_entity) { diff --git a/Deer/src/DeerCore/World/Serialization/EntitySerializationStruct.h b/Deer/src/DeerCore/Universe/Serialization/Entity/EntitySerializationStruct.h similarity index 88% rename from Deer/src/DeerCore/World/Serialization/EntitySerializationStruct.h rename to Deer/src/DeerCore/Universe/Serialization/Entity/EntitySerializationStruct.h index a413323..841d1d7 100644 --- a/Deer/src/DeerCore/World/Serialization/EntitySerializationStruct.h +++ b/Deer/src/DeerCore/Universe/Serialization/Entity/EntitySerializationStruct.h @@ -4,7 +4,7 @@ namespace Deer { class EntityEnvironment; struct EntitySerializationStruct { - uint16_t entityID; + uint32_t entityID; EntityEnvironment* env; }; } // namespace Deer \ No newline at end of file diff --git a/Deer/src/DeerCore/World/Serialization/EnvironmentSerialization.h b/Deer/src/DeerCore/Universe/Serialization/EnvironmentSerialization.h similarity index 100% rename from Deer/src/DeerCore/World/Serialization/EnvironmentSerialization.h rename to Deer/src/DeerCore/Universe/Serialization/EnvironmentSerialization.h diff --git a/Deer/src/DeerCore/World/Serialization/Serialization.cpp b/Deer/src/DeerCore/Universe/Serialization/Serialization.cpp similarity index 100% rename from Deer/src/DeerCore/World/Serialization/Serialization.cpp rename to Deer/src/DeerCore/Universe/Serialization/Serialization.cpp diff --git a/Deer/src/DeerCore/World/Serialization/Serialization.h b/Deer/src/DeerCore/Universe/Serialization/Serialization.h similarity index 100% rename from Deer/src/DeerCore/World/Serialization/Serialization.h rename to Deer/src/DeerCore/Universe/Serialization/Serialization.h diff --git a/Deer/src/DeerCore/World/Serialization/SerializationGlobalVars.cpp b/Deer/src/DeerCore/Universe/Serialization/SerializationGlobalVars.cpp similarity index 100% rename from Deer/src/DeerCore/World/Serialization/SerializationGlobalVars.cpp rename to Deer/src/DeerCore/Universe/Serialization/SerializationGlobalVars.cpp diff --git a/Deer/src/DeerCore/World/Serialization/SerializationGlobalVars.h b/Deer/src/DeerCore/Universe/Serialization/SerializationGlobalVars.h similarity index 100% rename from Deer/src/DeerCore/World/Serialization/SerializationGlobalVars.h rename to Deer/src/DeerCore/Universe/Serialization/SerializationGlobalVars.h diff --git a/Deer/src/DeerCore/Universe/Serialization/Settings.h b/Deer/src/DeerCore/Universe/Serialization/Settings.h new file mode 100644 index 0000000..0b6bbf1 --- /dev/null +++ b/Deer/src/DeerCore/Universe/Serialization/Settings.h @@ -0,0 +1,9 @@ +#pragma once + +namespace Deer { + namespace Serialization { + + + + } +} \ No newline at end of file diff --git a/Deer/src/DeerCore/Universe/Serialization/World.h b/Deer/src/DeerCore/Universe/Serialization/World.h new file mode 100644 index 0000000..af55133 --- /dev/null +++ b/Deer/src/DeerCore/Universe/Serialization/World.h @@ -0,0 +1,12 @@ +#pragma once +#include "DeerCore/World.h" +#include "DeerCore/EntityEnviroment.h" + +namespace Deer { + namespace Universe { + template + void save(Archive& archive, World const& world) { + World + } + } +} \ No newline at end of file diff --git a/Deer/src/DeerCore/Universe/Universe.cpp b/Deer/src/DeerCore/Universe/Universe.cpp index 9006994..a4bf639 100644 --- a/Deer/src/DeerCore/Universe/Universe.cpp +++ b/Deer/src/DeerCore/Universe/Universe.cpp @@ -9,82 +9,44 @@ namespace Deer { namespace Universe { - struct WorldSlot { - Scope world = nullptr; - uint32_t generation = 1; - }; - - std::vector universeWorldSlots; + std::vector> 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 lock(universeMutex); - unlockedFlushDestroyedWorlds(); - - int universeSlot = getFreeWorldSlot(); - if (universeSlot == -1) { - universeSlot = universeWorldSlots.size(); - universeWorldSlots.push_back({}); - } - - WorldSlot& worldSlot = universeWorldSlots[universeSlot]; - worldSlot.world = MakeScope(worldSettings); - - return WorldHandle(universeSlot, worldSlot.generation); - } - - World& Universe::getWorld(WorldHandle handle) { - std::lock_guard 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 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(new World(worldSettings))); + return universeWorlds.back().get(); } void Universe::destroyAllWorlds() { std::lock_guard lock(universeMutex); - for (WorldSlot& slot : universeWorldSlots) - slot.world->destroy(); - unlockedFlushDestroyedWorlds(); + for (Scope& 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 = universeWorlds[i]; + if (world->getExecutionState() == WorldState::ReadyToDestroy) { + world.reset(); + world = Scope(universeWorlds.back().release()); + universeWorlds.back() = nullptr; + universeWorlds.pop_back(); + return true; } } + return false; } void Universe::flushDestroyedWorlds() { std::lock_guard lock(universeMutex); - unlockedFlushDestroyedWorlds(); + while (unlockedFlushDestroyedWorlds());; } } // namespace Deer \ No newline at end of file diff --git a/Deer/src/DeerCore/Universe/UniverseSerialization.cpp b/Deer/src/DeerCore/Universe/UniverseSerialization.cpp new file mode 100644 index 0000000..6faa827 --- /dev/null +++ b/Deer/src/DeerCore/Universe/UniverseSerialization.cpp @@ -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 \ No newline at end of file diff --git a/Deer/src/DeerRender/Scripting/InternalAPI/Resources.cpp b/Deer/src/DeerRender/Scripting/InternalAPI/Resources.cpp index b8a14f6..4befd10 100644 --- a/Deer/src/DeerRender/Scripting/InternalAPI/Resources.cpp +++ b/Deer/src/DeerRender/Scripting/InternalAPI/Resources.cpp @@ -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 namespace Deer { @@ -89,6 +98,7 @@ namespace Deer { } void frameBuffer_clearRGBA(int r, int g, int b, int a, Resource& frameBuffer) { int data[] = {r, g, b, a}; + frameBuffer.getData().clear(); frameBuffer.getData().clearBuffer(0, data); } bool frameBuffer_isValid(Resource& frameBuffer) { @@ -97,5 +107,26 @@ namespace Deer { void frameBuffer_resize(int x, int y, Resource& frameBuffer) { frameBuffer.getData().resize(x, y); } + void frameBuffer_drawMesh(Resource mesh, Resource shaderResource, TransformComponent transform, WorldCamera camera, Resource& 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 \ No newline at end of file diff --git a/Deer/src/DeerRender/Scripting/InternalAPI/Resources.h b/Deer/src/DeerRender/Scripting/InternalAPI/Resources.h index b5b361e..2678483 100644 --- a/Deer/src/DeerRender/Scripting/InternalAPI/Resources.h +++ b/Deer/src/DeerRender/Scripting/InternalAPI/Resources.h @@ -1,16 +1,16 @@ #pragma once #include "DeerRender/Resource.h" +#include "DeerRender/World.h" #include "scriptarray.h" #include "scriptdictionary.h" #include #include -#include "DeerRender/Resource.h" - namespace Deer { class FrameBuffer; class GPUMesh; + class Shader; namespace Scripting { template @@ -47,6 +47,8 @@ namespace Deer { void frameBuffer_clearRGBA(int, int, int, int, Resource&); bool frameBuffer_isValid(Resource&); void frameBuffer_resize(int, int, Resource&); + void frameBuffer_drawMesh(Resource, Resource, TransformComponent, WorldCamera, Resource&); + Resource createFrameBuffer(std::string& name, int sixeX, int sizeY); } // namespace Scripting } // namespace Deer \ No newline at end of file diff --git a/Deer/src/DeerRender/Scripting/ResourcesRegistry.cpp b/Deer/src/DeerRender/Scripting/ResourcesRegistry.cpp index 7afa8e1..51ae80f 100644 --- a/Deer/src/DeerRender/Scripting/ResourcesRegistry.cpp +++ b/Deer/src/DeerRender/Scripting/ResourcesRegistry.cpp @@ -32,12 +32,9 @@ namespace Deer { AS_CHECK(scriptEngine->RegisterObjectType("Texture", sizeof(Resource), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits>())); AS_CHECK(scriptEngine->RegisterObjectType("FrameBuffer", sizeof(Resource), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits>())); } - int frameBuffer_getWidth(Resource&); - int frameBuffer_getHeight(Resource&); - void frameBuffer_clearRGBA(int, int, int, int, Resource&); - bool frameBuffer_isValid(Resource&); - void frameBuffer_resize(int, int, Resource&); + + Resource 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); diff --git a/DeerStudio/imgui.ini b/DeerStudio/imgui.ini deleted file mode 100644 index 12dc92c..0000000 --- a/DeerStudio/imgui.ini +++ /dev/null @@ -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 - diff --git a/Editor/Scripts/Previewer/Previewer.as b/Editor/Scripts/Previewer/Previewer.as new file mode 100644 index 0000000..9c140e2 --- /dev/null +++ b/Editor/Scripts/Previewer/Previewer.as @@ -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; + } +} \ No newline at end of file diff --git a/Editor/Scripts/ResourceExplorer/ResourceExplorer.as b/Editor/Scripts/ResourceExplorer/ResourceExplorer.as index ea077a8..fdbfb2d 100644 --- a/Editor/Scripts/ResourceExplorer/ResourceExplorer.as +++ b/Editor/Scripts/ResourceExplorer/ResourceExplorer.as @@ -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 subFolders; + array meshes; + array shaders; array 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(0); + shaders = array(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(""); } diff --git a/Editor/Scripts/TreeExplorer/Tree.as b/Editor/Scripts/TreeExplorer/Tree.as index 9d67029..821f657 100644 --- a/Editor/Scripts/TreeExplorer/Tree.as +++ b/Editor/Scripts/TreeExplorer/Tree.as @@ -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; diff --git a/Editor/Scripts/Viewport/Viewport.as b/Editor/Scripts/Viewport/Viewport.as index b715fb6..af9c303 100644 --- a/Editor/Scripts/Viewport/Viewport.as +++ b/Editor/Scripts/Viewport/Viewport.as @@ -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(); diff --git a/Resources/shader_blue.glsl b/Resources/shader_blue.glsl new file mode 100644 index 0000000..acda2c4 --- /dev/null +++ b/Resources/shader_blue.glsl @@ -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; +} \ No newline at end of file diff --git a/Resources/shader_darkBlue.glsl b/Resources/shader_darkBlue.glsl new file mode 100644 index 0000000..4768d47 --- /dev/null +++ b/Resources/shader_darkBlue.glsl @@ -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; +} \ No newline at end of file diff --git a/imgui.ini b/imgui.ini index aa4b925..29a2eb4 100644 --- a/imgui.ini +++ b/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