X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fcore%2Fframebuffer.h;h=48888459da363f7b24be4e7edd25aecbc0d00a8f;hp=3054bd646b3e4d4709c4ee7ec8a96a5b20bdfa7a;hb=006bdb4f8660098fc524dcca80b24c943c65b249;hpb=7aaec9a70b8d7733429bec043f8e33e02956f266 diff --git a/source/core/framebuffer.h b/source/core/framebuffer.h index 3054bd64..48888459 100644 --- a/source/core/framebuffer.h +++ b/source/core/framebuffer.h @@ -2,7 +2,8 @@ #define MSP_GL_FRAMEBUFFER_H_ #include -#include "bindable.h" +#include "color.h" +#include "frameformat.h" #include "gl.h" #include "texturecube.h" #include @@ -13,35 +14,11 @@ 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 { @@ -53,7 +30,7 @@ enum BufferBits class framebuffer_incomplete: public std::runtime_error { public: - framebuffer_incomplete(FramebufferStatus); + framebuffer_incomplete(const std::string &); virtual ~framebuffer_incomplete() throw() { } }; @@ -63,105 +40,106 @@ 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. +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 +class Framebuffer { + friend class Commands; + friend class PipelineState; + private: struct Attachment { - FramebufferAttachment attachment; - GLenum type; - union - { - Renderbuffer *rbuf; - Texture *tex; - }; + Texture *tex; unsigned level; - unsigned layer; + int layer; - Attachment(FramebufferAttachment); - void set(Renderbuffer &); - void set(Texture &, unsigned, unsigned); + 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 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_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 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 clear(); - void clear(BufferBits); + void refresh() const { if(dirty) update(); } - /** 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 set_debug_name(const std::string &); - /** 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)