#pragma once #include #include "renderbuffer.hpp" #include "texture.hpp" #include /* * One can attach either an external renderbuffer/texture, or move one into fbo * In the latter case, the fbo will own the renderbuffer/texture * * Attachment can be one of: GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, or GL_STENCIL_ATTACHMENT */ namespace moggle { struct fbo { explicit fbo(bool create_now = false) { if(create_now) create(); } ~fbo() { destroy(); } fbo(fbo const &) = delete; fbo & operator=(fbo const&) = delete; fbo(fbo && r) : id(r.id) { r.id = 0; } fbo & operator=(fbo && r) { std::swap(id, r.id); return *this; } bool created() const { return id; } explicit operator bool() const { return created(); } void create(){ if(!id) gl::generate_framebuffers(1, &id); } void destroy(){ gl::delete_renderbuffers(1, &id); id = 0; } void bind() { create(); gl::bind_framebuffer(GL_FRAMEBUFFER, id); } GLuint get_id() const { return id; } // Only well defined if the fbo owns the texture texture & get_texture() { return textures.front(); } void attach(GLenum attachment, renderbuffer const & rb){ bind(); gl::framebuffer_renderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, rb.get_id()); } void attach(GLenum attachment, renderbuffer && rb){ renderbuffers.push_back(std::move(rb)); attach(attachment, renderbuffers.back()); } void attach(GLenum attachment, GLenum textarget, texture const & t){ bind(); gl::framebuffer_texture_2d(GL_FRAMEBUFFER, attachment, textarget, t.get_id(), 0); } void attach(GLenum attachment, GLenum textarget, texture && t){ textures.push_back(std::move(t)); attach(attachment, textarget, textures.back()); } void clear(GLenum bufferbits){ bind(); gl::clear(bufferbits); } static fbo create_default(GLsizei width, GLsizei height){ fbo f; f.attach(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture::create(width, height, GL_RGBA32F)); f.attach(GL_DEPTH_ATTACHMENT, renderbuffer::create(width, height, 1, GL_DEPTH_COMPONENT16)); f.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); return f; } private: std::vector renderbuffers; std::vector textures; GLuint id = 0; }; }