X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fframebuffer.cpp;h=8e8be663e32f3ad48430b84eb9a55e1ed24543a0;hb=619aae12e01f25e79626a94c973927e5599e99a5;hp=3d9b0133622b3bcec7590c440b8841f478217d16;hpb=7f888de83aa5398fafaa7661547ee80395377b5c;p=libs%2Fgl.git diff --git a/source/framebuffer.cpp b/source/framebuffer.cpp index 3d9b0133..8e8be663 100644 --- a/source/framebuffer.cpp +++ b/source/framebuffer.cpp @@ -1,13 +1,7 @@ -/* $Id$ - -This file is part of libmspgl -Copyright © 2007-2011 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - -#include "extension.h" -#include "ext_framebuffer_blit.h" -#include "ext_framebuffer_object.h" +#include +#include +#include +#include "error.h" #include "framebuffer.h" #include "misc.h" #include "renderbuffer.h" @@ -18,12 +12,48 @@ 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 InvalidParameterValue("System framebuffer must have id 0"); + throw invalid_argument("System framebuffer must have id 0"); int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); @@ -36,15 +66,15 @@ Framebuffer::Framebuffer(): height(0), dirty(0) { - static RequireExtension _ext("GL_EXT_framebuffer_object"); + static Require _req(EXT_framebuffer_object); - glGenFramebuffersEXT(1, &id); + glGenFramebuffers(1, &id); } Framebuffer::~Framebuffer() { if(id) - glDeleteFramebuffersEXT(1, &id); + glDeleteFramebuffers(1, &id); if(current()==this) unbind(); } @@ -53,28 +83,42 @@ void Framebuffer::update_attachment(unsigned mask) const { if(current()==this) { - GLenum color_buf = GL_NONE; + std::vector color_bufs; + color_bufs.reserve(attachments.size()); for(unsigned i=0; iget_id()); + if(attch.type==GL_RENDERBUFFER) + 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); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attch.attachment, attch.type, attch.tex->get_id(), attch.level); + 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); + glFramebufferTexture2D(GL_FRAMEBUFFER, attch.attachment, attch.cube_face, attch.tex->get_id(), attch.level); } else - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attch.attachment, 0, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, attch.attachment, 0, 0); } if(attch.attachment>=COLOR_ATTACHMENT0 && attch.attachment<=COLOR_ATTACHMENT3) - color_buf = attch.attachment; + color_bufs.push_back(attch.attachment); } - glDrawBuffer(color_buf); + if(color_bufs.empty()) + glDrawBuffer(GL_NONE); + else if(color_bufs.size()==1) + glDrawBuffer(color_bufs.front()); + else + { + static Require _req(ARB_draw_buffers); + glDrawBuffers(color_bufs.size(), &color_bufs[0]); + } } else dirty |= mask; @@ -85,7 +129,7 @@ void Framebuffer::check_size() for(vector::iterator i=attachments.begin(); i!=attachments.end(); ++i) if(i->type) { - if(i->type==GL_RENDERBUFFER_EXT) + if(i->type==GL_RENDERBUFFER) { width = i->rbuf->get_width(); height = i->rbuf->get_height(); @@ -96,16 +140,30 @@ void Framebuffer::check_size() 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(current()==this) glViewport(0, 0, width, height); break; } } +unsigned Framebuffer::get_attachment_index(FramebufferAttachment attch) +{ + for(unsigned i=0; i(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)); + 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::clear(BufferBits bits) @@ -149,12 +225,12 @@ void Framebuffer::clear(BufferBits 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 RequireExtension _ext("GL_EXT_framebuffer_blit"); + static Require _req(EXT_framebuffer_blit); const Framebuffer *old = current(); if(set_current(this)) { - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, id); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, id); if(dirty) { update_attachment(dirty); @@ -162,12 +238,12 @@ void Framebuffer::blit_from(const Framebuffer &other, int sx0, int sy0, int sx1, } } if(old!=&other) - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, other.id); + glBindFramebuffer(GL_READ_FRAMEBUFFER, other.id); - glBlitFramebufferEXT(sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1, bits, (filter ? GL_LINEAR : GL_NEAREST)); + glBlitFramebuffer(sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1, bits, (filter ? GL_LINEAR : GL_NEAREST)); set_current(old); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (old ? old->id : 0)); + 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) @@ -184,7 +260,7 @@ void Framebuffer::bind() const { if(set_current(this)) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id); + glBindFramebuffer(GL_FRAMEBUFFER, id); if(dirty) { update_attachment(dirty); @@ -213,15 +289,6 @@ Framebuffer &Framebuffer::system() return sys_framebuf; } -unsigned Framebuffer::get_attachment_index(FramebufferAttachment attch) -{ - for(unsigned i=0; i