From 2061abadd8c63417379d9edaaa6011c698fce0bd Mon Sep 17 00:00:00 2001 From: Light Date: Fri, 16 Jul 2021 19:59:14 +0430 Subject: [PATCH] Framebuffer resizing - Added 'Camera::OnResize()' for keeping the aspect ratio updated to prevent streching/squashing the scene - Added 'FrameBuffe::Resize()' - Enabled ImGui docking and viewport - 'MirrorLayer::m_Camera' & 'MirrorLayer::m_Framebuffer' now adjust their properties when ImGui's available region changes --- Engine/src/Engine/Camera/Camera.cpp | 6 +++ Engine/src/Engine/Camera/Camera.h | 2 + Engine/src/Engine/Graphics/Framebuffer.h | 2 + .../GraphicsAPI/DirectX/dxFramebuffer.cpp | 16 ++++++ .../GraphicsAPI/DirectX/dxFramebuffer.h | 1 + .../GraphicsAPI/DirectX/dxUserInterface.cpp | 9 ++++ .../GraphicsAPI/OpenGL/glFramebuffer.cpp | 54 ++++++++++++------- .../GraphicsAPI/OpenGL/glFramebuffer.h | 2 + .../GraphicsAPI/OpenGL/glUserInterface.cpp | 12 +++++ .../GraphicsAPI/OpenGL/glUserInterface.h | 5 ++ Mirror/src/MirrorLayer.h | 14 ++++- 11 files changed, 103 insertions(+), 20 deletions(-) diff --git a/Engine/src/Engine/Camera/Camera.cpp b/Engine/src/Engine/Camera/Camera.cpp index 32acfd5..ce54896 100644 --- a/Engine/src/Engine/Camera/Camera.cpp +++ b/Engine/src/Engine/Camera/Camera.cpp @@ -25,6 +25,12 @@ namespace Light { FLT_MAX, FLT_MIN); } + void Camera::OnResize(const glm::vec2& size) + { + m_AspectRatio = size.x / size.y; + CalculateProjection(); + } + void Camera::Move(const glm::vec2& position) { m_Position += position; diff --git a/Engine/src/Engine/Camera/Camera.h b/Engine/src/Engine/Camera/Camera.h index bb3b8c9..49cf477 100644 --- a/Engine/src/Engine/Camera/Camera.h +++ b/Engine/src/Engine/Camera/Camera.h @@ -25,6 +25,8 @@ namespace Light { void CalculateView(); void CalculateProjection(); + void OnResize(const glm::vec2& size); + inline const glm::mat4& GetView() const { return m_View; } inline const glm::mat4& GetProjection() const { return m_Projection; } diff --git a/Engine/src/Engine/Graphics/Framebuffer.h b/Engine/src/Engine/Graphics/Framebuffer.h index 3d6f4ba..6868575 100644 --- a/Engine/src/Engine/Graphics/Framebuffer.h +++ b/Engine/src/Engine/Graphics/Framebuffer.h @@ -28,6 +28,8 @@ namespace Light { virtual void BindAsTarget() = 0; virtual void BindAsResource() = 0; + virtual void Resize(const glm::vec2& size) = 0; + protected: Framebuffer() = default; }; diff --git a/Engine/src/Platform/GraphicsAPI/DirectX/dxFramebuffer.cpp b/Engine/src/Platform/GraphicsAPI/DirectX/dxFramebuffer.cpp index cbd5978..e27b865 100644 --- a/Engine/src/Platform/GraphicsAPI/DirectX/dxFramebuffer.cpp +++ b/Engine/src/Platform/GraphicsAPI/DirectX/dxFramebuffer.cpp @@ -54,4 +54,20 @@ namespace Light { LT_ENGINE_ERROR("dxFramebuffer::BindAsResource: NO_IMPLEMENT"); } + void dxFramebuffer::Resize(const glm::vec2& size) + { + D3D11_TEXTURE2D_DESC textureDesc; + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + + m_ColorAttachment->GetDesc(&textureDesc); + m_RenderTargetView->GetDesc(&rtvDesc); + m_ResourceView->GetDesc(&srvDesc); + + HRESULT hr; + DXC(m_Context->GetDevice()->CreateTexture2D(&textureDesc, nullptr, &m_ColorAttachment)); + DXC(m_Context->GetDevice()->CreateRenderTargetView(m_ColorAttachment.Get(), &rtvDesc, &m_RenderTargetView)); + DXC(m_Context->GetDevice()->CreateShaderResourceView(m_ColorAttachment.Get(), &srvDesc, &m_ResourceView)); + } + } \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/DirectX/dxFramebuffer.h b/Engine/src/Platform/GraphicsAPI/DirectX/dxFramebuffer.h index 41cae45..a8e2352 100644 --- a/Engine/src/Platform/GraphicsAPI/DirectX/dxFramebuffer.h +++ b/Engine/src/Platform/GraphicsAPI/DirectX/dxFramebuffer.h @@ -31,6 +31,7 @@ namespace Light { void BindAsTarget() override; void BindAsResource() override; + void Resize(const glm::vec2& size) override; }; } \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/DirectX/dxUserInterface.cpp b/Engine/src/Platform/GraphicsAPI/DirectX/dxUserInterface.cpp index edcbc56..41b0ca7 100644 --- a/Engine/src/Platform/GraphicsAPI/DirectX/dxUserInterface.cpp +++ b/Engine/src/Platform/GraphicsAPI/DirectX/dxUserInterface.cpp @@ -22,6 +22,12 @@ namespace Light { ImGuiIO& io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; + + io.ConfigFlags |= ImGuiBackendFlags_PlatformHasViewports; + io.ConfigFlags |= ImGuiBackendFlags_RendererHasViewports; + // style ImGui::StyleColorsDark(); @@ -51,6 +57,9 @@ namespace Light { { ImGui::Render(); ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); } void dxUserInterface::LogDebugData() diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glFramebuffer.cpp b/Engine/src/Platform/GraphicsAPI/OpenGL/glFramebuffer.cpp index 10e444b..c5094de 100644 --- a/Engine/src/Platform/GraphicsAPI/OpenGL/glFramebuffer.cpp +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glFramebuffer.cpp @@ -1,13 +1,48 @@ #include "ltpch.h" #include "glFramebuffer.h" +#include + #include namespace Light { glFramebuffer::glFramebuffer(const FramebufferSpecification& specification) - : m_Specification(specification) + : m_Specification(specification), m_BufferID(0u), m_ColorAttachment(0u), m_DepthStencilAttachment(0u) { + Resize({ specification.width, specification.height }); + } + + glFramebuffer::~glFramebuffer() + { + glDeleteFramebuffers(1, &m_BufferID); + glDeleteTextures(1, &m_ColorAttachment); + // glDeleteTextures(1, &m_DepthStencilAttachment); + } + + void glFramebuffer::BindAsTarget() + { + glBindFramebuffer(GL_FRAMEBUFFER, m_BufferID); + glViewport(0, 0, m_Specification.width, m_Specification.height); + + glClearColor(m_Specification.defaultColor.r, m_Specification.defaultColor.g, m_Specification.defaultColor.b, m_Specification.defaultColor.a); + glClear(GL_COLOR_BUFFER_BIT); + } + + void glFramebuffer::BindAsResource() + { + LT_ENGINE_ERROR("glFramebuffer::BindAsResource: NO_IMPLEMENT!"); + } + + void glFramebuffer::Resize(const glm::vec2& size) + { + if (m_BufferID) + { + glDeleteFramebuffers(1, &m_BufferID); + glDeleteTextures(1, &m_ColorAttachment); + // glDeleteTextures(1, &m_DepthStencilAttachment); + } + glCreateFramebuffers(1, &m_BufferID); glBindFramebuffer(GL_FRAMEBUFFER, m_BufferID); @@ -32,21 +67,4 @@ namespace Light { glBindFramebuffer(GL_FRAMEBUFFER, 0); } - glFramebuffer::~glFramebuffer() - { - glDeleteFramebuffers(1, &m_BufferID); - } - - void glFramebuffer::BindAsTarget() - { - glBindFramebuffer(GL_FRAMEBUFFER, m_BufferID); - glClearColor(m_Specification.defaultColor.r, m_Specification.defaultColor.g, m_Specification.defaultColor.b, m_Specification.defaultColor.a); - glClear(GL_COLOR_BUFFER_BIT); - } - - void glFramebuffer::BindAsResource() - { - LT_ENGINE_ERROR("glFramebuffer::BindAsResource: NO_IMPLEMENT!"); - } - } \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glFramebuffer.h b/Engine/src/Platform/GraphicsAPI/OpenGL/glFramebuffer.h index c19f094..a314d48 100644 --- a/Engine/src/Platform/GraphicsAPI/OpenGL/glFramebuffer.h +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glFramebuffer.h @@ -20,6 +20,8 @@ namespace Light { void BindAsTarget() override; void BindAsResource() override; + + void Resize(const glm::vec2& size) override; }; } \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.cpp b/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.cpp index 2ee9138..9db08b0 100644 --- a/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.cpp +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.cpp @@ -5,9 +5,12 @@ #include #include +#include + namespace Light { glUserInterface::glUserInterface(GLFWwindow* windowHandle) + : m_WindowHandle(windowHandle) { // create context IMGUI_CHECKVERSION(); @@ -16,6 +19,11 @@ namespace Light { // configure io ImGuiIO& io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; + + io.ConfigFlags |= ImGuiBackendFlags_PlatformHasViewports; + io.ConfigFlags |= ImGuiBackendFlags_RendererHasViewports; // style color ImGui::StyleColorsDark(); @@ -46,6 +54,10 @@ namespace Light { { ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + glfwMakeContextCurrent(m_WindowHandle); } void glUserInterface::LogDebugData() diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.h b/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.h index cab0cbe..540c07a 100644 --- a/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.h +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.h @@ -3,10 +3,15 @@ #include "Base.h" #include "UserInterface/UserInterface.h" +class GLFWwindow; + namespace Light { class glUserInterface : public UserInterface { + private: + GLFWwindow* m_WindowHandle; + public: glUserInterface(GLFWwindow* windowHandle); ~glUserInterface(); diff --git a/Mirror/src/MirrorLayer.h b/Mirror/src/MirrorLayer.h index a33f73f..f8bea13 100644 --- a/Mirror/src/MirrorLayer.h +++ b/Mirror/src/MirrorLayer.h @@ -53,10 +53,20 @@ public: { ImGui::Begin("GameView"); + static ImVec2 regionAvailPrev = {0, 0}; + ImVec2 regionAvail = ImGui::GetContentRegionAvail(); + + if (regionAvail.x != regionAvailPrev.x || regionAvail.y != regionAvailPrev.y) + { + m_Framebuffer->Resize({ regionAvail.x, regionAvail.y }); + m_Camera->OnResize({ regionAvail.x, regionAvail.y }); + regionAvailPrev = regionAvail; + } + if(Light::GraphicsContext::GetGraphicsAPI() == Light::GraphicsAPI::DirectX) - ImGui::Image(m_Framebuffer->GetColorAttachment(), ImVec2(400, 300)); + ImGui::Image(m_Framebuffer->GetColorAttachment(), regionAvail); else - ImGui::Image(m_Framebuffer->GetColorAttachment(), ImVec2(400, 300), ImVec2(0, 1), ImVec2(1, 0)); + ImGui::Image(m_Framebuffer->GetColorAttachment(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); ImGui::End(); }