X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fframebuffer.cpp;h=cf478ce29b686d842ce2074078952633b2e47b02;hp=638a710f464431cd7a708434e1fa980157d9b009;hb=HEAD;hpb=08e19bc2b4eba572bc7699378cf55cd8772ac67e diff --git a/source/framebuffer.cpp b/source/framebuffer.cpp deleted file mode 100644 index 638a710f..00000000 --- a/source/framebuffer.cpp +++ /dev/null @@ -1,389 +0,0 @@ -#include -#include -#include -#include -#include -#include "error.h" -#include "framebuffer.h" -#include "misc.h" -#include "renderbuffer.h" -#include "texture2d.h" - -using namespace std; - -namespace Msp { -namespace GL { - -void operator<<(LexicalConverter &conv, FramebufferStatus status) -{ - switch(status) - { - case FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - conv.result("incomplete attachment"); - break; - case FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - conv.result("missing attachment"); - break; - case FRAMEBUFFER_INCOMPLETE_DIMENSIONS: - conv.result("mismatched attachment dimensions"); - break; - case FRAMEBUFFER_INCOMPLETE_FORMATS: - conv.result("mismatched attachment formats"); - break; - case FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - conv.result("missing draw buffer attachment"); - break; - case FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - conv.result("missing read buffer attachment"); - break; - case FRAMEBUFFER_UNSUPPORTED: - conv.result("unsupported"); - break; - default: - conv.result(lexical_cast(status, "%#x")); - break; - } -} - -framebuffer_incomplete::framebuffer_incomplete(FramebufferStatus status): - runtime_error(lexical_cast(status)) -{ } - - -Framebuffer::Framebuffer(unsigned i): - id(i), - dirty(0) -{ - if(id) - throw invalid_argument("System framebuffer must have id 0"); - - glGetIntegerv(GL_VIEWPORT, &view.left); - width = view.width; - height = view.height; -} - -Framebuffer::Framebuffer(): - width(0), - height(0), - dirty(0) -{ - static Require _req(EXT_framebuffer_object); - - if(ARB_direct_state_access) - glCreateFramebuffers(1, &id); - else - glGenFramebuffers(1, &id); -} - -Framebuffer::~Framebuffer() -{ - if(id) - glDeleteFramebuffers(1, &id); - if(current()==this) - unbind(); -} - -void Framebuffer::update_attachment(unsigned mask) const -{ - if(!ARB_direct_state_access && current()!=this) - { - dirty |= mask; - return; - } - - std::vector color_bufs; - color_bufs.reserve(attachments.size()); - for(unsigned i=0; iget_id()); - else - glFramebufferRenderbuffer(GL_FRAMEBUFFER, attch.attachment, GL_RENDERBUFFER, attch.rbuf->get_id()); - } - else if(attch.type==GL_TEXTURE_2D) - { - static_cast(attch.tex)->allocate(attch.level); - if(ARB_direct_state_access) - glNamedFramebufferTexture(id, attch.attachment, attch.tex->get_id(), attch.level); - else - glFramebufferTexture2D(GL_FRAMEBUFFER, attch.attachment, attch.type, attch.tex->get_id(), attch.level); - } - else if(attch.type==GL_TEXTURE_CUBE_MAP) - { - static_cast(attch.tex)->allocate(attch.level); - if(ARB_direct_state_access) - glNamedFramebufferTextureLayer(id, attch.attachment, attch.tex->get_id(), attch.level, attch.layer); - else - glFramebufferTexture2D(GL_FRAMEBUFFER, attch.attachment, TextureCube::enumerate_faces(attch.layer), attch.tex->get_id(), attch.level); - } - else if(ARB_direct_state_access) - glNamedFramebufferRenderbuffer(id, attch.attachment, 0, 0); - else - glFramebufferRenderbuffer(GL_FRAMEBUFFER, attch.attachment, 0, 0); - } - - if(attch.attachment>=COLOR_ATTACHMENT0 && attch.attachment<=COLOR_ATTACHMENT3) - color_bufs.push_back(attch.attachment); - } - - if(color_bufs.size()>1) - static Require _req(ARB_draw_buffers); - - GLenum first_buffer = (color_bufs.empty() ? GL_NONE : color_bufs.front()); - if(ARB_direct_state_access) - { - /* ARB_direct_state_access ties the availability of these functions to - framebuffers themselves, so no further checks are needed. */ - glNamedFramebufferDrawBuffers(id, color_bufs.size(), &color_bufs[0]); - glNamedFramebufferReadBuffer(id, first_buffer); - } - else - { - if(ARB_draw_buffers) - glDrawBuffers(color_bufs.size(), &color_bufs[0]); - else if(MSP_draw_buffer) - glDrawBuffer(first_buffer); - - if(MSP_draw_buffer) - glReadBuffer(first_buffer); - } -} - -void Framebuffer::check_size() -{ - bool full_viewport = (view.left==0 && view.bottom==0 && view.width==width && view.height==height); - for(vector::iterator i=attachments.begin(); i!=attachments.end(); ++i) - if(i->type) - { - if(i->type==GL_RENDERBUFFER) - { - width = i->rbuf->get_width(); - height = i->rbuf->get_height(); - } - else if(i->type==GL_TEXTURE_2D) - { - Texture2D *tex = static_cast(i->tex); - width = tex->get_width(); - height = tex->get_height(); - } - else if(i->type==GL_TEXTURE_CUBE_MAP) - { - width = static_cast(i->tex)->get_size(); - height = width; - } - if(full_viewport) - reset_viewport(); - break; - } -} - -unsigned Framebuffer::get_attachment_index(FramebufferAttachment attch) -{ - for(unsigned i=0; i(glCheckNamedFramebufferStatus(id, GL_FRAMEBUFFER)); - else - { - BindRestore _bind(this); - return static_cast(glCheckFramebufferStatus(GL_FRAMEBUFFER)); - } -} - -void Framebuffer::require_complete() const -{ - FramebufferStatus status = check_status(); - if(status!=FRAMEBUFFER_COMPLETE) - throw framebuffer_incomplete(status); -} - -void Framebuffer::viewport(int l, int b, unsigned w, unsigned h) -{ - view.left = l; - view.bottom = b; - view.width = w; - view.height = h; - - if(current()==this) - glViewport(view.left, view.bottom, view.width, view.height); -} - -void Framebuffer::reset_viewport() -{ - viewport(0, 0, width, height); -} - -void Framebuffer::clear(BufferBits bits) -{ - BindRestore _bind(this); - glClear(bits); -} - -void Framebuffer::blit_from(const Framebuffer &other, int sx0, int sy0, int sx1, int sy1, int dx0, int dy0, int dx1, int dy1, BufferBits bits, bool filter) -{ - static Require _req(EXT_framebuffer_blit); - - if(ARB_direct_state_access) - { - glBlitNamedFramebuffer(other.id, id, sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1, bits, (filter ? GL_LINEAR : GL_NEAREST)); - return; - } - - const Framebuffer *old = current(); - if(set_current(this)) - { - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, id); - if(dirty) - { - update_attachment(dirty); - dirty = 0; - } - } - if(old!=&other) - glBindFramebuffer(GL_READ_FRAMEBUFFER, other.id); - - glBlitFramebuffer(sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1, bits, (filter ? GL_LINEAR : GL_NEAREST)); - - set_current(old); - glBindFramebuffer(GL_FRAMEBUFFER, (old ? old->id : 0)); -} - -void Framebuffer::blit_from(const Framebuffer &other, int sx, int sy, unsigned wd, unsigned ht, int dx, int dy, BufferBits bits) -{ - blit_from(other, sx, sy, sx+wd, sy+ht, dx, dy, dx+wd, dy+ht, bits, false); -} - -void Framebuffer::blit_from(const Framebuffer &other, BufferBits bits, bool filter) -{ - blit_from(other, 0, 0, other.width, other.height, 0, 0, width, height, bits, filter); -} - -void Framebuffer::bind() const -{ - if(set_current(this)) - { - glBindFramebuffer(GL_FRAMEBUFFER, id); - if(dirty) - { - update_attachment(dirty); - dirty = 0; - } - - if(width && height) - glViewport(view.left, view.bottom, view.width, view.height); - } -} - -const Framebuffer *Framebuffer::current() -{ - if(!cur_obj) - cur_obj = &system(); - return cur_obj; -} - -void Framebuffer::unbind() -{ - system().bind(); -} - -Framebuffer &Framebuffer::system() -{ - static Framebuffer sys_framebuf(0); - return sys_framebuf; -} - - -Framebuffer::Attachment::Attachment(FramebufferAttachment a): - attachment(a), - type(0), - level(0), - layer(0) -{ } - -void Framebuffer::Attachment::set(Renderbuffer &r) -{ - type = GL_RENDERBUFFER; - rbuf = &r; - level = 0; - layer = 0; -} - -void Framebuffer::Attachment::set(Texture &t, unsigned l, unsigned z) -{ - type = t.get_target(); - tex = &t; - level = l; - layer = z; -} - -void Framebuffer::Attachment::clear() -{ - type = 0; -} - - -Framebuffer::Viewport::Viewport(): - left(0), - bottom(0), - width(0), - height(0) -{ } - -} // namespace GL -} // namespace Msp