2025-07-05 13:28:41 +03:30
|
|
|
#include <engine/camera/scene.hpp>
|
|
|
|
#include <engine/events/window.hpp>
|
|
|
|
#include <engine/graphics/blender.hpp>
|
|
|
|
#include <engine/graphics/buffers.hpp>
|
|
|
|
#include <engine/graphics/framebuffer.hpp>
|
|
|
|
#include <engine/graphics/render_command.hpp>
|
|
|
|
#include <engine/graphics/renderer.hpp>
|
|
|
|
#include <engine/graphics/texture.hpp>
|
2021-07-05 14:36:36 +04:30
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include <glm/gtc/matrix_transform.hpp>
|
2022-03-04 22:40:20 +03:30
|
|
|
#include <glm/matrix.hpp>
|
2021-06-29 11:01:11 +04:30
|
|
|
|
2021-05-30 16:45:54 +04:30
|
|
|
namespace Light {
|
|
|
|
|
2025-07-05 13:28:41 +03:30
|
|
|
Renderer *Renderer::s_Context = nullptr;
|
|
|
|
|
|
|
|
Renderer::Renderer(GLFWwindow *windowHandle, Ref<SharedContext> sharedContext)
|
|
|
|
: m_QuadRenderer(LT_MAX_QUAD_RENDERER_VERTICES, sharedContext)
|
|
|
|
, m_TextureRenderer(LT_MAX_TEXTURE_RENDERER_VERTICES, sharedContext)
|
|
|
|
, m_TintedTextureRenderer(LT_MAX_TINTED_TEXTURE_RENDERER_VERTICES, sharedContext)
|
|
|
|
, m_ViewProjectionBuffer(nullptr)
|
|
|
|
, m_RenderCommand(nullptr)
|
|
|
|
, m_Blender(nullptr)
|
|
|
|
, m_DefaultFramebufferCamera(nullptr)
|
|
|
|
, m_TargetFramebuffer(nullptr)
|
|
|
|
, m_ShouldClearBackbuffer(false)
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
2022-03-07 21:57:00 +03:30
|
|
|
ASSERT(!s_Context, "An instance of 'Renderer' already exists, do not construct this class!");
|
2022-03-04 22:40:20 +03:30
|
|
|
s_Context = this;
|
|
|
|
|
2025-07-05 13:28:41 +03:30
|
|
|
m_ViewProjectionBuffer = ConstantBuffer::Create(
|
|
|
|
ConstantBufferIndex::ViewProjection,
|
|
|
|
sizeof(glm::mat4),
|
|
|
|
sharedContext
|
|
|
|
);
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
m_RenderCommand = RenderCommand::Create(windowHandle, sharedContext);
|
2025-07-05 13:28:41 +03:30
|
|
|
m_Blender = Blender::Create(sharedContext);
|
2022-03-04 22:40:20 +03:30
|
|
|
m_Blender->Enable(BlendFactor::SRC_ALPHA, BlendFactor::INVERSE_SRC_ALPHA);
|
|
|
|
}
|
|
|
|
|
2025-07-05 13:28:41 +03:30
|
|
|
Scope<Renderer> Renderer::Create(GLFWwindow *windowHandle, Ref<SharedContext> sharedContext)
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
|
|
|
return MakeScope<Renderer>(new Renderer(windowHandle, sharedContext));
|
|
|
|
}
|
|
|
|
|
2025-07-05 13:28:41 +03:30
|
|
|
void Renderer::OnWindowResize(const WindowResizedEvent &event)
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
|
|
|
m_RenderCommand->SetViewport(0u, 0u, event.GetSize().x, event.GetSize().y);
|
|
|
|
}
|
|
|
|
|
|
|
|
//======================================== DRAW_QUAD ========================================//
|
|
|
|
/* tinted textures */
|
2025-07-05 13:28:41 +03:30
|
|
|
void Renderer::DrawQuadImpl(
|
|
|
|
const glm::vec3 &position,
|
|
|
|
const glm::vec2 &size,
|
|
|
|
const glm::vec4 &tint,
|
|
|
|
Ref<Texture> texture
|
|
|
|
)
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
2025-07-05 13:28:41 +03:30
|
|
|
DrawQuad(
|
|
|
|
glm::translate(glm::mat4(1.0f), position)
|
|
|
|
* glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f }),
|
|
|
|
tint,
|
|
|
|
texture
|
|
|
|
);
|
2022-03-04 22:40:20 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
/* tint */
|
2025-07-05 13:28:41 +03:30
|
|
|
void Renderer::DrawQuadImpl(const glm::vec3 &position, const glm::vec2 &size, const glm::vec4 &tint)
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
2025-07-05 13:28:41 +03:30
|
|
|
DrawQuad(
|
|
|
|
glm::translate(glm::mat4(1.0f), position)
|
|
|
|
* glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f }),
|
|
|
|
tint
|
|
|
|
);
|
2022-03-04 22:40:20 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
/* texture */
|
2025-07-05 13:28:41 +03:30
|
|
|
void Renderer::DrawQuadImpl(const glm::vec3 &position, const glm::vec2 &size, Ref<Texture> texture)
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
2025-07-05 13:28:41 +03:30
|
|
|
DrawQuad(
|
|
|
|
glm::translate(glm::mat4(1.0f), position)
|
|
|
|
* glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f }),
|
|
|
|
texture
|
|
|
|
);
|
2022-03-04 22:40:20 +03:30
|
|
|
}
|
|
|
|
//======================================== DRAW_QUAD ========================================//
|
|
|
|
|
|
|
|
//==================== DRAW_QUAD_TINT ====================//
|
2025-07-05 13:28:41 +03:30
|
|
|
void Renderer::DrawQuadImpl(const glm::mat4 &transform, const glm::vec4 &tint)
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
|
|
|
// locals
|
2025-07-05 13:28:41 +03:30
|
|
|
QuadRendererProgram::QuadVertexData *bufferMap = m_QuadRenderer.GetMapCurrent();
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
// top left
|
|
|
|
bufferMap[0].position = transform * glm::vec4(-0.5f, -0.5f, 0.0f, 1.0f);
|
2025-07-05 13:28:41 +03:30
|
|
|
bufferMap[0].tint = tint;
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
// top right
|
|
|
|
bufferMap[1].position = transform * glm::vec4(0.5f, -0.5f, 0.0f, 1.0f);
|
2025-07-05 13:28:41 +03:30
|
|
|
bufferMap[1].tint = tint;
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
// bottom right
|
|
|
|
bufferMap[2].position = transform * glm::vec4(0.5f, 0.5f, 0.0f, 1.0f);
|
2025-07-05 13:28:41 +03:30
|
|
|
bufferMap[2].tint = tint;
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
// bottom left
|
|
|
|
bufferMap[3].position = transform * glm::vec4(-0.5f, 0.5f, 0.0f, 1.0f);
|
2025-07-05 13:28:41 +03:30
|
|
|
bufferMap[3].tint = tint;
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
// advance
|
|
|
|
if (!m_QuadRenderer.Advance())
|
2021-05-30 16:45:54 +04:30
|
|
|
{
|
2022-03-07 21:57:00 +03:30
|
|
|
LOG(warn, "Exceeded LT_MAX_QUAD_RENDERER_VERTICES: {}", LT_MAX_QUAD_RENDERER_VERTICES);
|
2022-03-04 22:40:20 +03:30
|
|
|
FlushScene();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//==================== DRAW_QUAD_TINT ====================//
|
2021-05-30 16:45:54 +04:30
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
//==================== DRAW_QUAD_TEXTURE ====================//
|
2025-07-05 13:28:41 +03:30
|
|
|
void Renderer::DrawQuadImpl(const glm::mat4 &transform, Ref<Texture> texture)
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
|
|
|
// #todo: implement a proper binding
|
2022-03-07 21:57:00 +03:30
|
|
|
ASSERT(texture, "Texture passed to Renderer::DrawQuadImpl");
|
2022-03-04 22:40:20 +03:30
|
|
|
texture->Bind();
|
2021-07-09 11:56:31 +04:30
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
// locals
|
2025-07-05 13:28:41 +03:30
|
|
|
TextureRendererProgram::TextureVertexData *bufferMap = m_TextureRenderer.GetMapCurrent();
|
2021-05-30 16:45:54 +04:30
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
// top left
|
|
|
|
bufferMap[0].position = transform * glm::vec4(-0.5f, -0.5f, 0.0f, 1.0f);
|
|
|
|
bufferMap[0].texcoord = { 0.0f, 0.0f };
|
2021-05-30 16:45:54 +04:30
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
// top right
|
|
|
|
bufferMap[1].position = transform * glm::vec4(0.5f, -0.5f, 0.0f, 1.0f);
|
|
|
|
bufferMap[1].texcoord = { 1.0f, 0.0f };
|
|
|
|
|
|
|
|
// bottom right
|
|
|
|
bufferMap[2].position = transform * glm::vec4(0.5f, 0.5f, 0.0f, 1.0f);
|
|
|
|
bufferMap[2].texcoord = { 1.0f, 1.0f };
|
|
|
|
|
|
|
|
// bottom left
|
|
|
|
bufferMap[3].position = transform * glm::vec4(-0.5f, 0.5f, 0.0f, 1.0f);
|
|
|
|
bufferMap[3].texcoord = { 0.0f, 1.0f };
|
2021-07-14 00:17:30 +04:30
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
// advance
|
|
|
|
if (!m_TextureRenderer.Advance())
|
2021-08-05 21:24:20 +04:30
|
|
|
{
|
2025-07-05 13:28:41 +03:30
|
|
|
LOG(warn, "Exceeded LT_MAX_TEXTURE_RENDERER_VERTICES: {}", LT_MAX_TEXTURE_RENDERER_VERTICES
|
|
|
|
);
|
2022-03-04 22:40:20 +03:30
|
|
|
FlushScene();
|
2021-08-05 21:24:20 +04:30
|
|
|
}
|
2022-03-04 22:40:20 +03:30
|
|
|
}
|
|
|
|
|
2025-07-05 13:28:41 +03:30
|
|
|
void Renderer::DrawQuadImpl(const glm::mat4 &transform, const glm::vec4 &tint, Ref<Texture> texture)
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
|
|
|
// #todo: implement a proper binding
|
2022-03-07 21:57:00 +03:30
|
|
|
ASSERT(texture, "Texture passed to Renderer::DrawQuadImpl");
|
2022-03-04 22:40:20 +03:30
|
|
|
texture->Bind();
|
|
|
|
|
|
|
|
// locals
|
2025-07-05 13:28:41 +03:30
|
|
|
TintedTextureRendererProgram::TintedTextureVertexData *bufferMap = m_TintedTextureRenderer
|
|
|
|
.GetMapCurrent();
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
// top left
|
|
|
|
bufferMap[0].position = transform * glm::vec4(-0.5f, -0.5f, 0.0f, 1.0f);
|
2025-07-05 13:28:41 +03:30
|
|
|
bufferMap[0].tint = tint;
|
2022-03-04 22:40:20 +03:30
|
|
|
bufferMap[0].texcoord = { 0.0f, 0.0f };
|
|
|
|
|
|
|
|
// top right
|
|
|
|
bufferMap[1].position = transform * glm::vec4(0.5f, -0.5f, 0.0f, 1.0f);
|
2025-07-05 13:28:41 +03:30
|
|
|
bufferMap[1].tint = tint;
|
2022-03-04 22:40:20 +03:30
|
|
|
bufferMap[1].texcoord = { 1.0f, 0.0f };
|
|
|
|
|
|
|
|
// bottom right
|
|
|
|
bufferMap[2].position = transform * glm::vec4(0.5f, 0.5f, 0.0f, 1.0f);
|
2025-07-05 13:28:41 +03:30
|
|
|
bufferMap[2].tint = tint;
|
2022-03-04 22:40:20 +03:30
|
|
|
bufferMap[2].texcoord = { 1.0f, 1.0f };
|
|
|
|
|
|
|
|
// bottom left
|
|
|
|
bufferMap[3].position = transform * glm::vec4(-0.5f, 0.5f, 0.0f, 1.0f);
|
2025-07-05 13:28:41 +03:30
|
|
|
bufferMap[3].tint = tint;
|
2022-03-04 22:40:20 +03:30
|
|
|
bufferMap[3].texcoord = { 0.0f, 1.0f };
|
|
|
|
|
|
|
|
// advance
|
|
|
|
if (!m_TintedTextureRenderer.Advance())
|
2021-07-30 12:49:48 +04:30
|
|
|
{
|
2025-07-05 13:28:41 +03:30
|
|
|
LOG(warn, "Exceeded LT_MAX_TEXTURE_RENDERER_VERTICES: {}", LT_MAX_TEXTURE_RENDERER_VERTICES
|
|
|
|
);
|
2022-03-04 22:40:20 +03:30
|
|
|
FlushScene();
|
2021-07-30 12:49:48 +04:30
|
|
|
}
|
2022-03-04 22:40:20 +03:30
|
|
|
}
|
2021-07-30 12:49:48 +04:30
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
//==================== DRAW_QUAD_TEXTURE ====================//
|
|
|
|
|
|
|
|
void Renderer::BeginFrame()
|
|
|
|
{
|
|
|
|
}
|
2021-07-30 12:49:48 +04:30
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
void Renderer::EndFrame()
|
|
|
|
{
|
|
|
|
m_RenderCommand->SwapBuffers();
|
2025-07-05 13:28:41 +03:30
|
|
|
m_RenderCommand->ClearBackBuffer(
|
|
|
|
m_DefaultFramebufferCamera ? m_DefaultFramebufferCamera->GetBackgroundColor() :
|
|
|
|
glm::vec4(0.0f)
|
|
|
|
);
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
m_DefaultFramebufferCamera = nullptr;
|
|
|
|
}
|
|
|
|
|
2025-07-05 13:28:41 +03:30
|
|
|
void Renderer::BeginSceneImpl(
|
|
|
|
Camera *camera,
|
|
|
|
const glm::mat4 &cameraTransform,
|
|
|
|
const Ref<Framebuffer> &targetFrameBuffer /* = nullptr */
|
|
|
|
)
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
|
|
|
// determine the target frame buffer
|
|
|
|
m_TargetFramebuffer = targetFrameBuffer;
|
|
|
|
|
|
|
|
if (targetFrameBuffer)
|
|
|
|
targetFrameBuffer->BindAsTarget(camera->GetBackgroundColor());
|
|
|
|
else
|
2021-05-30 16:45:54 +04:30
|
|
|
{
|
2022-03-04 22:40:20 +03:30
|
|
|
m_DefaultFramebufferCamera = camera;
|
|
|
|
m_RenderCommand->DefaultTargetFramebuffer();
|
2021-07-01 19:25:46 +04:30
|
|
|
}
|
2021-06-29 11:01:11 +04:30
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
// update view projection buffer
|
2025-07-05 13:28:41 +03:30
|
|
|
glm::mat4 *map = (glm::mat4 *)m_ViewProjectionBuffer->Map();
|
|
|
|
map[0] = camera->GetProjection() * glm::inverse(cameraTransform);
|
2022-03-04 22:40:20 +03:30
|
|
|
m_ViewProjectionBuffer->UnMap();
|
|
|
|
|
|
|
|
// map renderers
|
|
|
|
m_QuadRenderer.Map();
|
|
|
|
m_TextureRenderer.Map();
|
|
|
|
m_TintedTextureRenderer.Map();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Renderer::FlushScene()
|
|
|
|
{
|
|
|
|
/* tinted texture renderer */
|
|
|
|
m_TintedTextureRenderer.UnMap();
|
|
|
|
if (m_TintedTextureRenderer.GetQuadCount())
|
2021-07-01 19:25:46 +04:30
|
|
|
{
|
2022-03-04 22:40:20 +03:30
|
|
|
m_TintedTextureRenderer.Bind();
|
|
|
|
m_RenderCommand->DrawIndexed(m_TintedTextureRenderer.GetQuadCount() * 6u);
|
2021-06-29 11:01:11 +04:30
|
|
|
}
|
2021-07-30 12:49:48 +04:30
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
/* quad renderer */
|
|
|
|
m_QuadRenderer.UnMap();
|
|
|
|
if (m_QuadRenderer.GetQuadCount())
|
2021-08-05 21:24:20 +04:30
|
|
|
{
|
2022-03-04 22:40:20 +03:30
|
|
|
m_QuadRenderer.Bind();
|
|
|
|
m_RenderCommand->DrawIndexed(m_QuadRenderer.GetQuadCount() * 6u);
|
2021-08-05 21:24:20 +04:30
|
|
|
}
|
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
/* texture renderer */
|
|
|
|
m_TextureRenderer.UnMap();
|
|
|
|
if (m_TextureRenderer.GetQuadCount())
|
2021-07-05 01:59:18 +04:30
|
|
|
{
|
2022-03-04 22:40:20 +03:30
|
|
|
m_TextureRenderer.Bind();
|
|
|
|
m_RenderCommand->DrawIndexed(m_TextureRenderer.GetQuadCount() * 6u);
|
2021-07-05 01:59:18 +04:30
|
|
|
}
|
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
m_QuadRenderer.Map();
|
|
|
|
m_TextureRenderer.Map();
|
|
|
|
m_TintedTextureRenderer.Map();
|
|
|
|
}
|
2021-07-31 09:37:09 +04:30
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
void Renderer::EndSceneImpl()
|
|
|
|
{
|
|
|
|
/* tinted texture renderer */
|
|
|
|
m_TintedTextureRenderer.UnMap();
|
|
|
|
if (m_TintedTextureRenderer.GetQuadCount())
|
|
|
|
{
|
|
|
|
m_TintedTextureRenderer.Bind();
|
|
|
|
m_RenderCommand->DrawIndexed(m_TintedTextureRenderer.GetQuadCount() * 6u);
|
2021-07-05 01:59:18 +04:30
|
|
|
}
|
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
/* quad renderer */
|
|
|
|
m_QuadRenderer.UnMap();
|
|
|
|
if (m_QuadRenderer.GetQuadCount())
|
2021-06-13 19:35:48 +04:30
|
|
|
{
|
2022-03-04 22:40:20 +03:30
|
|
|
m_QuadRenderer.Bind();
|
|
|
|
m_RenderCommand->DrawIndexed(m_QuadRenderer.GetQuadCount() * 6u);
|
2021-06-13 19:35:48 +04:30
|
|
|
}
|
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
/* texture renderer */
|
|
|
|
m_TextureRenderer.UnMap();
|
|
|
|
if (m_TextureRenderer.GetQuadCount())
|
2021-07-14 00:17:30 +04:30
|
|
|
{
|
2022-03-04 22:40:20 +03:30
|
|
|
m_TextureRenderer.Bind();
|
|
|
|
m_RenderCommand->DrawIndexed(m_TextureRenderer.GetQuadCount() * 6u);
|
2021-07-14 00:17:30 +04:30
|
|
|
}
|
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
// reset frame buffer
|
|
|
|
if (m_TargetFramebuffer)
|
2021-06-13 19:35:48 +04:30
|
|
|
{
|
2022-03-04 22:40:20 +03:30
|
|
|
m_TargetFramebuffer = nullptr;
|
|
|
|
m_RenderCommand->DefaultTargetFramebuffer();
|
2021-06-13 19:35:48 +04:30
|
|
|
}
|
2022-03-04 22:40:20 +03:30
|
|
|
}
|
2021-06-13 19:35:48 +04:30
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
} // namespace Light
|