]> git.tdb.fi Git - libs/gl.git/blobdiff - source/framebuffer.h
Use ARB_direct_state_access to avoid some bind calls
[libs/gl.git] / source / framebuffer.h
index e33deda9218d9bf3afea690b44fc1e9dd6329bc1..579d22f8f33c3993be7ee7f1d1f78d984a207267 100644 (file)
@@ -5,6 +5,8 @@
 #include "bindable.h"
 #include "gl.h"
 #include "texturecube.h"
+#include <msp/gl/extensions/ext_framebuffer_object.h>
+#include <msp/gl/extensions/msp_stereo_rendering.h>
 
 namespace Msp {
 namespace GL {
@@ -15,32 +17,31 @@ class Texture2D;
 
 enum FramebufferAttachment
 {
-       COLOR_ATTACHMENT0  = GL_COLOR_ATTACHMENT0_EXT,
-       COLOR_ATTACHMENT1  = GL_COLOR_ATTACHMENT1_EXT,
-       COLOR_ATTACHMENT2  = GL_COLOR_ATTACHMENT2_EXT,
-       COLOR_ATTACHMENT3  = GL_COLOR_ATTACHMENT3_EXT,
-       DEPTH_ATTACHMENT   = GL_DEPTH_ATTACHMENT_EXT,
-       STENCIL_ATTACHMENT = GL_STENCIL_ATTACHMENT_EXT
+       COLOR_ATTACHMENT0  = GL_COLOR_ATTACHMENT0,
+       COLOR_ATTACHMENT1  = GL_COLOR_ATTACHMENT1,
+       COLOR_ATTACHMENT2  = GL_COLOR_ATTACHMENT2,
+       COLOR_ATTACHMENT3  = GL_COLOR_ATTACHMENT3,
+       DEPTH_ATTACHMENT   = GL_DEPTH_ATTACHMENT,
+       STENCIL_ATTACHMENT = GL_STENCIL_ATTACHMENT
 };
 
 enum FramebufferStatus
 {
-       FRAMEBUFFER_INCOMPLETE_ATTACHMENT         = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT,
-       FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT,
-       FRAMEBUFFER_INCOMPLETE_DIMENSIONS         = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT,
-       FRAMEBUFFER_INCOMPLETE_FORMATS            = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT,
-       FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT,
-       FRAMEBUFFER_INCOMPLETE_READ_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT,
-       FRAMEBUFFER_UNSUPPORTED                   = GL_FRAMEBUFFER_UNSUPPORTED_EXT,
-       FRAMEBUFFER_COMPLETE                      = GL_FRAMEBUFFER_COMPLETE_EXT
+       FRAMEBUFFER_INCOMPLETE_ATTACHMENT         = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+       FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
+       FRAMEBUFFER_INCOMPLETE_DIMENSIONS         = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS,
+       FRAMEBUFFER_INCOMPLETE_FORMATS            = GL_FRAMEBUFFER_INCOMPLETE_FORMATS,
+       FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER,
+       FRAMEBUFFER_INCOMPLETE_READ_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER,
+       FRAMEBUFFER_UNSUPPORTED                   = GL_FRAMEBUFFER_UNSUPPORTED,
+       FRAMEBUFFER_COMPLETE                      = GL_FRAMEBUFFER_COMPLETE
 };
 
 enum BufferBits
 {
        COLOR_BUFFER_BIT   = GL_COLOR_BUFFER_BIT,
        DEPTH_BUFFER_BIT   = GL_DEPTH_BUFFER_BIT,
-       STENCIL_BUFFER_BIT = GL_STENCIL_BUFFER_BIT,
-       ACCUM_BUFFER_BIT   = GL_ACCUM_BUFFER_BIT
+       STENCIL_BUFFER_BIT = GL_STENCIL_BUFFER_BIT
 };
 
 enum RWBuffer
@@ -57,6 +58,13 @@ enum RWBuffer
        FRONT_AND_BACK = GL_FRONT_AND_BACK
 };
 
+class framebuffer_incomplete: public std::runtime_error
+{
+public:
+       framebuffer_incomplete(FramebufferStatus);
+       virtual ~framebuffer_incomplete() throw() { }
+};
+
 /**
 Framebuffer objects can be used to perform offscreen rendering.  The most
 common application is rendering to a texture, which can then be used for
@@ -66,7 +74,8 @@ A framebuffer consist of a number of logical buffers, such as color and depth
 buffers.  Renderbuffers and Textures can be attached to the logical buffers.  At
 least one image must be attached for the framebuffer to be usable.
 
-Requires the GL_EXT_framebuffer_object extension.
+Requires the GL_EXT_framebuffer_object extension.  The blit functions require
+the GL_EXT_framebuffer_blit extension.
 */
 class Framebuffer: public Bindable<Framebuffer>
 {
@@ -81,18 +90,29 @@ private:
                        Texture *tex;
                };
                unsigned level;
-               GLenum cube_face;
+               unsigned layer;
 
                Attachment(FramebufferAttachment);
                void set(Renderbuffer &);
-               void set(Texture &, GLenum, unsigned);
+               void set(Texture &, unsigned, unsigned);
                void clear();
        };
 
+       struct Viewport
+       {
+               int left;
+               int bottom;
+               unsigned width;
+               unsigned height;
+
+               Viewport();
+       };
+
        unsigned id;
        std::vector<Attachment> attachments;
        unsigned width;
        unsigned height;
+       Viewport view;
        mutable unsigned dirty;
 
        Framebuffer(unsigned);
@@ -106,23 +126,41 @@ public:
 private:
        void update_attachment(unsigned) const;
        void check_size();
+       unsigned get_attachment_index(FramebufferAttachment);
 public:
        void attach(FramebufferAttachment attch, Renderbuffer &rbuf);
        void attach(FramebufferAttachment attch, Texture2D &tex, unsigned level = 0);
        void attach(FramebufferAttachment attch, TextureCube &tex, TextureCubeFace face, unsigned level = 0);
        void detach(FramebufferAttachment attch);
 
-       /**
-       Checks the completeness status of the framebuffer.  Returns
-       FRAMEBUFFER_COMPLETE if the framebuffer is complate and can be rendered to,
-       or one of the error status codes otherwise.
-       */
+       /** Checks the completeness of the framebuffer.  Returns
+       FRAMEBUFFER_COMPLETE if the framebuffer is complete and can be rendered to,
+       or one of the error status codes otherwise. */
        FramebufferStatus check_status() const;
 
+       /** Ensures that the framebuffer is complete, throwing an exception if it
+       isn't. */
+       void require_complete() const;
+
+       void viewport(int, int, unsigned, unsigned);
+       void reset_viewport();
+
        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);
+
+       /** Blits a region from another framebuffer into this one.  If the source
+       and destination regions have different dimensions, the contents will be
+       stretched.  If filter is true, linear interpolation will be used, otherwise
+       no interpolation is done. */
+       void 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);
+
+       /** Blits a region from another framebuffer into this one, retaining its
+       dimensions. */
+       void blit_from(const Framebuffer & other, int sx, int sy,
+               unsigned wd, unsigned ht, int dx, int dy, BufferBits bits);
+
+       /** Blits the entire contents of another framebuffer into this one. */
+       void blit_from(const Framebuffer &other, BufferBits bits, bool filter);
 
        void bind() const;
 
@@ -130,8 +168,6 @@ public:
        static void unbind();
 
        static Framebuffer &system();
-private:
-       unsigned get_attachment_index(FramebufferAttachment);
 };
 
 inline BufferBits operator|(BufferBits a, BufferBits b)