#include "FrameBuffer.hpp" #include "Debug.hpp" TSE::OpenGL::FrameBuffer::FrameBuffer(const Vector2 &size, uint textureCount) { textureOutputCount = textureCount; width = size.x; height = size.y; CreateFBTexture(); for (auto const& i : objectsToResize) { i->OnResize(size.x, size.y, this); } Initialize(); } void TSE::OpenGL::FrameBuffer::Bind() { glBindFramebuffer(GL_FRAMEBUFFER, bufferID); } void TSE::OpenGL::FrameBuffer::Unbind() { glBindFramebuffer(GL_FRAMEBUFFER, 0); } TSE::OpenGL::FrameBuffer::~FrameBuffer() { glDeleteFramebuffers(1,&bufferID); for (int i = 0; i < textureOutputCount; i++) { glDeleteTextures(1, &(textureIDs[i])); } glDeleteRenderbuffers(1, &depthRboID); } void TSE::OpenGL::FrameBuffer::Resize(Vector2 size) { width = size.x; height = size.y; shouldResize = true; } void TSE::OpenGL::FrameBuffer::Update() { if (!shouldResize) return; shouldResize = false; CreateFBTexture(); for (auto const& i : objectsToResize) { i->OnResize(width, height, this); } } TSE::uint TSE::OpenGL::FrameBuffer::GetTextureId(uint id) const { return textureIDs[id]; } TSE::Vector2 TSE::OpenGL::FrameBuffer::GetSize() const { return {width, height}; } void TSE::OpenGL::FrameBuffer::Initialize() { glGenFramebuffers(1, &bufferID); Bind(); uint bufs[32]; for (int i = 0; i < textureOutputCount; i++) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textureIDs[i], 0); bufs[i] = GL_COLOR_ATTACHMENT0 + i; } glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRboID); if(textureOutputCount > 1) glDrawBuffers(textureOutputCount, bufs); if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { TSE_ERROR("Failed to create OpenGL FBO."); TSE_LOG(std::to_string(glGetError())); } Unbind(); } void TSE::OpenGL::FrameBuffer::LoadFBTexture() { for (int i = 0; i < textureOutputCount; i++) { glBindTexture(GL_TEXTURE_2D, textureIDs[i]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); 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_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glBindRenderbuffer(GL_RENDERBUFFER, depthRboID); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height); } } void TSE::OpenGL::FrameBuffer::CreateFBTexture() { glViewport(0,0, width, height); //resize for (int i = 0; i < textureOutputCount; i++) { if(textureIDs[i] == 0) glGenTextures(1, &(textureIDs[i])); } if(depthRboID == 0) glGenRenderbuffers(1, &depthRboID); LoadFBTexture(); }