#include #include #include #include "fbo.h" namespace { GLuint CreateFramebuffer() { GLuint fboId = 0; glGenFramebuffers(1, &fboId); return fboId; } GLuint CreateTexture(int width, int height, GLenum format) { GLuint textureId = 0; glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, format, GL_FLOAT, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); if(textureId == 0) { std::cerr << "Texture was not created!" << std::endl; } return textureId; } GLuint CreateDepthTexture(int width, int height) { GLuint depthId; glGenRenderbuffers(1, &depthId); glBindRenderbuffer(GL_RENDERBUFFER, depthId); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, width, height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthId); glBindRenderbuffer(GL_RENDERBUFFER, 0); if(depthId == 0) { std::cerr << "Depth Texture was not created!" << std::endl; } return depthId; } void AttachTextureToFramebuffer(GLuint framebufferId, GLuint textureId, GLenum attachment) { glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, textureId, 0); } } // namespace namespace FBO { Framebuffer GenerateFramebuffer(int width, int height) { Framebuffer fbo; fbo.id = CreateFramebuffer(); UpdateFrameBuffer(fbo, width, height); return fbo; } void UpdateFrameBuffer(Framebuffer& fbo, int width, int height) { glBindFramebuffer(GL_FRAMEBUFFER, fbo.id); fbo.albedoTexture = CreateTexture(width, height, GL_RGBA); fbo.positionTexture = CreateTexture(width, height, GL_RGBA); fbo.normalTexture = CreateTexture(width, height, GL_RGBA); fbo.depthTexture = CreateDepthTexture(width, height); AttachTextureToFramebuffer(fbo.id, fbo.albedoTexture, GL_COLOR_ATTACHMENT0); AttachTextureToFramebuffer(fbo.id, fbo.positionTexture, GL_COLOR_ATTACHMENT1); AttachTextureToFramebuffer(fbo.id, fbo.normalTexture, GL_COLOR_ATTACHMENT2); GLenum drawBuffers[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; glDrawBuffers(3, drawBuffers); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { std::cerr << "Error: Framebuffer is not complete!" << std::endl; } glBindFramebuffer(GL_FRAMEBUFFER, 0); } void Bind(const Framebuffer& fbo) { glBindFramebuffer(GL_FRAMEBUFFER, fbo.id); } void Unbind() { glBindFramebuffer(GL_FRAMEBUFFER, 0); } void Cleanup(const Framebuffer& fbo) { if (fbo.albedoTexture != 0) { glDeleteTextures(1, &fbo.albedoTexture); } if (fbo.positionTexture != 0) { glDeleteTextures(1, &fbo.positionTexture); } if (fbo.normalTexture != 0) { glDeleteTextures(1, &fbo.normalTexture); } if (fbo.depthTexture != 0) { glDeleteTextures(1, &fbo.depthTexture); } if (fbo.id != 0) { glDeleteFramebuffers(1, &fbo.id); } } } // namespace FBO