]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/framebuffer.h
Check the flat qualifier from the correct member
[libs/gl.git] / source / core / framebuffer.h
index 3086685e1ce29234e8f1e8629bb7ffd103f7050f..4932f29a31b687dff3fe8cd9abe52818eeef7b00 100644 (file)
 #define MSP_GL_FRAMEBUFFER_H_
 
 #include <vector>
-#include "bindable.h"
-#include "gl.h"
+#include "color.h"
+#include "framebuffer_backend.h"
+#include "frameformat.h"
+#include "rect.h"
 #include "texturecube.h"
-#include <msp/gl/extensions/arb_geometry_shader4.h>
-#include <msp/gl/extensions/ext_framebuffer_multisample.h>
-#include <msp/gl/extensions/ext_framebuffer_object.h>
-#include <msp/gl/extensions/nv_fbo_color_attachments.h>
 
 namespace Msp {
 namespace GL {
 
-class Renderbuffer;
-class Texture;
 class Texture2D;
+class Texture2DMultisample;
 class Texture3D;
-
-enum FramebufferAttachment
-{
-       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,
-       FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
-       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,
-       FRAMEBUFFER_INCOMPLETE_READ_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER,
-       FRAMEBUFFER_INCOMPLETE_MULTISAMPLE        = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
-       FRAMEBUFFER_INCOMPLETE_LAYER_COUNT        = GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB,
-       FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS      = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS,
-       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
-};
+class WindowView;
 
 class framebuffer_incomplete: public std::runtime_error
 {
 public:
-       framebuffer_incomplete(FramebufferStatus);
+       framebuffer_incomplete(const std::string &);
        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
-fullscreen shader effects.
-
-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.  The blit functions require
-the GL_EXT_framebuffer_blit extension.
+Uses one or more textures as buffers to draw into.  Framebuffers can contain
+multiple color buffers to match multiple outputs from a fragment shader, but
+only one depth and stencil buffer.
+
+If a framebuffer has a multisampled format, each attachment can optionally have
+a single-sampled resolve attachment associated with it.  When a multisample
+resolve operation is performed on the framebuffer (such as by a Sequence), the
+sample values from the primary attachments are converted to a single value per
+pixel in the corresponding resolve attachments.
+
+RenderTarget provides a higher-level interface which manages the textures as
+well as the framebuffer itself.
 */
-class Framebuffer: public Bindable<Framebuffer>
+class Framebuffer: public FramebufferBackend
 {
-private:
-       struct Attachment
-       {
-               FramebufferAttachment attachment;
-               GLenum type;
-               union
-               {
-                       Renderbuffer *rbuf;
-                       Texture *tex;
-               };
-               unsigned level;
-               unsigned layer;
-
-               Attachment(FramebufferAttachment);
-               void set(Renderbuffer &);
-               void set(Texture &, unsigned, unsigned);
-               void clear();
-       };
+       friend FramebufferBackend;
 
-       struct Viewport
+protected:
+       struct Attachment
        {
-               int left;
-               int bottom;
-               unsigned width;
-               unsigned height;
+               Texture *tex = 0;
+               Texture *resolve = 0;
+               unsigned level = 0;
+               int layer = 0;
 
-               Viewport();
+               void set(Texture &, Texture *, unsigned, int);
+               void clear();
        };
 
-       unsigned id;
+       FrameFormat format;
        std::vector<Attachment> attachments;
-       unsigned width;
-       unsigned height;
-       Viewport view;
-       mutable unsigned dirty;
+       unsigned width = 0;
+       unsigned height = 0;
+       unsigned layers = 0;
+       mutable unsigned dirty = 0;
 
-       Framebuffer(unsigned);
+       Framebuffer(bool);
 public:
+       /** Creates an empty framebuffer.  Format must be set before textures can
+       be attached. */
        Framebuffer();
-       ~Framebuffer();
+
+       /** Creates a framebuffer and sets its format to a single attachment. */
+       Framebuffer(FrameAttachment);
+
+       /** Creates a framebuffer and sets its format. */
+       Framebuffer(const FrameFormat &);
+
+       /** Sets the format of the framebuffer.  Once the format is set, it can't
+       be changed. */
+       void set_format(const FrameFormat &);
+
+       const FrameFormat &get_format() const { return format; }
 
        unsigned get_width() const { return width; }
        unsigned get_height() const { return height; }
+       Rect get_rect() const { return Rect(0, 0, width, height); }
+       unsigned get_layers() const { return layers; }
 
-private:
-       void update_attachment(unsigned) const;
+protected:
+       void update() const;
        void check_size();
-       unsigned get_attachment_index(FramebufferAttachment);
-       void set_texture_attachment(FramebufferAttachment, Texture &, unsigned, int);
+       void set_attachment(FrameAttachment, Texture &, Texture *, unsigned, int, unsigned);
+
 public:
-       void attach(FramebufferAttachment attch, Renderbuffer &rbuf);
-       void attach(FramebufferAttachment attch, Texture2D &tex, unsigned level = 0);
-       void attach(FramebufferAttachment attch, Texture3D &tex, unsigned layer, unsigned level = 0);
-       void attach(FramebufferAttachment attch, TextureCube &tex, TextureCubeFace face, unsigned level = 0);
-       void detach(FramebufferAttachment attch);
+       /** Attaches a texture to the framebuffer.  Only the attachment point
+       portion of attch is considered; pixel format is ignored.  The framebuffer
+       must have a format and the format of the texture must match that defined
+       in the framebuffer for this attachment point. */
+       void attach(FrameAttachment attch, Texture2D &, unsigned level = 0);
 
-       /** 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;
+       /** Attaches a multisample texture to the framebuffer.  The texture must
+       have a sample count matching the frame format.  A resolve attachment may
+       be given as well and used to resolve the multisample image into a single
+       value per texel. */
+       void attach(FrameAttachment attch, Texture2DMultisample &, Texture2D *);
 
-       /** Ensures that the framebuffer is complete, throwing an exception if it
-       isn't. */
-       void require_complete() const;
+       /** Attaches a single layer from a 3-dimensional texture to the
+       framebuffer. */
+       void attach(FrameAttachment attch, Texture3D &, unsigned layer, unsigned level = 0);
 
-       void viewport(int, int, unsigned, unsigned);
-       void reset_viewport();
+       void attach(FrameAttachment attch, TextureCube &, TextureCubeFace face, unsigned level = 0);
 
-       void clear();
-       void clear(BufferBits);
+       /** Attaches a layered texture to the framebuffer.  Shaders can direct
+       output to a particular layer. */
+       void attach_layered(FrameAttachment attch, Texture3D &, unsigned level = 0);
 
-       /** 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);
+       void attach_layered(FrameAttachment attch, TextureCube &, unsigned level = 0);
+       void detach(FrameAttachment attch);
 
-       /** 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);
+       const Texture *get_attachment(FrameAttachment) const;
+       const Texture *get_attachment(unsigned) const;
+       const Texture *get_resolve_attachment(FrameAttachment) const;
+       const Texture *get_resolve_attachment(unsigned) const;
+       bool has_resolve_attachments() const;
 
-       /** Blits the entire contents of another framebuffer into this one. */
-       void blit_from(const Framebuffer &other, BufferBits bits, bool filter);
+       using FramebufferBackend::is_presentable;
 
-       void bind() const;
+       /** Ensures that the framebuffer is complete, throwing an exception if it
+       isn't. */
+       void require_complete() const;
 
-       static const Framebuffer *current();
-       static void unbind();
+       void refresh() const { if(dirty) update(); }
 
-       static Framebuffer &system();
+       using FramebufferBackend::set_debug_name;
 };
 
-inline BufferBits operator|(BufferBits a, BufferBits b)
-{ return static_cast<BufferBits>(static_cast<int>(a)|static_cast<int>(b)); }
+
+union ClearValue
+{
+       Color color;
+       struct
+       {
+               float depth;
+               int stencil;
+       } depth_stencil;
+
+       ClearValue(): color(0.0f, 0.0f, 0.0f, 0.0f) { }
+};
 
 } // namespace GL
 } // namespace Msp