Working Mesh and Rendering component

This commit is contained in:
Arnau Alier Torres 2025-05-09 01:24:28 +02:00
parent 930a17d730
commit b3884b6bd5
24 changed files with 451 additions and 198 deletions

View File

@ -29,7 +29,7 @@ namespace Deer {
return MeshManager::getModel(meshId); return MeshManager::getModel(meshId);
} }
inline Path& getMeshName() { inline const Path& getMeshName() {
return MeshManager::getModelName(meshId); return MeshManager::getModelName(meshId);
} }
@ -46,34 +46,36 @@ namespace Deer {
} }
private: private:
uint16_t meshId; uint16_t meshId;
bool active = false; bool active = true;
}; };
struct ShaderComponent { struct ShaderComponent {
ShaderComponent() { clear(); } ShaderComponent() { clear(); }
ShaderComponent(uint16_t _shaderId) : shaderId(_shaderId), active(true) { } ShaderComponent(uint16_t _shaderId) : shaderId(_shaderId) { }
ShaderComponent(const ShaderComponent&) = default; ShaderComponent(const ShaderComponent&) = default;
inline void setShader(uint16_t _shaderId) { inline void setShader(uint16_t _shaderId) {
active = true;
shaderId = _shaderId; shaderId = _shaderId;
} }
inline void clear() {
active = false;
shaderId = 0;
}
inline Shader& getShader() { inline Shader& getShader() {
return ShaderManager::getShader(shaderId); return ShaderManager::getShader(shaderId);
} }
inline bool isActive() { inline const Path& getName() {
return active; return ShaderManager::getShaderName(shaderId);
} }
inline bool hasShader() {
return shaderId != 0;
}
inline void clear() {
shaderId = 0;
}
private: private:
uint16_t shaderId; uint16_t shaderId;
bool active;
}; };
struct TextureBindingComponent { struct TextureBindingComponent {

View File

@ -62,7 +62,7 @@ namespace Deer {
uint16_t loadModel(const Path&); uint16_t loadModel(const Path&);
uint16_t loadModel(const MeshData&, const Path&); uint16_t loadModel(const MeshData&, const Path&);
VertexArray& getModel(uint16_t model_id); VertexArray& getModel(uint16_t model_id);
Path& getModelName(uint16_t model_id); const Path& getModelName(uint16_t model_id);
void unloadAllModels(); void unloadAllModels();
} }

View File

@ -24,8 +24,10 @@ namespace Deer {
}; };
namespace ShaderManager { 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); Shader& getShader(uint16_t);
const Path& getShaderName(uint16_t);
void unloadAllShaders(); void unloadAllShaders();
} }

View File

@ -64,7 +64,7 @@ namespace Deer {
return *meshes[model_id].mesh_data; 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"); DEER_CORE_ASSERT(model_id >= 0 && model_id < minModelId, "Invalid model id, id is not loaded");
return meshes[model_id].mesh_name; return meshes[model_id].mesh_name;

View File

@ -28,6 +28,11 @@ namespace Deer {
auto& shaderComponent = view.get<ShaderComponent>(entityId); auto& shaderComponent = view.get<ShaderComponent>(entityId);
auto& tagComponent = view.get<TagComponent>(entityId); auto& tagComponent = view.get<TagComponent>(entityId);
if (!meshComponent.hasMesh() || !meshComponent.isActive())
continue;
if (!shaderComponent.hasShader())
continue;
Entity& entity = getEntity(tagComponent.entityUID); Entity& entity = getEntity(tagComponent.entityUID);
glm::mat4 matrix = entity.getWorldMatrix(); glm::mat4 matrix = entity.getWorldMatrix();

View File

@ -1,22 +1,44 @@
#include "DeerRender/Shader.h" #include "DeerRender/Shader.h"
#include "Deer/Log.h" #include "Deer/Log.h"
#include <unordered_map>
namespace Deer { namespace Deer {
namespace ShaderManager { namespace ShaderManager {
size_t minShaderId = 0; struct ShaderManagerContainer {
Shader* shaders[SCENE_MAX_SHADER_COUNT]{}; Path shader_name;
Shader* shader_data = nullptr;
};
size_t minShaderId = 1;
ShaderManagerContainer shaders[SCENE_MAX_SHADER_COUNT]{};
std::unordered_map<Path, size_t> shader_name_id;
} }
void ShaderManager::unloadAllShaders() { void ShaderManager::unloadAllShaders() {
for (uint16_t i = 0; i < minShaderId; i++) { for (uint16_t i = 0; i < minShaderId; i++) {
delete shaders[i]; delete shaders[i].shader_data;
shaders[i] = nullptr; shaders[i].shader_data = nullptr;
}
shader_name_id.clear();
shader_name_id["NULL"] = 0;
shaders[0].shader_name = nullptr;
shaders[0].shader_name = "NULL";
minShaderId = 1;
} }
minShaderId = 0; 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) { uint16_t ShaderManager::loadShader(const ShaderData& data, const Path& name) {
if (minShaderId >= SCENE_MAX_SHADER_COUNT) { if (minShaderId >= SCENE_MAX_SHADER_COUNT) {
DEER_CORE_ERROR("Max shader loaded into a scene"); DEER_CORE_ERROR("Max shader loaded into a scene");
return -1; return -1;
@ -25,7 +47,8 @@ namespace Deer {
uint16_t shaderId = minShaderId; uint16_t shaderId = minShaderId;
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; return shaderId;
} }
@ -33,6 +56,12 @@ namespace Deer {
Shader& ShaderManager::getShader(uint16_t shaderId) { Shader& ShaderManager::getShader(uint16_t shaderId) {
DEER_CORE_ASSERT(shaderId >= 0 && shaderId < minShaderId, "Invalid shader id, id is not loaded"); 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;
} }
} }

View File

@ -54,21 +54,6 @@ namespace Deer {
auto m_gamePanel = Ref<GamePanel>(new GamePanel()); auto m_gamePanel = Ref<GamePanel>(new GamePanel());
Panels.push_back(m_gamePanel); Panels.push_back(m_gamePanel);
Environment& env = Scene::environment;
Entity& exampleObject = env.createEntity("Example");
MeshComponent& renderComponent = exampleObject.addComponent<MeshComponent>();
ShaderComponent& shaderComponent = exampleObject.addComponent<ShaderComponent>();
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; return 0;
} }

View File

@ -51,6 +51,10 @@ namespace Deer {
bool hasMeshComponent(); bool hasMeshComponent();
void removeMeshComponent(); void removeMeshComponent();
EntityStruct getShaderComponent();
bool hasShaderComponent();
void removeShaderComponent();
// This is an internal function to avoid undefined behaviour from angelscript and avoid problems // This is an internal function to avoid undefined behaviour from angelscript and avoid problems
bool assertEntity(const char* funcName); bool assertEntity(const char* funcName);
@ -74,8 +78,6 @@ namespace Deer {
}; };
struct MeshComponentStruct : EntityStruct { struct MeshComponentStruct : EntityStruct {
bool assertMeshComponent();
bool isActive(); bool isActive();
void setActive(bool); void setActive(bool);
@ -88,6 +90,16 @@ namespace Deer {
bool assertMeshComponent(const char* funcName); 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(); EntityStruct getRoot();
void constructEntityStruct(int id, void* memory); void constructEntityStruct(int id, void* memory);
void copyEntityStruct(int id, void* memory); void copyEntityStruct(int id, void* memory);

View File

@ -23,5 +23,6 @@ namespace Deer {
bool treeNodeRecursive(std::string&, bool, CScriptAny*, asIScriptFunction&); bool treeNodeRecursive(std::string&, bool, CScriptAny*, asIScriptFunction&);
void space(); void space();
void space_params(int, int);
} }
} }

View File

@ -54,13 +54,16 @@ namespace Deer {
// Draws a button for a popup menu // Draws a button for a popup menu
bool menuItem(std::string&); 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 // Initializes the drag drop source with the id and the data you want to pass
void dragDropSource(std::string&, CScriptAny*, std::string&); void dragDropSource(std::string&, CScriptAny*, std::string&);
// Prepares the function to accept payload with the id and calls the function with the data // Prepares the function to accept payload with the id and calls the function with the data
void dragDropTarget(std::string&, CScriptAny*, asIScriptFunction*); void dragDropTarget(std::string&, CScriptAny*, asIScriptFunction*);
// Draws a simple input with a label, input and output string // Draws a simple input with a label, input and output string
bool inputText(std::string& label, std::string&, std::string&); bool inputText(std::string& label, std::string&, std::string&);
// Draws a simple checkbox // Draws a simple checkbox

View File

@ -5,7 +5,13 @@
#include "Deer/Scene.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<MeshComponent>()
#define GET_SHADER_COMPONENT(id) Scene::environment.getEntity(id).getComponent<ShaderComponent>()
#define ASSERT_ENTITY(func, ret) if (!assertEntity(func)) ret; #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 Deer {
namespace EditorEngine { namespace EditorEngine {
@ -154,6 +160,25 @@ namespace Deer {
.childCount; .childCount;
} }
bool MeshComponentStruct::assertMeshComponent(const char* funcName) {
if (!assertEntity(funcName)) return false;
Entity& ent = Scene::environment.getEntity(entityId);
if (!ent.hasComponent<MeshComponent>()) {
DEER_UI_ENGINE_ERROR("Error, calling MeshComponent.{0} entity {1} with id {2} has no MeshComponent",
funcName,
ent.getComponent<TagComponent>().tag.c_str(),
entityId
);
if (currentDockPanelExecution)
currentDockPanelExecution->invalidate();
return false;
}
return true;
}
EntityStruct EntityChildArrayStruct::getChild(int i) { EntityStruct EntityChildArrayStruct::getChild(int i) {
ASSERT_ENTITY("getChild()", return *this); ASSERT_ENTITY("getChild()", return *this);
@ -214,99 +239,114 @@ namespace Deer {
} }
} }
bool MeshComponentStruct::isActive() { EntityStruct EntityStruct::getShaderComponent() {
ASSERT_ENTITY("isActive()", return false); ASSERT_ENTITY("getShaderComponent()", return *this);
Entity& self = GET_ENTITY(entityId); Entity& self = GET_ENTITY(entityId);
if (!self.hasComponent<MeshComponent>()) { if (!self.hasComponent<ShaderComponent>()) {
DEER_UI_ENGINE_ERROR("Entity {0} has no component Mesh Component", entityId); self.addComponent<ShaderComponent>();
if (currentDockPanelExecution)
currentDockPanelExecution->invalidate();
return false;
} }
return self.getComponent<MeshComponent>().isActive(); return *this;
}
bool EntityStruct::hasShaderComponent() {
ASSERT_ENTITY("hasShaderComponent()", return false);
Entity& self = GET_ENTITY(entityId);
return self.hasComponent<ShaderComponent>();
}
void EntityStruct::removeShaderComponent() {
ASSERT_ENTITY("removeShaderComponent()", return);
Entity& self = GET_ENTITY(entityId);
if (self.hasComponent<ShaderComponent>()) {
self.removeComponent<ShaderComponent>();
}
}
bool MeshComponentStruct::isActive() {
ASSERT_MESH_COMPONENT("isActive()", return false);
return GET_MESH_COMPONENT(entityId).isActive();
} }
void MeshComponentStruct::setActive(bool value) { void MeshComponentStruct::setActive(bool value) {
ASSERT_ENTITY("setActive(bool)", return); ASSERT_MESH_COMPONENT("setActive(bool)", return);
Entity& self = GET_ENTITY(entityId);
if (!self.hasComponent<MeshComponent>()) { GET_MESH_COMPONENT(entityId).setActive(value);
DEER_UI_ENGINE_ERROR("Entity {0} has no component Mesh Component", entityId);
if (currentDockPanelExecution)
currentDockPanelExecution->invalidate();
return;
}
self.getComponent<MeshComponent>().setActive(value);
} }
bool MeshComponentStruct::hasMesh() { 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<MeshComponent>()) { void MeshComponentStruct::clear() {
DEER_UI_ENGINE_ERROR("Entity {0} has no component Mesh Component", entityId); 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<ShaderComponent>()) {
DEER_UI_ENGINE_ERROR("Error, calling ShaderComponent.{0} entity {1} with id {2} has no ShaderComponent",
funcName,
ent.getComponent<TagComponent>().tag.c_str(),
entityId
);
if (currentDockPanelExecution) if (currentDockPanelExecution)
currentDockPanelExecution->invalidate(); currentDockPanelExecution->invalidate();
return false; return false;
} }
return self.getComponent<MeshComponent>().hasMesh(); return true;
} }
void MeshComponentStruct::clear() { void ShaderComponentStruct::clear() {
ASSERT_ENTITY("clear()", return); ASSERT_SHADER_COMPONENT("clear()", return);
Entity& self = GET_ENTITY(entityId); GET_SHADER_COMPONENT(entityId).clear();
if (!self.hasComponent<MeshComponent>()) {
DEER_UI_ENGINE_ERROR("Entity {0} has no component Mesh Component", entityId);
if (currentDockPanelExecution)
currentDockPanelExecution->invalidate();
return;
} }
return self.removeComponent<MeshComponent>(); std::string ShaderComponentStruct::getShader() {
ASSERT_SHADER_COMPONENT("getShader()", return "NULL");
return GET_SHADER_COMPONENT(entityId).getName();
} }
std::string MeshComponentStruct::getMesh() { void ShaderComponentStruct::setShader(std::string& name) {
ASSERT_ENTITY("getMesh()", return "NULL"); ASSERT_SHADER_COMPONENT("getShader()", return);
Entity& self = GET_ENTITY(entityId); uint16_t shaderId = ShaderManager::loadShader(name);
GET_SHADER_COMPONENT(entityId).setShader(shaderId);
if (!self.hasComponent<MeshComponent>()) {
DEER_UI_ENGINE_ERROR("Entity {0} has no component Mesh Component", entityId);
if (currentDockPanelExecution)
currentDockPanelExecution->invalidate();
return "NULL";
} }
return self.getComponent<MeshComponent>().getMeshName();
}
void MeshComponentStruct::setMesh(std::string& name) {
ASSERT_ENTITY("setMesh()", return);
Entity& self = GET_ENTITY(entityId);
if (!self.hasComponent<MeshComponent>()) {
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<MeshComponent>().setMesh(meshId);
}
} }
} }

View File

@ -8,6 +8,9 @@
namespace Deer { namespace Deer {
namespace EditorEngine { namespace EditorEngine {
void registerTransformComponentFunctions();
void registerMeshComponentFunction();
void registerShaderComponentFunctions();
void registerEntityStructs() { void registerEntityStructs() {
AS_CHECK(scriptEngine->RegisterObjectType("Entity", sizeof(EntityStruct), AS_CHECK(scriptEngine->RegisterObjectType("Entity", sizeof(EntityStruct),
@ -27,9 +30,16 @@ namespace Deer {
AS_CHECK(scriptEngine->RegisterObjectType("MeshComponent", sizeof(EntityStruct), AS_CHECK(scriptEngine->RegisterObjectType("MeshComponent", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS)); asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectType("ShaderComponent", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
} }
void registerEntityFunctions() { void registerEntityFunctions() {
registerTransformComponentFunctions();
registerMeshComponentFunction();
registerShaderComponentFunctions();
// ENTITY // ENTITY
AS_CHECK(scriptEngine->RegisterObjectMethod( AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity", "Entity",
@ -165,6 +175,73 @@ namespace Deer {
asCALL_THISCALL 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 // TRANSFORM COMPONENT
AS_CHECK(scriptEngine->RegisterObjectMethod( AS_CHECK(scriptEngine->RegisterObjectMethod(
@ -209,59 +286,37 @@ namespace Deer {
asCALL_THISCALL asCALL_THISCALL
)); ));
}
void registerShaderComponentFunctions() {
AS_CHECK(scriptEngine->RegisterObjectMethod( AS_CHECK(scriptEngine->RegisterObjectMethod(
"MeshComponent", "ShaderComponent",
"bool get_isActive() const property", "bool get_hasShader() const property ",
asMETHOD(MeshComponentStruct, isActive), asMETHOD(ShaderComponentStruct, hasShader),
asCALL_THISCALL asCALL_THISCALL
)); ));
AS_CHECK(scriptEngine->RegisterObjectMethod( AS_CHECK(scriptEngine->RegisterObjectMethod(
"MeshComponent", "ShaderComponent",
"bool get_hasMesh() const property",
asMETHOD(MeshComponentStruct, hasMesh),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"MeshComponent",
"void clear() ", "void clear() ",
asMETHOD(MeshComponentStruct, clear), asMETHOD(ShaderComponentStruct, clear),
asCALL_THISCALL asCALL_THISCALL
)); ));
AS_CHECK(scriptEngine->RegisterObjectMethod( AS_CHECK(scriptEngine->RegisterObjectMethod(
"MeshComponent", "ShaderComponent",
"string getMesh()", "string getShader() ",
asMETHOD(MeshComponentStruct, getMesh), asMETHOD(ShaderComponentStruct, getShader),
asCALL_THISCALL asCALL_THISCALL
)); ));
AS_CHECK(scriptEngine->RegisterObjectMethod( AS_CHECK(scriptEngine->RegisterObjectMethod(
"MeshComponent", "ShaderComponent",
"void setMesh(string&in)", "void setShader(const string& in) ",
asMETHOD(MeshComponentStruct, setMesh), asMETHOD(ShaderComponentStruct, setShader),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"MeshComponent",
"void set_isActive(const bool) property",
asMETHOD(MeshComponentStruct, setActive),
asCALL_THISCALL asCALL_THISCALL
)); ));
} }
void registerTransformComponent() {
AS_CHECK(scriptEngine->RegisterObjectType("Entity", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectBehaviour(
"Entity", asBEHAVE_CONSTRUCT, "void f(int)",
asFunctionPtr(constructEntityStruct),
asCALL_CDECL_OBJLAST
));
}
} }
} }

View File

@ -133,5 +133,8 @@ namespace Deer {
ImGui::Dummy(ImVec2(10, 10)); ImGui::Dummy(ImVec2(10, 10));
} }
void space_params(int x, int y) {
ImGui::Dummy(ImVec2(x, y));
}
} }
} }

View File

@ -39,11 +39,11 @@ namespace Deer {
ImGui::PopFont(); ImGui::PopFont();
} }
void titleCenterY(std::string& txt, int) { void titleCenterY(std::string& txt, int height) {
ImGui::PushFont(titleText); ImGui::PushFont(titleText);
float textHeight = ImGui::GetFontSize(); float textHeight = ImGui::GetFontSize();
float yOffset = (64.0f - textHeight) * 0.5f; float yOffset = (height - textHeight) * 0.5f;
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + yOffset); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + yOffset);
ImGui::Text("%s", txt.c_str()); ImGui::Text("%s", txt.c_str());
@ -183,6 +183,30 @@ namespace Deer {
return ImGui::MenuItem(txt.c_str()); 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) { void dragDropSource(std::string& id, CScriptAny* data, std::string& debugText) {
if (DragDropPayload::payload && !ImGui::GetDragDropPayload()) { if (DragDropPayload::payload && !ImGui::GetDragDropPayload()) {
DragDropPayload::payload->Release(); DragDropPayload::payload->Release();

View File

@ -66,12 +66,30 @@ namespace Deer {
asCALL_CDECL asCALL_CDECL
)); ));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void space(int, int = 10)",
asFUNCTION(space_params),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction( AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool menuItem(const string& in)", "bool menuItem(const string& in)",
asFUNCTION(menuItem), asFUNCTION(menuItem),
asCALL_CDECL 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( AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool button(const string& in)", "bool button(const string& in)",
asFUNCTION(button), asFUNCTION(button),

BIN
roe/editor/icons/empty.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 309 B

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 270 B

View File

@ -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();
}
}
}

View File

@ -18,23 +18,67 @@ void renderMeshComponent(any@ data) {
MeshComponent meshComponent = entity.getMeshComponent(); 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) { if (meshComponent.hasMesh) {
meshComponent.isActive = checkbox("Active", meshComponent.isActive); meshComponent.isActive = checkbox("Active", meshComponent.isActive);
} else { } else {
checkboxDisabled("Active", meshComponent.isActive); checkboxDisabled("Active", meshComponent.isActive);
} }
}
space(); void renderShaderComponent(any@ data) {
Entity entity;
data.retrieve(entity);
drawIcon("object3d", 64); ShaderComponent shaderComponent = entity.getShaderComponent();
dragDropTarget("MESH", any(meshComponent), setMeshComponentMesh); if (shaderComponent.hasShader) {
drawIcon("shader", 32);
} else {
drawIcon("empty", 32);
}
dragDropTarget("SHADER", any(shaderComponent), setShaderComponent);
if (shaderComponent.hasShader) {
sameline();
space();
sameline(); sameline();
titleCenterY("Mesh Name", 64);
dragDropTarget("MESH", any(meshComponent), setMeshComponentMesh);
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){ void setMeshComponentMesh(any@ meshComponent_data, any@ mesh_data){
@ -44,6 +88,15 @@ void setMeshComponentMesh(any@ meshComponent_data, any@ mesh_data){
MeshComponent meshComponent; MeshComponent meshComponent;
meshComponent_data.retrieve(meshComponent); meshComponent_data.retrieve(meshComponent);
print(mesh);
meshComponent.setMesh(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);
}

View File

@ -33,6 +33,9 @@ class PropertiesPannel : DockPanel {
componentNode("Mesh Component", any(entity), renderMeshComponent); componentNode("Mesh Component", any(entity), renderMeshComponent);
} }
if (entity.hasShaderComponent()) {
componentNode("Shader Component", any(entity), renderShaderComponent);
}
space(); space();
separator(); separator();
@ -41,28 +44,10 @@ class PropertiesPannel : DockPanel {
openPopup("ADD_COMPONENT", any(entity)); openPopup("ADD_COMPONENT", any(entity));
} }
simplePopup("ADD_COMPONENT", ReciverFunc(this.addComponentPopup)); simplePopup("ADD_COMPONENT", addComponentPopup);
modalPopup("Rename entity", renameEntity); 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) { void renameEntityMenu(any@ data) {
Entity entity; Entity entity;
data.retrieve(entity); data.retrieve(entity);

View File

@ -32,6 +32,10 @@ class ShaderExplorer : DockPanel {
int meshCount = getResourceCount(resourceType, cache_currentPath); int meshCount = getResourceCount(resourceType, cache_currentPath);
for (int i = 0; i < meshCount; i++) { for (int i = 0; i < meshCount; i++) {
drawIconCentered("file", 64); drawIconCentered("file", 64);
dragDropSource("SHADER",
any(getResourcePathById(resourceType, cache_currentPath, i)),
getResourcePathById(resourceType, cache_currentPath, i));
textCenter(getResourceNameById(resourceType, cache_currentPath, i)); textCenter(getResourceNameById(resourceType, cache_currentPath, i));
nextColumn(); nextColumn();

View File

@ -16,7 +16,7 @@ DockId=0x00000004,1
[Window][Game Window] [Window][Game Window]
Pos=258,24 Pos=258,24
Size=620,474 Size=499,490
Collapsed=0 Collapsed=0
DockId=0x00000006,0 DockId=0x00000006,0
@ -27,14 +27,14 @@ Collapsed=0
DockId=0x00000001,0 DockId=0x00000001,0
[Window][Terrain Editor] [Window][Terrain Editor]
Pos=880,24 Pos=759,24
Size=400,474 Size=521,490
Collapsed=0 Collapsed=0
DockId=0x00000004,0 DockId=0x00000004,0
[Window][Viewport] [Window][Viewport]
Pos=258,24 Pos=258,24
Size=620,474 Size=499,490
Collapsed=0 Collapsed=0
DockId=0x00000006,1 DockId=0x00000006,1
@ -57,14 +57,14 @@ Collapsed=0
DockId=0x00000008,1 DockId=0x00000008,1
[Window][MeshExplorer] [Window][MeshExplorer]
Pos=0,500 Pos=0,516
Size=1280,220 Size=1280,204
Collapsed=0 Collapsed=0
DockId=0x00000008,0 DockId=0x00000008,0
[Window][TreePannel] [Window][TreePannel]
Pos=0,24 Pos=0,24
Size=256,474 Size=256,490
Collapsed=0 Collapsed=0
DockId=0x00000005,0 DockId=0x00000005,0
@ -79,8 +79,8 @@ Size=351,75
Collapsed=0 Collapsed=0
[Window][PropertiesPannel] [Window][PropertiesPannel]
Pos=880,24 Pos=759,24
Size=400,474 Size=521,490
Collapsed=0 Collapsed=0
DockId=0x00000004,1 DockId=0x00000004,1
@ -91,19 +91,19 @@ Collapsed=0
DockId=0x00000004,1 DockId=0x00000004,1
[Window][ShaderExplorer] [Window][ShaderExplorer]
Pos=0,500 Pos=0,516
Size=1280,220 Size=1280,204
Collapsed=0 Collapsed=0
DockId=0x00000008,1 DockId=0x00000008,1
[Docking][Data] [Docking][Data]
DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=1280,696 Split=Y 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=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=0x00000005 Parent=0x00000003 SizeRef=256,446 Selected=0xE45B9F93
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=620,446 CentralNode=1 Selected=0x13926F0B DockNode ID=0x00000006 Parent=0x00000003 SizeRef=499,446 CentralNode=1 Selected=0x13926F0B
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=400,338 Selected=0x2A2C795E DockNode ID=0x00000004 Parent=0x00000001 SizeRef=521,338 Selected=0xA35A27E3
DockNode ID=0x00000002 Parent=0x00000007 SizeRef=2560,331 Selected=0xCF339702 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