diff --git a/Deer/Include/DeerRender/Components.h b/Deer/Include/DeerRender/Components.h index 81da652..02e1409 100755 --- a/Deer/Include/DeerRender/Components.h +++ b/Deer/Include/DeerRender/Components.h @@ -29,7 +29,7 @@ namespace Deer { return MeshManager::getModel(meshId); } - inline Path& getMeshName() { + inline const Path& getMeshName() { return MeshManager::getModelName(meshId); } @@ -46,34 +46,36 @@ namespace Deer { } private: uint16_t meshId; - bool active = false; + bool active = true; }; struct ShaderComponent { ShaderComponent() { clear(); } - ShaderComponent(uint16_t _shaderId) : shaderId(_shaderId), active(true) { } + ShaderComponent(uint16_t _shaderId) : shaderId(_shaderId) { } ShaderComponent(const ShaderComponent&) = default; inline void setShader(uint16_t _shaderId) { - active = true; shaderId = _shaderId; } - inline void clear() { - active = false; - shaderId = 0; - } - inline Shader& getShader() { return ShaderManager::getShader(shaderId); } - inline bool isActive() { - return active; + inline const Path& getName() { + return ShaderManager::getShaderName(shaderId); } + + inline bool hasShader() { + return shaderId != 0; + } + + inline void clear() { + shaderId = 0; + } + private: uint16_t shaderId; - bool active; }; struct TextureBindingComponent { diff --git a/Deer/Include/DeerRender/Mesh.h b/Deer/Include/DeerRender/Mesh.h index 73da33e..c7eb9d3 100644 --- a/Deer/Include/DeerRender/Mesh.h +++ b/Deer/Include/DeerRender/Mesh.h @@ -62,7 +62,7 @@ namespace Deer { uint16_t loadModel(const Path&); uint16_t loadModel(const MeshData&, const Path&); VertexArray& getModel(uint16_t model_id); - Path& getModelName(uint16_t model_id); + const Path& getModelName(uint16_t model_id); void unloadAllModels(); } diff --git a/Deer/Include/DeerRender/Shader.h b/Deer/Include/DeerRender/Shader.h index eac7536..da9d3f0 100644 --- a/Deer/Include/DeerRender/Shader.h +++ b/Deer/Include/DeerRender/Shader.h @@ -24,8 +24,10 @@ namespace Deer { }; namespace ShaderManager { - uint16_t loadShader(const ShaderData&); + uint16_t loadShader(const Path& name); + uint16_t loadShader(const ShaderData&, const Path& name); Shader& getShader(uint16_t); + const Path& getShaderName(uint16_t); void unloadAllShaders(); } diff --git a/Deer/src/DeerRender/Mesh/MeshModelLoading.cpp b/Deer/src/DeerRender/Mesh/MeshModelLoading.cpp index 86b9006..283556b 100644 --- a/Deer/src/DeerRender/Mesh/MeshModelLoading.cpp +++ b/Deer/src/DeerRender/Mesh/MeshModelLoading.cpp @@ -64,7 +64,7 @@ namespace Deer { return *meshes[model_id].mesh_data; } - Path& MeshManager::getModelName(uint16_t model_id) { + const Path& MeshManager::getModelName(uint16_t model_id) { DEER_CORE_ASSERT(model_id >= 0 && model_id < minModelId, "Invalid model id, id is not loaded"); return meshes[model_id].mesh_name; diff --git a/Deer/src/DeerRender/Scene/Environment.cpp b/Deer/src/DeerRender/Scene/Environment.cpp index f8fcde8..e213cc8 100755 --- a/Deer/src/DeerRender/Scene/Environment.cpp +++ b/Deer/src/DeerRender/Scene/Environment.cpp @@ -28,6 +28,11 @@ namespace Deer { auto& shaderComponent = view.get(entityId); auto& tagComponent = view.get(entityId); + if (!meshComponent.hasMesh() || !meshComponent.isActive()) + continue; + if (!shaderComponent.hasShader()) + continue; + Entity& entity = getEntity(tagComponent.entityUID); glm::mat4 matrix = entity.getWorldMatrix(); diff --git a/Deer/src/DeerRender/Shader/ShaderLoad.cpp b/Deer/src/DeerRender/Shader/ShaderLoad.cpp index 781b656..7f4fed2 100644 --- a/Deer/src/DeerRender/Shader/ShaderLoad.cpp +++ b/Deer/src/DeerRender/Shader/ShaderLoad.cpp @@ -1,22 +1,44 @@ #include "DeerRender/Shader.h" #include "Deer/Log.h" +#include namespace Deer { namespace ShaderManager { - size_t minShaderId = 0; - Shader* shaders[SCENE_MAX_SHADER_COUNT]{}; + struct ShaderManagerContainer { + Path shader_name; + Shader* shader_data = nullptr; + }; + + size_t minShaderId = 1; + ShaderManagerContainer shaders[SCENE_MAX_SHADER_COUNT]{}; + std::unordered_map shader_name_id; } void ShaderManager::unloadAllShaders() { for (uint16_t i = 0; i < minShaderId; i++) { - delete shaders[i]; - shaders[i] = nullptr; + delete shaders[i].shader_data; + shaders[i].shader_data = nullptr; } + shader_name_id.clear(); - minShaderId = 0; + shader_name_id["NULL"] = 0; + shaders[0].shader_name = nullptr; + shaders[0].shader_name = "NULL"; + minShaderId = 1; } - uint16_t ShaderManager::loadShader(const ShaderData& data) { + uint16_t ShaderManager::loadShader(const Path& name) { + if (shader_name_id.contains(name)) + return shader_name_id[name]; + + + ShaderData shaderData; + DataStore::loadShader(shaderData, name); + + return loadShader(shaderData, name); + } + + uint16_t ShaderManager::loadShader(const ShaderData& data, const Path& name) { if (minShaderId >= SCENE_MAX_SHADER_COUNT) { DEER_CORE_ERROR("Max shader loaded into a scene"); return -1; @@ -25,7 +47,8 @@ namespace Deer { uint16_t shaderId = minShaderId; minShaderId++; - shaders[shaderId] = Shader::create(data.vertexShader, data.fragmentShader); + shaders[shaderId].shader_data = Shader::create(data.vertexShader, data.fragmentShader); + shaders[shaderId].shader_name = name; return shaderId; } @@ -33,6 +56,12 @@ namespace Deer { Shader& ShaderManager::getShader(uint16_t shaderId) { DEER_CORE_ASSERT(shaderId >= 0 && shaderId < minShaderId, "Invalid shader id, id is not loaded"); - return *shaders[shaderId]; + return *shaders[shaderId].shader_data; + } + + const Path& ShaderManager::getShaderName(uint16_t shaderId) { + DEER_CORE_ASSERT(shaderId >= 0 && shaderId < minShaderId, "Invalid shader id, id is not loaded"); + + return shaders[shaderId].shader_name; } } \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/DeerStudio.cpp b/DeerStudio/src/DeerStudio/DeerStudio.cpp index a9b8a4a..7e08fd0 100755 --- a/DeerStudio/src/DeerStudio/DeerStudio.cpp +++ b/DeerStudio/src/DeerStudio/DeerStudio.cpp @@ -54,21 +54,6 @@ namespace Deer { auto m_gamePanel = Ref(new GamePanel()); Panels.push_back(m_gamePanel); - Environment& env = Scene::environment; - - Entity& exampleObject = env.createEntity("Example"); - MeshComponent& renderComponent = exampleObject.addComponent(); - ShaderComponent& shaderComponent = exampleObject.addComponent(); - - MeshData meshData; - DataStore::loadModel(meshData, "example"); - - ShaderData shaderData; - DataStore::loadShader(shaderData, "shader"); - - renderComponent.setMesh(MeshManager::loadModel(meshData, "SIMPLE MESH")); - shaderComponent.setShader(ShaderManager::loadShader(shaderData)); - return 0; } diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API/Entity.h b/DeerStudio/src/DeerStudio/EditorEngine/API/Entity.h index e4689d9..83901e6 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API/Entity.h +++ b/DeerStudio/src/DeerStudio/EditorEngine/API/Entity.h @@ -51,6 +51,10 @@ namespace Deer { bool hasMeshComponent(); void removeMeshComponent(); + EntityStruct getShaderComponent(); + bool hasShaderComponent(); + void removeShaderComponent(); + // This is an internal function to avoid undefined behaviour from angelscript and avoid problems bool assertEntity(const char* funcName); @@ -74,8 +78,6 @@ namespace Deer { }; struct MeshComponentStruct : EntityStruct { - bool assertMeshComponent(); - bool isActive(); void setActive(bool); @@ -88,6 +90,16 @@ namespace Deer { bool assertMeshComponent(const char* funcName); }; + struct ShaderComponentStruct : EntityStruct { + bool hasShader(); + void clear(); + + std::string getShader(); + void setShader(std::string&); + + bool assertShaderComponent(const char* funcName); + }; + EntityStruct getRoot(); void constructEntityStruct(int id, void* memory); void copyEntityStruct(int id, void* memory); diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API/Layout.h b/DeerStudio/src/DeerStudio/EditorEngine/API/Layout.h index 969ba15..0f46906 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API/Layout.h +++ b/DeerStudio/src/DeerStudio/EditorEngine/API/Layout.h @@ -23,5 +23,6 @@ namespace Deer { bool treeNodeRecursive(std::string&, bool, CScriptAny*, asIScriptFunction&); void space(); + void space_params(int, int); } } \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API/UI.h b/DeerStudio/src/DeerStudio/EditorEngine/API/UI.h index 93a2f7d..af30c6f 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API/UI.h +++ b/DeerStudio/src/DeerStudio/EditorEngine/API/UI.h @@ -54,13 +54,16 @@ namespace Deer { // Draws a button for a popup menu bool menuItem(std::string&); + // Draws a button disabled + void menuItemDisabled(std::string&); + // Draws a space where you can put buttons inside + void menuSpace(std::string&, CScriptAny*, asIScriptFunction*); // Initializes the drag drop source with the id and the data you want to pass void dragDropSource(std::string&, CScriptAny*, std::string&); // Prepares the function to accept payload with the id and calls the function with the data void dragDropTarget(std::string&, CScriptAny*, asIScriptFunction*); - // Draws a simple input with a label, input and output string bool inputText(std::string& label, std::string&, std::string&); // Draws a simple checkbox diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Entity.cpp b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Entity.cpp index d4e8efe..4c9115e 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Entity.cpp +++ b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Entity.cpp @@ -4,8 +4,14 @@ #include "DeerStudio/EditorEngine/DockPanelObject.h" #include "Deer/Scene.h" -#define GET_ENTITY(id) Scene::environment.getEntity(id) +#define GET_ENTITY(id) Scene::environment.getEntity(id) +#define GET_MESH_COMPONENT(id) Scene::environment.getEntity(id).getComponent() +#define GET_SHADER_COMPONENT(id) Scene::environment.getEntity(id).getComponent() + #define ASSERT_ENTITY(func, ret) if (!assertEntity(func)) ret; +#define ASSERT_MESH_COMPONENT(func, ret) if (!assertMeshComponent(func)) ret; +#define ASSERT_SHADER_COMPONENT(func, ret) if (!assertShaderComponent(func)) ret; + namespace Deer { namespace EditorEngine { @@ -154,6 +160,25 @@ namespace Deer { .childCount; } + bool MeshComponentStruct::assertMeshComponent(const char* funcName) { + if (!assertEntity(funcName)) return false; + Entity& ent = Scene::environment.getEntity(entityId); + + if (!ent.hasComponent()) { + DEER_UI_ENGINE_ERROR("Error, calling MeshComponent.{0} entity {1} with id {2} has no MeshComponent", + funcName, + ent.getComponent().tag.c_str(), + entityId + ); + + if (currentDockPanelExecution) + currentDockPanelExecution->invalidate(); + return false; + } + + return true; + } + EntityStruct EntityChildArrayStruct::getChild(int i) { ASSERT_ENTITY("getChild()", return *this); @@ -214,99 +239,114 @@ namespace Deer { } } - bool MeshComponentStruct::isActive() { - ASSERT_ENTITY("isActive()", return false); - Entity& self = GET_ENTITY(entityId); + EntityStruct EntityStruct::getShaderComponent() { + ASSERT_ENTITY("getShaderComponent()", return *this); - if (!self.hasComponent()) { - DEER_UI_ENGINE_ERROR("Entity {0} has no component Mesh Component", entityId); - - if (currentDockPanelExecution) - currentDockPanelExecution->invalidate(); - return false; + Entity& self = GET_ENTITY(entityId); + + if (!self.hasComponent()) { + self.addComponent(); } - return self.getComponent().isActive(); + return *this; + } + + bool EntityStruct::hasShaderComponent() { + ASSERT_ENTITY("hasShaderComponent()", return false); + + Entity& self = GET_ENTITY(entityId); + return self.hasComponent(); + } + + void EntityStruct::removeShaderComponent() { + ASSERT_ENTITY("removeShaderComponent()", return); + + Entity& self = GET_ENTITY(entityId); + + if (self.hasComponent()) { + self.removeComponent(); + } + } + + bool MeshComponentStruct::isActive() { + ASSERT_MESH_COMPONENT("isActive()", return false); + return GET_MESH_COMPONENT(entityId).isActive(); } void MeshComponentStruct::setActive(bool value) { - ASSERT_ENTITY("setActive(bool)", return); - Entity& self = GET_ENTITY(entityId); - - if (!self.hasComponent()) { - DEER_UI_ENGINE_ERROR("Entity {0} has no component Mesh Component", entityId); - - if (currentDockPanelExecution) - currentDockPanelExecution->invalidate(); - return; - } - - self.getComponent().setActive(value); + ASSERT_MESH_COMPONENT("setActive(bool)", return); + + GET_MESH_COMPONENT(entityId).setActive(value); } bool MeshComponentStruct::hasMesh() { - ASSERT_ENTITY("hasMesh()", return false); + ASSERT_MESH_COMPONENT("hasMesh()", return false); - Entity& self = GET_ENTITY(entityId); + return GET_MESH_COMPONENT(entityId).hasMesh(); + } - if (!self.hasComponent()) { - DEER_UI_ENGINE_ERROR("Entity {0} has no component Mesh Component", entityId); - + void MeshComponentStruct::clear() { + ASSERT_MESH_COMPONENT("clear()", return); + + return GET_MESH_COMPONENT(entityId).clear(); + } + + std::string MeshComponentStruct::getMesh() { + ASSERT_MESH_COMPONENT("getMesh()", return "NULL"); + + return GET_MESH_COMPONENT(entityId).getMeshName(); + } + + void MeshComponentStruct::setMesh(std::string& name) { + ASSERT_MESH_COMPONENT("setMesh()", return); + + uint16_t meshId = MeshManager::loadModel(name); + GET_MESH_COMPONENT(entityId).setMesh(meshId); + } + + bool ShaderComponentStruct::hasShader() { + ASSERT_ENTITY("hasShader()", return false); + + return GET_SHADER_COMPONENT(entityId).hasShader(); + } + + bool ShaderComponentStruct::assertShaderComponent(const char* funcName) { + if (!assertEntity(funcName)) return false; + Entity& ent = Scene::environment.getEntity(entityId); + + if (!ent.hasComponent()) { + DEER_UI_ENGINE_ERROR("Error, calling ShaderComponent.{0} entity {1} with id {2} has no ShaderComponent", + funcName, + ent.getComponent().tag.c_str(), + entityId + ); + if (currentDockPanelExecution) currentDockPanelExecution->invalidate(); return false; } - return self.getComponent().hasMesh(); + return true; } - void MeshComponentStruct::clear() { - ASSERT_ENTITY("clear()", return); + void ShaderComponentStruct::clear() { + ASSERT_SHADER_COMPONENT("clear()", return); - Entity& self = GET_ENTITY(entityId); - - if (!self.hasComponent()) { - DEER_UI_ENGINE_ERROR("Entity {0} has no component Mesh Component", entityId); - - if (currentDockPanelExecution) - currentDockPanelExecution->invalidate(); - return; - } - - return self.removeComponent(); + GET_SHADER_COMPONENT(entityId).clear(); } - std::string MeshComponentStruct::getMesh() { - ASSERT_ENTITY("getMesh()", return "NULL"); + std::string ShaderComponentStruct::getShader() { + ASSERT_SHADER_COMPONENT("getShader()", return "NULL"); - Entity& self = GET_ENTITY(entityId); - - if (!self.hasComponent()) { - DEER_UI_ENGINE_ERROR("Entity {0} has no component Mesh Component", entityId); - - if (currentDockPanelExecution) - currentDockPanelExecution->invalidate(); - return "NULL"; - } - - return self.getComponent().getMeshName(); + return GET_SHADER_COMPONENT(entityId).getName(); } - void MeshComponentStruct::setMesh(std::string& name) { - ASSERT_ENTITY("setMesh()", return); + void ShaderComponentStruct::setShader(std::string& name) { + ASSERT_SHADER_COMPONENT("getShader()", return); - Entity& self = GET_ENTITY(entityId); - - if (!self.hasComponent()) { - DEER_UI_ENGINE_ERROR("Entity {0} has no component Mesh Component", entityId); - - if (currentDockPanelExecution) - currentDockPanelExecution->invalidate(); - return; - } - - uint16_t meshId = MeshManager::loadModel(name); - self.getComponent().setMesh(meshId); + uint16_t shaderId = ShaderManager::loadShader(name); + GET_SHADER_COMPONENT(entityId).setShader(shaderId); } + } } \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Entity_Register.cpp b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Entity_Register.cpp index 8427e28..bcf7757 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Entity_Register.cpp +++ b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Entity_Register.cpp @@ -8,6 +8,9 @@ namespace Deer { namespace EditorEngine { + void registerTransformComponentFunctions(); + void registerMeshComponentFunction(); + void registerShaderComponentFunctions(); void registerEntityStructs() { AS_CHECK(scriptEngine->RegisterObjectType("Entity", sizeof(EntityStruct), @@ -27,9 +30,16 @@ namespace Deer { AS_CHECK(scriptEngine->RegisterObjectType("MeshComponent", sizeof(EntityStruct), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits() | asOBJ_APP_CLASS_ALLINTS)); + + AS_CHECK(scriptEngine->RegisterObjectType("ShaderComponent", sizeof(EntityStruct), + asOBJ_VALUE | asOBJ_POD | asGetTypeTraits() | asOBJ_APP_CLASS_ALLINTS)); } void registerEntityFunctions() { + registerTransformComponentFunctions(); + registerMeshComponentFunction(); + registerShaderComponentFunctions(); + // ENTITY AS_CHECK(scriptEngine->RegisterObjectMethod( "Entity", @@ -165,6 +175,73 @@ namespace Deer { asCALL_THISCALL )); + AS_CHECK(scriptEngine->RegisterObjectMethod( + "Entity", + "ShaderComponent getShaderComponent() ", + asMETHOD(EntityStruct, getShaderComponent), + asCALL_THISCALL + )); + + AS_CHECK(scriptEngine->RegisterObjectMethod( + "Entity", + "bool hasShaderComponent() ", + asMETHOD(EntityStruct, hasShaderComponent), + asCALL_THISCALL + )); + + AS_CHECK(scriptEngine->RegisterObjectMethod( + "Entity", + "void removeShaderComponent() ", + asMETHOD(EntityStruct, removeShaderComponent), + asCALL_THISCALL + )); + } + + void registerMeshComponentFunction() { + AS_CHECK(scriptEngine->RegisterObjectMethod( + "MeshComponent", + "bool get_isActive() const property", + asMETHOD(MeshComponentStruct, isActive), + asCALL_THISCALL + )); + + AS_CHECK(scriptEngine->RegisterObjectMethod( + "MeshComponent", + "bool get_hasMesh() const property", + asMETHOD(MeshComponentStruct, hasMesh), + asCALL_THISCALL + )); + + AS_CHECK(scriptEngine->RegisterObjectMethod( + "MeshComponent", + "void clear()", + asMETHOD(MeshComponentStruct, clear), + asCALL_THISCALL + )); + + AS_CHECK(scriptEngine->RegisterObjectMethod( + "MeshComponent", + "string getMesh()", + asMETHOD(MeshComponentStruct, getMesh), + asCALL_THISCALL + )); + + AS_CHECK(scriptEngine->RegisterObjectMethod( + "MeshComponent", + "void setMesh(string&in)", + asMETHOD(MeshComponentStruct, setMesh), + asCALL_THISCALL + )); + + AS_CHECK(scriptEngine->RegisterObjectMethod( + "MeshComponent", + "void set_isActive(const bool) property", + asMETHOD(MeshComponentStruct, setActive), + asCALL_THISCALL + )); + } + + void registerTransformComponentFunctions() { // TRANSFORM COMPONENT AS_CHECK(scriptEngine->RegisterObjectMethod( @@ -209,59 +286,37 @@ namespace Deer { asCALL_THISCALL )); + } + + void registerShaderComponentFunctions() { AS_CHECK(scriptEngine->RegisterObjectMethod( - "MeshComponent", - "bool get_isActive() const property", - asMETHOD(MeshComponentStruct, isActive), + "ShaderComponent", + "bool get_hasShader() const property ", + asMETHOD(ShaderComponentStruct, hasShader), asCALL_THISCALL )); AS_CHECK(scriptEngine->RegisterObjectMethod( - "MeshComponent", - "bool get_hasMesh() const property", - asMETHOD(MeshComponentStruct, hasMesh), + "ShaderComponent", + "void clear() ", + asMETHOD(ShaderComponentStruct, clear), asCALL_THISCALL )); AS_CHECK(scriptEngine->RegisterObjectMethod( - "MeshComponent", - "void clear()", - asMETHOD(MeshComponentStruct, clear), + "ShaderComponent", + "string getShader() ", + asMETHOD(ShaderComponentStruct, getShader), asCALL_THISCALL )); AS_CHECK(scriptEngine->RegisterObjectMethod( - "MeshComponent", - "string getMesh()", - asMETHOD(MeshComponentStruct, getMesh), - asCALL_THISCALL - )); - - AS_CHECK(scriptEngine->RegisterObjectMethod( - "MeshComponent", - "void setMesh(string&in)", - asMETHOD(MeshComponentStruct, setMesh), - asCALL_THISCALL - )); - - AS_CHECK(scriptEngine->RegisterObjectMethod( - "MeshComponent", - "void set_isActive(const bool) property", - asMETHOD(MeshComponentStruct, setActive), + "ShaderComponent", + "void setShader(const string& in) ", + asMETHOD(ShaderComponentStruct, setShader), asCALL_THISCALL )); } - - void registerTransformComponent() { - AS_CHECK(scriptEngine->RegisterObjectType("Entity", sizeof(EntityStruct), - asOBJ_VALUE | asOBJ_POD | asGetTypeTraits() | asOBJ_APP_CLASS_ALLINTS)); - - - AS_CHECK(scriptEngine->RegisterObjectBehaviour( - "Entity", asBEHAVE_CONSTRUCT, "void f(int)", - asFunctionPtr(constructEntityStruct), - asCALL_CDECL_OBJLAST - )); - } + } } \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Layout.cpp b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Layout.cpp index 69883b4..da86834 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Layout.cpp +++ b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/Layout.cpp @@ -133,5 +133,8 @@ namespace Deer { ImGui::Dummy(ImVec2(10, 10)); } + void space_params(int x, int y) { + ImGui::Dummy(ImVec2(x, y)); + } } } \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/UI.cpp b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/UI.cpp index 167634b..d1a3197 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/UI.cpp +++ b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/UI.cpp @@ -39,11 +39,11 @@ namespace Deer { ImGui::PopFont(); } - void titleCenterY(std::string& txt, int) { + void titleCenterY(std::string& txt, int height) { ImGui::PushFont(titleText); float textHeight = ImGui::GetFontSize(); - float yOffset = (64.0f - textHeight) * 0.5f; + float yOffset = (height - textHeight) * 0.5f; ImGui::SetCursorPosY(ImGui::GetCursorPosY() + yOffset); ImGui::Text("%s", txt.c_str()); @@ -183,6 +183,30 @@ namespace Deer { return ImGui::MenuItem(txt.c_str()); } + void menuSpace(std::string& txt, CScriptAny* data ,asIScriptFunction* func) { + if (ImGui::BeginMenu(txt.c_str())) { + + if (scriptContext && scriptContext->PushState() == asSUCCESS) { + + AS_CHECK(scriptContext->Prepare(func)); + + AS_CHECK(scriptContext->SetArgObject(0, data)); + + AS_CHECK(scriptContext->Execute()); + + scriptContext->PopState(); + } + + ImGui::EndMenu(); + } + } + + void menuItemDisabled(std::string& txt) { + ImGui::BeginDisabled(); + ImGui::MenuItem(txt.c_str()); + ImGui::EndDisabled(); + } + void dragDropSource(std::string& id, CScriptAny* data, std::string& debugText) { if (DragDropPayload::payload && !ImGui::GetDragDropPayload()) { DragDropPayload::payload->Release(); diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/UI_Register.cpp b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/UI_Register.cpp index 4a20537..4b0bec0 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/UI_Register.cpp +++ b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/UI_Register.cpp @@ -66,12 +66,30 @@ namespace Deer { asCALL_CDECL )); + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "void space(int, int = 10)", + asFUNCTION(space_params), + asCALL_CDECL + )); + AS_CHECK(scriptEngine->RegisterGlobalFunction( "bool menuItem(const string& in)", asFUNCTION(menuItem), asCALL_CDECL )); + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "void menuSpace(const string& in, any@+, ReciverFunc@+)", + asFUNCTION(menuSpace), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "void menuItemDisabled(const string& in)", + asFUNCTION(menuItemDisabled), + asCALL_CDECL + )); + AS_CHECK(scriptEngine->RegisterGlobalFunction( "bool button(const string& in)", asFUNCTION(button), diff --git a/roe/editor/icons/empty.png b/roe/editor/icons/empty.png new file mode 100644 index 0000000..a215a30 Binary files /dev/null and b/roe/editor/icons/empty.png differ diff --git a/roe/editor/icons/emptyIcon.png b/roe/editor/icons/emptyIcon.png new file mode 100644 index 0000000..a215a30 Binary files /dev/null and b/roe/editor/icons/emptyIcon.png differ diff --git a/roe/editor/icons/object3d.png b/roe/editor/icons/object3d.png index 26a7369..e4b3382 100644 Binary files a/roe/editor/icons/object3d.png and b/roe/editor/icons/object3d.png differ diff --git a/roe/editor/icons/shader.png b/roe/editor/icons/shader.png index b13a3e9..80393c2 100755 Binary files a/roe/editor/icons/shader.png and b/roe/editor/icons/shader.png differ diff --git a/roe/editor/properties/addComponentMenu.as b/roe/editor/properties/addComponentMenu.as new file mode 100644 index 0000000..725fb37 --- /dev/null +++ b/roe/editor/properties/addComponentMenu.as @@ -0,0 +1,32 @@ + +void addComponentPopup(any@ data) { + Entity entity; + data.retrieve(entity); + + titleCenter("Component"); + separator(); + menuSpace("Rendering", any(entity), addComponentRendering ); + if (menuItem("Script Component")) { + } +} + +void addComponentRendering(any@ data) { + Entity entity; + data.retrieve(entity); + + if (entity.hasMeshComponent()) { + menuItemDisabled("Mesh Render Component"); + } else { + if (menuItem("Mesh Render Component")) { + entity.getMeshComponent(); + } + } + + if (entity.hasShaderComponent()) { + menuItemDisabled("Shader Render Component"); + } else { + if (menuItem("Shader Render Component")) { + entity.getShaderComponent(); + } + } +} \ No newline at end of file diff --git a/roe/editor/properties/components_render.as b/roe/editor/properties/components_render.as index 5a3b0c1..2360836 100644 --- a/roe/editor/properties/components_render.as +++ b/roe/editor/properties/components_render.as @@ -18,25 +18,69 @@ void renderMeshComponent(any@ data) { MeshComponent meshComponent = entity.getMeshComponent(); + if (meshComponent.hasMesh) { + drawIcon("object3d", 32); + } else { + drawIcon("empty", 32); + } + + dragDropTarget("MESH", any(meshComponent), setMeshComponentMesh); + + if (meshComponent.hasMesh) { + sameline(); + space(); + sameline(); + + titleCenterY(meshComponent.getMesh(), 32); + dragDropTarget("MESH", any(meshComponent), setMeshComponentMesh); + } + + space(20, 20); + + if (button("Clear")) { + meshComponent.clear(); + } + + sameline(); + space(10, 20); + sameline(); + if (meshComponent.hasMesh) { meshComponent.isActive = checkbox("Active", meshComponent.isActive); } else { checkboxDisabled("Active", meshComponent.isActive); } - - space(); - - drawIcon("object3d", 64); - - dragDropTarget("MESH", any(meshComponent), setMeshComponentMesh); - - sameline(); - titleCenterY("Mesh Name", 64); - dragDropTarget("MESH", any(meshComponent), setMeshComponentMesh); - - } +void renderShaderComponent(any@ data) { + Entity entity; + data.retrieve(entity); + + ShaderComponent shaderComponent = entity.getShaderComponent(); + + if (shaderComponent.hasShader) { + drawIcon("shader", 32); + } else { + drawIcon("empty", 32); + } + dragDropTarget("SHADER", any(shaderComponent), setShaderComponent); + + if (shaderComponent.hasShader) { + sameline(); + space(); + sameline(); + + titleCenterY(shaderComponent.getShader(), 32); + dragDropTarget("SHADER", any(shaderComponent), setShaderComponent); + } + + space(20, 20); + + if (button("Clear")) { + shaderComponent.clear(); + } +} + void setMeshComponentMesh(any@ meshComponent_data, any@ mesh_data){ string mesh; mesh_data.retrieve(mesh); @@ -44,6 +88,15 @@ void setMeshComponentMesh(any@ meshComponent_data, any@ mesh_data){ MeshComponent meshComponent; meshComponent_data.retrieve(meshComponent); - print(mesh); meshComponent.setMesh(mesh); +} + +void setShaderComponent(any@ shaderComponent_data, any@ shader_data) { + string shader; + shader_data.retrieve(shader); + + ShaderComponent shaderComponent; + shaderComponent_data.retrieve(shaderComponent); + + shaderComponent.setShader(shader); } \ No newline at end of file diff --git a/roe/editor/properties/properties_pannel.as b/roe/editor/properties/properties_pannel.as index 8b7892f..a3ceaa9 100644 --- a/roe/editor/properties/properties_pannel.as +++ b/roe/editor/properties/properties_pannel.as @@ -33,6 +33,9 @@ class PropertiesPannel : DockPanel { componentNode("Mesh Component", any(entity), renderMeshComponent); } + if (entity.hasShaderComponent()) { + componentNode("Shader Component", any(entity), renderShaderComponent); + } space(); separator(); @@ -41,28 +44,10 @@ class PropertiesPannel : DockPanel { openPopup("ADD_COMPONENT", any(entity)); } - simplePopup("ADD_COMPONENT", ReciverFunc(this.addComponentPopup)); + simplePopup("ADD_COMPONENT", addComponentPopup); modalPopup("Rename entity", renameEntity); } - void addComponentPopup(any@ data) { - titleCenter("Component"); - - separator(); - - if (menuItem("Mesh Render Component")) { - - } - - if (menuItem("Camera Component")) { - - } - - if (menuItem("Script Component")) { - - } - } - void renameEntityMenu(any@ data) { Entity entity; data.retrieve(entity); diff --git a/roe/editor/shader_explorer.as b/roe/editor/shader_explorer.as index ab1f466..54ef6df 100644 --- a/roe/editor/shader_explorer.as +++ b/roe/editor/shader_explorer.as @@ -32,6 +32,10 @@ class ShaderExplorer : DockPanel { int meshCount = getResourceCount(resourceType, cache_currentPath); for (int i = 0; i < meshCount; i++) { drawIconCentered("file", 64); + dragDropSource("SHADER", + any(getResourcePathById(resourceType, cache_currentPath, i)), + getResourcePathById(resourceType, cache_currentPath, i)); + textCenter(getResourceNameById(resourceType, cache_currentPath, i)); nextColumn(); diff --git a/roe/imgui.ini b/roe/imgui.ini index 083d79f..caf4aef 100644 --- a/roe/imgui.ini +++ b/roe/imgui.ini @@ -16,7 +16,7 @@ DockId=0x00000004,1 [Window][Game Window] Pos=258,24 -Size=620,474 +Size=499,490 Collapsed=0 DockId=0x00000006,0 @@ -27,14 +27,14 @@ Collapsed=0 DockId=0x00000001,0 [Window][Terrain Editor] -Pos=880,24 -Size=400,474 +Pos=759,24 +Size=521,490 Collapsed=0 DockId=0x00000004,0 [Window][Viewport] Pos=258,24 -Size=620,474 +Size=499,490 Collapsed=0 DockId=0x00000006,1 @@ -57,14 +57,14 @@ Collapsed=0 DockId=0x00000008,1 [Window][MeshExplorer] -Pos=0,500 -Size=1280,220 +Pos=0,516 +Size=1280,204 Collapsed=0 DockId=0x00000008,0 [Window][TreePannel] Pos=0,24 -Size=256,474 +Size=256,490 Collapsed=0 DockId=0x00000005,0 @@ -79,8 +79,8 @@ Size=351,75 Collapsed=0 [Window][PropertiesPannel] -Pos=880,24 -Size=400,474 +Pos=759,24 +Size=521,490 Collapsed=0 DockId=0x00000004,1 @@ -91,19 +91,19 @@ Collapsed=0 DockId=0x00000004,1 [Window][ShaderExplorer] -Pos=0,500 -Size=1280,220 +Pos=0,516 +Size=1280,204 Collapsed=0 DockId=0x00000008,1 [Docking][Data] DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=1280,696 Split=Y - DockNode ID=0x00000007 Parent=0xA1672E74 SizeRef=1280,474 Split=Y + DockNode ID=0x00000007 Parent=0xA1672E74 SizeRef=1280,490 Split=Y DockNode ID=0x00000001 Parent=0x00000007 SizeRef=2560,363 Split=X Selected=0x13926F0B - DockNode ID=0x00000003 Parent=0x00000001 SizeRef=878,338 Split=X Selected=0x13926F0B + DockNode ID=0x00000003 Parent=0x00000001 SizeRef=757,338 Split=X Selected=0x13926F0B DockNode ID=0x00000005 Parent=0x00000003 SizeRef=256,446 Selected=0xE45B9F93 - DockNode ID=0x00000006 Parent=0x00000003 SizeRef=620,446 CentralNode=1 Selected=0x13926F0B - DockNode ID=0x00000004 Parent=0x00000001 SizeRef=400,338 Selected=0x2A2C795E + DockNode ID=0x00000006 Parent=0x00000003 SizeRef=499,446 CentralNode=1 Selected=0x13926F0B + DockNode ID=0x00000004 Parent=0x00000001 SizeRef=521,338 Selected=0xA35A27E3 DockNode ID=0x00000002 Parent=0x00000007 SizeRef=2560,331 Selected=0xCF339702 - DockNode ID=0x00000008 Parent=0xA1672E74 SizeRef=1280,220 Selected=0xD962995A + DockNode ID=0x00000008 Parent=0xA1672E74 SizeRef=1280,204 Selected=0xD962995A