From 57616d755c7f8c7eaf2d7b1fe7599920669f1fc3 Mon Sep 17 00:00:00 2001 From: Light Date: Wed, 14 Jul 2021 00:17:30 +0430 Subject: [PATCH] WindowResizeEvent | FlushScene - 'Renderer' now receives 'WindowResizedEvent' and handle the 'Framebuffer' and viewport stuff - Added 'Renderer' now uses the new 'FlushScene' function to flush when the mapped vertex buffer is filled - The viewport is now set by 'RenderCommand' via the 'Renderer' rather than the 'GraphicsConntext' - 'Window' no longer sends 'WindowResizedEvent' to 'GraphicsContext' - 'GraphicsContext' no longer receives 'OnWindowResize' events - Note: Sending events should be done by the 'Application' --- Engine/src/Engine/Core/Application.cpp | 9 ++++-- Engine/src/Engine/Graphics/GraphicsContext.h | 2 -- Engine/src/Engine/Graphics/RenderCommand.h | 2 ++ Engine/src/Engine/Graphics/Renderer.cpp | 32 +++++++++++++------ Engine/src/Engine/Graphics/Renderer.h | 15 ++++++--- Engine/src/Engine/Graphics/Texture.h | 3 +- .../GraphicsAPI/DirectX/dxGraphicsContext.cpp | 22 ------------- .../GraphicsAPI/DirectX/dxGraphicsContext.h | 5 --- .../GraphicsAPI/DirectX/dxRenderCommand.cpp | 18 +++++++++++ .../GraphicsAPI/DirectX/dxRenderCommand.h | 2 ++ .../GraphicsAPI/OpenGL/glGraphicsContext.cpp | 11 ------- .../GraphicsAPI/OpenGL/glGraphicsContext.h | 2 -- .../GraphicsAPI/OpenGL/glRenderCommand.cpp | 5 +++ .../GraphicsAPI/OpenGL/glRenderCommand.h | 2 ++ Engine/src/Platform/OS/Linux/lWindow.cpp | 9 ++++-- Engine/src/Platform/OS/Linux/lWindow.h | 3 ++ Engine/src/Platform/OS/Windows/wWindow.h | 7 ++-- 17 files changed, 86 insertions(+), 63 deletions(-) diff --git a/Engine/src/Engine/Core/Application.cpp b/Engine/src/Engine/Core/Application.cpp index d9cf9c6..d6d0023 100644 --- a/Engine/src/Engine/Core/Application.cpp +++ b/Engine/src/Engine/Core/Application.cpp @@ -5,14 +5,14 @@ #include "Events/Event.h" +#include "Debug/Instrumentor.h" + #include "Graphics/GraphicsContext.h" #include "Graphics/Renderer.h" #include "Graphics/RenderCommand.h" #include "UserInterface/UserInterface.h" -#include "Debug/Instrumentor.h" - #include "Time/Timer.h" #include @@ -94,8 +94,13 @@ namespace Light { { // window if (event.HasCategory(WindowEventCategory)) + { m_Window->OnEvent(event); + if(event.GetEventType() == EventType::WindowResized) + m_Window->GetGfxContext()->GetRenderer()->OnWindowResize((const WindowResizedEvent&)event); + } + // user interface if (event.HasCategory(InputEventCategory)) m_Window->GetGfxContext()->GetUserInterface()->OnInput(event); diff --git a/Engine/src/Engine/Graphics/GraphicsContext.h b/Engine/src/Engine/Graphics/GraphicsContext.h index c2d2b97..5b2e47d 100644 --- a/Engine/src/Engine/Graphics/GraphicsContext.h +++ b/Engine/src/Engine/Graphics/GraphicsContext.h @@ -44,8 +44,6 @@ namespace Light { virtual ~GraphicsContext(); - virtual void OnWindowResize(const WindowResizedEvent& event) = 0; - virtual void LogDebugData() = 0; static inline GraphicsAPI GetGraphicsAPI() { return s_Context->m_GraphicsAPI; } diff --git a/Engine/src/Engine/Graphics/RenderCommand.h b/Engine/src/Engine/Graphics/RenderCommand.h index 4150f83..8e8a8d9 100644 --- a/Engine/src/Engine/Graphics/RenderCommand.h +++ b/Engine/src/Engine/Graphics/RenderCommand.h @@ -24,6 +24,8 @@ namespace Light { virtual void Draw(unsigned int count) = 0; virtual void DrawIndexed(unsigned int count) = 0; + virtual void SetViewport(unsigned int x, unsigned int y, unsigned int width, unsigned int height) = 0; + protected: RenderCommand() = default; }; diff --git a/Engine/src/Engine/Graphics/Renderer.cpp b/Engine/src/Engine/Graphics/Renderer.cpp index d7dd1f4..b3047a9 100644 --- a/Engine/src/Engine/Graphics/Renderer.cpp +++ b/Engine/src/Engine/Graphics/Renderer.cpp @@ -6,6 +6,8 @@ #include "Texture.h" #include "RenderCommand.h" +#include "Events/WindowEvents.h" + #include "Camera/Camera.h" #include @@ -28,6 +30,7 @@ namespace Light { m_ViewProjectionBuffer = std::unique_ptr(ConstantBuffer::Create(ConstantBufferIndex::ViewProjection, sizeof(glm::mat4), sharedContext)); m_Blender = std::unique_ptr(Blender::Create(sharedContext)); + m_Blender->Enable(BlendFactor::SRC_ALPHA, BlendFactor::INVERSE_SRC_ALPHA); } Renderer* Renderer::Create(GLFWwindow* windowHandle, std::shared_ptr sharedContext) @@ -35,6 +38,11 @@ namespace Light { return new Renderer(windowHandle, sharedContext); } + void Renderer::OnWindowResize(const WindowResizedEvent& event) + { + m_RenderCommand->SetViewport(0u, 0u, event.GetSize().x, event.GetSize().y); + } + void Renderer::DrawQuadImpl(const glm::vec3& position, const glm::vec2& size, const glm::vec4& tint) { // locals @@ -64,8 +72,8 @@ namespace Light { // advance if (!m_QuadRenderer.Advance()) { - EndFrame(); - BeginFrame(); + LT_ENGINE_WARN("Renderer::DrawQuadImpl: exceeded LT_MAX_QUAD_RENDERER_VERTICES: {}", LT_MAX_QUAD_RENDERER_VERTICES); + FlushScene(); } } @@ -101,38 +109,42 @@ namespace Light { // advance if (!m_TextureRenderer.Advance()) { - EndFrame(); - BeginFrame(); + LT_ENGINE_WARN("Renderer::DrawQuadImpl: exceeded LT_MAX_TEXTURE_RENDERER_VERTICES: {}", LT_MAX_TEXTURE_RENDERER_VERTICES); + FlushScene(); } } void Renderer::BeginFrame() { - } void Renderer::EndFrame() { - } - void Renderer::BeginSceneImpl(const Camera& camera) + void Renderer::BeginSceneImpl(const std::shared_ptr& camera) { glm::mat4* map = (glm::mat4*)m_ViewProjectionBuffer->Map(); - map[0] = camera.GetProjection() * camera.GetView(); + map[0] = camera->GetProjection() * camera->GetView(); m_ViewProjectionBuffer->UnMap(); m_QuadRenderer.Map(); m_TextureRenderer.Map(); } + void Renderer::FlushScene() + { + EndScene(); + + m_QuadRenderer.Map(); + m_TextureRenderer.Map(); + } + void Renderer::EndSceneImpl() { m_QuadRenderer.UnMap(); m_TextureRenderer.UnMap(); - m_Blender->Enable(BlendFactor::SRC_ALPHA, BlendFactor::INVERSE_SRC_ALPHA); - //** QUAD_RENDERER **// if (m_QuadRenderer.GetQuadCount()) { diff --git a/Engine/src/Engine/Graphics/Renderer.h b/Engine/src/Engine/Graphics/Renderer.h index 3db7ca7..250745c 100644 --- a/Engine/src/Engine/Graphics/Renderer.h +++ b/Engine/src/Engine/Graphics/Renderer.h @@ -22,19 +22,23 @@ namespace Light { class Texture; + class WindowResizedEvent; + class SharedContext; class Renderer { private: static Renderer* s_Context; - + + // renderer programs QuadRendererProgram m_QuadRenderer; TextureRendererProgram m_TextureRenderer; - std::unique_ptr m_RenderCommand; + // constant buffers std::unique_ptr m_ViewProjectionBuffer; + std::unique_ptr m_RenderCommand; std::unique_ptr m_Blender; public: @@ -43,8 +47,10 @@ namespace Light { static inline void DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& tint) { s_Context->DrawQuadImpl(position, size, tint); } static inline void DrawQuad(const glm::vec3& position, const glm::vec2& size, std::shared_ptr texture) { s_Context->DrawQuadImpl(position, size, texture); } - static inline void BeginScene(const Camera& camera) { s_Context->BeginSceneImpl(camera); } + static inline void BeginScene(const std::shared_ptr& camera) { s_Context->BeginSceneImpl(camera); } static inline void EndScene() { s_Context->EndSceneImpl(); } + + void OnWindowResize(const WindowResizedEvent& event); void BeginFrame(); void EndFrame(); @@ -55,7 +61,8 @@ namespace Light { void DrawQuadImpl(const glm::vec3& position, const glm::vec2& size, const glm::vec4& tint); void DrawQuadImpl(const glm::vec3& position, const glm::vec2& size, std::shared_ptr texture); - void BeginSceneImpl(const Camera& camera); + void BeginSceneImpl(const std::shared_ptr& camera); + void FlushScene(); void EndSceneImpl(); }; diff --git a/Engine/src/Engine/Graphics/Texture.h b/Engine/src/Engine/Graphics/Texture.h index 5d8d3d6..34b0826 100644 --- a/Engine/src/Engine/Graphics/Texture.h +++ b/Engine/src/Engine/Graphics/Texture.h @@ -6,9 +6,10 @@ namespace Light { class SharedContext; + // #todo: improve textures class Texture { - public: + public: static Texture* Create(unsigned int width, unsigned int height, unsigned int components, unsigned char* pixels, std::shared_ptr sharedContext); Texture(const Texture&) = delete; diff --git a/Engine/src/Platform/GraphicsAPI/DirectX/dxGraphicsContext.cpp b/Engine/src/Platform/GraphicsAPI/DirectX/dxGraphicsContext.cpp index 272ede1..03ddd8a 100644 --- a/Engine/src/Platform/GraphicsAPI/DirectX/dxGraphicsContext.cpp +++ b/Engine/src/Platform/GraphicsAPI/DirectX/dxGraphicsContext.cpp @@ -31,11 +31,6 @@ namespace Light { m_SharedContext = std::make_shared(m_Device, m_DeviceContext, m_SwapChain, m_RenderTargetView); } - void dxGraphicsContext::OnWindowResize(const WindowResizedEvent& event) - { - SetResolution(event.GetSize().x, event.GetSize().y); - } - void dxGraphicsContext::SetupDeviceAndSwapChain(GLFWwindow* windowHandle) { // swap chain desc @@ -129,23 +124,6 @@ namespace Light { #endif } - void dxGraphicsContext::SetResolution(unsigned int width, unsigned int height) - { - // viewport - D3D11_VIEWPORT viewport; - - viewport.Width = width; - viewport.Height = height; - - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - viewport.TopLeftX = 0.0f; - viewport.TopLeftY = 0.0f; - - // set viewport - m_DeviceContext->RSSetViewports(1u, &viewport); - } - void dxGraphicsContext::LogDebugData() { // locals diff --git a/Engine/src/Platform/GraphicsAPI/DirectX/dxGraphicsContext.h b/Engine/src/Platform/GraphicsAPI/DirectX/dxGraphicsContext.h index 5b3bd8c..1c46cce 100644 --- a/Engine/src/Platform/GraphicsAPI/DirectX/dxGraphicsContext.h +++ b/Engine/src/Platform/GraphicsAPI/DirectX/dxGraphicsContext.h @@ -25,17 +25,12 @@ namespace Light { public: dxGraphicsContext(GLFWwindow* windowHandle); - virtual void OnWindowResize(const WindowResizedEvent& event) override; - virtual void LogDebugData() override; private: void SetupDeviceAndSwapChain(GLFWwindow* windowHandle); void SetupRenderTargets(); void SetupDebugInterface(); - - - void SetResolution(unsigned int width, unsigned int height); }; } \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/DirectX/dxRenderCommand.cpp b/Engine/src/Platform/GraphicsAPI/DirectX/dxRenderCommand.cpp index 0472714..7c90e7f 100644 --- a/Engine/src/Platform/GraphicsAPI/DirectX/dxRenderCommand.cpp +++ b/Engine/src/Platform/GraphicsAPI/DirectX/dxRenderCommand.cpp @@ -42,4 +42,22 @@ namespace Light { m_Context->GetDeviceContext()->DrawIndexed(count, 0u, 0u); } + void dxRenderCommand::SetViewport(unsigned int x, unsigned int y, unsigned int width, unsigned int height) + { + // create viewport + D3D11_VIEWPORT viewport; + + viewport.TopLeftX = x; + viewport.TopLeftY = y; + + viewport.Width = width; + viewport.Height = height; + + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + + // set viewport + m_Context->GetDeviceContext()->RSSetViewports(1u, &viewport); + } + } \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/DirectX/dxRenderCommand.h b/Engine/src/Platform/GraphicsAPI/DirectX/dxRenderCommand.h index 5c097cc..d33339c 100644 --- a/Engine/src/Platform/GraphicsAPI/DirectX/dxRenderCommand.h +++ b/Engine/src/Platform/GraphicsAPI/DirectX/dxRenderCommand.h @@ -23,6 +23,8 @@ namespace Light { virtual void Draw(unsigned int count) override; virtual void DrawIndexed(unsigned int count) override; + + virtual void SetViewport(unsigned int x, unsigned int y, unsigned int width, unsigned int height) override; }; } \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glGraphicsContext.cpp b/Engine/src/Platform/GraphicsAPI/OpenGL/glGraphicsContext.cpp index acd9d88..fe18410 100644 --- a/Engine/src/Platform/GraphicsAPI/OpenGL/glGraphicsContext.cpp +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glGraphicsContext.cpp @@ -29,17 +29,6 @@ namespace Light { SetDebugMessageCallback(); } - void glGraphicsContext::OnWindowResize(const WindowResizedEvent& event) - { - if (event.GetSize().x < 0 || event.GetSize().y < 0) - { - LT_ENGINE_ERROR("glGraphicsContext::OnWindowResize: 'width'/'height' cannot be negative: [{}x{}]", event.GetSize().x, event.GetSize().y); - return; - } - - glViewport(0, 0, event.GetSize().x, event.GetSize().y); - } - void glGraphicsContext::LogDebugData() { // #todo: log more information diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glGraphicsContext.h b/Engine/src/Platform/GraphicsAPI/OpenGL/glGraphicsContext.h index 0dfc53f..6a558fb 100644 --- a/Engine/src/Platform/GraphicsAPI/OpenGL/glGraphicsContext.h +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glGraphicsContext.h @@ -17,8 +17,6 @@ namespace Light { public: glGraphicsContext(GLFWwindow* windowHandle); - virtual void OnWindowResize(const WindowResizedEvent& event) override; - virtual void LogDebugData() override; private: diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glRenderCommand.cpp b/Engine/src/Platform/GraphicsAPI/OpenGL/glRenderCommand.cpp index f878b01..42225c5 100644 --- a/Engine/src/Platform/GraphicsAPI/OpenGL/glRenderCommand.cpp +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glRenderCommand.cpp @@ -31,4 +31,9 @@ namespace Light { glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr); } + void glRenderCommand::SetViewport(unsigned int x, unsigned int y, unsigned int width, unsigned int height) + { + glViewport(x, y, width, height); + } + } \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glRenderCommand.h b/Engine/src/Platform/GraphicsAPI/OpenGL/glRenderCommand.h index e66f6b1..6864089 100644 --- a/Engine/src/Platform/GraphicsAPI/OpenGL/glRenderCommand.h +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glRenderCommand.h @@ -18,6 +18,8 @@ namespace Light { void Draw(unsigned int count) override; void DrawIndexed(unsigned int count) override; + + virtual void SetViewport(unsigned int x, unsigned int y, unsigned int width, unsigned int height) override; }; } \ No newline at end of file diff --git a/Engine/src/Platform/OS/Linux/lWindow.cpp b/Engine/src/Platform/OS/Linux/lWindow.cpp index c89979d..52ea6ec 100644 --- a/Engine/src/Platform/OS/Linux/lWindow.cpp +++ b/Engine/src/Platform/OS/Linux/lWindow.cpp @@ -36,7 +36,7 @@ namespace Light { glfwSetWindowUserPointer(m_Handle, &m_EventCallback); BindGlfwEvents(); - // create graphics context + // create graphics contextG m_GraphicsContext = std::unique_ptr(GraphicsContext::Create(GraphicsAPI::OpenGL, m_Handle)); LT_ENGINE_ASSERT(m_GraphicsContext, "lWindow::lWindow: failed to create 'GraphicsContext'"); } @@ -62,11 +62,16 @@ namespace Light { // resized case EventType::WindowResized: - m_GraphicsContext->OnWindowResize((const WindowResizedEvent&)event); + OnWindowResize((const WindowResizedEvent&)event); break; } } + void lWindow::OnWindowResize(const WindowResizedEvent& event) + { + m_Properties.size = event.GetSize(); + } + void lWindow::SetProperties(const WindowProperties& properties, bool affectsVisiblity /* = false */) { // save the visibility status and re-assign if 'affectVisibility' is false diff --git a/Engine/src/Platform/OS/Linux/lWindow.h b/Engine/src/Platform/OS/Linux/lWindow.h index d79f602..9e8558d 100644 --- a/Engine/src/Platform/OS/Linux/lWindow.h +++ b/Engine/src/Platform/OS/Linux/lWindow.h @@ -8,6 +8,7 @@ struct GLFWwindow; namespace Light { class Event; + class WindowResizedEvent; class lWindow : public Window { @@ -35,6 +36,8 @@ namespace Light { private: void BindGlfwEvents(); + + void OnWindowResize(const WindowResizedEvent& event); }; } \ No newline at end of file diff --git a/Engine/src/Platform/OS/Windows/wWindow.h b/Engine/src/Platform/OS/Windows/wWindow.h index 2fa1341..5863116 100644 --- a/Engine/src/Platform/OS/Windows/wWindow.h +++ b/Engine/src/Platform/OS/Windows/wWindow.h @@ -8,16 +8,17 @@ struct GLFWwindow; namespace Light { class Event; + class WindowResizedEvent; class wWindow : public Window { private: - // #todo: don't handle Windows's window with glfw, create it yourself + // #todo: don't handle Windows's window with glfw, create an HWND GLFWwindow* m_Handle = nullptr; std::function m_EventCallback; - public: + public: wWindow(std::function callback); ~wWindow(); @@ -37,6 +38,8 @@ namespace Light { private: void BindGlfwEvents(); + + void OnWindowResize(const WindowResizedEvent& event); }; } \ No newline at end of file