#define MSP_GL_FRAMEBUFFER_H_
#include <vector>
-#include "bindable.h"
+#include "color.h"
+#include "frameformat.h"
#include "gl.h"
#include "texturecube.h"
#include <msp/gl/extensions/arb_geometry_shader4.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
-};
+class WindowView;
enum BufferBits
{
class framebuffer_incomplete: public std::runtime_error
{
public:
- framebuffer_incomplete(FramebufferStatus);
+ framebuffer_incomplete(const std::string &);
virtual ~framebuffer_incomplete() throw() { }
};
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.
+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.
*/
-class Framebuffer: public Bindable<Framebuffer>
+class Framebuffer
{
+ friend class Commands;
+ friend class PipelineState;
+
private:
struct Attachment
{
- FramebufferAttachment attachment;
- GLenum type;
- union
- {
- Renderbuffer *rbuf;
- Texture *tex;
- };
+ Texture *tex;
unsigned level;
int layer;
- Attachment(FramebufferAttachment);
- void set(Renderbuffer &);
+ Attachment();
void set(Texture &, unsigned, int);
void clear();
};
- struct Viewport
- {
- int left;
- int bottom;
- unsigned width;
- unsigned height;
-
- Viewport();
- };
-
unsigned id;
+ FrameFormat format;
std::vector<Attachment> attachments;
unsigned width;
unsigned height;
- Viewport view;
+ mutable unsigned status;
mutable unsigned dirty;
Framebuffer(unsigned);
public:
+ /** Creates an empty framebuffer. Format must be set before textures can
+ be attached. */
Framebuffer();
+
+ /** Creates a framebuffer and sets its format to a single attachment. */
+ Framebuffer(FrameAttachment);
+
+ /** 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 &);
+
+ const FrameFormat &get_format() const { return format; }
+
unsigned get_width() const { return width; }
unsigned get_height() const { return height; }
private:
- void update_attachment(unsigned) const;
+ void update() const;
void check_size();
- unsigned get_attachment_index(FramebufferAttachment);
- void set_texture_attachment(FramebufferAttachment, Texture &, unsigned, int);
+ void set_attachment(FrameAttachment, 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 attach_layered(FramebufferAttachment attch, Texture3D &tex, unsigned level = 0);
- void attach_layered(FramebufferAttachment attch, TextureCube &tex, unsigned level = 0);
- void detach(FramebufferAttachment attch);
-
- /** 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 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, 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 resize(const WindowView &);
/** 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 refresh() const { if(dirty) update(); }
- void clear();
- void clear(BufferBits);
+ void set_debug_name(const std::string &);
- /** 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);
+ static Framebuffer &system();
+};
- void bind() const;
- static const Framebuffer *current();
- static void unbind();
+union ClearValue
+{
+ Color color;
+ struct
+ {
+ float depth;
+ int stencil;
+ } depth_stencil;
- static Framebuffer &system();
+ ClearValue(): color(0.0f, 0.0f, 0.0f, 0.0f) { }
};
inline BufferBits operator|(BufferBits a, BufferBits b)