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