diff --git a/build.log b/build.log index 93e9d33..115fa93 100644 --- a/build.log +++ b/build.log @@ -16,25 +16,12 @@ In file included from C:/msys64/mingw64/include/yaml-cpp/parser.h:13, C:/msys64/mingw64/include/yaml-cpp/dll.h:22:65: note: '#pragma message: Defining YAML_CPP_API for DLL import' 22 | # pragma message( "Defining YAML_CPP_API for DLL import" ) | ^ - -[COMPILE] g++ -std=c++20 -Wall -Isrc/include -Isrc/vendor -Isrc/vendor/imgui -IC:/msys64/mingw64/include -MMD -MP -c src\src\Renderer.cpp -o src\build\src\Renderer.oIn file included from C:/msys64/mingw64/include/yaml-cpp/parser.h:13, - from C:/msys64/mingw64/include/yaml-cpp/yaml.h:10, - from src\src\Components/Component.h:5, - from src\src\Components/SpriteComponent.h:3, - from src\src\Renderer.cpp:2: -C:/msys64/mingw64/include/yaml-cpp/dll.h:22:65: note: '#pragma message: Defining YAML_CPP_API for DLL import' - 22 | # pragma message( "Defining YAML_CPP_API for DLL import" ) - | ^ - -[COMPILE] g++ -std=c++20 -Wall -Isrc/include -Isrc/vendor -Isrc/vendor/imgui -IC:/msys64/mingw64/include -MMD -MP -c src\src\Components\CameraComponent.cpp -o src\build\src\Components\CameraComponent.oIn file included from C:/msys64/mingw64/include/yaml-cpp/parser.h:13, - from C:/msys64/mingw64/include/yaml-cpp/yaml.h:10, - from src\src\Components\Component.h:5, - from src\src\Components\CameraComponent.h:2, - from src\src\Components\CameraComponent.cpp:1: -C:/msys64/mingw64/include/yaml-cpp/dll.h:22:65: note: '#pragma message: Defining YAML_CPP_API for DLL import' - 22 | # pragma message( "Defining YAML_CPP_API for DLL import" ) - | ^ +src\src\Engine.cpp:35:13: warning: 'isDragging' defined but not used [-Wunused-variable] + 35 | static bool isDragging = false; + | ^~~~~~~~~~ [LINK] g++ src\build\src\Engine.o src\build\src\main.o src\build\src\Renderer.o src\build\src\Components\CameraComponent.o src\build\src\Components\SpriteComponent.o src\build\src\Entitys\Object.o src\build\src\utils\FileDialog.o src\build\src\utils\Shader.o src\build\vendor\imgui\imgui.o src\build\vendor\imgui\imgui_demo.o src\build\vendor\imgui\imgui_draw.o src\build\vendor\imgui\imgui_impl_glfw.o src\build\vendor\imgui\imgui_impl_opengl3.o src\build\vendor\imgui\imgui_tables.o src\build\vendor\imgui\imgui_widgets.o -o src\build\app.exe -LC:/msys64/mingw64/lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto -[TIME] Build duration: 11.26s +[TIME] Build duration: 6.12s +[RUN] Executed app.exe successfully. +[TIME] Total runtime: 72.36s diff --git a/src/build/imgui.ini b/src/build/imgui.ini new file mode 100644 index 0000000..b58bc05 --- /dev/null +++ b/src/build/imgui.ini @@ -0,0 +1,31 @@ +[Window][WindowOverViewport_11111111] +Pos=0,19 +Size=1280,701 +Collapsed=0 + +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Scene Tree] +Pos=60,60 +Size=128,48 +Collapsed=0 + +[Window][Inspector] +Pos=1123,19 +Size=157,701 +Collapsed=0 +DockId=0x00000002,0 + +[Window][Viewport] +Pos=60,60 +Size=32,35 +Collapsed=0 + +[Docking][Data] +DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X + DockNode ID=0x00000001 Parent=0x11111111 SizeRef=1121,701 CentralNode=1 + DockNode ID=0x00000002 Parent=0x11111111 SizeRef=157,701 Selected=0x36DC96AB + diff --git a/src/src/Components/SpriteComponent.cpp b/src/src/Components/SpriteComponent.cpp index 1ecf75e..7bf722b 100644 --- a/src/src/Components/SpriteComponent.cpp +++ b/src/src/Components/SpriteComponent.cpp @@ -11,11 +11,11 @@ unsigned int SpriteComponent::LoadTexture(const std::string& path) { stbi_set_flip_vertically_on_load(1); unsigned char* data = stbi_load(path.c_str(), &w, &h, &channels, 4); if (!data) { - std::cerr << "Failed to load image: " << path << std::endl; + std::cerr << "Failed to load image: " << path << "\nReason: " << stbi_failure_reason() << std::endl; return 0; } - size = glm::vec2(w,h); + size = glm::vec2(w, h); unsigned int id; glGenTextures(1, &id); @@ -33,6 +33,7 @@ unsigned int SpriteComponent::LoadTexture(const std::string& path) { return id; } + void SpriteComponent::SetTexture(const std::string& path) { texturePath = path; textureID = LoadTexture(path); diff --git a/src/src/Engine.cpp b/src/src/Engine.cpp index 52ec1ae..01a622f 100644 --- a/src/src/Engine.cpp +++ b/src/src/Engine.cpp @@ -30,34 +30,10 @@ static std::vector<std::shared_ptr<Object>> objects; static std::shared_ptr<Object> selected = nullptr; static bool playing = false; -struct EditorCamera -{ - glm::vec2 position = glm::vec2(0.0f); - float zoom = 1.0f; - - void HandleInput() - { - if (ImGui::IsWindowHovered()) - { - if (ImGui::IsMouseDragging(ImGuiMouseButton_Right)) - { - ImVec2 delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right); - ImGui::ResetMouseDragDelta(ImGuiMouseButton_Right); - position -= glm::vec2(delta.x, -delta.y) / zoom; - } - - float wheel = ImGui::GetIO().MouseWheel; - if (wheel != 0.0f) - { - float zoomFactor = 1.1f; - zoom *= (wheel > 0) ? zoomFactor : (1.0f / zoomFactor); - zoom = std::clamp(zoom, 0.1f, 10.0f); - } - } - } -}; - -static EditorCamera editorCamera; +static glm::vec2 cameraPos = {0, 0}; +static float cameraZoom = 1.0f; +static bool isDragging = false; +static ImVec2 lastMousePos = {}; GLFWwindow *window = nullptr; @@ -257,32 +233,47 @@ void Engine::Run() ImGui::Begin("Viewport", nullptr, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); ImVec2 size = ImGui::GetContentRegionAvail(); - if (!playing) - editorCamera.HandleInput(); - - glm::vec2 cameraOffset = editorCamera.position; - float camZoom = editorCamera.zoom; - - if (playing) + if (!playing && ImGui::IsWindowHovered()) { - for (const auto &obj : objects) + if (ImGui::IsMouseDragging(ImGuiMouseButton_Right)) { - if (auto cam = obj->GetComponent<CameraComponent>()) - { - if (cam->IsPrimary()) - { - cameraOffset = obj->GetWorldPosition(); - camZoom = cam->GetZoom(); - break; - } - } + ImVec2 mouseDelta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right); + ImGui::ResetMouseDragDelta(ImGuiMouseButton_Right); + cameraPos -= glm::vec2(mouseDelta.x, mouseDelta.y) / cameraZoom; + } + + float wheel = ImGui::GetIO().MouseWheel; + if (wheel != 0.0f) + { + float zoomFactor = (wheel > 0) ? 1.1f : 1.0f / 1.1f; + + // Get mouse position in screen space + ImVec2 mousePos = ImGui::GetMousePos(); + ImVec2 windowPos = ImGui::GetWindowPos(); + ImVec2 contentRegionMin = ImGui::GetWindowContentRegionMin(); + glm::vec2 relativeMouse = glm::vec2(mousePos.x - windowPos.x - contentRegionMin.x, + mousePos.y - windowPos.y - contentRegionMin.y); + + // Convert to world position before zoom + glm::vec2 beforeZoom = (relativeMouse - glm::vec2(size.x / 2, size.y / 2)) / cameraZoom + cameraPos; + + // Apply zoom + cameraZoom *= zoomFactor; + cameraZoom = std::clamp(cameraZoom, 0.1f, 10.0f); + + // Convert to world position after zoom + glm::vec2 afterZoom = (relativeMouse - glm::vec2(size.x / 2, size.y / 2)) / cameraZoom + cameraPos; + + // Offset camera so zoom is centered at mouse + cameraPos += beforeZoom - afterZoom; } } Renderer::Resize((int)size.x, (int)size.y); - Renderer::Begin(); + Renderer::Begin(); // assumes orthographic matrix is set up here std::vector<std::shared_ptr<Object>> toDraw; + std::function<void(const std::shared_ptr<Object> &)> collect = [&](const std::shared_ptr<Object> &obj) { toDraw.push_back(obj); @@ -301,8 +292,8 @@ void Engine::Run() { if (auto sprite = obj->GetComponent<SpriteComponent>()) { - glm::vec2 renderPos = (obj->GetWorldPosition() - cameraOffset) * camZoom; - Renderer::DrawSprite(sprite.get(), renderPos, camZoom); + glm::vec2 worldPos = obj->GetWorldPosition(); + Renderer::DrawSprite(sprite.get(), worldPos, cameraZoom, cameraPos); } } diff --git a/src/src/Renderer.cpp b/src/src/Renderer.cpp index c77242c..2a52772 100644 --- a/src/src/Renderer.cpp +++ b/src/src/Renderer.cpp @@ -92,18 +92,71 @@ void Renderer::End() { glBindFramebuffer(GL_FRAMEBUFFER, 0); } -void Renderer::DrawSprite(SpriteComponent* sprite, const glm::vec2& pos, float scale) { - GLuint tex = sprite->GetTextureID(); - if (!tex) return; +//void Renderer::DrawSprite(SpriteComponent* sprite, const glm::vec2& pos, float scale) { +// GLuint tex = sprite->GetTextureID(); +// if (!tex) return; +// +// glBindTexture(GL_TEXTURE_2D, tex); +// glBegin(GL_QUADS); +// float size = 100.0f * scale; +// +// glTexCoord2f(0, 0); glVertex2f(pos.x, pos.y); +// glTexCoord2f(1, 0); glVertex2f(pos.x + size, pos.y); +// glTexCoord2f(1, 1); glVertex2f(pos.x + size, pos.y + size); +// glTexCoord2f(0, 1); glVertex2f(pos.x, pos.y + size); +// glEnd(); +//} - glBindTexture(GL_TEXTURE_2D, tex); - glBegin(GL_QUADS); - float size = 100.0f * scale; +void Renderer::DrawSprite(SpriteComponent* sprite, const glm::vec2& pos, float zoom, glm::vec2& CameraPos) { + if (!sprite || sprite->GetTextureID() == 0) return; + + spriteShader.Use(); + glm::vec2 size = sprite->GetSize(); + glm::vec2 screenPos = (pos - CameraPos) * zoom + glm::vec2(size.x / 2, size.y / 2); + spriteShader.SetVec2("uPos", screenPos); + spriteShader.SetVec2("uSize", size*zoom); + spriteShader.SetVec2("uScreen", glm::vec2(width, height)); + spriteShader.SetInt("uTex", 0); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, sprite->GetTextureID()); + + glBindVertexArray(quadVAO); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glBindVertexArray(0); +} + + +void Renderer::DrawEditorGrid(const glm::vec2& cameraPos, float zoom) { + glUseProgram(0); + glColor4f(0.5f, 0.5f, 0.5f, 0.25f); + glLineWidth(1.0f); + + glBegin(GL_LINES); + float spacing = 100.0f; + float viewWidth = width / zoom; + float viewHeight = height / zoom; + + float left = cameraPos.x - viewWidth / 2; + float right = cameraPos.x + viewWidth / 2; + float bottom = cameraPos.y + viewHeight / 2; + float top = cameraPos.y - viewHeight / 2; + + int minX = static_cast<int>(std::floor(left / spacing)) * spacing; + int maxX = static_cast<int>(std::ceil(right / spacing)) * spacing; + int minY = static_cast<int>(std::floor(top / spacing)) * spacing; + int maxY = static_cast<int>(std::ceil(bottom / spacing)) * 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) { + glVertex2f(left, (float)y); + glVertex2f(right, (float)y); + } - glTexCoord2f(0, 0); glVertex2f(pos.x, pos.y); - glTexCoord2f(1, 0); glVertex2f(pos.x + size, pos.y); - glTexCoord2f(1, 1); glVertex2f(pos.x + size, pos.y + size); - glTexCoord2f(0, 1); glVertex2f(pos.x, pos.y + size); glEnd(); } diff --git a/src/src/Renderer.h b/src/src/Renderer.h index 8ec5d0e..3d0d0e8 100644 --- a/src/src/Renderer.h +++ b/src/src/Renderer.h @@ -10,7 +10,8 @@ public: static void Resize(int w, int h); static void Begin(); static void End(); - static void DrawSprite(SpriteComponent* sprite, const glm::vec2& pos, float scale); + static void DrawSprite(SpriteComponent* sprite, const glm::vec2& pos, float zoom, glm::vec2& CameraPos); + static void DrawEditorGrid(const glm::vec2& cameraPos, float zoom); static GLuint GetRenderTexture(); static glm::ivec2 GetSize();