From ab4a94dc68ce39f00fa70182589a32b3271cd0a5 Mon Sep 17 00:00:00 2001 From: OusmBlueNinja <89956790+OusmBlueNinja@users.noreply.github.com> Date: Thu, 17 Apr 2025 17:07:39 -0500 Subject: [PATCH] Updated Lighting and stuff, error handling --- imgui.ini | 10 +- remake/build.log | 4 +- src/assets/icons/error.png | Bin 0 -> 9615 bytes src/assets/icons/lightbulb-on-10.png | Bin 0 -> 8471 bytes src/assets/scenes/lighting_test_2.cene | 160 ++++++++++++++++++++++++ src/src/Components/Component.h | 3 + src/src/Components/ScriptComponent.cpp | 38 ++++++ src/src/Components/ScriptComponent.h | 21 ++++ src/src/Components/SpriteComponent.cpp | 50 ++++++-- src/src/Components/SpriteComponent.h | 13 +- src/src/Components/TextComonent.cpp | 50 ++++++++ src/src/Components/TextComponent.h | 23 ++++ src/src/Engine.cpp | 56 ++++++--- src/src/Engine.h | 1 + src/src/Entitys/Object.cpp | 118 ++++++++++++------ src/src/Entitys/Object.h | 14 +-- src/src/Renderer.cpp | 161 +++++++++++++------------ src/src/utils/ExceptionHandler.cpp | 31 +++++ src/src/utils/ExceptionHandler.h | 32 +++++ src/src/utils/UID.cpp | 31 +++++ src/src/utils/UID.h | 12 ++ 21 files changed, 676 insertions(+), 152 deletions(-) create mode 100644 src/assets/icons/error.png create mode 100644 src/assets/icons/lightbulb-on-10.png create mode 100644 src/assets/scenes/lighting_test_2.cene create mode 100644 src/src/Components/ScriptComponent.cpp create mode 100644 src/src/Components/ScriptComponent.h create mode 100644 src/src/Components/TextComonent.cpp create mode 100644 src/src/Components/TextComponent.h create mode 100644 src/src/utils/ExceptionHandler.cpp create mode 100644 src/src/utils/ExceptionHandler.h create mode 100644 src/src/utils/UID.cpp create mode 100644 src/src/utils/UID.h diff --git a/imgui.ini b/imgui.ini index a5f7bf4..287ef1a 100644 --- a/imgui.ini +++ b/imgui.ini @@ -27,7 +27,7 @@ DockId=0x00000001,0 [Window][Viewport] Pos=265,19 -Size=1263,674 +Size=1263,786 Collapsed=0 DockId=0x00000007,0 @@ -42,8 +42,8 @@ Collapsed=0 DockId=0x00000006,0 [Window][Console] -Pos=265,695 -Size=1263,482 +Pos=265,807 +Size=1263,370 Collapsed=0 DockId=0x00000008,0 @@ -58,8 +58,8 @@ DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1920,1158 Split=X DockNode ID=0x00000003 Parent=0x11111111 SizeRef=888,1158 Split=X DockNode ID=0x00000001 Parent=0x00000003 SizeRef=263,701 HiddenTabBar=1 Selected=0x12EF0F59 DockNode ID=0x00000002 Parent=0x00000003 SizeRef=623,701 Split=Y Selected=0xC450F867 - DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,674 CentralNode=1 Selected=0x36D5F628 - DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,482 Selected=0xEA83D666 + DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,329 CentralNode=1 Selected=0xC450F867 + DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,370 Selected=0xEA83D666 DockNode ID=0x00000004 Parent=0x11111111 SizeRef=390,1158 Split=Y Selected=0x36DC96AB DockNode ID=0x00000005 Parent=0x00000004 SizeRef=407,835 HiddenTabBar=1 Selected=0x36DC96AB DockNode ID=0x00000006 Parent=0x00000004 SizeRef=407,321 HiddenTabBar=1 Selected=0x3FC1A724 diff --git a/remake/build.log b/remake/build.log index c8c354d..d897fca 100644 --- a/remake/build.log +++ b/remake/build.log @@ -1,3 +1,3 @@ -[COMPILE] g++ -std=c++20 -Wall -Isrc/include -Isrc/vendor -Isrc/vendor/imgui -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\utils\Logging.cpp -o src\build\utils\Logging.o -[LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\CameraComponent.o src\build\Components\LightComponent.o src\build\Components\SpriteComponent.o src\build\Components\TilemapComponent.o src\build\Entitys\Object.o src\build\utils\EngineConfig.o src\build\utils\FileDialog.o src\build\utils\Logging.o src\build\utils\Shader.o src\build\utils\utils.o src\build\imgui\imgui.o src\build\imgui\imgui_demo.o src\build\imgui\imgui_draw.o src\build\imgui\imgui_impl_glfw.o src\build\imgui\imgui_impl_opengl3.o src\build\imgui\imgui_tables.o src\build\imgui\imgui_widgets.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto +[COMPILE] g++ -std=c++20 -Wall -Isrc/include -Isrc/vendor -Isrc/vendor/imgui -IC:/msys64/mingw64/include -Isrc\vendor\imgui -IC:\msys64\mingw64\lib\libyaml-cpp.a -MMD -MP -c src\src\Entitys\Object.cpp -o src\build\Entitys\Object.o +[LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\CameraComponent.o src\build\Components\LightComponent.o src\build\Components\SpriteComponent.o src\build\Components\TextComonent.o src\build\Components\TilemapComponent.o src\build\Entitys\Object.o src\build\utils\EngineConfig.o src\build\utils\ExceptionHandler.o src\build\utils\FileDialog.o src\build\utils\Logging.o src\build\utils\Shader.o src\build\utils\UID.o src\build\utils\utils.o src\build\imgui\imgui.o src\build\imgui\imgui_demo.o src\build\imgui\imgui_draw.o src\build\imgui\imgui_impl_glfw.o src\build\imgui\imgui_impl_opengl3.o src\build\imgui\imgui_tables.o src\build\imgui\imgui_widgets.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto [RUN] Executed app.exe successfully. diff --git a/src/assets/icons/error.png b/src/assets/icons/error.png new file mode 100644 index 0000000000000000000000000000000000000000..031b0aa18a46214e9d22bc7e81b9445e1acc5dee GIT binary patch literal 9615 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 MlBQy{yk*$`0WpoHGXMYp literal 0 HcmV?d00001 diff --git a/src/assets/icons/lightbulb-on-10.png b/src/assets/icons/lightbulb-on-10.png new file mode 100644 index 0000000000000000000000000000000000000000..5367091b495e38e5d827a630fc2d62437fd9f309 GIT binary patch literal 8471 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 literal 0 HcmV?d00001 diff --git a/src/assets/scenes/lighting_test_2.cene b/src/assets/scenes/lighting_test_2.cene new file mode 100644 index 0000000..3f26606 --- /dev/null +++ b/src/assets/scenes/lighting_test_2.cene @@ -0,0 +1,160 @@ +engine_version: 0.1.0 +scene_name: lighting_test_2 +scene_hash: 0d3581851da4c35a61a9f3eb409408b8ca1d440c1a1ff97cc4ac73d2ef0682a2 +format_version: 1 +objects: + - name: Tiles + uid: f5e01f7892874a67b662633650b41dbd + id: 3 + position: [0, 0] + layer: 0 + components: [] + children: + - name: Bark + uid: 7dc3bbf8affb4844ae3801f03857b904 + id: 4 + position: [0, 0] + layer: 0 + components: + - type: SpriteComponent + texture: C:\Users\spenc\OneDrive\Pictures\textures\bark_willow_02_diff_1k.png + normalMap: C:\Users\spenc\OneDrive\Pictures\textures\bark_willow_02_nor_gl_1k.png + renderType: Lit + children: [] + - name: Planks + uid: 13d8988343354e3c8a1f51c03ed40cda + id: 5 + position: [1024, 0] + layer: 0 + components: + - type: SpriteComponent + texture: C:\Users\spenc\OneDrive\Pictures\textures\wood_floor_worn_diff_1k.png + normalMap: C:\Users\spenc\OneDrive\Pictures\textures\wood_floor_worn_nor_gl_1k.png + renderType: Lit + children: [] + - name: Rocks + uid: cff28abe7e3b455ab9b756acc84cd2d7 + id: 6 + position: [0, 1024] + layer: 0 + components: + - type: SpriteComponent + texture: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_diff_1k.png + normalMap: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_nor_gl_1k.png + renderType: Lit + children: [] + - name: Metal + uid: 98967eb30e5b429b992766d8062b7c17 + id: 7 + position: [1024, 1025] + layer: 0 + components: + - type: SpriteComponent + texture: C:\Users\spenc\OneDrive\Pictures\textures\metal_plate_diff_1k.png + normalMap: C:\Users\spenc\OneDrive\Pictures\textures\metal_plate_nor_gl_1k.png + renderType: Lit + children: [] + - name: Logo + uid: c4ce6f16dfb347b0ae0ac67f5881b243 + id: 8 + position: [2048, 0] + layer: 0 + components: + - type: SpriteComponent + texture: C:\Users\spenc\OneDrive\Pictures\blue_logo.png + normalMap: C:\Users\spenc\OneDrive\Pictures\textures\images.jpg + renderType: Lit + children: [] + - name: Carbooon Fobar + uid: 5ea269572751401da6d86519d3513b7d + id: 9 + position: [2567, 1545] + layer: 1 + components: + - type: SpriteComponent + texture: C:\Users\spenc\OneDrive\Pictures\textures\carbon-fiber-smooth-bl\carbon-fiber-smooth-bl\carbon-fiber_smooth_albedo.png + normalMap: C:\Users\spenc\OneDrive\Pictures\textures\carbon-fiber-smooth-bl\carbon-fiber-smooth-bl\carbon-fiber_smooth_normal-ogl.png + renderType: Lit + children: [] + - name: Mud + uid: a36b71937ba349bd8e6414f75be9ee16 + id: 10 + position: [0, 2578] + layer: 0 + components: + - type: SpriteComponent + texture: C:\Users\spenc\OneDrive\Pictures\textures\mud-bl\mud-bl\mud_albedo.png + normalMap: C:\Users\spenc\OneDrive\Pictures\textures\mud-bl\mud-bl\mud_normal-ogl.png + renderType: Lit + children: [] + - name: Lights + uid: 051b338a725a4076ad53ad8fa00c5f4e + id: 12 + position: [-556, 951] + layer: 0 + components: [] + children: + - name: Red + uid: 6afde2dd47aa4557b6afb1a607c99dc8 + id: 13 + position: [1, 0] + layer: 0 + components: + - type: LightComponent + color: + - 1 + - 0 + - 0 + intensity: 2 + radius: 1000 + falloff: 0.100000001 + type: 0 + children: [] + - name: Green + uid: 0f950d76d24b4dc18f54cab2c3aaaf9a + id: 14 + position: [500, 0] + layer: 0 + components: + - type: LightComponent + color: + - 0 + - 1 + - 0 + intensity: 2 + radius: 1000 + falloff: 1 + type: 0 + children: [] + - name: Blue + uid: 09f722f51c7c4b0f98de3a0a16d127c4 + id: 15 + position: [250, 250] + layer: 0 + components: + - type: LightComponent + color: + - 0 + - 0 + - 1 + intensity: 2 + radius: 1000 + falloff: 1 + type: 0 + children: [] + - name: Ambient light + uid: d4fb425522d84a8cbbd7d1415bcd93df + id: 16 + position: [500, 500] + layer: 0 + components: + - type: LightComponent + color: + - 1 + - 1 + - 1 + intensity: 1 + radius: 1000000 + falloff: 1 + type: 0 + children: [] \ No newline at end of file diff --git a/src/src/Components/Component.h b/src/src/Components/Component.h index 2e31662..7574c23 100644 --- a/src/src/Components/Component.h +++ b/src/src/Components/Component.h @@ -3,6 +3,8 @@ #include #include #include +#include "../utils/ExceptionHandler.h" + class Object; @@ -21,4 +23,5 @@ public: protected: Object* owner; + }; diff --git a/src/src/Components/ScriptComponent.cpp b/src/src/Components/ScriptComponent.cpp new file mode 100644 index 0000000..c27cf4e --- /dev/null +++ b/src/src/Components/ScriptComponent.cpp @@ -0,0 +1,38 @@ +#include "ScriptComponent.h" +#include "../utils/Logging.h" +#include "../utils/ExceptionHandler.h" + +ScriptComponent::ScriptComponent(Object* owner) + : Component(owner) {} + +void ScriptComponent::SetScriptPath(const std::string& path) { + scriptPath = path; +} + +const std::string& ScriptComponent::GetScriptPath() const { + return scriptPath; +} + +void ScriptComponent::Save(YAML::Emitter& out) const { + out << YAML::BeginMap; + out << YAML::Key << "type" << YAML::Value << "ScriptComponent"; + out << YAML::Key << "scriptPath" << YAML::Value << scriptPath; + out << YAML::EndMap; +} + +void ScriptComponent::Load(const YAML::Node& node) { + try { + if (!node["scriptPath"]) { + RecoverableError("Missing 'scriptPath' in ScriptComponent", Create::Exceptions::MissingField).Handle(); + return; + } + if (!node["scriptPath"].IsScalar()) { + RecoverableError("'scriptPath' must be a string", Create::Exceptions::InvalidFormat).Handle(); + return; + } + + scriptPath = node["scriptPath"].as(); + } catch (const YAML::Exception& e) { + RecoverableError("Failed to load ScriptComponent: " + std::string(e.what()), Create::Exceptions::ComponentLoad).Handle(); + } +} diff --git a/src/src/Components/ScriptComponent.h b/src/src/Components/ScriptComponent.h new file mode 100644 index 0000000..338bcd2 --- /dev/null +++ b/src/src/Components/ScriptComponent.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Component.h" +#include +#include + +class ScriptComponent : public Component { +public: + ScriptComponent(Object* owner); + + void SetScriptPath(const std::string& path); + const std::string& GetScriptPath() const; + + virtual std::string GetName() const override { return "ScriptComponent"; } + + virtual void Save(YAML::Emitter& out) const override; + virtual void Load(const YAML::Node& node) override; + +private: + std::string scriptPath; +}; diff --git a/src/src/Components/SpriteComponent.cpp b/src/src/Components/SpriteComponent.cpp index 0243792..6b5d37f 100644 --- a/src/src/Components/SpriteComponent.cpp +++ b/src/src/Components/SpriteComponent.cpp @@ -45,7 +45,7 @@ unsigned int SpriteComponent::LoadTexture(const std::string& path, bool updateSi if (!data) { Logger::LogError("Failed to load image: '%s': %s", path.c_str(), stbi_failure_reason()); - textureCache.erase(it); // clean up placeholder + textureCache.erase(it); return 0; } @@ -130,14 +130,50 @@ void SpriteComponent::Save(YAML::Emitter &out) const out << YAML::Key << "type" << YAML::Value << "SpriteComponent"; out << YAML::Key << "texture" << YAML::Value << texturePath; out << YAML::Key << "normalMap" << YAML::Value << normalMapPath; + out << YAML::Key << "renderType" << YAML::Value << (renderType == RenderType::Lit ? "Lit" : "Unlit"); out << YAML::EndMap; } -void SpriteComponent::Load(const YAML::Node &node) -{ - if (node["texture"] && !node["texture"].as().empty()) - SetTexture(node["texture"].as()); - if (node["normalMap"] && !node["normalMap"].as().empty()) - SetNormalMap(node["normalMap"].as()); +void SpriteComponent::Load(const YAML::Node& node) +{ + try { + if (!node["texture"]) + { + RecoverableError("Missing 'texture' key in SpriteComponent YAML node", Create::Exceptions::MissingField).Handle(); + } + else if (!node["texture"].IsScalar()) + { + RecoverableError("'texture' field must be a string", Create::Exceptions::InvalidFormat).Handle(); + } + else if (!node["texture"].as().empty()) + { + SetTexture(node["texture"].as()); + } + + if (!node["normalMap"]) + { + RecoverableError("Missing 'normalMap' key in SpriteComponent YAML node", Create::Exceptions::MissingField).Handle(); + } + else if (!node["normalMap"].IsScalar()) + { + RecoverableError("'normalMap' field must be a string", Create::Exceptions::InvalidFormat).Handle(); + } + else if (!node["normalMap"].as().empty()) + { + SetNormalMap(node["normalMap"].as()); + } + + if (node["renderType"] && node["renderType"].IsScalar()) { + std::string typeStr = node["renderType"].as(); + if (typeStr == "Lit") renderType = RenderType::Lit; + else if (typeStr == "Unlit") renderType = RenderType::Unlit; + else + RecoverableError("Invalid 'renderType' value in SpriteComponent: " + typeStr, Create::Exceptions::InvalidFormat).Handle(); + } + + } catch (const YAML::Exception& e) { + RecoverableError("YAML parsing error in SpriteComponent::Load: " + std::string(e.what()), + Create::Exceptions::ComponentLoad).Handle(); + } } diff --git a/src/src/Components/SpriteComponent.h b/src/src/Components/SpriteComponent.h index f974e05..d534622 100644 --- a/src/src/Components/SpriteComponent.h +++ b/src/src/Components/SpriteComponent.h @@ -4,9 +4,16 @@ #include #include + + class SpriteComponent : public Component { public: SpriteComponent(Object* owner); + + enum class RenderType { + Unlit, + Lit + }; void SetTexture(const std::string& path); @@ -20,7 +27,8 @@ public: bool HasTexture(); - + RenderType GetRenderType() const { return renderType; } + void SetRenderType(RenderType type) { renderType = type; } virtual glm::vec2 GetSize() const { return size; } @@ -35,8 +43,11 @@ private: glm::vec2 size = { 64, 64 }; std::string texturePath; std::string normalMapPath; + RenderType renderType = RenderType::Lit; unsigned int textureID = 0; unsigned int normalMapID = 0; bool texture_loaded = false; unsigned int LoadTexture(const std::string& path, bool updateSize); + + }; diff --git a/src/src/Components/TextComonent.cpp b/src/src/Components/TextComonent.cpp new file mode 100644 index 0000000..e4fafea --- /dev/null +++ b/src/src/Components/TextComonent.cpp @@ -0,0 +1,50 @@ +#include "TextComponent.h" +#include +#include +#include + +TextComponent::TextComponent(Object* owner) + : Component(owner), text("") {} + +TextComponent::TextComponent(Object* owner, std::string initialText) + : Component(owner), text(std::move(initialText)) {} + +std::string TextComponent::GetName() const { + return "TextComponent"; +} + +void TextComponent::Save(YAML::Emitter& out) const { + out << YAML::BeginMap; + out << YAML::Key << "component" << YAML::Value << GetName(); + out << YAML::Key << "text" << YAML::Value << text; + out << YAML::EndMap; +} + + +void TextComponent::Load(const YAML::Node& node) { + if (!node["text"]) { + text = ""; + RecoverableError("'text' key missing in YAML", Create::Exceptions::MissingField).Handle(); + return; + } + + try { + text = node["text"].as(); + } catch (const YAML::BadConversion& e) { + RecoverableError("Invalid 'text' format: " + std::string(e.what()), Create::Exceptions::InvalidFormat).Handle(); + return; + } +} + + +const std::string& TextComponent::GetText() const { + return text; +} + +void TextComponent::SetText(const std::string& newText) { + text = newText; +} + +void TextComponent::SetText(std::string&& newText) { + text = std::move(newText); +} \ No newline at end of file diff --git a/src/src/Components/TextComponent.h b/src/src/Components/TextComponent.h new file mode 100644 index 0000000..894c632 --- /dev/null +++ b/src/src/Components/TextComponent.h @@ -0,0 +1,23 @@ +#pragma once + +#include "Component.h" // Base class definition +#include + + + +class TextComponent : public Component { +public: + TextComponent(Object* owner); + TextComponent(Object* owner, std::string initialText); + + std::string GetName() const override; + void Save(YAML::Emitter& out) const override; + void Load(const YAML::Node& node) override; + + const std::string& GetText() const; + void SetText(const std::string& newText); + void SetText(std::string&& newText); + +private: + std::string text; +}; \ No newline at end of file diff --git a/src/src/Engine.cpp b/src/src/Engine.cpp index 444df75..43fa793 100644 --- a/src/src/Engine.cpp +++ b/src/src/Engine.cpp @@ -9,6 +9,8 @@ #include "utils/FileDialog.h" #include "utils/Logging.h" +#include "utils/EngineConfig.h" + #include #include #include @@ -147,6 +149,11 @@ void DrawInspectorUI(std::shared_ptr selected) ImGui::InputInt("Layer", &selected->layer); + ImGui::Text("ID:%d", selected->uid.id); + ImGui::Text("UID:%s", selected->uid.uuid.c_str()); + + + ImGui::SeparatorText("Add Components"); if (ImGui::Button("Add SpriteComponent")) @@ -170,13 +177,20 @@ void DrawInspectorUI(std::shared_ptr selected) selected->AddComponent(); } - // Sprite UI... if (auto sprite = selected->GetComponent()) { ImGui::SeparatorText("Sprite Component"); - std::string tex = sprite->GetTexturePath(); - std::string norm = sprite->GetNormalMapPath(); + const char *renderTypes[] = {"Unlit", "Lit"}; + SpriteComponent::RenderType currentType = sprite->GetRenderType(); + int currentTypeIndex = static_cast(currentType); + + if (ImGui::Combo("Render Type", ¤tTypeIndex, renderTypes, IM_ARRAYSIZE(renderTypes))) + { + sprite->SetRenderType(static_cast(currentTypeIndex)); + } + + std::string tex = sprite->GetTexturePath(); ImGui::Text("Texture: %s", tex.c_str()); if (ImGui::Button("Load Texture")) { @@ -185,6 +199,7 @@ void DrawInspectorUI(std::shared_ptr selected) sprite->SetTexture(path); } + std::string norm = sprite->GetNormalMapPath(); ImGui::Text("Normal Map: %s", norm.c_str()); if (ImGui::Button("Load Normal Map")) { @@ -193,6 +208,9 @@ void DrawInspectorUI(std::shared_ptr selected) sprite->SetNormalMap(path); } + glm::vec2 size = sprite->GetSize(); + ImGui::Text("Size: %.0f x %.0f", size.x, size.y); + if (ImGui::Button("Remove SpriteComponent")) selected->RemoveComponent(); } @@ -313,16 +331,15 @@ void Engine::Run() if (ImGui::BeginPopupContextWindow("SceneTreeContext", ImGuiPopupFlags_MouseButtonRight)) { - if (ImGui::MenuItem("Create New Object")) + if (ImGui::MenuItem("Create New")) { auto obj = std::make_shared("NewObject"); - obj->AddComponent(); objects.push_back(obj); selected = obj; ImGui::OpenPopup("RenameObject"); } ImGui::Separator(); - if (ImGui::MenuItem("Create New Sprite Object")) + if (ImGui::MenuItem("Create New Sprite")) { auto obj = std::make_shared("NewSprite"); obj->AddComponent(); @@ -330,6 +347,14 @@ void Engine::Run() selected = obj; ImGui::OpenPopup("RenameObject"); } + if (ImGui::MenuItem("Create New Light")) + { + auto obj = std::make_shared("NewSprite"); + obj->AddComponent(); + objects.push_back(obj); + selected = obj; + ImGui::OpenPopup("RenameObject"); + } ImGui::EndPopup(); } @@ -488,7 +513,6 @@ void Engine::Run() } pendingDeletion.clear(); } - } void Engine::DrawObjectNode(const std::shared_ptr &obj) @@ -497,7 +521,7 @@ void Engine::DrawObjectNode(const std::shared_ptr &obj) ImGuiTreeNodeFlags_SpanAvailWidth | (obj == selected ? ImGuiTreeNodeFlags_Selected : 0); - bool open = ImGui::TreeNodeEx((void *)(intptr_t)obj->id, flags, "%s", obj->GetName().c_str()); + bool open = ImGui::TreeNodeEx((void *)(intptr_t)obj->uid.id, flags, "%s", obj->GetName().c_str()); if (ImGui::IsItemClicked()) selected = obj; @@ -561,26 +585,28 @@ void Engine::SaveScene(const std::string &path) YAML::Emitter out; YAML::Emitter sceneData; + // Serialize object list only sceneData << YAML::BeginSeq; for (const auto &obj : objects) obj->Save(sceneData); sceneData << YAML::EndSeq; - std::string sceneString = sceneData.c_str(); + // Hash the serialized object data + std::string objectData = sceneData.c_str(); unsigned char hash[SHA256_DIGEST_LENGTH]; - SHA256(reinterpret_cast(sceneString.c_str()), sceneString.size(), hash); + SHA256(reinterpret_cast(objectData.c_str()), objectData.size(), hash); std::ostringstream hashHex; for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) hashHex << std::hex << std::setw(2) << std::setfill('0') << static_cast(hash[i]); - // Output full file + // Build final full YAML output out << YAML::BeginMap; - out << YAML::Key << "engine_version" << YAML::Value << "0.1.0"; + out << YAML::Key << "engine_version" << YAML::Value << g_engineConfig.version; out << YAML::Key << "scene_name" << YAML::Value << std::filesystem::path(path).stem().string(); out << YAML::Key << "scene_hash" << YAML::Value << hashHex.str(); out << YAML::Key << "format_version" << YAML::Value << 1; - out << YAML::Key << "objects" << YAML::Value << YAML::Load(sceneString); + out << YAML::Key << "objects" << YAML::Value << YAML::Load(objectData); out << YAML::EndMap; std::ofstream file(path); @@ -614,7 +640,6 @@ void Engine::LoadScene(const std::string &path) Logger::LogDebug("[LoadScene] Verifying Scene"); - if (!root["engine_version"] || !root["format_version"] || !root["scene_name"]) { Logger::LogError("[LoadScene] Missing required metadata!"); @@ -633,7 +658,7 @@ void Engine::LoadScene(const std::string &path) } Logger::LogDebug("[LoadScene] Reseting Scene."); - + objects.clear(); Logger::LogDebug("[LoadScene] Recreting Objects"); @@ -644,7 +669,6 @@ void Engine::LoadScene(const std::string &path) auto obj = std::make_shared("[DefaultObject]"); obj->Load(node); objects.push_back(obj); - } Logger::LogInfo("[LoadScene] Loaded scene: %s", root["scene_name"].as().c_str()); diff --git a/src/src/Engine.h b/src/src/Engine.h index c04ffe6..64a8477 100644 --- a/src/src/Engine.h +++ b/src/src/Engine.h @@ -21,6 +21,7 @@ private: void SaveScene(const std::string& path); void LoadScene(const std::string& path); void ShowDebugOverlay(float deltaTime); + int m_Reserved_draws; diff --git a/src/src/Entitys/Object.cpp b/src/src/Entitys/Object.cpp index fd81daa..0100dbc 100644 --- a/src/src/Entitys/Object.cpp +++ b/src/src/Entitys/Object.cpp @@ -1,112 +1,156 @@ #include "Object.h" - #include "../Components/Component.h" #include "../Components/SpriteComponent.h" #include "../Components/CameraComponent.h" #include "../Components/LightComponent.h" #include "../Components/TilemapComponent.h" - +#include "../Components/TextComponent.h" #include "../utils/Logging.h" - - +#include "../utils/UID.h" #include -static int nextID = 0; - -Object::Object(const std::string& name) - : name(name), localPosition(0.0f, 0.0f), id(nextID++) {} +Object::Object(const std::string &name) + : name(name), localPosition(0.0f, 0.0f), uid() {} Object::~Object() {} -void Object::SetParent(Object* newParent) { +void Object::SetParent(Object *newParent) +{ if (parent) parent->RemoveChild(this); parent = newParent; } -void Object::AddChild(std::shared_ptr child) { +void Object::AddChild(std::shared_ptr child) +{ child->SetParent(this); children.push_back(child); } -void Object::RemoveChild(Object* child) { +void Object::RemoveChild(Object *child) +{ children.erase(std::remove_if(children.begin(), children.end(), - [child](const std::shared_ptr& obj) { - return obj.get() == child; - }), children.end()); + [child](const std::shared_ptr &obj) + { + return obj.get() == child; + }), + children.end()); } -glm::vec2 Object::GetLocalPosition() const { +glm::vec2 Object::GetLocalPosition() const +{ return localPosition; } -void Object::SetLocalPosition(glm::vec2 pos) { +void Object::SetLocalPosition(glm::vec2 pos) +{ localPosition = pos; } -glm::vec2 Object::GetWorldPosition() const { +glm::vec2 Object::GetWorldPosition() const +{ if (parent) return parent->GetWorldPosition() + localPosition; return localPosition; } -const std::string& Object::GetName() const { return name; } -void Object::SetName(const std::string& n) { name = n; } -std::vector>& Object::GetChildren() { return children; } -Object* Object::GetParent() const { return parent; } +const std::string &Object::GetName() const { return name; } +void Object::SetName(const std::string &n) { name = n; } +std::vector> &Object::GetChildren() { return children; } +Object *Object::GetParent() const { return parent; } + +void Object::Save(YAML::Emitter &out) const +{ + Logger::LogVerbose("[LoadScene] Saving Object: [%s, %d]", name.c_str(), uid.id); + -void Object::Save(YAML::Emitter& out) const { out << YAML::BeginMap; out << YAML::Key << "name" << YAML::Value << name; + out << YAML::Key << "uid" << YAML::Value << uid.uuid; + out << YAML::Key << "id" << YAML::Value << uid.id; out << YAML::Key << "position" << YAML::Value << YAML::Flow << YAML::BeginSeq << localPosition.x << localPosition.y << YAML::EndSeq; out << YAML::Key << "layer" << YAML::Value << layer; + out << YAML::Key << "components" << YAML::Value << YAML::BeginSeq; - for (const auto& comp : components) + for (const auto &comp : components) + { + Logger::LogVerbose("[LoadScene] Saving Component: %s", comp->GetName().c_str()); comp->Save(out); + } out << YAML::EndSeq; + out << YAML::Key << "children" << YAML::Value << YAML::BeginSeq; - for (const auto& child : children) + for (const auto &child : children) child->Save(out); out << YAML::EndSeq; + out << YAML::EndMap; } -void Object::Load(const YAML::Node& node) { +void Object::Load(const YAML::Node &node) +{ name = node["name"].as(); - + + if (node["uid"]) + uid.uuid = node["uid"].as(); + else + uid.uuid = GenerateUUID(); + + if (node["id"]) + uid.id = node["id"].as(); + auto pos = node["position"]; - if (pos && pos.IsSequence() && pos.size() == 2) { + if (pos && pos.IsSequence() && pos.size() == 2) + { localPosition.x = pos[0].as(); localPosition.y = pos[1].as(); } + if (node["layer"]) layer = node["layer"].as(); - Logger::LogVerbose("[LoadScene] Loading Object: [%s, (%f,%f), %d]", name.c_str(), localPosition.x, localPosition.y, layer); - + Logger::LogVerbose("[LoadScene] Loading Object: [%s, %d]", name.c_str(), uid.id); - if (node["components"]) { - for (const auto& compNode : node["components"]) { + if (node["components"]) + { + for (const auto &compNode : node["components"]) + { std::string type = compNode["type"].as(); - if (type == "SpriteComponent") { + Logger::LogVerbose("[LoadScene] Createing Component: %s", type.c_str()); + + if (type == "SpriteComponent") + { auto comp = AddComponent(); comp->Load(compNode); - } else if (type == "CameraComponent") { + } + else if (type == "CameraComponent") + { auto comp = AddComponent(); comp->Load(compNode); - } else if (type == "LightComponent") { + } + else if (type == "LightComponent") + { auto comp = AddComponent(); comp->Load(compNode); - } else if (type == "TilemapComponent") { + } + else if (type == "TilemapComponent") + { auto comp = AddComponent(); comp->Load(compNode); } + else if (type == "TextComponent") + { + auto comp = AddComponent(); + comp->Load(compNode); + } } } - if (node["children"]) { - for (const auto& childNode : node["children"]) { + if (node["children"]) + { + for (const auto &childNode : node["children"]) + { auto child = std::make_shared("Child"); child->Load(childNode); AddChild(child); diff --git a/src/src/Entitys/Object.h b/src/src/Entitys/Object.h index b61314e..f32b5af 100644 --- a/src/src/Entitys/Object.h +++ b/src/src/Entitys/Object.h @@ -5,6 +5,7 @@ #include #include #include +#include "../utils/UID.h" class Component; @@ -26,19 +27,14 @@ public: void RemoveChild(Object* child); std::vector>& GetChildren(); - template - std::shared_ptr GetComponent() const; - - template - std::shared_ptr AddComponent(); - - template - void RemoveComponent(); + template std::shared_ptr GetComponent() const; + template std::shared_ptr AddComponent(); + template void RemoveComponent(); void Save(YAML::Emitter& out) const; void Load(const YAML::Node& node); - int id = 0; + UID uid; int layer = 0; private: diff --git a/src/src/Renderer.cpp b/src/src/Renderer.cpp index 3cdcd51..7af2a83 100644 --- a/src/src/Renderer.cpp +++ b/src/src/Renderer.cpp @@ -28,15 +28,14 @@ std::vector Renderer::s_Lights; static Shader tilemapShader; - -void Renderer::InitQuad() { +void Renderer::InitQuad() +{ float vertices[] = { // pos // uv 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 1.f, 1.f, 1.f, - 0.f, 1.f, 0.f, 1.f - }; + 0.f, 1.f, 0.f, 1.f}; glGenVertexArrays(1, &quadVAO); glBindVertexArray(quadVAO); @@ -46,14 +45,15 @@ void Renderer::InitQuad() { glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); // position - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)0); glEnableVertexAttribArray(1); // UV - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)(2 * sizeof(float))); glBindVertexArray(0); } -void Renderer::Init() { +void Renderer::Init() +{ glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); @@ -82,7 +82,7 @@ void Renderer::Init() { unlitShader.LoadFromFile("src/assets/shaders/unlit.vert", "src/assets/shaders/unlit.frag"); // Create a 1x1 flat normal map (RGB: 128,128,255) - unsigned char flatNormal[3] = { 128, 128, 255 }; + unsigned char flatNormal[3] = {128, 128, 255}; glGenTextures(1, &defaultNormalMap); glBindTexture(GL_TEXTURE_2D, defaultNormalMap); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, flatNormal); @@ -92,8 +92,10 @@ void Renderer::Init() { s_DrawCalls = 0; } -void Renderer::Resize(int w, int h) { - if (w == width && h == height) return; +void Renderer::Resize(int w, int h) +{ + if (w == width && h == height) + return; width = w; height = h; @@ -105,7 +107,8 @@ void Renderer::Resize(int w, int h) { glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); } -void Renderer::Begin() { +void Renderer::Begin() +{ glBindFramebuffer(GL_FRAMEBUFFER, fbo); glViewport(0, 0, width, height); glEnable(GL_BLEND); @@ -116,30 +119,37 @@ void Renderer::Begin() { ClearLights(); } -void Renderer::End() { +void Renderer::End() +{ glBindFramebuffer(GL_FRAMEBUFFER, 0); } -void Renderer::ClearLights() { +void Renderer::ClearLights() +{ s_Lights.clear(); } -void Renderer::AddLight(const glm::vec2& screenPos, const glm::vec3& color, float intensity, float radius) { - if (s_Lights.size() >= 8) return; +void Renderer::AddLight(const glm::vec2 &screenPos, const glm::vec3 &color, float intensity, float radius) +{ + if (s_Lights.size() >= 8) + return; s_Lights.push_back({screenPos, color, intensity, radius}); } -void Renderer::DrawTilemap(TilemapComponent* tilemap, const glm::vec2& worldPos, float zoom, const glm::vec2& cameraPos) { - if (!tilemap || tilemap->GetAtlasPath().empty()) return; +void Renderer::DrawTilemap(TilemapComponent *tilemap, const glm::vec2 &worldPos, float zoom, const glm::vec2 &cameraPos) +{ + if (!tilemap || tilemap->GetAtlasPath().empty()) + return; glm::ivec2 grid = tilemap->GetGridSize(); glm::ivec2 tileSize = tilemap->GetTileSize(); int cols = tilemap->GetAtlasCols(); int rows = tilemap->GetAtlasRows(); - const std::string& atlasPath = tilemap->GetAtlasPath(); + const std::string &atlasPath = tilemap->GetAtlasPath(); GLuint atlasTex = LoadTextureIfNeeded(atlasPath); - if (atlasTex == 0) return; + if (atlasTex == 0) + return; tilemapShader.Use(); tilemapShader.SetVec2("uScreen", glm::vec2(width, height)); @@ -149,10 +159,13 @@ void Renderer::DrawTilemap(TilemapComponent* tilemap, const glm::vec2& worldPos, glBindVertexArray(quadVAO); - for (int y = 0; y < grid.y; ++y) { - for (int x = 0; x < grid.x; ++x) { + for (int y = 0; y < grid.y; ++y) + { + for (int x = 0; x < grid.x; ++x) + { int index = tilemap->GetTile(x, y); - if (index < 0 || index >= cols * rows) continue; + if (index < 0 || index >= cols * rows) + continue; int atlasX = index % cols; int atlasY = index / cols; @@ -177,74 +190,68 @@ void Renderer::DrawTilemap(TilemapComponent* tilemap, const glm::vec2& worldPos, glBindVertexArray(0); } - - -void Renderer::DrawSprite(SpriteComponent* sprite, const glm::vec2& pos, float zoom, glm::vec2& CameraPos) { - if (!sprite->HasTexture()) { - Logger::LogWarning("Tried to draw sprite with no texture"); +void Renderer::DrawSprite(SpriteComponent *sprite, const glm::vec2 &pos, float zoom, glm::vec2 &CameraPos) +{ + if (!sprite->HasTexture()) + { + static bool warned = false; + if (!warned) + { + Logger::LogWarning("Tried to draw sprite with no texture"); + warned = true; + } return; } - // Choose the shader based on engine configuration - if (g_engineConfig.lighting_enabled) { - spriteShader.Use(); - } else { - unlitShader.Use(); + Shader *shader = &unlitShader; + bool useLighting = false; + if (g_engineConfig.lighting_enabled && sprite->GetRenderType() == SpriteComponent::RenderType::Lit) + { + shader = &spriteShader; + useLighting = true; } + shader->Use(); glm::vec2 size = sprite->GetSize(); glm::vec2 screenPos = (pos - CameraPos) * zoom + glm::vec2(width, height) * 0.5f - (size * zoom * 0.5f); - // Set common uniforms - if (g_engineConfig.lighting_enabled) { - spriteShader.SetVec2("uPos", screenPos); - spriteShader.SetVec2("uSize", size * zoom); - spriteShader.SetVec2("uScreen", glm::vec2(width, height)); + shader->SetVec2("uPos", screenPos); + shader->SetVec2("uSize", size * zoom); + shader->SetVec2("uScreen", glm::vec2(width, height)); + shader->SetInt("uTex", 0); - spriteShader.SetInt("uLightCount", static_cast(s_Lights.size())); - for (size_t i = 0; i < s_Lights.size(); ++i) { - spriteShader.SetVec2(("uLightPos[" + std::to_string(i) + "]").c_str(), s_Lights[i].screenPos); - spriteShader.SetVec3(("uLightColor[" + std::to_string(i) + "]").c_str(), s_Lights[i].color); - spriteShader.SetFloat(("uLightIntensity[" + std::to_string(i) + "]").c_str(), s_Lights[i].intensity); - spriteShader.SetFloat(("uLightRadius[" + std::to_string(i) + "]").c_str(), s_Lights[i].radius); - } - } else { - // Unlit shader uniforms - unlitShader.SetVec2("uPos", screenPos); - unlitShader.SetVec2("uSize", size * zoom); - unlitShader.SetVec2("uScreen", glm::vec2(width, height)); - } - - // Bind the diffuse texture (common to both shaders) - if (g_engineConfig.lighting_enabled) { - spriteShader.SetInt("uTex", 0); - } else { - unlitShader.SetInt("uTex", 0); - } glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, sprite->GetTextureID()); - if (g_engineConfig.lighting_enabled) { - spriteShader.SetInt("uNormalMap", 1); - glActiveTexture(GL_TEXTURE1); - if (sprite->GetNormalMapID()) { - glBindTexture(GL_TEXTURE_2D, sprite->GetNormalMapID()); - } else { - glBindTexture(GL_TEXTURE_2D, defaultNormalMap); + if (useLighting) + { + shader->SetInt("uLightCount", static_cast(s_Lights.size())); + for (size_t i = 0; i < s_Lights.size(); ++i) + { + shader->SetVec2(("uLightPos[" + std::to_string(i) + "]").c_str(), s_Lights[i].screenPos); + shader->SetVec3(("uLightColor[" + std::to_string(i) + "]").c_str(), s_Lights[i].color); + shader->SetFloat(("uLightIntensity[" + std::to_string(i) + "]").c_str(), s_Lights[i].intensity); + shader->SetFloat(("uLightRadius[" + std::to_string(i) + "]").c_str(), s_Lights[i].radius); } + + shader->SetInt("uNormalMap", 1); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, sprite->GetNormalMapID() ? sprite->GetNormalMapID() : defaultNormalMap); } - + glBindVertexArray(quadVAO); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindVertexArray(0); s_DrawCalls++; } -int Renderer::GetDrawCallCount() { +int Renderer::GetDrawCallCount() +{ return s_DrawCalls; } -void Renderer::DrawEditorGrid(const glm::vec2& cameraPos, float zoom) { +void Renderer::DrawEditorGrid(const glm::vec2 &cameraPos, float zoom) +{ glUseProgram(0); glColor4f(0.5f, 0.5f, 0.5f, 0.25f); glLineWidth(1.0f); @@ -254,32 +261,36 @@ void Renderer::DrawEditorGrid(const glm::vec2& cameraPos, float zoom) { float viewWidth = width / zoom; float viewHeight = height / zoom; - float left = cameraPos.x - viewWidth / 2; - float right = cameraPos.x + viewWidth / 2; + float left = cameraPos.x - viewWidth / 2; + float right = cameraPos.x + viewWidth / 2; float bottom = cameraPos.y + viewHeight / 2; - float top = cameraPos.y - viewHeight / 2; + float top = cameraPos.y - viewHeight / 2; int minX = static_cast(std::floor(left / spacing)) * spacing; int maxX = static_cast(std::ceil(right / spacing)) * spacing; int minY = static_cast(std::floor(top / spacing)) * spacing; int maxY = static_cast(std::ceil(bottom / spacing)) * spacing; - for (int x = minX; x <= maxX; x += spacing) { + for (int x = minX; x <= maxX; x += spacing) + { glVertex2f((float)x, top); glVertex2f((float)x, bottom); } - for (int y = minY; y <= maxY; y += spacing) { + for (int y = minY; y <= maxY; y += spacing) + { glVertex2f(left, (float)y); glVertex2f(right, (float)y); } glEnd(); } -GLuint Renderer::GetRenderTexture() { +GLuint Renderer::GetRenderTexture() +{ return textureColorBuffer; } -glm::ivec2 Renderer::GetSize() { - return { width, height }; +glm::ivec2 Renderer::GetSize() +{ + return {width, height}; } diff --git a/src/src/utils/ExceptionHandler.cpp b/src/src/utils/ExceptionHandler.cpp new file mode 100644 index 0000000..1b6675e --- /dev/null +++ b/src/src/utils/ExceptionHandler.cpp @@ -0,0 +1,31 @@ +#include "ExceptionHandler.h" +#include "Logging.h" +#include + + + +const char* Create::Exceptions::ExceptionToString(Create::Exceptions::Type type) { + switch (type) { + case Create::Exceptions::None: return "None"; + case Create::Exceptions::ComponentLoad: return "ComponentLoad"; + case Create::Exceptions::MissingField: return "MissingField"; + case Create::Exceptions::InvalidFormat: return "InvalidFormat"; + case Create::Exceptions::SystemFailure: return "SystemFailure"; + case Create::Exceptions::AssetMissing: return "AssetMissing"; + case Create::Exceptions::FileIO: return "FileIO"; + case Create::Exceptions::RuntimeLogic: return "RuntimeLogic"; + default: return "Unknown"; + } +} + +RecoverableError::RecoverableError(const std::string& msg, Create::Exceptions::Type type) + : message(msg), type(type) {} + +void RecoverableError::Handle() const { + Logger::LogWarning("[Recoverable][%s] %s", ExceptionToString(type), message.c_str()); +} + +FatalError::FatalError(const std::string& msg, Create::Exceptions::Type type) { + Logger::LogError("[Fatal][%s] %s", ExceptionToString(type), msg.c_str()); + std::exit(1); +} diff --git a/src/src/utils/ExceptionHandler.h b/src/src/utils/ExceptionHandler.h new file mode 100644 index 0000000..f70fb13 --- /dev/null +++ b/src/src/utils/ExceptionHandler.h @@ -0,0 +1,32 @@ +#pragma once +#include + +namespace Create::Exceptions { + enum Type { + None, + ComponentLoad, + MissingField, + InvalidFormat, + SystemFailure, + AssetMissing, + FileIO, + RuntimeLogic + }; + + const char* ExceptionToString(Type type); +} + +class RecoverableError { +public: + RecoverableError(const std::string& msg, Create::Exceptions::Type type = Create::Exceptions::None); + void Handle() const; + +private: + std::string message; + Create::Exceptions::Type type; +}; + +class FatalError { +public: + FatalError(const std::string& msg, Create::Exceptions::Type type = Create::Exceptions::None); +}; diff --git a/src/src/utils/UID.cpp b/src/src/utils/UID.cpp new file mode 100644 index 0000000..8f4dce9 --- /dev/null +++ b/src/src/utils/UID.cpp @@ -0,0 +1,31 @@ +#include "UID.h" +#include +#include +#include + +static int nextID = 0; + +std::string GenerateUUID() { + + std::ostringstream ss; + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution dis(0, 15); + std::uniform_int_distribution dis2(8, 11); + + for (int i = 0; i < 32; i++) { + if (i == 12) + ss << 4; + else if (i == 16) + ss << dis2(gen); + else + ss << std::hex << dis(gen); + } + return ss.str(); +} + +UID::UID() + : id(nextID++), uuid(GenerateUUID()) {} + +UID::UID(int id, const std::string& uuid) + : id(id), uuid(uuid) {} diff --git a/src/src/utils/UID.h b/src/src/utils/UID.h new file mode 100644 index 0000000..92c37c2 --- /dev/null +++ b/src/src/utils/UID.h @@ -0,0 +1,12 @@ +#pragma once +#include +std::string GenerateUUID(); + +struct UID { + int id = 0; + std::string uuid; + + UID(); + UID(int id, const std::string& uuid); + +};