#include "framebuffer.h" #include "texture.h" #include const FrameBuffer* FrameBuffer::screen = new FrameBuffer(0); FrameBuffer::FrameBuffer() : allocated(true), m_target(GL_FRAMEBUFFER) { glGenFramebuffers(1, &m_frameBufferId); } FrameBuffer::~FrameBuffer() { if(allocated) glDeleteFramebuffers(1, &m_frameBufferId); for(Texture* t : m_textures) { t->unbind(); delete(t); } } void FrameBuffer::addTexture(Texture* tex, GLenum attachment) { if(m_frameBufferId != 0) { m_textures.push_back(tex); bindFBO(); if(tex->isCubeMap()) glFramebufferTexture(m_target, attachment, tex->getId(), 0); else glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, tex->getTarget(), tex->getId(), 0); if((attachment != GL_DEPTH_ATTACHMENT && attachment != GL_STENCIL_ATTACHMENT) && attachment != GL_DEPTH_STENCIL_ATTACHMENT) m_attachments.push_back(attachment); } } void FrameBuffer::initColorAttachments() { if(m_frameBufferId != 0 && m_attachments.size() != 0) { bindFBO(); glDrawBuffers(m_attachments.size(), m_attachments.data()); } else { glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } check(); } void FrameBuffer::deleteTextures() { for(Texture* t : m_textures) delete(t); m_textures.clear(); glDrawBuffer(GL_NONE); } void FrameBuffer::bindFBO() const { glBindFramebuffer(m_target, m_frameBufferId); } bool FrameBuffer::check() { GLenum err; err = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (err != GL_FRAMEBUFFER_COMPLETE) { std::cerr << "FBO not complete (error = " << err << ") : "; switch (err) { case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; break; case GL_FRAMEBUFFER_UNSUPPORTED: std::cerr << "GL_FRAMEBUFFER_UNSUPPORTED"; break; default: std::cerr << "Unknown ERROR"; } std::cerr << std::endl; } return err == GL_FRAMEBUFFER_COMPLETE; } Texture* FrameBuffer::getTexture(int texId) { if(m_frameBufferId != 0) return m_textures[texId]; else return NULL; }