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'
This commit is contained in:
Light 2021-07-14 00:17:30 +04:30
parent 44b135f157
commit 57616d755c
17 changed files with 86 additions and 63 deletions

View file

@ -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 <filesystem>
@ -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);

View file

@ -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; }

View file

@ -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;
};

View file

@ -6,6 +6,8 @@
#include "Texture.h"
#include "RenderCommand.h"
#include "Events/WindowEvents.h"
#include "Camera/Camera.h"
#include <glm/glm.hpp>
@ -28,6 +30,7 @@ namespace Light {
m_ViewProjectionBuffer = std::unique_ptr<ConstantBuffer>(ConstantBuffer::Create(ConstantBufferIndex::ViewProjection, sizeof(glm::mat4), sharedContext));
m_Blender = std::unique_ptr<Blender>(Blender::Create(sharedContext));
m_Blender->Enable(BlendFactor::SRC_ALPHA, BlendFactor::INVERSE_SRC_ALPHA);
}
Renderer* Renderer::Create(GLFWwindow* windowHandle, std::shared_ptr<SharedContext> 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>& 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())
{

View file

@ -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<RenderCommand> m_RenderCommand;
// constant buffers
std::unique_ptr<ConstantBuffer> m_ViewProjectionBuffer;
std::unique_ptr<RenderCommand> m_RenderCommand;
std::unique_ptr<Blender> 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> 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>& 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> texture);
void BeginSceneImpl(const Camera& camera);
void BeginSceneImpl(const std::shared_ptr<Camera>& camera);
void FlushScene();
void EndSceneImpl();
};

View file

@ -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> sharedContext);
Texture(const Texture&) = delete;

View file

@ -31,11 +31,6 @@ namespace Light {
m_SharedContext = std::make_shared<dxSharedContext>(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

View file

@ -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);
};
}

View file

@ -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);
}
}

View file

@ -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;
};
}

View file

@ -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

View file

@ -17,8 +17,6 @@ namespace Light {
public:
glGraphicsContext(GLFWwindow* windowHandle);
virtual void OnWindowResize(const WindowResizedEvent& event) override;
virtual void LogDebugData() override;
private:

View file

@ -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);
}
}

View file

@ -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;
};
}

View file

@ -36,7 +36,7 @@ namespace Light {
glfwSetWindowUserPointer(m_Handle, &m_EventCallback);
BindGlfwEvents();
// create graphics context
// create graphics contextG
m_GraphicsContext = std::unique_ptr<GraphicsContext>(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

View file

@ -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);
};
}

View file

@ -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<void(Event&)> m_EventCallback;
public:
public:
wWindow(std::function<void(Event&)> callback);
~wWindow();
@ -37,6 +38,8 @@ namespace Light {
private:
void BindGlfwEvents();
void OnWindowResize(const WindowResizedEvent& event);
};
}