From aaa6b6ef2026953e875ac01ee566c68daac3f8e7 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 3 Dec 2015 18:32:01 +0100 Subject: [PATCH] Added FrameBuffer wrapper class --- include/Engine/Rendering/Renderer.h | 3 +- include/Engine/Rendering/Util/FrameBuffer.h | 64 +++++++++++++++ src/Engine/Rendering/Renderer.cpp | 23 ++---- src/Engine/Rendering/Util/FrameBuffer.cpp | 88 +++++++++++++++++++++ 4 files changed, 160 insertions(+), 18 deletions(-) create mode 100644 include/Engine/Rendering/Util/FrameBuffer.h create mode 100644 src/Engine/Rendering/Util/FrameBuffer.cpp diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 6fb0b10f..9b07f885 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -8,6 +8,7 @@ //TODO: Temp resourceManager #include "../Core/ResourceManager.h" #include "Util/UnorderedMapVec2.h" +#include "Util/FrameBuffer.h" class Renderer : public IRenderer { @@ -22,7 +23,7 @@ private: Texture* m_ErrorTexture; Texture* m_WhiteTexture; float m_CameraMoveSpeed; - GLuint m_PickingBuffer; + FrameBuffer m_PickingBuffer; GLuint m_PickingTexture; GLuint m_DepthBuffer; diff --git a/include/Engine/Rendering/Util/FrameBuffer.h b/include/Engine/Rendering/Util/FrameBuffer.h new file mode 100644 index 00000000..5c9e0c3f --- /dev/null +++ b/include/Engine/Rendering/Util/FrameBuffer.h @@ -0,0 +1,64 @@ +#ifndef FrameBuffer_h__ +#define FrameBuffer_h__ + +#include "OpenGL.h" +#include "GLError.h" + +class BufferResource +{ +public: + BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment); + + GLuint* m_ResourceHandle; + GLenum m_ResourceType; + GLenum m_Attachment; +private: + +}; + +template +class ResourceType : public BufferResource +{ +public: + ResourceType(GLuint* resourceHandle, GLenum attachment) + : BufferResource(resourceHandle, RESOURCETYPE, attachment) { } +}; + +class Texture2D : public ResourceType +{ +public: + Texture2D(GLuint* resourceHandle, GLenum attachment) + : ResourceType(resourceHandle, attachment) { }; + + ~Texture2D(); +}; + +class RenderBuffer : public ResourceType +{ +public: + RenderBuffer(GLuint* resourceHandle, GLenum attachment) + : ResourceType(resourceHandle, attachment) + { }; + + ~RenderBuffer(); +}; + +class FrameBuffer +{ +public: + FrameBuffer() + : m_BufferHandle(0) { } + ~FrameBuffer(); + + void AddResource(std::shared_ptr resource); + void Generate(); + void Bind(); + void Unbind(); + GLuint GetHandle(); + +private: + GLuint m_BufferHandle; + std::vector> m_Resources; +}; + +#endif diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index bbaab41e..9abde6b9 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -286,7 +286,7 @@ void Renderer::DrawScene(RenderQueueCollection& rq) void Renderer::PickingPass() { - glBindFramebuffer(GL_FRAMEBUFFER, m_PickingBuffer); + m_PickingBuffer.Bind(); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); @@ -356,7 +356,7 @@ void Renderer::DrawScreenQuad(GLuint textureToDraw) // Will return a vec3 where RG is the PickColor and B is the Depth glm::vec3 Renderer::GetClickedPixelData(float x, float y) { - glBindFramebuffer(GL_FRAMEBUFFER, m_PickingBuffer); + m_PickingBuffer.Bind(); glm::vec2 pixelData; glReadPixels(x, y, 1, 1, GL_RG, GL_FLOAT, &pixelData); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -389,19 +389,8 @@ void Renderer::InitializeFrameBuffers()//TODO: Renderer: Get this to a better lo glGenRenderbuffers(1, &m_DepthBuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Resolution.Width, m_Resolution.Height); - - - glGenFramebuffers(1, &m_PickingBuffer); - glBindFramebuffer(GL_FRAMEBUFFER, m_PickingBuffer); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_DepthBuffer); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_PickingTexture, 0); - GLenum PickingBufferTextures[] = { GL_COLOR_ATTACHMENT0 }; - glDrawBuffers(1, PickingBufferTextures); - - if (GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - LOG_ERROR("m_FbDeferred2 incomplete: 0x%x\n", fbStatus); - exit(EXIT_FAILURE); - } - - + + m_PickingBuffer.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT))); + m_PickingBuffer.AddResource(std::shared_ptr(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0))); + m_PickingBuffer.Generate(); } \ No newline at end of file diff --git a/src/Engine/Rendering/Util/FrameBuffer.cpp b/src/Engine/Rendering/Util/FrameBuffer.cpp new file mode 100644 index 00000000..b8d3e078 --- /dev/null +++ b/src/Engine/Rendering/Util/FrameBuffer.cpp @@ -0,0 +1,88 @@ + +#include "Rendering/Util/FrameBuffer.h" + + +BufferResource::BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment) +{ + m_ResourceHandle = resourceHandle; + m_ResourceType = resourceType; + m_Attachment = attachment; +} + +Texture2D::~Texture2D() +{ + if (m_ResourceHandle != 0) { + glDeleteTextures(1, m_ResourceHandle); + } +} + + +RenderBuffer::~RenderBuffer() +{ + if (m_ResourceHandle != 0) { + glDeleteRenderbuffers(1, m_ResourceHandle); + } +} + + +FrameBuffer::~FrameBuffer() +{ + if (m_BufferHandle != 0) { + glDeleteFramebuffers(1, &m_BufferHandle); + } +} + +void FrameBuffer::AddResource(std::shared_ptr resource) +{ + m_Resources.push_back(resource); +} + +void FrameBuffer::Generate() +{ + std::vector attachments; + + glGenFramebuffers(1, &m_BufferHandle); + glBindFramebuffer(GL_FRAMEBUFFER, m_BufferHandle); + + for (auto it = m_Resources.begin(); it != m_Resources.end(); it++) { + switch ((*it)->m_ResourceType) { + case GL_TEXTURE_2D: + glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0); + break; + case GL_RENDERBUFFER: + glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle); + break; + } + + GLERROR("FrameBuffer generate"); + + if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT) { + attachments.push_back((*it)->m_Attachment); + } + } + + + + GLenum* bufferTextures = &attachments[0]; + glDrawBuffers(1, bufferTextures); + + if (GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + LOG_ERROR("FrameBuffer incomplete: 0x%x\n", frameBufferStatus); + exit(EXIT_FAILURE); + } +} + +void FrameBuffer::Bind() +{ + glBindFramebuffer(GL_FRAMEBUFFER, m_BufferHandle); +} + +void FrameBuffer::Unbind() +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +GLuint FrameBuffer::GetHandle() +{ + return m_BufferHandle; +}