]> git.tdb.fi Git - libs/gl.git/commitdiff
Add EXT_framebuffer_blit and EXT_framebuffer_multisample
authorMikko Rasa <tdb@tdb.fi>
Tue, 11 Jan 2011 21:13:42 +0000 (21:13 +0000)
committerMikko Rasa <tdb@tdb.fi>
Tue, 11 Jan 2011 21:13:42 +0000 (21:13 +0000)
Make Framebuffer attach level 0 of textures by default
Add multisampling support for Pipeline
Separate functions for setting HDR and multisample in Pipeline
Make the hdr parameter to Pipeline constructor optional

source/ext_framebuffer_blit.cpp [new file with mode: 0644]
source/ext_framebuffer_blit.h [new file with mode: 0644]
source/ext_framebuffer_multisample.cpp [new file with mode: 0644]
source/ext_framebuffer_multisample.h [new file with mode: 0644]
source/extension.cpp
source/framebuffer.cpp
source/framebuffer.h
source/pipeline.cpp
source/pipeline.h
source/renderbuffer.cpp
source/renderbuffer.h

diff --git a/source/ext_framebuffer_blit.cpp b/source/ext_framebuffer_blit.cpp
new file mode 100644 (file)
index 0000000..613f514
--- /dev/null
@@ -0,0 +1,15 @@
+#include "extension.h"
+#include "ext_framebuffer_blit.h"
+
+namespace Msp {
+namespace GL {
+
+PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT=0;
+
+void init_ext_framebuffer_blit()
+{
+       glBlitFramebufferEXT=reinterpret_cast<PFNGLBLITFRAMEBUFFEREXTPROC>(get_proc_address("glBlitFramebufferEXT"));
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/ext_framebuffer_blit.h b/source/ext_framebuffer_blit.h
new file mode 100644 (file)
index 0000000..0b65197
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef MSP_GL_EXT_FRAMEBUFFER_BLIT_
+#define MSP_GL_EXT_FRAMEBUFFER_BLIT_
+
+#include "gl.h"
+#include <GL/glext.h>
+
+namespace Msp {
+namespace GL {
+
+extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
+
+void init_ext_framebuffer_blit();
+
+} // namespace GL
+} // namespace Msp
+
+#endif
diff --git a/source/ext_framebuffer_multisample.cpp b/source/ext_framebuffer_multisample.cpp
new file mode 100644 (file)
index 0000000..22b00a9
--- /dev/null
@@ -0,0 +1,15 @@
+#include "extension.h"
+#include "ext_framebuffer_multisample.h"
+
+namespace Msp {
+namespace GL {
+
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT=0;
+
+void init_ext_framebuffer_multisample()
+{
+       glRenderbufferStorageMultisampleEXT=reinterpret_cast<PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC>(get_proc_address("glRenderbufferStorageMultisampleEXT"));
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/ext_framebuffer_multisample.h b/source/ext_framebuffer_multisample.h
new file mode 100644 (file)
index 0000000..479ef69
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef MSP_GL_EXT_FRAMEBUFFER_MULTISAMPLE_
+#define MSP_GL_EXT_FRAMEBUFFER_MULTISAMPLE_
+
+#include "gl.h"
+#include <GL/glext.h>
+
+namespace Msp {
+namespace GL {
+
+extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
+
+void init_ext_framebuffer_multisample();
+
+} // namespace GL
+} // namespace Msp
+
+#endif
index c2f1f6005f02260f034fe5c5d6adf27054ddc175..fbed6e2648c610595ee03451429d19c681416c92 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2007, 2009-2010  Mikko Rasa, Mikkosoft Productions
+Copyright © 2007, 2009-2011  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
@@ -16,6 +16,8 @@ Distributed under the LGPL
 #include "arb_vertex_buffer_object.h"
 #include "arb_vertex_program.h"
 #include "arb_vertex_shader.h"
+#include "ext_framebuffer_blit.h"
+#include "ext_framebuffer_multisample.h"
 #include "ext_framebuffer_object.h"
 #include "except.h"
 #include "extension.h"
@@ -52,6 +54,10 @@ bool is_supported(const string &ext)
                        init_arb_vertex_program();
                if(extensions.count("GL_EXT_framebuffer_object"))
                        init_ext_framebuffer_object();
+               if(extensions.count("GL_EXT_framebuffer_blit"))
+                       init_ext_framebuffer_blit();
+               if(extensions.count("GL_EXT_framebuffer_multisample"))
+                       init_ext_framebuffer_multisample();
                if(extensions.count("GL_ARB_vertex_buffer_object"))
                        init_arb_vertex_buffer_object();
                if(extensions.count("GL_NV_primitive_restart"))
index ea28d5db2d261eeb999d1e6c05eea38b6aefe70a..3d9b0133622b3bcec7590c440b8841f478217d16 100644 (file)
@@ -1,11 +1,12 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+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 "framebuffer.h"
 #include "misc.h"
@@ -146,6 +147,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))
index 89147b2c250cb265be3a7805cb927062499f1655..ea462bf6ad432bd78da37afef4fa77103bc676ff 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Copyright © 2007, 2009-2011  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
@@ -110,7 +110,7 @@ private:
        void check_size();
 public:
        void attach(FramebufferAttachment attch, Renderbuffer &rbuf);
-       void attach(FramebufferAttachment attch, Texture2D &tex, unsigned level);
+       void attach(FramebufferAttachment attch, Texture2D &tex, unsigned level = 0);
        void detach(FramebufferAttachment attch);
 
        /**
@@ -121,6 +121,9 @@ public:
        FramebufferStatus check_status() const;
 
        void clear(BufferBits);
+       void blit_from(const Framebuffer &, int, int, int, int, int, int, int, int, BufferBits, bool);
+       void blit_from(const Framebuffer &, int, int, unsigned, unsigned, int, int, BufferBits);
+       void blit_from(const Framebuffer &, BufferBits, bool);
 
        void bind() const;
 
index 570014d3692e4ab1405e22761b90511a02379020..8517805e23197aef724029280d0684cdadde2ec6 100644 (file)
@@ -28,9 +28,13 @@ Pipeline::Pipeline(unsigned w, unsigned h, bool d):
        width(w),
        height(h),
        hdr(d),
+       samples(0),
        fbo(0),
        color_buf(0),
-       depth_buf(0)
+       depth_buf(0),
+       fbo_ms(0),
+       color_buf_ms(0),
+       depth_buf_ms(0)
 { }
 
 Pipeline::~Pipeline()
@@ -40,6 +44,20 @@ Pipeline::~Pipeline()
        delete depth_buf;
 }
 
+void Pipeline::set_hdr(bool h)
+{
+       hdr = h;
+       if(!postproc.empty())
+               create_fbos();
+}
+
+void Pipeline::set_multisample(unsigned s)
+{
+       samples = s;
+       if(!postproc.empty())
+               create_fbos();
+}
+
 void Pipeline::set_camera(const Camera *c)
 {
        camera = c;
@@ -115,22 +133,8 @@ void Pipeline::add_postprocessor(PostProcessor &pp)
 {
        postproc.push_back(&pp);
        if(!fbo)
+               create_fbos();
        {
-               fbo = new Framebuffer;
-
-               color_buf = new Texture2D;
-               color_buf->set_min_filter(NEAREST);
-               color_buf->set_mag_filter(NEAREST);
-               color_buf->set_wrap(CLAMP_TO_EDGE);
-               color_buf->storage((hdr ? RGB16F : RGB), width, height);
-               fbo->attach(COLOR_ATTACHMENT0, *color_buf, 0);
-
-               depth_buf = new Texture2D;
-               depth_buf->set_min_filter(NEAREST);
-               depth_buf->set_mag_filter(NEAREST);
-               depth_buf->set_wrap(CLAMP_TO_EDGE);
-               depth_buf->storage(DEPTH_COMPONENT, width, height);
-               fbo->attach(DEPTH_ATTACHMENT, *depth_buf, 0);
        }
 }
 
@@ -160,8 +164,9 @@ void Pipeline::render_all() const
 
        if(fbo)
        {
-               fbo->bind();
-               fbo->clear(COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT);
+               Framebuffer *f = (fbo_ms ? fbo_ms : fbo);
+               f->bind();
+               f->clear(COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT);
        }
 
        for(vector<Effect *>::const_iterator i=effects.begin(); i!=effects.end(); ++i)
@@ -175,13 +180,60 @@ void Pipeline::render_all() const
                (*--i)->cleanup();
 
        if(fbo)
+       {
+               if(fbo_ms)
+                       fbo->blit_from(*fbo_ms, COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT, false);
                Framebuffer::unbind();
+       }
 
        // XXX Need two color buffer textures to handle multiple post-processors correctly
        for(vector<PostProcessor *>::const_iterator i=postproc.begin(); i!=postproc.end(); ++i)
                (*i)->render(*color_buf, *depth_buf);
 }
 
+void Pipeline::create_fbos()
+{
+       delete fbo;
+       delete color_buf;
+       delete depth_buf;
+
+       delete fbo_ms;
+       fbo_ms = 0;
+       delete color_buf_ms;
+       color_buf_ms = 0;
+       delete depth_buf_ms;
+       depth_buf_ms = 0;
+
+       fbo = new Framebuffer;
+
+       color_buf = new Texture2D;
+       color_buf->set_min_filter(NEAREST);
+       color_buf->set_mag_filter(NEAREST);
+       color_buf->set_wrap(CLAMP_TO_EDGE);
+       color_buf->storage((hdr ? RGB16F : RGB), width, height);
+       fbo->attach(COLOR_ATTACHMENT0, *color_buf, 0);
+
+       depth_buf = new Texture2D;
+       depth_buf->set_min_filter(NEAREST);
+       depth_buf->set_mag_filter(NEAREST);
+       depth_buf->set_wrap(CLAMP_TO_EDGE);
+       depth_buf->storage(DEPTH_COMPONENT, width, height);
+       fbo->attach(DEPTH_ATTACHMENT, *depth_buf, 0);
+
+       if(samples)
+       {
+               fbo_ms = new Framebuffer;
+
+               color_buf_ms = new Renderbuffer;
+               color_buf_ms->storage_multisample(samples, (hdr ? RGB16F : RGB), width, height);
+               fbo_ms->attach(COLOR_ATTACHMENT0, *color_buf_ms);
+
+               depth_buf_ms = new Renderbuffer;
+               depth_buf_ms->storage_multisample(samples, DEPTH_COMPONENT, width, height);
+               fbo_ms->attach(DEPTH_ATTACHMENT, *depth_buf_ms);
+       }
+}
+
 
 Pipeline::Slot::Slot(const Renderable *r):
        renderable(r)
index e4509af8364c77b84c512f141d8d3f30b66f0a78..f7f7e06ca198d84fe0a7b0aad583898f3eabd6cc 100644 (file)
@@ -45,14 +45,20 @@ private:
        unsigned width;
        unsigned height;
        bool hdr;
+       unsigned samples;
        Framebuffer *fbo;
        Texture2D *color_buf;
        Texture2D *depth_buf;
+       Framebuffer *fbo_ms;
+       Renderbuffer *color_buf_ms;
+       Renderbuffer *depth_buf_ms;
 
 public:
-       Pipeline(unsigned, unsigned, bool);
+       Pipeline(unsigned, unsigned, bool = false);
        ~Pipeline();
 
+       void set_hdr(bool);
+       void set_multisample(unsigned);
        void set_camera(const Camera *);
 
        PipelinePass &add_pass(const Tag &tag);
@@ -67,6 +73,9 @@ public:
 
        virtual void render(Renderer &, const Tag &tag = Tag()) const;
        void render_all() const;
+
+private:
+       void create_fbos();
 };
 
 } // namespace GL
index d28237bed7e33f55aa5ae7245c63e98707bb06e1..bd37aeea2bc59b460bbf17d4ecc32351bdfbe8dd 100644 (file)
@@ -1,11 +1,12 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2011  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
 #include "extension.h"
+#include "ext_framebuffer_multisample.h"
 #include "ext_framebuffer_object.h"
 #include "renderbuffer.h"
 
@@ -32,6 +33,16 @@ void Renderbuffer::storage(PixelFormat fmt, unsigned w, unsigned h)
        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, fmt, width, height);
 }
 
+void Renderbuffer::storage_multisample(unsigned samples, PixelFormat fmt, unsigned w, unsigned h)
+{
+       static RequireExtension _ext("GL_EXT_framebuffer_multisample");
+
+       Bind _bind(this, true);
+       width = w;
+       height = h;
+       glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, fmt, width, height);
+}
+
 void Renderbuffer::bind() const
 {
        if(set_current(this))
index b88db17a8a25a6417835290c1caf8fc0273d3712..7f9d7a422a0f5f6378075f2a0ed34622ad06f585 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Copyright © 2007, 2009-2011  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
@@ -37,6 +37,7 @@ public:
        unsigned get_height() const { return height; }
 
        void storage(PixelFormat fmt, unsigned width, unsigned height);
+       void storage_multisample(unsigned, PixelFormat fmt, unsigned, unsigned);
 
        void bind() const;