diff --git a/.vscode/settings.json b/.vscode/settings.json index 8bd2625..894df0c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,7 @@ "*.js": "javascript", "*.c": "c", "*.scene": "yaml", + "*.cene": "yaml", "memory": "cpp", "array": "cpp", "atomic": "cpp", @@ -74,6 +75,7 @@ "valarray": "cpp", "variant": "cpp", "fstream": "cpp", - "codecvt": "cpp" + "codecvt": "cpp", + "*.inc": "cpp" } } \ No newline at end of file diff --git a/imgui.ini b/imgui.ini index 9fec006..a5f7bf4 100644 --- a/imgui.ini +++ b/imgui.ini @@ -10,24 +10,24 @@ Collapsed=1 [Window][WindowOverViewport_11111111] Pos=0,19 -Size=1280,701 +Size=1920,1158 Collapsed=0 [Window][Inspector] -Pos=768,19 -Size=512,505 +Pos=1530,19 +Size=390,835 Collapsed=0 DockId=0x00000005,0 [Window][Scene Tree] Pos=0,19 -Size=263,701 +Size=263,1158 Collapsed=0 DockId=0x00000001,0 [Window][Viewport] Pos=265,19 -Size=501,590 +Size=1263,674 Collapsed=0 DockId=0x00000007,0 @@ -36,31 +36,31 @@ Size=1280,19 Collapsed=0 [Window][Performance Info] -Pos=768,526 -Size=512,194 +Pos=1530,856 +Size=390,321 Collapsed=0 DockId=0x00000006,0 [Window][Console] -Pos=265,611 -Size=501,109 +Pos=265,695 +Size=1263,482 Collapsed=0 DockId=0x00000008,0 [Window][Tilemap Editor] Pos=265,19 -Size=1141,1047 +Size=1263,674 Collapsed=0 DockId=0x00000007,1 [Docking][Data] -DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X - DockNode ID=0x00000003 Parent=0x11111111 SizeRef=1406,1158 Split=X +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=1141,701 Split=Y Selected=0xC450F867 - DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,1047 CentralNode=1 Selected=0xC450F867 - DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,109 Selected=0xEA83D666 - DockNode ID=0x00000004 Parent=0x11111111 SizeRef=512,1158 Split=Y Selected=0x36DC96AB + 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=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 9adaeac..c8c354d 100644 --- a/remake/build.log +++ b/remake/build.log @@ -1,19 +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\Renderer.cpp -o src\build\Renderer.o -[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\Components\CameraComponent.cpp -o src\build\Components\CameraComponent.o -[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\Components\LightComponent.cpp -o src\build\Components\LightComponent.o -[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\Components\SpriteComponent.cpp -o src\build\Components\SpriteComponent.o -[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\Components\TilemapComponent.cpp -o src\build\Components\TilemapComponent.o -[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\Entitys\Object.cpp -o src\build\Entitys\Object.o -[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\EngineConfig.cpp -o src\build\utils\EngineConfig.o -[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\FileDialog.cpp -o src\build\utils\FileDialog.o [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 -[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\Shader.cpp -o src\build\utils\Shader.o -[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\utils.cpp -o src\build\utils\utils.o -[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\vendor\imgui\imgui.cpp -o src\build\imgui\imgui.o -[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\vendor\imgui\imgui_demo.cpp -o src\build\imgui\imgui_demo.o -[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\vendor\imgui\imgui_draw.cpp -o src\build\imgui\imgui_draw.o -[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\vendor\imgui\imgui_impl_glfw.cpp -o src\build\imgui\imgui_impl_glfw.o -[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\vendor\imgui\imgui_impl_opengl3.cpp -o src\build\imgui\imgui_impl_opengl3.o -[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\vendor\imgui\imgui_tables.cpp -o src\build\imgui\imgui_tables.o -[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\vendor\imgui\imgui_widgets.cpp -o src\build\imgui\imgui_widgets.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 +[RUN] Executed app.exe successfully. diff --git a/src/assets/scenes/lighting_test.cene b/src/assets/scenes/lighting_test.cene new file mode 100644 index 0000000..88ebedc --- /dev/null +++ b/src/assets/scenes/lighting_test.cene @@ -0,0 +1,108 @@ +engine_version: 0.1.0 +scene_name: lighting_test +scene_hash: 20f69ee98c99f659ed799cb6546a6b48a26678324d4bc1518d49b531fc048d9b +format_version: 1 +objects: + - name: Red Light + position: [2051, 1540] + layer: 0 + components: + - type: LightComponent + color: + - 1 + - 0 + - 0 + intensity: 3.79999995 + radius: 5000 + falloff: 0.100000001 + type: 0 + children: [] + - name: Sun + position: [551, 0] + layer: 0 + components: + - type: LightComponent + color: + - 1 + - 1 + - 1 + intensity: 0.850000024 + radius: 10000 + falloff: 1 + type: 0 + children: [] + - name: Tiles + position: [0, 0] + layer: 0 + components: [] + children: + - name: Bark + 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 + children: [] + - name: Planks + 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 + children: [] + - name: Rocks + 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 + children: [] + - name: Metal + 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 + children: [] + - name: Logo + 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 + children: [] + - name: Carbooon Fobar + 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 + children: [] + - name: Mud + 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 + children: [] + - name: Green Light + position: [1364, 0] + layer: 0 + components: + - type: LightComponent + color: + - 0 + - 1 + - 0.176470518 + intensity: 10 + radius: 1000 + falloff: 1 + type: 0 + children: [] \ No newline at end of file diff --git a/src/src/Components/SpriteComponent.cpp b/src/src/Components/SpriteComponent.cpp index 16eace5..0243792 100644 --- a/src/src/Components/SpriteComponent.cpp +++ b/src/src/Components/SpriteComponent.cpp @@ -1,30 +1,57 @@ #include "SpriteComponent.h" #define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> +#include <unordered_map> #include <GL/glew.h> #include <iostream> #include "../utils/Logging.h" #include "../utils/utils.h" + +struct ImageCacheEntry { + unsigned int textureID; + glm::vec2 size; +}; + +static std::unordered_map<std::string, ImageCacheEntry> textureCache; + + + + + + SpriteComponent::SpriteComponent(Object *owner) : Component(owner) {} -unsigned int SpriteComponent::LoadTexture(const std::string &path, bool updateSize) -{ - int w, h, channels; - std::string filename = GetFilenameFromPath(path); - stbi_set_flip_vertically_on_load(false); - unsigned char *data = stbi_load(path.c_str(), &w, &h, &channels, 4); + +unsigned int SpriteComponent::LoadTexture(const std::string& path, bool updateSize) +{ + auto [it, inserted] = textureCache.try_emplace(path, ImageCacheEntry{}); + + if (!inserted) + { + if (updateSize) + size = it->second.size; + Logger::LogDebug("Using Cached Image: '%s', Texture ID: %u", path.c_str(), it->second.textureID); + return it->second.textureID; + } + + int w, h, channels; + stbi_set_flip_vertically_on_load(false); + unsigned char* data = stbi_load(path.c_str(), &w, &h, &channels, 4); + if (!data) { - Logger::LogError("Failed to load asset: '%s': %s", filename.c_str(), stbi_failure_reason()); + Logger::LogError("Failed to load image: '%s': %s", path.c_str(), stbi_failure_reason()); + textureCache.erase(it); // clean up placeholder return 0; } + glm::vec2 imageSize(w, h); if (updateSize) - size = glm::vec2(w, h); + size = imageSize; unsigned int id; glGenTextures(1, &id); @@ -39,13 +66,19 @@ unsigned int SpriteComponent::LoadTexture(const std::string &path, bool updateSi glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); stbi_image_free(data); - Logger::LogDebug("Loaded Asset: %s, %d", filename.c_str(), id); + + it->second = { id, imageSize }; + + Logger::LogDebug("Loaded Image: '%s' (%dx%d), Texture ID: %u", path.c_str(), w, h, id); return id; } + + + bool SpriteComponent::HasTexture() { return texture_loaded; diff --git a/src/src/Engine.cpp b/src/src/Engine.cpp index d4a4e1c..444df75 100644 --- a/src/src/Engine.cpp +++ b/src/src/Engine.cpp @@ -6,7 +6,6 @@ #include "components/LightComponent.h" #include "components/TilemapComponent.h" - #include "utils/FileDialog.h" #include "utils/Logging.h" @@ -32,6 +31,7 @@ static std::vector<std::shared_ptr<Object>> objects; static std::shared_ptr<Object> selected = nullptr; static bool playing = false; +static std::vector<std::shared_ptr<Object>> pendingDeletion; static glm::vec2 cameraPos = {0, 0}; static float cameraZoom = 1.0f; @@ -205,9 +205,12 @@ void DrawInspectorUI(std::shared_ptr<Object> selected) float aspect = cam->GetAspect(); float zoom = cam->GetZoom(); - if (ImGui::DragFloat("FOV", &fov, 0.1f, 1.0f, 179.0f)) cam->SetFOV(fov); - if (ImGui::DragFloat("Aspect", &aspect, 0.01f, 0.1f, 5.0f)) cam->SetAspect(aspect); - if (ImGui::DragFloat("Zoom", &zoom, 0.1f, 0.1f, 10.0f)) cam->SetZoom(zoom); + if (ImGui::DragFloat("FOV", &fov, 0.1f, 1.0f, 179.0f)) + cam->SetFOV(fov); + if (ImGui::DragFloat("Aspect", &aspect, 0.01f, 0.1f, 5.0f)) + cam->SetAspect(aspect); + if (ImGui::DragFloat("Zoom", &zoom, 0.1f, 0.1f, 10.0f)) + cam->SetZoom(zoom); if (ImGui::Button("Remove CameraComponent")) selected->RemoveComponent<CameraComponent>(); @@ -224,14 +227,18 @@ void DrawInspectorUI(std::shared_ptr<Object> selected) float falloff = light->GetFalloff(); int type = light->GetType(); - if (ImGui::ColorEdit3("Color", &color.x)) light->SetColor(color); - if (ImGui::DragFloat("Intensity", &intensity, 0.05f, 0.0f, 10.0f)) light->SetIntensity(intensity); - if (ImGui::DragFloat("Radius", &radius, 1.0f, 10.0f, 1000.0f)) light->SetRadius(radius); - if (ImGui::DragFloat("Falloff", &falloff, 0.05f, 0.1f, 5.0f)) light->SetFalloff(falloff); + if (ImGui::ColorEdit3("Color", &color.x)) + light->SetColor(color); + if (ImGui::DragFloat("Intensity", &intensity, 0.05f, 0.0f, 10.0f)) + light->SetIntensity(intensity); + if (ImGui::DragFloat("Radius", &radius, 1.0f, 10.0f, 1000.0f)) + light->SetRadius(radius); + if (ImGui::DragFloat("Falloff", &falloff, 0.05f, 0.1f, 5.0f)) + light->SetFalloff(falloff); - //const char* types[] = { "Point", "Directional" }; - //if (ImGui::Combo("Type", &type, types, IM_ARRAYSIZE(types))) - // light->SetType(type); + // const char* types[] = { "Point", "Directional" }; + // if (ImGui::Combo("Type", &type, types, IM_ARRAYSIZE(types))) + // light->SetType(type); if (ImGui::Button("Remove LightComponent")) selected->RemoveComponent<LightComponent>(); @@ -252,11 +259,9 @@ void DrawInspectorUI(std::shared_ptr<Object> selected) if (auto tilemap = selected->GetComponent<TilemapComponent>()) { tilemap->DrawEditorUI(); - } } - void Engine::Run() { while (!glfwWindowShouldClose(window)) @@ -293,6 +298,8 @@ void Engine::Run() if (ImGui::MenuItem("Load Scene")) { std::string file = OpenFileDialog(FileDialogType::Scenes); + Logger::LogInfo("[LoadScene] Loading Scene."); + if (!file.empty()) LoadScene(file); } @@ -464,7 +471,24 @@ void Engine::Run() glClear(GL_COLOR_BUFFER_BIT); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers(window); + + for (auto &obj : pendingDeletion) + { + if (obj->GetParent()) + { + obj->GetParent()->RemoveChild(obj.get()); + } + else + { + objects.erase(std::remove_if(objects.begin(), objects.end(), + [&](const std::shared_ptr<Object> &o) + { return o == obj; }), + objects.end()); + } + } + pendingDeletion.clear(); } + } void Engine::DrawObjectNode(const std::shared_ptr<Object> &obj) @@ -478,7 +502,8 @@ void Engine::DrawObjectNode(const std::shared_ptr<Object> &obj) if (ImGui::IsItemClicked()) selected = obj; - // === Context Menu on Object === + // Global or class-level list + if (ImGui::BeginPopupContextItem()) { if (ImGui::MenuItem("Rename")) @@ -488,20 +513,9 @@ void Engine::DrawObjectNode(const std::shared_ptr<Object> &obj) } if (ImGui::MenuItem("Delete")) { - // Remove from parent or root - if (obj->GetParent()) - { - obj->GetParent()->RemoveChild(obj.get()); - } - else - { - objects.erase(std::remove_if(objects.begin(), objects.end(), - [&](const std::shared_ptr<Object> &o) - { return o == obj; }), - objects.end()); - } + pendingDeletion.push_back(obj); ImGui::EndPopup(); - return; // Don't draw deleted node + return; // Still return so you don't draw the item } if (ImGui::MenuItem("Create Child")) { @@ -594,8 +608,13 @@ bool VerifySceneHash(const YAML::Node &root) void Engine::LoadScene(const std::string &path) { + Logger::LogDebug("[LoadScene] Reading Scene File."); + YAML::Node root = YAML::LoadFile(path); + Logger::LogDebug("[LoadScene] Verifying Scene"); + + if (!root["engine_version"] || !root["format_version"] || !root["scene_name"]) { Logger::LogError("[LoadScene] Missing required metadata!"); @@ -613,13 +632,19 @@ void Engine::LoadScene(const std::string &path) Logger::LogWarning("[LoadScene] Scene hash does not match! File may be corrupted or tampered."); } + Logger::LogDebug("[LoadScene] Reseting Scene."); + objects.clear(); + + Logger::LogDebug("[LoadScene] Recreting Objects"); + const auto &objectArray = root["objects"]; for (const auto &node : objectArray) { auto obj = std::make_shared<Object>("[DefaultObject]"); obj->Load(node); objects.push_back(obj); + } Logger::LogInfo("[LoadScene] Loaded scene: %s", root["scene_name"].as<std::string>().c_str()); diff --git a/src/src/Entitys/Object.cpp b/src/src/Entitys/Object.cpp index c995849..fd81daa 100644 --- a/src/src/Entitys/Object.cpp +++ b/src/src/Entitys/Object.cpp @@ -6,6 +6,8 @@ #include "../Components/LightComponent.h" #include "../Components/TilemapComponent.h" +#include "../utils/Logging.h" + #include <algorithm> @@ -72,6 +74,7 @@ void Object::Save(YAML::Emitter& out) const { void Object::Load(const YAML::Node& node) { name = node["name"].as<std::string>(); + auto pos = node["position"]; if (pos && pos.IsSequence() && pos.size() == 2) { localPosition.x = pos[0].as<float>(); @@ -80,6 +83,9 @@ void Object::Load(const YAML::Node& node) { if (node["layer"]) layer = node["layer"].as<int>(); + Logger::LogVerbose("[LoadScene] Loading Object: [%s, (%f,%f), %d]", name.c_str(), localPosition.x, localPosition.y, layer); + + if (node["components"]) { for (const auto& compNode : node["components"]) { std::string type = compNode["type"].as<std::string>(); diff --git a/src/src/utils/FileDialog.cpp b/src/src/utils/FileDialog.cpp index 345f3c7..8532849 100644 --- a/src/src/utils/FileDialog.cpp +++ b/src/src/utils/FileDialog.cpp @@ -7,25 +7,29 @@ #include <filesystem> #include "FileDialog.h" -static std::unordered_map<FileDialogType, std::string> filters = { +// Correctly null-terminated filter strings +static std::unordered_map<FileDialogType, const char*> filters = { { FileDialogType::Images, "Image Files\0*.png;*.jpg;*.jpeg;*.bmp\0" }, - { FileDialogType::Scenes, "CreateScene Files\0*.cene\0" }, - { FileDialogType::Audio, "Audio Files\0*.mp3;*.wav;*.ogg\0" }, - { FileDialogType::All, "All Files\0*.*\0" } + { FileDialogType::Scenes, "CreateScene Files\0*.cene;*.cscene\0" }, + { FileDialogType::Audio, "Audio Files\0*.mp3;*.wav;*.ogg\0" }, + { FileDialogType::All, "All Files\0*.*\0" } }; std::string OpenFileDialog(FileDialogType type) { char file[260] = { 0 }; OPENFILENAMEA ofn = {}; ofn.lStructSize = sizeof(ofn); - ofn.lpstrFilter = filters.count(type) ? filters[type].c_str() : filters[FileDialogType::All].c_str(); + + const char* filterStr = filters.count(type) ? filters[type] : filters[FileDialogType::All]; + ofn.lpstrFilter = filterStr; ofn.lpstrFile = file; ofn.nMaxFile = sizeof(file); ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR; - auto current = std::filesystem::current_path(); + auto originalPath = std::filesystem::current_path(); bool result = GetOpenFileNameA(&ofn); - std::filesystem::current_path(current); + std::filesystem::current_path(originalPath); + return result ? std::string(file) : ""; } @@ -33,13 +37,16 @@ std::string SaveFileDialog(FileDialogType type) { char file[260] = { 0 }; OPENFILENAMEA ofn = {}; ofn.lStructSize = sizeof(ofn); - ofn.lpstrFilter = filters.count(type) ? filters[type].c_str() : filters[FileDialogType::All].c_str(); + + const char* filterStr = filters.count(type) ? filters[type] : filters[FileDialogType::All]; + ofn.lpstrFilter = filterStr; ofn.lpstrFile = file; ofn.nMaxFile = sizeof(file); ofn.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR; - auto current = std::filesystem::current_path(); + auto originalPath = std::filesystem::current_path(); bool result = GetSaveFileNameA(&ofn); - std::filesystem::current_path(current); + std::filesystem::current_path(originalPath); + return result ? std::string(file) : ""; } diff --git a/src/src/utils/Logging.cpp b/src/src/utils/Logging.cpp index 499b94c..3926395 100644 --- a/src/src/utils/Logging.cpp +++ b/src/src/utils/Logging.cpp @@ -10,32 +10,48 @@ bool Logger::s_ShowInfo = true; bool Logger::s_ShowWarning = true; bool Logger::s_ShowError = true; bool Logger::s_ShowDebug = true; +bool Logger::s_ShowVerbose = true; -const char* Logger::ToString(Level level) +const char *Logger::ToString(Level level) { switch (level) { - case Info: return "Info"; - case Warning: return "Warning"; - case Error: return "Error"; - case Debug: return "Debug"; - default: return "Unknown"; + case Info: + return "Info"; + case Warning: + return "Warning"; + case Error: + return "Error"; + case Debug: + return "Debug"; + case Verbose: + return "Verbose"; + default: + return "Unknown"; } } -const char* Logger::GetAnsiColor(Level level) +const char *Logger::GetAnsiColor(Level level) { switch (level) { - case Info: return "\033[0;37m"; // Gray - case Warning: return "\033[1;33m"; // Yellow - case Error: return "\033[1;31m"; // Red - case Debug: return "\033[1;36m"; // Cyan - default: return "\033[0m"; + case Info: + return "\033[0;37m"; // Gray + case Warning: + return "\033[1;33m"; // Yellow + case Error: + return "\033[1;31m"; // Red + case Debug: + return "\033[1;36m"; // Cyan + case Verbose: + return "\033[0;90m"; // Dim gray + + default: + return "\033[0m"; // Reset } } -void Logger::Log(Level level, const char* fmt, ...) +void Logger::Log(Level level, const char *fmt, ...) { va_list args; va_start(args, fmt); @@ -43,19 +59,18 @@ void Logger::Log(Level level, const char* fmt, ...) va_end(args); } -void Logger::LogVA(Level level, const char* fmt, va_list args) +void Logger::LogVA(Level level, const char *fmt, va_list args) { char buffer[1024]; vsnprintf(buffer, sizeof(buffer), fmt, args); - s_Messages.push_back({ buffer, level }); + s_Messages.push_back({buffer, level}); std::cout << GetAnsiColor(level) << "[Logger][" << ToString(level) << "] " << buffer << "\033[0m" << std::endl; } - -void Logger::LogInfo(const char* fmt, ...) +void Logger::LogInfo(const char *fmt, ...) { va_list args; va_start(args, fmt); @@ -63,7 +78,7 @@ void Logger::LogInfo(const char* fmt, ...) va_end(args); } -void Logger::LogWarning(const char* fmt, ...) +void Logger::LogWarning(const char *fmt, ...) { va_list args; va_start(args, fmt); @@ -71,7 +86,7 @@ void Logger::LogWarning(const char* fmt, ...) va_end(args); } -void Logger::LogError(const char* fmt, ...) +void Logger::LogError(const char *fmt, ...) { va_list args; va_start(args, fmt); @@ -79,7 +94,7 @@ void Logger::LogError(const char* fmt, ...) va_end(args); } -void Logger::LogDebug(const char* fmt, ...) +void Logger::LogDebug(const char *fmt, ...) { va_list args; va_start(args, fmt); @@ -87,33 +102,50 @@ void Logger::LogDebug(const char* fmt, ...) va_end(args); } +void Logger::LogVerbose(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + LogVA(Verbose, fmt, args); + va_end(args); +} + void Logger::Clear() { s_Messages.clear(); } -void Logger::Draw(const char* title) +void Logger::Draw(const char *title) { ImGui::Begin(title); - if (ImGui::Button("Clear")) Clear(); - ImGui::SameLine(); ImGui::Checkbox("Auto-scroll", &s_AutoScroll); + if (ImGui::Button("Clear")) + Clear(); + ImGui::SameLine(); + ImGui::Checkbox("Auto-scroll", &s_AutoScroll); ImGui::Separator(); - ImGui::Checkbox("Info", &s_ShowInfo); ImGui::SameLine(); - ImGui::Checkbox("Warning", &s_ShowWarning); ImGui::SameLine(); - ImGui::Checkbox("Error", &s_ShowError); ImGui::SameLine(); + ImGui::Checkbox("Info", &s_ShowInfo); + ImGui::SameLine(); + ImGui::Checkbox("Warning", &s_ShowWarning); + ImGui::SameLine(); + ImGui::Checkbox("Error", &s_ShowError); + ImGui::SameLine(); ImGui::Checkbox("Debug", &s_ShowDebug); + ImGui::SameLine(); + ImGui::Checkbox("Verbose", &s_ShowVerbose); + ImGui::Separator(); ImGui::BeginChild("LogMessages"); - for (const auto& msg : s_Messages) + for (const auto &msg : s_Messages) { if ((msg.level == Info && !s_ShowInfo) || (msg.level == Warning && !s_ShowWarning) || (msg.level == Error && !s_ShowError) || - (msg.level == Debug && !s_ShowDebug)) + (msg.level == Debug && !s_ShowDebug) || + (msg.level == Verbose && !s_ShowVerbose)) { continue; } @@ -121,11 +153,24 @@ void Logger::Draw(const char* title) ImVec4 color; switch (msg.level) { - case Info: color = ImVec4(0.8f, 0.8f, 0.8f, 1.0f); break; - case Warning: color = ImVec4(1.0f, 0.85f, 0.3f, 1.0f); break; - case Error: color = ImVec4(1.0f, 0.3f, 0.3f, 1.0f); break; - case Debug: color = ImVec4(0.3f, 0.9f, 1.0f, 1.0f); break; - default: color = ImVec4(1, 1, 1, 1); break; + case Info: + color = ImVec4(0.8f, 0.8f, 0.8f, 1.0f); + break; // Light gray + case Warning: + color = ImVec4(1.0f, 0.85f, 0.3f, 1.0f); + break; // Yellow + case Error: + color = ImVec4(1.0f, 0.3f, 0.3f, 1.0f); + break; // Red + case Debug: + color = ImVec4(0.3f, 0.9f, 1.0f, 1.0f); + break; // Cyan + case Verbose: + color = ImVec4(0.5f, 0.5f, 0.5f, 1.0f); + break; // Dim gray + default: + color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); + break; // Fallback white } ImGui::PushStyleColor(ImGuiCol_Text, color); diff --git a/src/src/utils/Logging.h b/src/src/utils/Logging.h index b17f624..bf3a6d5 100644 --- a/src/src/utils/Logging.h +++ b/src/src/utils/Logging.h @@ -11,7 +11,8 @@ public: Info, Warning, Error, - Debug + Debug, + Verbose }; static void Log(Level level, const char* fmt, ...); static void LogVA(Level level, const char* fmt, va_list args); @@ -20,6 +21,8 @@ public: static void LogWarning(const char* fmt, ...); static void LogError(const char* fmt, ...); static void LogDebug(const char* fmt, ...); + static void LogVerbose(const char* fmt, ...); + static void Clear(); static void Draw(const char* title = "Console"); @@ -37,6 +40,8 @@ private: static bool s_ShowWarning; static bool s_ShowError; static bool s_ShowDebug; + static bool s_ShowVerbose; + static const char* ToString(Level level); static const char* GetAnsiColor(Level level);