X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fframebuffer.cpp;h=6877f4808b7402c7f1660097c3860bb7fcbbe5bc;hb=e4638ccfdcdb58f81740fe707ec93b1be3208d2c;hp=8dbd2d0ee93bd20940b26326c1d2aaeb0c3f25a1;hpb=3663bed18358a2399b2a8a8f7779d85e0ed81bd0;p=libs%2Fgl.git diff --git a/source/framebuffer.cpp b/source/framebuffer.cpp index 8dbd2d0e..6877f480 100644 --- a/source/framebuffer.cpp +++ b/source/framebuffer.cpp @@ -1,11 +1,6 @@ -/* $Id$ - -This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - +#include "error.h" #include "extension.h" +#include "ext_framebuffer_blit.h" #include "ext_framebuffer_object.h" #include "framebuffer.h" #include "misc.h" @@ -22,7 +17,7 @@ Framebuffer::Framebuffer(unsigned 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); @@ -52,8 +47,7 @@ void Framebuffer::update_attachment(unsigned mask) const { if(current()==this) { - bool has_color = false; - bool has_depth = false; + GLenum color_buf = GL_NONE; for(unsigned i=0; iget_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); + } else glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attch.attachment, 0, 0); } if(attch.attachment>=COLOR_ATTACHMENT0 && attch.attachment<=COLOR_ATTACHMENT3) - has_color = true; - if(attch.attachment==DEPTH_ATTACHMENT) - has_depth = true; + color_buf = attch.attachment; } - glDrawBuffer(has_color ? GL_FRONT : GL_NONE); - glDepthMask(has_depth); + glDrawBuffer(color_buf); } else dirty |= mask; @@ -105,7 +99,7 @@ void Framebuffer::check_size() void Framebuffer::attach(FramebufferAttachment attch, Renderbuffer &rbuf) { if(!id) - throw InvalidState("Can't attach to system framebuffer"); + throw invalid_operation("Framebuffer::attach"); unsigned i = get_attachment_index(attch); attachments[i].set(rbuf); @@ -113,10 +107,10 @@ void Framebuffer::attach(FramebufferAttachment attch, Renderbuffer &rbuf) check_size(); } -void Framebuffer::attach(FramebufferAttachment attch, Texture2D &tex, int level) +void Framebuffer::attach(FramebufferAttachment attch, Texture2D &tex, unsigned level) { if(!id) - throw InvalidState("Can't attach to system framebuffer"); + throw invalid_operation("Framebuffer::attach"); unsigned i = get_attachment_index(attch); attachments[i].set(tex, level); @@ -127,7 +121,7 @@ void Framebuffer::attach(FramebufferAttachment attch, Texture2D &tex, int level) void Framebuffer::detach(FramebufferAttachment attch) { if(!id) - throw InvalidState("Can't detach from system framebuffer"); + throw invalid_operation("Framebuffer::detach"); unsigned i = get_attachment_index(attch); attachments[i].clear(); @@ -147,6 +141,39 @@ void Framebuffer::clear(BufferBits bits) 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 RequireExtension _ext("GL_EXT_framebuffer_blit"); + + const Framebuffer *old = current(); + if(set_current(this)) + { + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, id); + if(dirty) + { + update_attachment(dirty); + dirty = 0; + } + } + if(old!=&other) + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, other.id); + + glBlitFramebufferEXT(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)); +} + +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)) @@ -203,7 +230,7 @@ void Framebuffer::Attachment::set(Renderbuffer &r) level = 0; } -void Framebuffer::Attachment::set(Texture &t, int l) +void Framebuffer::Attachment::set(Texture &t, unsigned l) { type = t.get_target(); tex = &t;