]> git.tdb.fi Git - libs/gl.git/blobdiff - source/framebuffer.cpp
Add get_width() / get_height() methods to Renderbuffer and Framebuffer
[libs/gl.git] / source / framebuffer.cpp
index 7ae391a4a18c600dfe68c7461419dcaf3928d412..229c7f0a094c01ce64bfc43563a62882b6606164 100644 (file)
@@ -8,13 +8,18 @@ Distributed under the LGPL
 #include "extension.h"
 #include "ext_framebuffer_object.h"
 #include "framebuffer.h"
+#include "misc.h"
 #include "renderbuffer.h"
 #include "texture2d.h"
 
+using namespace std;
+
 namespace Msp {
 namespace GL {
 
-Framebuffer::Framebuffer()
+Framebuffer::Framebuffer():
+       width(0),
+       height(0)
 {
        static RequireExtension _ext("GL_EXT_framebuffer_object");
 
@@ -29,20 +34,44 @@ Framebuffer::~Framebuffer()
 
 void Framebuffer::bind() const
 {
+       if(!cur_fbo)
+               get(GL_VIEWPORT, sys_viewport);
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
        cur_fbo=this;
+       if(width && height)
+               viewport(0, 0, width, height);
 }
 
 void Framebuffer::attach(FramebufferAttachment attch, Renderbuffer &rbuf)
 {
        maybe_bind();
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attch, GL_RENDERBUFFER_EXT, rbuf.get_id());
+       get_or_create_attachment(attch)=rbuf;
+       check_size();
 }
 
 void Framebuffer::attach(FramebufferAttachment attch, Texture2D &tex, int level)
 {
        maybe_bind();
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attch, tex.get_target(), tex.get_id(), level);
+       get_or_create_attachment(attch)=tex;
+       check_size();
+}
+
+void Framebuffer::detach(FramebufferAttachment attch)
+{
+       maybe_bind();
+       for(vector<Attachment>::iterator i=attachments.begin(); i!=attachments.end(); ++i)
+               if(i->attachment==attch)
+               {
+                       if(i->type==GL_RENDERBUFFER_EXT)
+                               glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attch, GL_RENDERBUFFER_EXT, 0);
+                       else if(i->type==GL_TEXTURE_2D)
+                               glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attch, GL_TEXTURE_2D, 0, 0);
+                       attachments.erase(i);
+                       check_size();
+                       return;
+               }
 }
 
 FramebufferStatus Framebuffer::check_status() const
@@ -62,6 +91,7 @@ void Framebuffer::unbind()
        {
                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
                cur_fbo=0;
+               viewport(sys_viewport[0], sys_viewport[1], sys_viewport[2], sys_viewport[3]);
        }
 }
 
@@ -71,7 +101,79 @@ void Framebuffer::maybe_bind() const
                bind();
 }
 
+Framebuffer::Attachment &Framebuffer::get_or_create_attachment(FramebufferAttachment attch)
+{
+       for(vector<Attachment>::iterator i=attachments.begin(); i!=attachments.end(); ++i)
+               if(i->attachment==attch)
+                       return *i;
+       attachments.push_back(Attachment(attch));
+       return attachments.back();
+}
+
+void Framebuffer::check_size()
+{
+       if(!attachments.empty())
+       {
+               const Attachment &attch=attachments.front();
+               if(attch.type==GL_RENDERBUFFER_EXT)
+               {
+                       width=attch.rbuf->get_width();
+                       height=attch.rbuf->get_height();
+               }
+               else if(attch.type==GL_TEXTURE_2D)
+               {
+                       Texture2D *tex=static_cast<Texture2D *>(attch.tex);
+                       width=tex->get_width();
+                       height=tex->get_height();
+               }
+               if(cur_fbo==this)
+                       viewport(0, 0, width, height);
+       }
+}
+
 const Framebuffer *Framebuffer::cur_fbo=0;
+int Framebuffer::sys_viewport[4]={ 0, 0, 1, 1 };
+
+
+Framebuffer::Attachment::Attachment(FramebufferAttachment a):
+       attachment(a),
+       type(0)
+{ }
+
+Framebuffer::Attachment &Framebuffer::Attachment::operator=(Renderbuffer &r)
+{
+       type=GL_RENDERBUFFER_EXT;
+       rbuf=&r;
+       return *this;
+}
+
+Framebuffer::Attachment &Framebuffer::Attachment::operator=(Texture &t)
+{
+       type=t.get_target();
+       tex=&t;
+       return *this;
+}
+
+
+void viewport(int x, int y, unsigned w, unsigned h)
+{
+       glViewport(x, y, w, h);
+}
+
+void clear(BufferBits bits)
+{
+       glClear(bits);
+}
+
+void draw_buffer(RWBuffer buf)
+{
+       glDrawBuffer(buf);
+}
+
+void read_buffer(RWBuffer buf)
+{
+       glReadBuffer(buf);
+}
 
 } // namespace GL
 } // namespace Msp