X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fcore%2Fframebuffer.h;h=5476596317000dbecd53eca3146adce3dcc4407c;hp=2f867e6c591ec69706df22fc2a90bbeef52575f8;hb=HEAD;hpb=2e09b4f72f06537431151fe8b2574e1aa886ad48 diff --git a/source/core/framebuffer.h b/source/core/framebuffer.h index 2f867e6c..4932f29a 100644 --- a/source/core/framebuffer.h +++ b/source/core/framebuffer.h @@ -2,90 +2,65 @@ #define MSP_GL_FRAMEBUFFER_H_ #include +#include "color.h" +#include "framebuffer_backend.h" #include "frameformat.h" -#include "gl.h" +#include "rect.h" #include "texturecube.h" -#include -#include -#include -#include 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. - -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. +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 +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; + Texture *resolve = 0; + unsigned level = 0; + int layer = 0; - Attachment(); - void set(Texture &, unsigned, int); + void set(Texture &, Texture *, unsigned, int); void clear(); }; - unsigned id; FrameFormat format; std::vector 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. */ @@ -97,11 +72,6 @@ public: /** 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 &); @@ -110,31 +80,47 @@ public: 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: +protected: void update() const; void check_size(); - void set_attachment(FrameAttachment, Texture &, unsigned, int, unsigned); -public: + void set_attachment(FrameAttachment, Texture &, Texture *, unsigned, int, unsigned); +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); + + /** 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 *); + + /** 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, 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 attach(FrameAttachment attch, TextureCube &, TextureCubeFace face, unsigned level = 0); + + /** Attaches a layered texture to the framebuffer. Shaders can direct + output to a particular layer. */ + void attach_layered(FrameAttachment attch, Texture3D &, unsigned level = 0); + + void attach_layered(FrameAttachment attch, TextureCube &, unsigned level = 0); void detach(FrameAttachment attch); - void resize(const WindowView &); + 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; - /** 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; } + using FramebufferBackend::is_presentable; /** Ensures that the framebuffer is complete, throwing an exception if it isn't. */ @@ -142,13 +128,21 @@ public: 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(static_cast(a)|static_cast(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