#define MSP_GL_FRAMEBUFFER_H_
#include <vector>
+#include "color.h"
+#include "framebuffer_backend.h"
#include "frameformat.h"
-#include "gl.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 Texture;
class Texture2D;
class Texture2DMultisample;
class Texture3D;
class WindowView;
-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 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.
+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.
-A framebuffer consist of a number of logical buffers, such as color and depth
-buffers. 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.
+RenderTarget provides a higher-level interface which manages the textures as
+well as the framebuffer itself.
*/
-class Framebuffer
+class Framebuffer: public FramebufferBackend
{
- friend class Commands;
- friend class PipelineState;
+ friend FramebufferBackend;
-private:
+protected:
struct Attachment
{
- Texture *tex;
- unsigned level;
- int layer;
+ Texture *tex = 0;
+ unsigned level = 0;
+ int layer = 0;
- Attachment();
void set(Texture &, unsigned, int);
void clear();
};
- unsigned id;
FrameFormat format;
std::vector<Attachment> attachments;
- unsigned width;
- unsigned height;
- mutable FramebufferStatus status;
- 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. */
/** Creates a framebuffer and sets its format. */
Framebuffer(const FrameFormat &);
-private:
- void init();
-public:
- ~Framebuffer();
-
/** Sets the format of the framebuffer. Once the format is set, it can't
be changed. */
void set_format(const FrameFormat &);
unsigned get_width() const { return width; }
unsigned get_height() const { return height; }
+ unsigned get_layers() const { return layers; }
-private:
+protected:
void update() const;
void check_size();
void set_attachment(FrameAttachment, Texture &, unsigned, int, unsigned);
-public:
+public:
/** 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 &tex, unsigned level = 0);
+ void attach(FrameAttachment attch, Texture2D &, unsigned level = 0);
- void attach(FrameAttachment attch, Texture2DMultisample &tex);
- void attach(FrameAttachment attch, Texture3D &tex, unsigned layer, unsigned level = 0);
- void attach(FrameAttachment attch, TextureCube &tex, TextureCubeFace face, unsigned level = 0);
- void attach_layered(FrameAttachment attch, Texture3D &tex, unsigned level = 0);
- void attach_layered(FrameAttachment attch, TextureCube &tex, unsigned level = 0);
- void detach(FrameAttachment attch);
+ void attach(FrameAttachment attch, Texture2DMultisample &);
+
+ /** Attaches a single layer from a 3-dimensional texture to the
+ framebuffer. */
+ void attach(FrameAttachment attch, Texture3D &, unsigned layer, unsigned level = 0);
+
+ void attach(FrameAttachment attch, TextureCube &, TextureCubeFace face, unsigned level = 0);
- void resize(const WindowView &);
+ /** Attaches a layered texture to the framebuffer. Shaders can direct
+ output to a particular layer. */
+ void attach_layered(FrameAttachment attch, Texture3D &, unsigned level = 0);
- /** Returns FRAMEBUFFER_COMPLETE if the framebuffer is complete and can be
- rendered to, or one of the error status codes otherwise. */
- FramebufferStatus get_status() const { return status; }
+ void attach_layered(FrameAttachment attch, TextureCube &, unsigned level = 0);
+ void detach(FrameAttachment attch);
+
+ const Texture *get_attachment(FrameAttachment) const;
+ const Texture *get_attachment(unsigned) const;
/** Ensures that the framebuffer is complete, throwing an exception if it
isn't. */
void refresh() const { if(dirty) update(); }
- void set_debug_name(const std::string &);
-
- 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