diff --git a/editor/include/e_sandbox2d.hpp b/editor/include/e_sandbox2d.hpp index 20aa9b8..f6b2e93 100755 --- a/editor/include/e_sandbox2d.hpp +++ b/editor/include/e_sandbox2d.hpp @@ -64,7 +64,7 @@ class Sandbox2DLayer : public ViewLayer grid_shader->SetMat4("u_InverseViewProjection", inverseVP); OpenEngine::Transform screen = {glm::vec3(0.0f, 0.0f, -0.9f), glm::vec3(2.0f, 2.0f, 0.0f), 0.0f}; - OpenEngine::Renderer2D::DrawQuad(screen, glm::vec4(0.8f, 0.4f, 0.3f, 1.0f)); + //OpenEngine::Renderer2D::DrawQuad(screen, glm::vec4(0.8f, 0.4f, 0.3f, 1.0f)); OpenEngine::Renderer2D::EndScene(); @@ -76,8 +76,8 @@ class Sandbox2DLayer : public ViewLayer OE_PROFILE_SCOPE("Drawing Quads"); OpenEngine::Transform tr1 = {glm::vec3(0.0f, 0.0f, -0.1f), glm::vec3(1.0f, 1.0f, 0.0f), angle}; OpenEngine::Transform tr3 = {glm::vec3(-0.5f, -0.5f, 0.0f), glm::vec3(1.0f, 0.5f, 0.0f), angle * 0.5f}; - OpenEngine::Renderer2D::DrawQuad(tr1, face); - OpenEngine::Renderer2D::DrawQuad(tr3, rectangle_color); + //OpenEngine::Renderer2D::DrawQuad(tr1, face); + //OpenEngine::Renderer2D::DrawQuad(tr3, rectangle_color); } OpenEngine::Renderer2D::EndScene(); @@ -88,18 +88,18 @@ class Sandbox2DLayer : public ViewLayer for (float x = -5.0f; x < 5.0f; x += 0.5f) { glm::vec4 gradient_color = {(x + 5.0f) / 10.0f, 0.3f, (y + 5.0f) / 10.0f, 1.0f}; - OpenEngine::Renderer2D::DrawQuad({{x, y, 0.0f}, glm::vec3(0.45f, 0.45f, 0.0f)}, gradient_color); + //OpenEngine::Renderer2D::DrawQuad({{x, y, 0.0f}, glm::vec3(0.45f, 0.45f, 0.0f)}, gradient_color); } } OpenEngine::Transform tr2 = {glm::vec3(0, 0, 0.2f), glm::vec3(1.0f, 1.0f, 0.0f), 0.0f}; OpenEngine::Transform tr4 = {glm::vec3(-1.0, 0.0, 0.2f), glm::vec3(1.0f, 2.0f, 0.0f), 0.0f}; - OpenEngine::Renderer2D::DrawQuad(tr2, stairs); - OpenEngine::Renderer2D::DrawQuad(tr4, tree); + //OpenEngine::Renderer2D::DrawQuad(tr2, stairs); + //OpenEngine::Renderer2D::DrawQuad(tr4, tree); auto& cursor = GetCursorPos(); OpenEngine::Transform tr5 = {glm::vec3(cursor.x, cursor.y, 0.9f), glm::vec3(0.1f, 0.1f, 0.0f), 0.0f}; - OpenEngine::Renderer2D::DrawQuad(tr5, {1, 1, 1, 1}); + //OpenEngine::Renderer2D::DrawQuad(tr5, {1, 1, 1, 1}); OpenEngine::Renderer2D::EndScene(); diff --git a/editor/include/editor.hpp b/editor/include/editor.hpp index 593a130..6bc4396 100755 --- a/editor/include/editor.hpp +++ b/editor/include/editor.hpp @@ -3,18 +3,22 @@ #include +#include "open_engine/input/input_system.hpp" +#include "open_engine/renderer/render_command.hpp" #include "panels/scene_hierarchy.hpp" -//#include #include #include #include #include #include #include +#include #include #include -#include + +#include +#include namespace OpenEngine { @@ -62,6 +66,7 @@ namespace OpenEngine { OE_PROFILE_FUNCTION(); FramebufferSpecification specs; + specs.attachments = { FramebufferTextureFormat::RGBA8, FramebufferTextureFormat::RED_INTEGER, FramebufferTextureFormat::Depth }; specs.width = 1280; specs.height = 720; @@ -81,6 +86,7 @@ namespace OpenEngine { void OnUpdate() override { FramebufferSpecification spec = framebuffer->GetSpecification(); + if (viewport_size.x > 0.0f && viewport_size.y > 0.0f && (spec.width != viewport_size.x || spec.height != viewport_size.y)) { OE_PROFILE_SCOPE("Setting up Rendering"); @@ -95,11 +101,28 @@ namespace OpenEngine { Renderer2D::ResetStats(); RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f}); RenderCommand::Clear(); + RenderCommand::ClearBufferI(1, -1); editor_camera.OnUpdate(); scene->OnUpdateEditor(editor_camera); + auto [mx, my] = ImGui::GetMousePos(); + + mx -= viewport_bounds[0].x; + my -= viewport_bounds[0].y; + auto viewport_size= viewport_bounds[1] - viewport_bounds[0]; + my = viewport_size.y - my; + + int mouse_x = (int)mx; + int mouse_y = (int)my; + + if (mouse_x >= 0 && mouse_y >= 0 && mouse_x < (int)viewport_size.x && (int)viewport_size.y) { + int id = framebuffer->ReadPixel(1, mouse_x, mouse_y); + if (Input::IsMouseButtonPressed(Mouse::ButtonLeft) && id != -1) + scene_hierarchy.SetSelectedEntity({ (entt::entity)id, scene.get() }); + } + framebuffer->Unbind(); } @@ -200,15 +223,24 @@ namespace OpenEngine { viewport_size = { viewport_panel_size.x, viewport_panel_size.y }; - ImVec2 imgui_cursor_position = ImGui::GetCursorScreenPos(); - auto pair_position = Input::GetMousePosition(); - glm::vec2 mouse_position = { pair_position.first, pair_position.second }; + ImVec2 imgui_cursor_position = ImGui::GetCursorPos(); + + uint32_t texture_id = framebuffer->GetColorAttachmentRendererID(); + ImGui::Image((void*)(uint64_t)texture_id, ImVec2{ viewport_size.x, viewport_size.y }, ImVec2{ 0, 1 }, ImVec2{ 1, 0 }); int max_x = viewport_size.x + imgui_cursor_position.x; int max_y = viewport_size.y + imgui_cursor_position.y; - uint32_t texture_id = framebuffer->GetColorAttachmentRendererID(); - ImGui::Image((void*)(uint64_t)texture_id, ImVec2{ viewport_size.x, viewport_size.y }, ImVec2{ 0, 1 }, ImVec2{ 1, 0 }); + auto window_size = ImGui::GetWindowSize(); + ImVec2 min_bound = ImGui::GetWindowPos(); + + min_bound.x += imgui_cursor_position.x; + min_bound.y += imgui_cursor_position.y; + + ImVec2 max_bound = { min_bound.x + window_size.x, min_bound.y + window_size.y }; + + viewport_bounds[0] = { min_bound.x, min_bound.y}; + viewport_bounds[1] = { max_bound.x, max_bound.y}; DrawGuizmos(); @@ -234,47 +266,21 @@ namespace OpenEngine { ImGui::Text("\t\tQuad count: %d", stats.quad_count); ImGui::Text("\t\tVertices count: %d", stats.GetTotalVertexCount()); ImGui::Text("\t\tIndices count: %d", stats.GetTotalIndexCount()); - - /* - for (auto& result : profiling_results) - { - char label[50]; - strcpy(label, "%.3fms "); - strcat(label, result.name); - ImGui::Text(label, result.duration); - } - - profiling_results.clear(); - */ - ImGui::End(); }; - /* - void test2() - { - // (optional) set browser properties - fileDialog.SetTitle("title"); - fileDialog.SetTypeFilters({ ".oes" }); - fileDialog.Open(); - }; - */ - void DrawGuizmos() { Entity selected_entity = scene_hierarchy.GetSelectedEntity(); if (selected_entity && selected_entity.HasComponent() && guizmo_operation != -1) { ImGuizmo::SetOrthographic(false); ImGuizmo::SetDrawlist(); + ImGuizmo::Enable(!editor_camera.GetMoving()); auto window_position = ImGui::GetWindowPos(); auto window_size = ImGui::GetWindowSize(); ImGuizmo::SetRect(window_position.x, window_position.y, window_size.x, window_size.y); - //auto camera_entity = scene->GetPrimaryCamera(); - //auto camera = camera_entity.GetComponents().camera; - //const glm::mat4& projection = camera.GetProjection(); - //glm::mat4 camera_view = glm::inverse(camera_entity.GetComponents().GetTransform()); const glm::mat4& camera_projection = editor_camera.GetProjection(); glm::mat4 camera_view = editor_camera.GetViewMatrix(); @@ -309,8 +315,8 @@ namespace OpenEngine { { OE_PROFILE_FUNCTION(); + ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(450, 200)); { - // Testing file pickers if (ImGui::BeginMainMenuBar()) { if (ImGui::BeginMenu("File")) { if (ImGui::MenuItem("Save Scene As", "Ctrl+S")) { @@ -345,16 +351,6 @@ namespace OpenEngine { } ImGui::EndMainMenuBar(); } - - /* - fileDialog.Display(); - - if(fileDialog.HasSelected()) - { - OE_TRACE("Selected filename {}", fileDialog.GetSelected().string()); - fileDialog.ClearSelected(); - } - */ } ImGui::DockSpaceOverViewport(); @@ -364,6 +360,7 @@ namespace OpenEngine { DrawViewport(); ImGui::ShowDemoWindow(); + ImGui::PopStyleVar(); }; private: @@ -373,6 +370,7 @@ namespace OpenEngine { glm::vec2 viewport_size = { 0.0f, 0.0f }; Ref framebuffer; + glm::vec2 viewport_bounds[2]; SceneHierarchy scene_hierarchy; @@ -382,8 +380,6 @@ namespace OpenEngine { Ref scene; Entity sq_entity; - //ImGui::FileBrowser fileDialog; - }; } diff --git a/editor/include/level_editor.hpp b/editor/include/level_editor.hpp index 7e379e3..134e21b 100644 --- a/editor/include/level_editor.hpp +++ b/editor/include/level_editor.hpp @@ -41,14 +41,14 @@ class LevelEditor : public ViewLayer for (float x = -5.0f; x < 5.0f; x += 0.5f) { glm::vec4 gradient_color = {(x + 5.0f) / 10.0f, 0.3f, (y + 5.0f) / 10.0f, 1.0f}; - OpenEngine::Renderer2D::DrawQuad({{x, y, 0.0f}, glm::vec3(0.45f, 0.45f, 0.0f)}, gradient_color); + //OpenEngine::Renderer2D::DrawQuad({{x, y, 0.0f}, glm::vec3(0.45f, 0.45f, 0.0f)}, gradient_color); } } auto& cursor = GetCursorPos(); OpenEngine::Transform tr5 = {glm::vec3(cursor.x, cursor.y, 0.9f), glm::vec3(0.1f, 0.1f, 0.0f), 0.0f}; - OpenEngine::Renderer2D::DrawQuad(tr5, {1, 1, 1, 1}); + //OpenEngine::Renderer2D::DrawQuad(tr5, {1, 1, 1, 1}); OpenEngine::Renderer2D::EndScene(); diff --git a/editor/include/shmup.hpp b/editor/include/shmup.hpp index 2dc94dc..f6dfc46 100755 --- a/editor/include/shmup.hpp +++ b/editor/include/shmup.hpp @@ -200,12 +200,12 @@ class Shmup : public OpenEngine::Layer } { OE_PROFILE_SCOPE("Drawing Quads"); - OpenEngine::Renderer2D::DrawQuad(tr1, ship); + OpenEngine::Renderer2D::DrawQuad(tr1, ship, -1); for (auto& enemy : enemies) - OpenEngine::Renderer2D::DrawQuad(enemy, enemy_ship); + OpenEngine::Renderer2D::DrawQuad(enemy, enemy_ship, -1); for (auto& bullet : bullets) - OpenEngine::Renderer2D::DrawQuad(bullet, bullet_tx); + OpenEngine::Renderer2D::DrawQuad(bullet, bullet_tx, -1); } OpenEngine::Renderer2D::EndScene(); diff --git a/imgui.ini b/imgui.ini index f3921b3..bbd499b 100644 --- a/imgui.ini +++ b/imgui.ini @@ -1,40 +1,40 @@ [Window][WindowOverViewport_11111111] Pos=0,24 -Size=1272,1362 +Size=2560,1371 Collapsed=0 [Window][Debug##Default] -Pos=-32,545 +Pos=-32,513 Size=400,400 Collapsed=0 [Window][Statistics] Pos=0,24 -Size=343,227 +Size=409,228 Collapsed=0 DockId=0x00000003,0 [Window][Properties] -Pos=829,24 -Size=443,738 +Pos=2110,24 +Size=450,743 Collapsed=0 DockId=0x00000007,0 [Window][Viewport] -Pos=345,24 -Size=482,1362 +Pos=411,24 +Size=1697,1371 Collapsed=0 DockId=0x00000009,0 [Window][Dear ImGui Demo] -Pos=829,764 -Size=443,622 +Pos=2110,769 +Size=450,626 Collapsed=0 DockId=0x00000008,0 [Window][Scene] -Pos=0,253 -Size=343,1133 +Pos=0,254 +Size=409,1141 Collapsed=0 DockId=0x00000004,0 @@ -129,16 +129,28 @@ Pos=287,467 Size=700,450 Collapsed=0 +[Window][Graph editor] +Pos=343,24 +Size=1665,1371 +Collapsed=0 +DockId=0x00000009,1 + +[Window][Graph Editor] +Pos=343,24 +Size=1665,1371 +Collapsed=0 +DockId=0x00000009,1 + [Docking][Data] -DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,24 Size=1272,1362 Split=X - DockNode ID=0x00000005 Parent=0x08BD597D SizeRef=827,1386 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=343,1386 Split=Y Selected=0xE601B12F +DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,24 Size=2560,1371 Split=X + DockNode ID=0x00000005 Parent=0x08BD597D SizeRef=820,1386 Split=X + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=409,1386 Split=Y Selected=0xE601B12F DockNode ID=0x00000003 Parent=0x00000001 SizeRef=255,231 Selected=0x553E127E DockNode ID=0x00000004 Parent=0x00000001 SizeRef=255,1153 Selected=0xE601B12F - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=482,1386 Split=Y Selected=0xC450F867 + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1697,1386 Split=Y Selected=0xC450F867 DockNode ID=0x00000009 Parent=0x00000002 SizeRef=483,784 CentralNode=1 Selected=0xC450F867 DockNode ID=0x0000000A Parent=0x00000002 SizeRef=483,600 Selected=0x1BCA3180 - DockNode ID=0x00000006 Parent=0x08BD597D SizeRef=443,1386 Split=Y Selected=0x8C72BEA8 + DockNode ID=0x00000006 Parent=0x08BD597D SizeRef=450,1386 Split=Y Selected=0x8C72BEA8 DockNode ID=0x00000007 Parent=0x00000006 SizeRef=444,738 Selected=0x8C72BEA8 DockNode ID=0x00000008 Parent=0x00000006 SizeRef=444,622 Selected=0x5E5F7166 diff --git a/open_engine/include/open_engine/opengl/opengl_framebuffer.hpp b/open_engine/include/open_engine/opengl/opengl_framebuffer.hpp index 10b5a96..f86626e 100644 --- a/open_engine/include/open_engine/opengl/opengl_framebuffer.hpp +++ b/open_engine/include/open_engine/opengl/opengl_framebuffer.hpp @@ -1,9 +1,11 @@ #ifndef OPENGL_FRAMEBUFFER_HPP #define OPENGL_FRAMEBUFFER_HPP +#include "core.hpp" #include #include +#include namespace OpenEngine { class OpenGLFramebuffer : public FrameBuffer @@ -18,15 +20,24 @@ namespace OpenEngine { virtual void Unbind() override; virtual void Resize(uint32_t width, uint32_t height) override; + virtual int ReadPixel(uint32_t index, int x, int y) override; - virtual uint32_t GetColorAttachmentRendererID() const override { return color_attachment; } + virtual uint32_t GetColorAttachmentRendererID(uint32_t index = 0) const override { + OE_CORE_ASSERT(index < color_attachment_ids.size(), "Index is greater than color attachment count."); + return color_attachment_ids[index]; + } virtual const FramebufferSpecification& GetSpecification() const override { return specs; } private: uint32_t id = 0; - uint32_t color_attachment = 0, depth_attachment = 0; FramebufferSpecification specs; + + std::vector color_attachment_specs; + FramebufferTextureSpecification depth_attachment_specs = FramebufferTextureFormat::None; + + std::vector color_attachment_ids; + uint32_t depth_attachment_id; }; } diff --git a/open_engine/include/open_engine/opengl/opengl_renderer_api.hpp b/open_engine/include/open_engine/opengl/opengl_renderer_api.hpp index 9d94bb7..1a80a15 100644 --- a/open_engine/include/open_engine/opengl/opengl_renderer_api.hpp +++ b/open_engine/include/open_engine/opengl/opengl_renderer_api.hpp @@ -13,6 +13,7 @@ namespace OpenEngine { virtual void SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override; virtual void SetClearColor(const glm::vec4& color) override; + virtual void ClearBufferI(int buffer, int value) override; virtual void Clear() override; virtual void DrawIndexed(const Ref& vertex_array, uint32_t index_count = 0) override; diff --git a/open_engine/include/open_engine/renderer/editor_camera.hpp b/open_engine/include/open_engine/renderer/editor_camera.hpp index 5059adc..aaa242e 100644 --- a/open_engine/include/open_engine/renderer/editor_camera.hpp +++ b/open_engine/include/open_engine/renderer/editor_camera.hpp @@ -34,6 +34,9 @@ namespace OpenEngine { float GetPitch() const { return pitch; } float GetYaw() const { return yaw; } + + bool GetMoving() { return moving; }; + private: void UpdateProjection(); void UpdateView(); @@ -49,6 +52,7 @@ namespace OpenEngine { std::pair PanSpeed() const; float RotationSpeed() const; float ZoomSpeed() const; + private: float fov = 45.0f, aspect_ratio = 1.778f, near_clip = 0.1f, far_clip = 1000.0f; @@ -61,6 +65,8 @@ namespace OpenEngine { float distance = 10.0f; float pitch = 0.0f, yaw = 0.0f; + bool moving = false; + float viewport_width = 1280, viewport_height = 720; }; diff --git a/open_engine/include/open_engine/renderer/framebuffer.hpp b/open_engine/include/open_engine/renderer/framebuffer.hpp index 233b077..1d56d6f 100644 --- a/open_engine/include/open_engine/renderer/framebuffer.hpp +++ b/open_engine/include/open_engine/renderer/framebuffer.hpp @@ -4,11 +4,50 @@ #include "open_engine/ref_scope.hpp" #include +#include +#include namespace OpenEngine { + + enum class FramebufferTextureFormat + { + None = 0, + + // Color + RGBA8, + RED_INTEGER, + + // Depth/Stencil + DEPTH24STENCIL8, + + // Default + Depth = DEPTH24STENCIL8 + }; + + struct FramebufferTextureSpecification + { + FramebufferTextureSpecification() = default; + FramebufferTextureSpecification(FramebufferTextureFormat format) + : texture_format(format) + {}; + + FramebufferTextureFormat texture_format = FramebufferTextureFormat::None; + }; + + struct FramebufferAttachmentSpecification + { + FramebufferAttachmentSpecification() = default; + FramebufferAttachmentSpecification(std::initializer_list attachments) + : attachments(attachments) + {} + + std::vector attachments; + }; + struct FramebufferSpecification { uint32_t width, height; + FramebufferAttachmentSpecification attachments; uint32_t samples = 1; bool swap_chain_target = false; @@ -22,8 +61,9 @@ namespace OpenEngine { virtual void Unbind() = 0; virtual void Resize(uint32_t width, uint32_t height) = 0; + virtual int ReadPixel(uint32_t index, int x, int y) = 0; - virtual uint32_t GetColorAttachmentRendererID() const = 0; + virtual uint32_t GetColorAttachmentRendererID(uint32_t index = 0) const = 0; virtual const FramebufferSpecification& GetSpecification() const = 0; diff --git a/open_engine/include/open_engine/renderer/render_command.hpp b/open_engine/include/open_engine/renderer/render_command.hpp index 53c14c6..7410394 100644 --- a/open_engine/include/open_engine/renderer/render_command.hpp +++ b/open_engine/include/open_engine/renderer/render_command.hpp @@ -24,6 +24,11 @@ namespace OpenEngine { api->SetClearColor(color); }; + inline static void ClearBufferI(int buffer, int value) + { + api->ClearBufferI(buffer, value); + }; + inline static void Clear() { api->Clear(); diff --git a/open_engine/include/open_engine/renderer/renderer2d.hpp b/open_engine/include/open_engine/renderer/renderer2d.hpp index d48146b..6c2303a 100644 --- a/open_engine/include/open_engine/renderer/renderer2d.hpp +++ b/open_engine/include/open_engine/renderer/renderer2d.hpp @@ -39,13 +39,23 @@ namespace OpenEngine { static void EndScene(); static void Flush(); - static void DrawQuad(const Transform& transform_data, const glm::vec4& color); - static void DrawQuad(const Transform& transform_data, const Ref& texture, float tiling_factor = 1.0f); - static void DrawQuad(const Transform& transform_data, const Ref& subtexture, float tiling_factor = 1.0f); + static void DrawQuad(const Transform& transform_data, + const glm::vec4& color, int entity_id); + static void DrawQuad(const Transform& transform_data, + const Ref& texture, int entity_id, + float tiling_factor = 1.0f); + static void DrawQuad(const Transform& transform_data, + const Ref& subtexture, int entity_id, + float tiling_factor = 1.0f); - static void DrawQuad(const glm::mat4& transform, const glm::vec4& color); - static void DrawQuad(const glm::mat4& transform, const Ref& texture, float tiling_factor = 1.0f); - static void DrawQuad(const glm::mat4& transform, const Ref& subtexture, float tiling_factor = 1.0f); + static void DrawQuad(const glm::mat4& transform, + const glm::vec4& color, int entity_id); + static void DrawQuad(const glm::mat4& transform, + const Ref& texture, int entity_id, + float tiling_factor = 1.0f); + static void DrawQuad(const glm::mat4& transform, + const Ref& subtexture, int entity_id, + float tiling_factor = 1.0f); static void ResetStats(); static const Statistics& GetStats(); diff --git a/open_engine/include/open_engine/renderer/renderer_api.hpp b/open_engine/include/open_engine/renderer/renderer_api.hpp index 2d9efb0..62fa255 100644 --- a/open_engine/include/open_engine/renderer/renderer_api.hpp +++ b/open_engine/include/open_engine/renderer/renderer_api.hpp @@ -21,6 +21,7 @@ namespace OpenEngine { virtual void SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0; virtual void SetClearColor(const glm::vec4& color) = 0; + virtual void ClearBufferI(int buffer, int value) = 0; virtual void Clear() = 0; virtual void DrawIndexed(const Ref& vertex_array, uint32_t count = 0) = 0; diff --git a/open_engine/src/open_engine/opengl/opengl_framebuffer.cpp b/open_engine/src/open_engine/opengl/opengl_framebuffer.cpp old mode 100644 new mode 100755 index 0eb322e..3c831f7 --- a/open_engine/src/open_engine/opengl/opengl_framebuffer.cpp +++ b/open_engine/src/open_engine/opengl/opengl_framebuffer.cpp @@ -1,49 +1,166 @@ -#include "logging.hpp" +#include #include #include -#include - #include +#include +#include + namespace OpenEngine { + static const uint32_t max_framebuffer_size = 8192; + + namespace Utils { + + static bool IsDepthFormat(FramebufferTextureFormat format) + { + switch (format) { + case FramebufferTextureFormat::DEPTH24STENCIL8: return true; + } + + return false; + } + + static GLenum TextureTarget(bool multisampled) + { + return multisampled ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; + } + + static void CreateTexture(bool multisampled, uint32_t* out_id, + uint32_t count) + { + glCreateTextures(TextureTarget(multisampled), count, out_id); + } + + static void BindTexture(bool multisampled, uint32_t id) + { + glBindTexture(TextureTarget(multisampled), id); + } + + static void AttachColorTexture(uint32_t id, int samples, + GLenum internal_format, GLenum format, + uint32_t width, uint32_t height, int index) + { + bool multisampled = samples > 1; + if (multisampled) { + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, + internal_format, width, height, GL_FALSE); + } else { + glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, + 0, format, GL_UNSIGNED_BYTE, nullptr); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + index, + TextureTarget(multisampled), id, 0); + } + + static void AttachDepthTexture(uint32_t id, int samples, GLenum format, + GLenum attachment_type, uint32_t width, uint32_t height) + { + bool multisampled = samples > 1; + if (multisampled) { + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, + format, width, height, GL_FALSE); + } else { + glTexStorage2D(GL_TEXTURE_2D, 1, format, width, height); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + glFramebufferTexture2D(GL_FRAMEBUFFER, attachment_type, + TextureTarget(multisampled), id, 0); + } + + } + OpenGLFramebuffer::OpenGLFramebuffer(const FramebufferSpecification& spec) : specs(spec) { + for (auto format : specs.attachments.attachments) { + if (!Utils::IsDepthFormat(format.texture_format)) + color_attachment_specs.emplace_back(format); + else + depth_attachment_specs = format.texture_format; + } Invalidate(); } OpenGLFramebuffer::~OpenGLFramebuffer() { glDeleteFramebuffers(1, &id); - glDeleteTextures(1, &color_attachment); - glDeleteTextures(1, &depth_attachment); + glDeleteTextures(color_attachment_ids.size(), color_attachment_ids.data()); + glDeleteTextures(1, &depth_attachment_id); } void OpenGLFramebuffer::Invalidate() { if (id) { glDeleteFramebuffers(1, &id); - glDeleteTextures(1, &color_attachment); - glDeleteTextures(1, &depth_attachment); + glDeleteTextures(color_attachment_ids.size(), color_attachment_ids.data()); + glDeleteTextures(1, &depth_attachment_id); + + color_attachment_ids.clear(); + depth_attachment_id = 0; } glCreateFramebuffers(1, &id); glBindFramebuffer(GL_FRAMEBUFFER, id); - glCreateTextures(GL_TEXTURE_2D, 1, &color_attachment); - glBindTexture(GL_TEXTURE_2D, color_attachment); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, specs.width, specs.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + bool multisample = specs.samples > 1; - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_attachment, 0); + // Attachments + if (color_attachment_specs.size()) { + color_attachment_ids.resize(color_attachment_specs.size()); + Utils::CreateTexture(multisample, color_attachment_ids.data(), color_attachment_ids.size()); - glCreateTextures(GL_TEXTURE_2D, 1, &depth_attachment); - glBindTexture(GL_TEXTURE_2D, depth_attachment); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, specs.width, specs.height); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depth_attachment, 0); + for (size_t i = 0; i < color_attachment_specs.size(); i++) { + Utils::BindTexture(multisample, color_attachment_ids[i]); + switch (color_attachment_specs[i].texture_format) { + case FramebufferTextureFormat::RGBA8: + Utils::AttachColorTexture(color_attachment_ids[i], + specs.samples, GL_RGBA8, GL_RGBA, + specs.width, specs.height, i); + break; + case FramebufferTextureFormat::RED_INTEGER: + Utils::AttachColorTexture(color_attachment_ids[i], + specs.samples, GL_R32I, GL_RED_INTEGER, + specs.width, specs.height, i); + break; + } + } + } + + if (depth_attachment_specs.texture_format != FramebufferTextureFormat::None) { + Utils::CreateTexture(multisample, &depth_attachment_id, 1); + Utils::BindTexture(multisample, depth_attachment_id); + + switch (depth_attachment_specs.texture_format) { + case OpenEngine::FramebufferTextureFormat::DEPTH24STENCIL8: + Utils::AttachDepthTexture(depth_attachment_id, specs.samples, + GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL_ATTACHMENT, + specs.width, specs.height); + break; + } + } + + if (color_attachment_ids.size() > 1) { + OE_CORE_ASSERT(color_attachment_ids.size() < 4, "Only 4 color attachments supported."); + GLenum buffers[4] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; + glDrawBuffers(color_attachment_ids.size(), buffers); + } else if (color_attachment_ids.empty()) { + glDrawBuffer(GL_NONE); + } OE_CORE_ASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Framebuffer is incomplete!"); @@ -72,4 +189,16 @@ namespace OpenEngine { Invalidate(); } + + int OpenGLFramebuffer::ReadPixel(uint32_t index, int x, int y) + { + OE_CORE_ASSERT(index < color_attachment_ids.size(), "Index is greater than attachment count."); + + glReadBuffer(GL_COLOR_ATTACHMENT0 + index); + + int pixel_data; + glReadPixels(x, y, 1, 1, GL_RED_INTEGER, GL_INT, &pixel_data); + + return pixel_data; + } } diff --git a/open_engine/src/open_engine/opengl/opengl_renderer_api.cpp b/open_engine/src/open_engine/opengl/opengl_renderer_api.cpp index 2b14df8..18e8b2e 100644 --- a/open_engine/src/open_engine/opengl/opengl_renderer_api.cpp +++ b/open_engine/src/open_engine/opengl/opengl_renderer_api.cpp @@ -57,6 +57,11 @@ namespace OpenEngine { glClearColor(color.r, color.g, color.b, color.a); } + void OpenGLRendererAPI::ClearBufferI(int buffer, int value) + { + glClearBufferiv(GL_COLOR, buffer, &value); + } + void OpenGLRendererAPI::Clear() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); diff --git a/open_engine/src/open_engine/opengl/opengl_vertex_array.cpp b/open_engine/src/open_engine/opengl/opengl_vertex_array.cpp index 7ea80f7..b96a7d5 100644 --- a/open_engine/src/open_engine/opengl/opengl_vertex_array.cpp +++ b/open_engine/src/open_engine/opengl/opengl_vertex_array.cpp @@ -1,3 +1,4 @@ +#include "renderer/buffer.hpp" #include #include @@ -64,12 +65,22 @@ namespace OpenEngine { const auto& layout = vertex_buffer->GetLayout(); for (const auto& element : layout) { glEnableVertexAttribArray(index); - glVertexAttribPointer(index, - element.GetComponentCount(), - ShaderDataTypeToOpenGLBaseType(element.type), - element.normalized? GL_TRUE : GL_FALSE, - layout.GetStride(), - (const void*)(intptr_t)element.offset); + + if (element.type == ShaderDataType::Int) { + glVertexAttribIPointer(index, + element.GetComponentCount(), + ShaderDataTypeToOpenGLBaseType(element.type), + layout.GetStride(), + (const void*)(intptr_t)element.offset); + } else { + glVertexAttribPointer(index, + element.GetComponentCount(), + ShaderDataTypeToOpenGLBaseType(element.type), + element.normalized? GL_TRUE : GL_FALSE, + layout.GetStride(), + (const void*)(intptr_t)element.offset); + + } index++; } diff --git a/open_engine/src/open_engine/renderer/editor_camera.cpp b/open_engine/src/open_engine/renderer/editor_camera.cpp index 4f6cc3c..7c8dd53 100644 --- a/open_engine/src/open_engine/renderer/editor_camera.cpp +++ b/open_engine/src/open_engine/renderer/editor_camera.cpp @@ -69,13 +69,22 @@ namespace OpenEngine { glm::vec2 delta = (mouse - initial_mouse_position) * 0.003f; initial_mouse_position = mouse; - if (Input::IsMouseButtonPressed(Mouse::ButtonMiddle)) + if (Input::IsMouseButtonPressed(Mouse::ButtonMiddle)) { MousePan(delta); - else if (Input::IsMouseButtonPressed(Mouse::ButtonLeft)) + moving = true; + } + else if (Input::IsMouseButtonPressed(Mouse::ButtonLeft)) { MouseRotate(delta); - else if (Input::IsMouseButtonPressed(Mouse::ButtonRight)) + moving = true; + } + else if (Input::IsMouseButtonPressed(Mouse::ButtonRight)) { MouseZoom(delta.y); - } + moving = true; + } + + } else { + moving = false; + } UpdateView(); } diff --git a/open_engine/src/open_engine/renderer/renderer2d.cpp b/open_engine/src/open_engine/renderer/renderer2d.cpp index 8479e4a..76ef848 100755 --- a/open_engine/src/open_engine/renderer/renderer2d.cpp +++ b/open_engine/src/open_engine/renderer/renderer2d.cpp @@ -22,6 +22,7 @@ namespace OpenEngine { glm::vec2 tex_coord; float tex_index; float tiling_factor; + int id = -1; }; struct Renderer2DData @@ -55,14 +56,15 @@ namespace OpenEngine { OE_PROFILE_FUNCTION(); renderer_data.vertex_array = VertexArray::Create(); - renderer_data.vertex_buffer = VertexBuffer::Create(renderer_data.max_indices * sizeof(QuadVertex)); + renderer_data.vertex_buffer = VertexBuffer::Create(renderer_data.max_vertices * sizeof(QuadVertex)); BufferLayout layout = { { ShaderDataType::Float3, "a_Position" }, { ShaderDataType::Float4, "a_Color" }, { ShaderDataType::Float2, "a_TexCoords" }, { ShaderDataType::Float, "a_TexIndex" }, - { ShaderDataType::Float, "a_TilingFactor" } + { ShaderDataType::Float, "a_TilingFactor" }, + { ShaderDataType::Int, "a_EntityID"} }; renderer_data.vertex_buffer->SetLayout(layout); @@ -183,7 +185,8 @@ namespace OpenEngine { renderer_data.stats.draw_calls++; } - void Renderer2D::DrawQuad(const Transform& transform_data, const Ref& texture, float tiling_factor) + void Renderer2D::DrawQuad(const Transform& transform_data, + const Ref& texture, int entity_id, float tiling_factor) { OE_PROFILE_FUNCTION(); @@ -219,10 +222,12 @@ namespace OpenEngine { * glm::rotate(glm::mat4(1.0f), glm::radians(transform_data.rotation), { 0.0f, 0.0f, 1.0f }) * glm::scale(glm::mat4(1.0f), transform_data.size); - DrawQuad(transform, texture); + DrawQuad(transform, texture, entity_id); } - void Renderer2D::DrawQuad(const Transform& transform_data, const Ref& subtexture, float tiling_factor) + void Renderer2D::DrawQuad(const Transform& transform_data, + const Ref& subtexture, int entity_id, + float tiling_factor) { OE_PROFILE_FUNCTION(); @@ -259,10 +264,11 @@ namespace OpenEngine { * glm::rotate(glm::mat4(1.0f), glm::radians(transform_data.rotation), { 0.0f, 0.0f, 1.0f }) * glm::scale(glm::mat4(1.0f), transform_data.size); - DrawQuad(transform, subtexture); + DrawQuad(transform, subtexture, entity_id); } - void Renderer2D::DrawQuad(const Transform& transform_data, const glm::vec4& color) + void Renderer2D::DrawQuad(const Transform& transform_data, + const glm::vec4& color, int entity_id) { OE_PROFILE_FUNCTION(); @@ -280,10 +286,11 @@ namespace OpenEngine { * glm::scale(glm::mat4(1.0f), transform_data.size); - DrawQuad(transform, color); + DrawQuad(transform, color, entity_id); } - void Renderer2D::DrawQuad(const glm::mat4& transform, const Ref& texture, float tiling_factor) + void Renderer2D::DrawQuad(const glm::mat4& transform, + const Ref& texture, int entity_id, float tiling_factor) { OE_PROFILE_FUNCTION(); @@ -318,6 +325,7 @@ namespace OpenEngine { renderer_data.quad_vertex_ptr->tex_coord = texture_coords[i]; renderer_data.quad_vertex_ptr->tex_index = texture_index; renderer_data.quad_vertex_ptr->tiling_factor = tiling_factor; + renderer_data.quad_vertex_ptr->id = entity_id; renderer_data.quad_vertex_ptr++; } @@ -325,7 +333,9 @@ namespace OpenEngine { renderer_data.stats.quad_count++; } - void Renderer2D::DrawQuad(const glm::mat4& transform, const Ref& subtexture, float tiling_factor) + void Renderer2D::DrawQuad(const glm::mat4& transform, + const Ref& subtexture, int entity_id, + float tiling_factor) { OE_PROFILE_FUNCTION(); @@ -361,6 +371,7 @@ namespace OpenEngine { renderer_data.quad_vertex_ptr->tex_coord = texture_coords[i]; renderer_data.quad_vertex_ptr->tex_index = texture_index; renderer_data.quad_vertex_ptr->tiling_factor = tiling_factor; + renderer_data.quad_vertex_ptr->id = entity_id; renderer_data.quad_vertex_ptr++; } @@ -368,7 +379,8 @@ namespace OpenEngine { renderer_data.stats.quad_count++; } - void Renderer2D::DrawQuad(const glm::mat4& transform, const glm::vec4& color) + void Renderer2D::DrawQuad(const glm::mat4& transform, + const glm::vec4& color, int entity_id) { OE_PROFILE_FUNCTION(); @@ -384,6 +396,7 @@ namespace OpenEngine { renderer_data.quad_vertex_ptr->tex_coord = texture_coords[i]; renderer_data.quad_vertex_ptr->tex_index = 0; renderer_data.quad_vertex_ptr->tiling_factor = 1.0f; + renderer_data.quad_vertex_ptr->id = entity_id; renderer_data.quad_vertex_ptr++; } diff --git a/open_engine/src/open_engine/scene/scene.cpp b/open_engine/src/open_engine/scene/scene.cpp index f4f49aa..f226b43 100644 --- a/open_engine/src/open_engine/scene/scene.cpp +++ b/open_engine/src/open_engine/scene/scene.cpp @@ -1,3 +1,4 @@ +#include "logging.hpp" #include #include @@ -60,7 +61,7 @@ namespace OpenEngine { for (const auto& entity : view) { auto [transform, sprite] = view.get(entity); - Renderer2D::DrawQuad(transform.GetTransform(), sprite.color); + Renderer2D::DrawQuad(transform.GetTransform(), sprite.color, (int)entity); } Renderer2D::EndScene(); @@ -77,7 +78,7 @@ namespace OpenEngine { { auto [transform, sprite] = group.get(entity); - Renderer2D::DrawQuad(transform.GetTransform(), sprite.color); + Renderer2D::DrawQuad(transform.GetTransform(), sprite.color, (int)entity); } Renderer2D::EndScene(); diff --git a/untitled_persp.oes b/untitled_persp.oes new file mode 100644 index 0000000..d3317d5 --- /dev/null +++ b/untitled_persp.oes @@ -0,0 +1,38 @@ +Scene: N/A +Entities: + - Entity: 412741205 + TagComponent: + Tag: camera + TransformComponent: + Translation: [0, 0, 20.8999996] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + CameraComponent: + Camera: + ProjectionType: 0 + PerspectiveFOV: 45 + PerspectiveNear: 0.00999999978 + PerspectiveFar: 1000 + OrthographicSize: 10 + OrthographicNear: -1 + OrthographicFar: 1 + Primary: true + FixedAspectRatio: false + - Entity: 412741205 + TagComponent: + Tag: square + TransformComponent: + Translation: [0, 1.79999995, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + SpriteRendererComponent: + Color: [0.517647088, 0.0901960805, 1, 1] + - Entity: 412741205 + TagComponent: + Tag: "square 2 " + TransformComponent: + Translation: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + SpriteRendererComponent: + Color: [0.882352948, 0.745098054, 0.376470596, 1] \ No newline at end of file