add RenderPass

This commit is contained in:
2025-11-29 20:03:32 +08:00
parent b2ea361518
commit 3f1515bb63
17 changed files with 362 additions and 82 deletions

View File

@ -113,8 +113,32 @@ namespace Prism
void EditorLayer::OnAttach() void EditorLayer::OnAttach()
{ {
// RenderPass
FramebufferSpecification geoFramebufferSpec;
geoFramebufferSpec.Width = 1280;
geoFramebufferSpec.Height = 720;
geoFramebufferSpec.Format = FramebufferFormat::RGBA16F;
geoFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f };
RenderPassSpecification geoRenderPassSpec;
geoRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(geoFramebufferSpec);
m_GeoPass = RenderPass::Create(geoRenderPassSpec);
FramebufferSpecification compFramebufferSpec;
compFramebufferSpec.Width = 1280;
compFramebufferSpec.Height = 720;
compFramebufferSpec.Format = FramebufferFormat::RGBA8;
compFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f };
RenderPassSpecification compRenderPassSpec;
compRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(compFramebufferSpec);
m_CompositePass = RenderPass::Create(compRenderPassSpec);
/*
m_Framebuffer.reset(FrameBuffer::Create(1280, 720, FramebufferFormat::RGBA16F)); m_Framebuffer.reset(FrameBuffer::Create(1280, 720, FramebufferFormat::RGBA16F));
m_FinalPresentBuffer.reset(FrameBuffer::Create(1280, 720, FramebufferFormat::RGBA8)); m_FinalPresentBuffer.reset(FrameBuffer::Create(1280, 720, FramebufferFormat::RGBA8));
*/
m_QuadShader = Shader::Create("assets/shaders/quad.glsl"); m_QuadShader = Shader::Create("assets/shaders/quad.glsl");
m_HDRShader = Shader::Create("assets/shaders/hdr.glsl"); m_HDRShader = Shader::Create("assets/shaders/hdr.glsl");
@ -151,7 +175,7 @@ namespace Prism
mi->Set("u_Roughness", roughness); mi->Set("u_Roughness", roughness);
mi->Set("u_ModelMatrix", glm::translate(glm::mat4(1.0f), glm::vec3(x, 0.0f, 0.0f))); mi->Set("u_ModelMatrix", glm::translate(glm::mat4(1.0f), glm::vec3(x, 0.0f, 0.0f)));
x += 1.1f; x += 1.1f;
roughness += 0.15f; roughness += 0.125f;
m_MetalSphereMaterialInstances.push_back(mi); m_MetalSphereMaterialInstances.push_back(mi);
} }
@ -165,26 +189,17 @@ namespace Prism
mi->Set("u_Roughness", roughness); mi->Set("u_Roughness", roughness);
mi->Set("u_ModelMatrix", translate(glm::mat4(1.0f), glm::vec3(x, 1.2f, 0.0f))); mi->Set("u_ModelMatrix", translate(glm::mat4(1.0f), glm::vec3(x, 1.2f, 0.0f)));
x += 1.1f; x += 1.1f;
roughness += 0.15f; roughness += 0.125f;
m_DielectricSphereMaterialInstances.push_back(mi); m_DielectricSphereMaterialInstances.push_back(mi);
} }
// Create Quad
x = -1;
float y = -1;
float width = 2, height = 2;
struct QuadVertex
{
glm::vec3 Position;
glm::vec2 TexCoord;
};
// Create Quad
static float QuadVertex[] = { static float QuadVertex[] = {
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f -1.0f, 1.0f, 0.0f, 0.0f, 1.0f
}; };
static uint32_t QuadIndices[] = { static uint32_t QuadIndices[] = {
0, 1, 2, 2, 3, 0 0, 1, 2, 2, 3, 0
}; };
@ -225,7 +240,8 @@ namespace Prism
m_Camera.Update(deltaTime); m_Camera.Update(deltaTime);
auto viewProjection = m_Camera.GetProjectionMatrix() * m_Camera.GetViewMatrix(); auto viewProjection = m_Camera.GetProjectionMatrix() * m_Camera.GetViewMatrix();
m_Framebuffer->Bind(); // m_Framebuffer->Bind();
Renderer::BeginRenderPass(m_GeoPass);
Renderer::Clear(m_ClearColor[0], m_ClearColor[1], m_ClearColor[2], m_ClearColor[3]); Renderer::Clear(m_ClearColor[0], m_ClearColor[1], m_ClearColor[2], m_ClearColor[3]);
m_QuadShader->Bind(); m_QuadShader->Bind();
@ -252,7 +268,6 @@ namespace Prism
m_MeshMaterial->Set("u_MetalnessTexToggle", m_MetalnessInput.UseTexture ? 1.0f : 0.0f); m_MeshMaterial->Set("u_MetalnessTexToggle", m_MetalnessInput.UseTexture ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_RoughnessTexToggle", m_RoughnessInput.UseTexture ? 1.0f : 0.0f); m_MeshMaterial->Set("u_RoughnessTexToggle", m_RoughnessInput.UseTexture ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_EnvMapRotation", m_EnvMapRotation); m_MeshMaterial->Set("u_EnvMapRotation", m_EnvMapRotation);
m_MeshMaterial->Set("u_EnvRadianceTex", m_EnvironmentCubeMap); m_MeshMaterial->Set("u_EnvRadianceTex", m_EnvironmentCubeMap);
m_MeshMaterial->Set("u_EnvIrradianceTex", m_EnvironmentIrradiance); m_MeshMaterial->Set("u_EnvIrradianceTex", m_EnvironmentIrradiance);
m_MeshMaterial->Set("u_BRDFLUTTexture", m_BRDFLUT); m_MeshMaterial->Set("u_BRDFLUTTexture", m_BRDFLUT);
@ -317,19 +332,23 @@ namespace Prism
m_GridMaterial->Set("u_MVP", viewProjection * glm::scale(glm::mat4(1.0f), glm::vec3(16.0f))); m_GridMaterial->Set("u_MVP", viewProjection * glm::scale(glm::mat4(1.0f), glm::vec3(16.0f)));
m_PlaneMesh->Render(deltaTime, m_GridMaterial); m_PlaneMesh->Render(deltaTime, m_GridMaterial);
m_Framebuffer->Unbind(); // m_Framebuffer->Unbind();
Renderer::EndRenderPass();
m_FinalPresentBuffer->Bind(); Renderer::BeginRenderPass(m_CompositePass);
// m_FinalPresentBuffer->Bind();
m_HDRShader->Bind(); m_HDRShader->Bind();
m_HDRShader->SetFloat("u_Exposure", m_Exposure); m_HDRShader->SetFloat("u_Exposure", m_Exposure);
m_Framebuffer->BindTexture(); // m_Framebuffer->BindTexture();
m_GeoPass->GetSpecification().TargetFramebuffer->BindTexture();
/* /*
m_VertexBuffer->Bind(); m_VertexBuffer->Bind();
m_IndexBuffer->Bind(); m_IndexBuffer->Bind();
*/ */
m_FullscreenQuadVertexArray->Bind(); m_FullscreenQuadVertexArray->Bind();
Renderer::DrawIndexed(m_FullscreenQuadVertexArray->GetIndexBuffer()->GetCount(), false); Renderer::DrawIndexed(m_FullscreenQuadVertexArray->GetIndexBuffer()->GetCount(), false);
m_FinalPresentBuffer->Unbind(); // m_FinalPresentBuffer->Unbind();
Renderer::EndRenderPass();
} }
} }
@ -681,10 +700,15 @@ namespace Prism
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
ImGui::Begin("Viewport"); ImGui::Begin("Viewport");
auto viewportSize = ImGui::GetContentRegionAvail(); auto viewportSize = ImGui::GetContentRegionAvail();
m_Framebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_FinalPresentBuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y); m_GeoPass->GetSpecification().TargetFramebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_CompositePass->GetSpecification().TargetFramebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
// m_Framebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
// m_FinalPresentBuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_Camera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f)); m_Camera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
ImGui::Image((ImTextureRef)m_FinalPresentBuffer->GetColorAttachmentRendererID(), viewportSize, {0, 1}, {1, 0}); // ImGui::Image((ImTextureRef)m_FinalPresentBuffer->GetColorAttachmentRendererID(), viewportSize, {0, 1}, {1, 0});
ImGui::Image((ImTextureRef)m_CompositePass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(), viewportSize, { 0, 1 }, { 1, 0 });
// ImGuizmo // ImGuizmo
if (m_GizmoType != -1) if (m_GizmoType != -1)

View File

@ -27,7 +27,8 @@ private:
private: private:
float m_ClearColor[4]; float m_ClearColor[4];
Ref<FrameBuffer> m_Framebuffer, m_FinalPresentBuffer; // Ref<FrameBuffer> m_Framebuffer, m_FinalPresentBuffer;
Ref<RenderPass> m_GeoPass, m_CompositePass;
/* /*
Ref<VertexBuffer> m_VertexBuffer; Ref<VertexBuffer> m_VertexBuffer;

View File

@ -18,6 +18,7 @@
#include "Prism/Renderer/Buffer.h" #include "Prism/Renderer/Buffer.h"
#include "Prism/Renderer/Renderer.h" #include "Prism/Renderer/Renderer.h"
#include "Prism/Renderer/RenderPass.h"
#include "Prism/Renderer/Shader.h" #include "Prism/Renderer/Shader.h"
#include "Prism/Renderer/Texture.h" #include "Prism/Renderer/Texture.h"
#include "Prism/Renderer/FrameBuffer.h" #include "Prism/Renderer/FrameBuffer.h"

View File

@ -181,7 +181,7 @@ namespace Prism
bool Application::OnWindowResize(const WindowResizeEvent& e) bool Application::OnWindowResize(const WindowResizeEvent& e)
{ {
int width = e.GetWidth(), height = e.GetHeight(); uint32_t width = e.GetWidth(), height = e.GetHeight();
if (width == 0 || height == 0) if (width == 0 || height == 0)
{ {
m_Minimized = true; m_Minimized = true;
@ -192,7 +192,10 @@ namespace Prism
PM_RENDER_2(width, height, { glViewport(0, 0, width, height); }); PM_RENDER_2(width, height, { glViewport(0, 0, width, height); });
auto& fbs = FrameBufferPool::GetGlobal()->GetAll(); auto& fbs = FrameBufferPool::GetGlobal()->GetAll();
for (auto& fb : fbs) for (auto& fb : fbs)
fb->Resize(width, height); {
if (const auto fbp = fb.lock())
fbp->Resize(width, height);
}
return false; return false;
} }

View File

@ -10,14 +10,13 @@
namespace Prism namespace Prism
{ {
OpenGLFrameBuffer::OpenGLFrameBuffer(const uint32_t width, const uint32_t height, const FramebufferFormat format) OpenGLFrameBuffer::OpenGLFrameBuffer(const FramebufferSpecification& spec)
: m_Format(format) : m_Specification(spec)
{ {
OpenGLFrameBuffer::Resize(width, height); OpenGLFrameBuffer::Resize(spec.Width, spec.Height);
m_Width = width;
m_Height = height;
} }
OpenGLFrameBuffer::~OpenGLFrameBuffer() OpenGLFrameBuffer::~OpenGLFrameBuffer()
{ {
PM_RENDER_S({ PM_RENDER_S({
@ -29,7 +28,7 @@ namespace Prism
{ {
PM_RENDER_S({ PM_RENDER_S({
glBindFramebuffer(GL_FRAMEBUFFER, self->m_RendererID); glBindFramebuffer(GL_FRAMEBUFFER, self->m_RendererID);
glViewport(0, 0, self->m_Width, self->m_Height); glViewport(0, 0, self->m_Specification.Width, self->m_Specification.Height);
}); });
} }
@ -40,13 +39,13 @@ namespace Prism
}); });
} }
void OpenGLFrameBuffer::Resize(uint32_t width, uint32_t height) void OpenGLFrameBuffer::Resize(const uint32_t width, const uint32_t height)
{ {
if (m_Width == width && m_Height == height) if (m_RendererID && m_Specification.Width == width && m_Specification.Height == height)
return; return;
m_Width = width; m_Specification.Width = width;
m_Height = height; m_Specification.Height = height;
PM_RENDER_S({ PM_RENDER_S({
if (self->m_RendererID) if (self->m_RendererID)
{ {
@ -62,13 +61,13 @@ namespace Prism
glBindTexture(GL_TEXTURE_2D, self->m_ColorAttachment); glBindTexture(GL_TEXTURE_2D, self->m_ColorAttachment);
// TODO: Create Hazel texture object based on format here // TODO: Create Hazel texture object based on format here
if (self->m_Format == FramebufferFormat::RGBA16F) if (self->m_Specification.Format == FramebufferFormat::RGBA16F)
{ {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, self->m_Width, self->m_Height, 0, GL_RGBA, GL_FLOAT, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, self->m_Specification.Width, self->m_Specification.Height, 0, GL_RGBA, GL_FLOAT, nullptr);
} }
else if (self->m_Format == FramebufferFormat::RGBA8) else if (self->m_Specification.Format == FramebufferFormat::RGBA8)
{ {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->m_Width, self->m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->m_Specification.Width, self->m_Specification.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
} }
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 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_MAG_FILTER, GL_LINEAR);
@ -77,7 +76,7 @@ namespace Prism
glGenTextures(1, &self->m_DepthAttachment); glGenTextures(1, &self->m_DepthAttachment);
glBindTexture(GL_TEXTURE_2D, self->m_DepthAttachment); glBindTexture(GL_TEXTURE_2D, self->m_DepthAttachment);
glTexImage2D( glTexImage2D(
GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, self->m_Width, self->m_Height, 0, GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, self->m_Specification.Width, self->m_Specification.Height, 0,
GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL
); );

View File

@ -12,7 +12,7 @@ namespace Prism
class OpenGLFrameBuffer : public FrameBuffer class OpenGLFrameBuffer : public FrameBuffer
{ {
public: public:
OpenGLFrameBuffer(uint32_t width, uint32_t height, FramebufferFormat format); OpenGLFrameBuffer(const FramebufferSpecification& spec);
virtual ~OpenGLFrameBuffer(); virtual ~OpenGLFrameBuffer();
void Bind() const override; void Bind() const override;
@ -26,15 +26,13 @@ namespace Prism
RendererID GetColorAttachmentRendererID() const override { return m_ColorAttachment; } RendererID GetColorAttachmentRendererID() const override { return m_ColorAttachment; }
RendererID GetDepthAttachmentRendererID() const override { return m_DepthAttachment; } RendererID GetDepthAttachmentRendererID() const override { return m_DepthAttachment; }
virtual uint32_t GetWidth() const { return m_Width; } virtual const FramebufferSpecification& GetSpecification() const override { return m_Specification; }
virtual uint32_t GetHeight() const { return m_Height; }
virtual FramebufferFormat GetFormat() const { return m_Format; }
private: private:
RendererID m_RendererID = 0; FramebufferSpecification m_Specification;
uint32_t m_Width = 0, m_Height = 0;
FramebufferFormat m_Format;
RendererID m_ColorAttachment, m_DepthAttachment; RendererID m_RendererID = 0;
RendererID m_ColorAttachment = 0, m_DepthAttachment = 0;
}; };
} }

View File

@ -0,0 +1,17 @@
//
// Created by sfd on 25-11-29.
//
#include "OpenGLRenderPass.h"
namespace Prism
{
OpenGLRenderPass::OpenGLRenderPass(const RenderPassSpecification& spec)
: m_spec(spec)
{
}
OpenGLRenderPass::~OpenGLRenderPass()
{
}
}

View File

@ -0,0 +1,26 @@
//
// Created by sfd on 25-11-29.
//
#ifndef OPENGLRENDERPASS_H
#define OPENGLRENDERPASS_H
#include "Prism/Renderer/RenderPass.h"
namespace Prism
{
class OpenGLRenderPass : public RenderPass
{
public:
OpenGLRenderPass(const RenderPassSpecification& spec);
virtual ~OpenGLRenderPass();
virtual const RenderPassSpecification& GetSpecification() const override { return m_spec; }
private:
RenderPassSpecification m_spec;
};
}
#endif //OPENGLRENDERPASS_H

View File

@ -8,13 +8,13 @@
namespace Prism namespace Prism
{ {
FrameBuffer* FrameBuffer::Create(uint32_t width, uint32_t height, FramebufferFormat format) Ref<FrameBuffer> FrameBuffer::Create(const FramebufferSpecification& spec)
{ {
FrameBuffer* result = nullptr; Ref<FrameBuffer> result = nullptr;
switch (RendererAPI::Current()) switch (RendererAPI::Current())
{ {
case RendererAPIType::None: return nullptr; case RendererAPIType::None: return nullptr;
case RendererAPIType::OpenGL: result = new OpenGLFrameBuffer(width, height, format); case RendererAPIType::OpenGL: result = CreateRef<OpenGLFrameBuffer>(spec);
} }
FrameBufferPool::GetGlobal()->Add(result); FrameBufferPool::GetGlobal()->Add(result);
return result; return result;
@ -39,7 +39,12 @@ namespace Prism
return std::weak_ptr<FrameBuffer>(); return std::weak_ptr<FrameBuffer>();
} }
void FrameBufferPool::Add(FrameBuffer* framebuffer) FrameBufferPool* FrameBufferPool::GetGlobal()
{
return s_Instance;
}
void FrameBufferPool::Add(std::weak_ptr<FrameBuffer> framebuffer)
{ {
m_Pool.push_back(framebuffer); m_Pool.push_back(framebuffer);
} }

View File

@ -5,6 +5,7 @@
#ifndef FRAMEBUFFER_H #ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H #define FRAMEBUFFER_H
#include "RendererAPI.h" #include "RendererAPI.h"
#include "glm/glm.hpp"
namespace Prism namespace Prism
@ -16,12 +17,25 @@ namespace Prism
RGBA16F = 2 RGBA16F = 2
}; };
struct FramebufferSpecification
{
uint32_t Width = 1280;
uint32_t Height = 720;
glm::vec4 ClearColor;
FramebufferFormat Format;
// SwapChainTarget = screen buffer (i.e. no framebuffer)
bool SwapChainTarget = false;
};
class PRISM_API FrameBuffer class PRISM_API FrameBuffer
{ {
public: public:
static FrameBuffer* Create(uint32_t width, uint32_t height, FramebufferFormat format);
virtual ~FrameBuffer() {} virtual ~FrameBuffer() {}
static Ref<FrameBuffer> Create(const FramebufferSpecification& spec);
virtual const FramebufferSpecification& GetSpecification() const = 0;
virtual void Bind() const = 0; virtual void Bind() const = 0;
virtual void Unbind() const = 0; virtual void Unbind() const = 0;
@ -41,13 +55,14 @@ namespace Prism
~FrameBufferPool(); ~FrameBufferPool();
std::weak_ptr<FrameBuffer> AllocateBuffer(); std::weak_ptr<FrameBuffer> AllocateBuffer();
void Add(FrameBuffer* framebuffer); void Add(std::weak_ptr<FrameBuffer> framebuffer);
const std::vector<FrameBuffer*>& GetAll() const { return m_Pool; } const std::vector<std::weak_ptr<FrameBuffer>>& GetAll() const { return m_Pool; }
static FrameBufferPool* GetGlobal();
inline static FrameBufferPool* GetGlobal() { return s_Instance; }
private: private:
std::vector<FrameBuffer*> m_Pool; std::vector<std::weak_ptr<FrameBuffer>> m_Pool;
static FrameBufferPool* s_Instance; static FrameBufferPool* s_Instance;
}; };

View File

@ -317,8 +317,8 @@ namespace Prism
} }
} }
if (!materialOverride) // if (!materialOverride)
self->m_MeshShader->SetMat4FromRenderThread("u_ModelMatrix", transform * submesh.Transform); // self->m_MeshShader->SetMat4FromRenderThread("u_ModelMatrix", transform * submesh.Transform);
glDrawElementsBaseVertex(GL_TRIANGLES, submesh.IndexCount, GL_UNSIGNED_INT, (void*)(sizeof(uint32_t) * submesh.BaseIndex), submesh.BaseVertex); glDrawElementsBaseVertex(GL_TRIANGLES, submesh.IndexCount, GL_UNSIGNED_INT, (void*)(sizeof(uint32_t) * submesh.BaseIndex), submesh.BaseVertex);
} }

View File

@ -0,0 +1,22 @@
//
// Created by sfd on 25-11-29.
//
#include "RenderPass.h"
#include "Prism/Platform/OpenGL/OpenGLRenderPass.h"
namespace Prism
{
Ref<RenderPass> RenderPass::Create(const RenderPassSpecification& spec)
{
switch (RendererAPI::Current())
{
case RendererAPIType::None: PM_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); return nullptr;
case RendererAPIType::OpenGL: return std::make_shared<OpenGLRenderPass>(spec);
}
PM_CORE_ASSERT(false, "Unknown RendererAPI!");
return nullptr;
}
}

View File

@ -0,0 +1,29 @@
//
// Created by sfd on 25-11-29.
//
#ifndef RENDERPASS_H
#define RENDERPASS_H
#include "FrameBuffer.h"
namespace Prism
{
struct RenderPassSpecification
{
Ref<FrameBuffer> TargetFramebuffer;
};
class PRISM_API RenderPass
{
public:
virtual ~RenderPass() {}
virtual const RenderPassSpecification& GetSpecification() const = 0;
static Ref<RenderPass> Create(const RenderPassSpecification& spec);
};
}
#endif //RENDERPASS_H

View File

@ -52,4 +52,38 @@ namespace Prism
{ {
s_Instance->m_CommandQueue.Execute(); s_Instance->m_CommandQueue.Execute();
} }
void Renderer::BeginRenderPass(const Ref<RenderPass>& renderPass)
{
s_Instance->IBeginRenderPass(renderPass);
}
void Renderer::EndRenderPass()
{
s_Instance->IEndRenderPass();
}
void Renderer::SubmitMesh(const Ref<Mesh>& mesh)
{
s_Instance->SubmitMeshI(mesh);
}
void Renderer::IBeginRenderPass(const Ref<RenderPass>& renderPass)
{
// TODO: Convert all of this into a render command buffer
m_ActiveRenderPass = renderPass;
renderPass->GetSpecification().TargetFramebuffer->Bind();
}
void Renderer::IEndRenderPass()
{
PM_CORE_ASSERT(m_ActiveRenderPass, "No active render pass! Have you called Renderer::EndRenderPass twice?");
m_ActiveRenderPass->GetSpecification().TargetFramebuffer->Unbind();
m_ActiveRenderPass = nullptr;
}
void Renderer::SubmitMeshI(const Ref<Mesh>& mesh)
{
}
} }

View File

@ -4,7 +4,9 @@
#ifndef RENDERER_H #ifndef RENDERER_H
#define RENDERER_H #define RENDERER_H
#include "Mesh.h"
#include "RenderCommandQueue.h" #include "RenderCommandQueue.h"
#include "RenderPass.h"
#include "Shader.h" #include "Shader.h"
#include "Prism/Core/Application.h" #include "Prism/Core/Application.h"
@ -36,10 +38,25 @@ namespace Prism
void WaitAndRender(); void WaitAndRender();
inline static Renderer& Get() { return *s_Instance; } inline static Renderer& Get() { return *s_Instance; }
public:
static void BeginRenderPass(const Ref<RenderPass>& renderPass);
static void EndRenderPass();
static void SubmitMesh(const Ref<Mesh>& mesh);
private:
void IBeginRenderPass(const Ref<RenderPass>& renderPass);
void IEndRenderPass();
void SubmitMeshI(const Ref<Mesh>& mesh);
private: private:
static Renderer* s_Instance; static Renderer* s_Instance;
private:
Ref<RenderPass> m_ActiveRenderPass;
Scope<ShaderLibrary> m_ShaderLibrary; Scope<ShaderLibrary> m_ShaderLibrary;
RenderCommandQueue m_CommandQueue; RenderCommandQueue m_CommandQueue;
}; };

View File

@ -148,8 +148,26 @@ TestLayer::TestLayer()
void TestLayer::OnAttach() void TestLayer::OnAttach()
{ {
m_FrameBuffer.reset(Prism::FrameBuffer::Create(1280, 720, Prism::FramebufferFormat::RGBA16F)); Prism::FramebufferSpecification geoFramebufferspec;
m_FinalPresentBuffer.reset(Prism::FrameBuffer::Create(1280, 720, Prism::FramebufferFormat::RGBA8)); geoFramebufferspec.Width = 1280;
geoFramebufferspec.Height = 720;
geoFramebufferspec.Format = Prism::FramebufferFormat::RGBA16F;
geoFramebufferspec.ClearColor = {0.1f, 0.1f, 0.1f, 1.0f};
Prism::RenderPassSpecification geoRenderPass;
geoRenderPass.TargetFramebuffer = Prism::FrameBuffer::Create(geoFramebufferspec);
m_GeoPass = Prism::RenderPass::Create(geoRenderPass);
Prism::FramebufferSpecification finalFramebufferspec;
finalFramebufferspec.Width = 1280;
finalFramebufferspec.Height = 720;
finalFramebufferspec.Format = Prism::FramebufferFormat::RGBA8;
finalFramebufferspec.ClearColor = {0.1f, 0.1f, 0.1f, 1.0f};
Prism::RenderPassSpecification finalRenderPass;
finalRenderPass.TargetFramebuffer = Prism::FrameBuffer::Create(finalFramebufferspec);
m_FinalPass = Prism::RenderPass::Create(finalRenderPass);
static float QuadVertex[] = { static float QuadVertex[] = {
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
@ -174,13 +192,18 @@ void TestLayer::OnAttach()
m_VertexArray->SetIndexBuffer(ib); m_VertexArray->SetIndexBuffer(ib);
m_SkyBoxTextureCube.reset(Prism::TextureCube::Create("assets/textures/environments/Arches_E_PineTree_Radiance.tga")); m_SkyBoxTextureCube.reset(Prism::TextureCube::Create("assets/textures/environments/Arches_E_PineTree_Radiance.tga"));
m_EnvironmentIrradiance.reset(Prism::TextureCube::Create("assets/textures/environments/Arches_E_PineTree_Irradiance.tga"));
m_SkyboxShader = Prism::Shader::Create("assets/shaders/quad.glsl"); m_SkyBoxShader = Prism::Shader::Create("assets/shaders/quad.glsl");
m_Shader = Prism::Shader::Create("assets/shaders/demo.glsl");
m_HDRShader = Prism::Shader::Create("assets/shaders/hdr.glsl"); m_HDRShader = Prism::Shader::Create("assets/shaders/hdr.glsl");
// m_Mesh = std::make_unique<Prism::Mesh>("assets/meshes/cerberus.fbx"); m_Mesh = std::make_unique<Prism::Mesh>("assets/models/m1911/m1911.fbx");
// m_MeshMaterial = Prism::CreateRef<Prism::MaterialInstance>(m_Mesh->GetMaterial()); m_MeshMaterial = Prism::CreateRef<Prism::MaterialInstance>(m_Mesh->GetMaterial());
m_BRDFLUT.reset(Prism::Texture2D::Create("assets/textures/BRDF_LUT.tga"));
m_Light.Direction = {-0.5f, -0.5f, 1.0f};
m_Light.Radiance = {1.0f, 1.0f, 1.0f};
} }
void TestLayer::OnDetach() void TestLayer::OnDetach()
@ -193,26 +216,47 @@ void TestLayer::OnUpdate(Prism::TimeStep deltaTime)
m_Camera.Update(deltaTime); m_Camera.Update(deltaTime);
auto viewProjection = m_Camera.GetProjectionMatrix() * m_Camera.GetViewMatrix(); auto viewProjection = m_Camera.GetProjectionMatrix() * m_Camera.GetViewMatrix();
m_FrameBuffer->Bind(); Prism::Renderer::BeginRenderPass(m_GeoPass);
Prism::Renderer::Clear(m_clearColor[0], m_clearColor[1], m_clearColor[2], m_clearColor[3]); Prism::Renderer::Clear(m_clearColor[0], m_clearColor[1], m_clearColor[2], m_clearColor[3]);
// SkyBox // SkyBox
m_SkyboxShader->Bind(); m_SkyBoxShader->Bind();
m_SkyboxShader->SetMat4("u_InverseVP", inverse(viewProjection)); m_SkyBoxShader->SetMat4("u_InverseVP", inverse(viewProjection));
m_SkyBoxTextureCube->Bind(0); m_SkyBoxTextureCube->Bind(0);
m_VertexArray->Bind(); m_VertexArray->Bind();
Prism::Renderer::DrawIndexed(m_VertexArray->GetIndexBuffer()->GetCount(), false); Prism::Renderer::DrawIndexed(m_VertexArray->GetIndexBuffer()->GetCount(), false);
m_FrameBuffer->Unbind();
m_MeshMaterial->Set("u_AlbedoColor", m_AlbedoInput.Color);
m_MeshMaterial->Set("u_Metalness", m_MetalnessInput.Value);
m_MeshMaterial->Set("u_Roughness", m_RoughnessInput.Value);
m_MeshMaterial->Set("u_ViewProjectionMatrix", viewProjection);
m_MeshMaterial->Set("u_ModelMatrix", glm::scale(glm::mat4(1.0f), glm::vec3(m_MeshScale)));
m_MeshMaterial->Set("lights", m_Light);
m_MeshMaterial->Set("u_CameraPosition", m_Camera.GetPosition());
m_MeshMaterial->Set("u_RadiancePrefilter", m_RadiancePrefilter ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_AlbedoTexToggle", m_AlbedoInput.UseTexture ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_NormalTexToggle", m_NormalInput.UseTexture ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_MetalnessTexToggle", m_MetalnessInput.UseTexture ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_RoughnessTexToggle", m_RoughnessInput.UseTexture ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_EnvMapRotation", m_EnvMapRotation);
m_MeshMaterial->Set("u_EnvRadianceTex", m_SkyBoxTextureCube);
m_MeshMaterial->Set("u_EnvIrradianceTex", m_EnvironmentIrradiance);
m_MeshMaterial->Set("u_BRDFLUTTexture", m_BRDFLUT);
m_Mesh->Render(deltaTime, glm::mat4(1.0f), m_MeshMaterial);
Prism::Renderer::EndRenderPass();
// HDR // HDR
m_FinalPresentBuffer->Bind(); Prism::Renderer::BeginRenderPass(m_FinalPass);
m_HDRShader->Bind(); m_HDRShader->Bind();
m_HDRShader->SetFloat("u_Exposure", m_Exposure); m_HDRShader->SetFloat("u_Exposure", m_Exposure);
m_FrameBuffer->BindTexture(); m_GeoPass->GetSpecification().TargetFramebuffer->BindTexture();
m_VertexArray->Bind();
Prism::Renderer::DrawIndexed(m_VertexArray->GetIndexBuffer()->GetCount(), false); Prism::Renderer::DrawIndexed(m_VertexArray->GetIndexBuffer()->GetCount(), false);
m_FinalPresentBuffer->Unbind(); Prism::Renderer::EndRenderPass();
} }
void TestLayer::OnImGuiRender() void TestLayer::OnImGuiRender()
@ -225,16 +269,18 @@ void TestLayer::OnImGuiRender()
ImGui::DragFloat("Exposure", &m_Exposure, 0.01f, 0.0f); ImGui::DragFloat("Exposure", &m_Exposure, 0.01f, 0.0f);
const auto& position = m_Camera.GetPosition(); const auto& position = m_Camera.GetPosition();
ImGui::Text("Camera: (%.2f, %.2f, %.2f)", position.x, position.y, position.z); ImGui::Text("Camera: (%.2f, %.2f, %.2f)", position.x, position.y, position.z);
ImGui::End(); ImGui::End();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
ImGui::Begin("Viewport"); ImGui::Begin("Viewport");
auto viewportSize = ImGui::GetContentRegionAvail(); auto viewportSize = ImGui::GetContentRegionAvail();
m_FrameBuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y); m_GeoPass->GetSpecification().TargetFramebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_FinalPresentBuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y); m_FinalPass->GetSpecification().TargetFramebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_Camera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f)); m_Camera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
ImGui::Image((ImTextureRef)m_FinalPresentBuffer->GetColorAttachmentRendererID(), viewportSize, {0, 1}, {1, 0}); ImGui::Image((ImTextureRef)m_FinalPass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(), viewportSize, {0, 1}, {1, 0});
ImGui::End(); ImGui::End();
ImGui::PopStyleVar(); ImGui::PopStyleVar();
} }

View File

@ -10,6 +10,7 @@
#include "Prism/Renderer/Camera.h" #include "Prism/Renderer/Camera.h"
#include "Prism/Renderer/FrameBuffer.h" #include "Prism/Renderer/FrameBuffer.h"
#include "Prism/Renderer/Mesh.h" #include "Prism/Renderer/Mesh.h"
#include "Prism/Renderer/RenderPass.h"
#include "Prism/Renderer/Shader.h" #include "Prism/Renderer/Shader.h"
#include "Prism/Renderer/Texture.h" #include "Prism/Renderer/Texture.h"
@ -28,20 +29,62 @@ private:
glm::vec4 m_clearColor = glm::vec4(0.1f, 0.1f, 0.1f, 1.0f); glm::vec4 m_clearColor = glm::vec4(0.1f, 0.1f, 0.1f, 1.0f);
glm::vec4 m_TriangleColor = glm::vec4(1.0f); glm::vec4 m_TriangleColor = glm::vec4(1.0f);
Prism::Ref<Prism::FrameBuffer> m_FrameBuffer, m_FinalPresentBuffer; Prism::Ref<Prism::RenderPass> m_GeoPass, m_FinalPass;
Prism::Ref<Prism::TextureCube> m_SkyBoxTextureCube;
Prism::Ref<Prism::VertexArray> m_VertexArray; Prism::Ref<Prism::VertexArray> m_VertexArray;
Prism::Ref<Prism::Shader> m_SkyboxShader; Prism::Ref<Prism::TextureCube> m_SkyBoxTextureCube, m_EnvironmentIrradiance;
Prism::Ref<Prism::Shader> m_Shader; Prism::Ref<Prism::Shader> m_HDRShader, m_SkyBoxShader;
Prism::Ref<Prism::Shader> m_HDRShader;
Prism::Ref<Prism::Mesh> m_Mesh; Prism::Ref<Prism::Mesh> m_Mesh;
Prism::Ref<Prism::MaterialInstance> m_MeshMaterial; Prism::Ref<Prism::MaterialInstance> m_MeshMaterial;
Prism::Ref<Prism::Texture2D> m_BRDFLUT;
Prism::Camera m_Camera; Prism::Camera m_Camera;
float m_Exposure = 1.0f; float m_Exposure = 1.0f;
struct AlbedoInput
{
glm::vec3 Color = { 0.972f, 0.96f, 0.915f };
Prism::Ref<Prism::Texture2D> TextureMap;
bool SRGB = true;
bool UseTexture = false;
};
AlbedoInput m_AlbedoInput;
struct NormalInput
{
Prism::Ref<Prism::Texture2D> TextureMap;
bool UseTexture = false;
};
NormalInput m_NormalInput;
struct MetalnessInput
{
float Value = 1.0f;
Prism::Ref<Prism::Texture2D> TextureMap;
bool UseTexture = false;
};
MetalnessInput m_MetalnessInput;
struct RoughnessInput
{
float Value = 0.5f;
Prism::Ref<Prism::Texture2D> TextureMap;
bool UseTexture = false;
};
RoughnessInput m_RoughnessInput;
struct Light
{
glm::vec3 Direction;
glm::vec3 Radiance;
};
Light m_Light;
float m_LightMultiplier = 0.3f;
float m_MeshScale = 1.0f;
bool m_RadiancePrefilter = false;
float m_EnvMapRotation = 0.0f;
}; };