From 80cd503bbd3109ed78fe46dec5b6857ff148d543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 13 Aug 2012 19:44:49 +0200 Subject: [PATCH] Reorganized Framebuffer class and grouped its members. Also marked everything related to blitting as unsupported in OpenGL ES 2.0. --- src/Framebuffer.h | 438 ++++++++++++++++++++++++---------------------- 1 file changed, 229 insertions(+), 209 deletions(-) diff --git a/src/Framebuffer.h b/src/Framebuffer.h index 27ee0cb85..69827bb49 100644 --- a/src/Framebuffer.h +++ b/src/Framebuffer.h @@ -42,6 +42,8 @@ class MAGNUM_EXPORT Framebuffer { Framebuffer& operator=(Framebuffer&& other) = delete; public: + /** @{ @name Framebuffer features */ + /** * @brief Features * @@ -66,6 +68,21 @@ class MAGNUM_EXPORT Framebuffer { FaceCulling = GL_CULL_FACE /**< Back face culling */ }; + /** @brief Set feature */ + static void setFeature(Feature feature, bool enabled); + + /** + * @brief Set viewport size + * + * Call when window size changes. + * @see Camera::setViewport() + */ + static void setViewport(const Math::Vector2& position, const Math::Vector2& size); + + /*@}*/ + + /** @{ @name Clearing the framebuffer */ + /** * @brief Mask for clearing * @@ -79,6 +96,61 @@ class MAGNUM_EXPORT Framebuffer { typedef Corrade::Utility::Set ClearMask; /**< @brief Mask for clearing */ + /** + * @brief Clear framebuffer + * + * Clears color buffer, depth and stencil buffer in currently active + * framebuffer. If depth or stencil test is not enabled, it doesn't + * clear these buffers. + * + * @see setFeature(), clear(ClearMask) + */ + inline static void clear() { glClear(static_cast(clearMask)); } + + /** + * @brief Clear specified buffers in framebuffer + * + * @see clear() + */ + inline static void clear(ClearMask mask) { glClear(static_cast(mask)); } + + /** + * @brief Set clear color + * + * Initial value is `{0.0f, 0.0f, 0.0f, 1.0f}`. + */ + inline static void setClearColor(const Color4& color) { + glClearColor(color.r(), color.g(), color.b(), color.a()); + } + + #ifndef MAGNUM_TARGET_GLES + /** + * @brief Set clear depth + * + * Initial value is `1.0`. + * @requires_gl See setClearDepth(GLfloat), which is supported in OpenGL ES. + */ + inline static void setClearDepth(GLdouble depth) { glClearDepth(depth); } + #endif + + /** + * @overload + * + * @requires_gl41 Extension @extension{ARB,ES2_compatibility} + */ + inline static void setClearDepth(GLfloat depth) { glClearDepthf(depth); } + + /** + * @brief Set clear stencil + * + * Initial value is `0`. + */ + inline static void setClearStencil(GLint stencil) { glClearStencil(stencil); } + + /*@}*/ + + /** @{ @name Framebuffer creation and binding */ + /** * @brief %Framebuffer target * @@ -142,119 +214,38 @@ class MAGNUM_EXPORT Framebuffer { #endif /** - * @brief Attachment for depth/stencil part of fragment shader output + * @brief Constructor * - * @see attachRenderbuffer(Target, DepthStencilAttachment, Renderbuffer*), - * attachTexture1D(Target, DepthStencilAttachment, Texture1D*, GLint), - * attachTexture2D(Target, DepthStencilAttachment, Texture2D*, GLint), - * attachCubeMapTexture(Target, DepthStencilAttachment, CubeMapTexture*, CubeMapTexture::Coordinate, GLint), - * attachTexture3D(Target, DepthStencilAttachment, Texture3D*, GLint) + * Generates new OpenGL framebuffer. * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ - enum class DepthStencilAttachment: GLenum { - Depth = GL_DEPTH_ATTACHMENT, /**< Depth output only. */ - - Stencil = GL_STENCIL_ATTACHMENT /**< Stencil output only. */ - - #ifndef MAGNUM_TARGET_GLES - , - /** - * Both depth and stencil output. - */ - DepthStencil = GL_DEPTH_STENCIL_ATTACHMENT - #endif - }; + inline Framebuffer() { glGenFramebuffers(1, &framebuffer); } /** - * @brief Output mask for blitting + * @brief Destructor * - * Specifies which data are copied when performing blit operation - * using blit(). - * @see BlitMask - * @requires_gl30 Extension @extension{EXT,framebuffer_object} - */ - enum class Blit: GLbitfield { - Color = GL_COLOR_BUFFER_BIT, /**< Color */ - Depth = GL_DEPTH_BUFFER_BIT, /**< Depth value */ - Stencil = GL_STENCIL_BUFFER_BIT /**< Stencil value */ - }; - - /** - * @brief Output mask for blitting + * Deletes associated OpenGL framebuffer. * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ - typedef Corrade::Utility::Set BlitMask; - - /** @brief Set feature */ - static void setFeature(Feature feature, bool enabled); + inline ~Framebuffer() { glDeleteFramebuffers(1, &framebuffer); } /** - * @brief Set clear color + * @brief Bind default framebuffer to given target + * @param target %Target * - * Initial value is `{0.0f, 0.0f, 0.0f, 1.0f}`. + * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ - inline static void setClearColor(const Color4& color) { - glClearColor(color.r(), color.g(), color.b(), color.a()); + inline static void bindDefault(Target target) { + glBindFramebuffer(static_cast(target), 0); } /** - * @brief Clear framebuffer - * - * Clears color buffer, depth and stencil buffer in currently active - * framebuffer. If depth or stencil test is not enabled, it doesn't - * clear these buffers. - * - * @see setFeature(), clear(ClearMask) - */ - inline static void clear() { glClear(static_cast(clearMask)); } - - /** - * @brief Clear specified buffers in framebuffer - * - * @see clear() - */ - inline static void clear(ClearMask mask) { glClear(static_cast(mask)); } - - #ifndef MAGNUM_TARGET_GLES - /** - * @brief Set clear depth - * - * Initial value is `1.0`. - * @requires_gl See setClearDepth(GLfloat), which is supported in OpenGL ES. - */ - inline static void setClearDepth(GLdouble depth) { glClearDepth(depth); } - #endif - - /** - * @overload - * - * @requires_gl41 Extension @extension{ARB,ES2_compatibility} - */ - inline static void setClearDepth(GLfloat depth) { glClearDepthf(depth); } - - /** - * @brief Set clear stencil - * - * Initial value is `0`. - */ - inline static void setClearStencil(GLint stencil) { glClearStencil(stencil); } - - /** - * @brief Set viewport size - * - * Call when window size changes. - * @see Camera::setViewport() - */ - static void setViewport(const Math::Vector2& position, const Math::Vector2& size); - - /** - * @brief Bind default framebuffer to given target - * @param target %Target + * @brief Bind framebuffer * * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ - inline static void bindDefault(Target target) { - glBindFramebuffer(static_cast(target), 0); + inline void bind(Target target) { + glBindFramebuffer(static_cast(target), framebuffer); } #ifndef MAGNUM_TARGET_GLES @@ -274,120 +265,6 @@ class MAGNUM_EXPORT Framebuffer { */ static void mapDefaultForDraw(std::initializer_list attachments); - /** - * @brief Map given attachment of default framebuffer for reading - * @param attachment Default attachment - * - * Each used attachment should have either renderbuffer or texture - * attached to work properly. - * @see mapForRead(), mapDefaultForDraw() - * @requires_gl - * @requires_gl30 Extension @extension{EXT,framebuffer_object} - */ - inline static void mapDefaultForRead(DefaultReadAttachment attachment) { - bindDefault(Target::Read); - glReadBuffer(static_cast(attachment)); - } - #endif - - #ifndef MAGNUM_TARGET_GLES - /** - * @brief Copy block of pixels from read to draw framebuffer - * @param bottomLeft Bottom left coordinates of source rectangle - * @param topRight Top right coordinates of source rectangle - * @param destinationBottomLeft Bottom left coordinates of destination rectangle - * @param destinationTopRight Top right coordinates of destination - * rectangle - * @param blitMask Blit mask - * @param filter Interpolation applied if the image is - * stretched - * - * See mapForRead() / mapDefaultForRead() and mapForDraw() / - * mapDefaultForDraw() for binding particular framebuffer for reading - * and drawing. If multiple attachments are specified in mapForDraw() - * / mapDefaultForDraw(), the data are written to each of them. - * @requires_gl - * @requires_gl30 Extension @extension{EXT,framebuffer_blit} - */ - inline static void blit(const Math::Vector2& bottomLeft, const Math::Vector2& topRight, const Math::Vector2& destinationBottomLeft, const Math::Vector2& destinationTopRight, BlitMask blitMask, AbstractTexture::Filter filter) { - glBlitFramebuffer(bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), destinationBottomLeft.x(), destinationBottomLeft.y(), destinationTopRight.x(), destinationTopRight.y(), static_cast(blitMask), static_cast(filter)); - } - - /** - * @brief Copy block of pixels from read to draw framebuffer - * @param bottomLeft Bottom left coordinates of source and - * destination rectangle - * @param topRight Top right coordinates of source and - * destination rectangle - * @param blitMask Blit mask - * - * Convenience function when source rectangle is the same as - * destination rectangle. As the image is copied pixel-by-pixel, - * no interpolation is needed and thus - * AbstractTexture::Filter::NearestNeighbor filtering is used by - * default. - * @requires_gl - * @requires_gl30 Extension @extension{EXT,framebuffer_blit} - */ - inline static void blit(const Math::Vector2& bottomLeft, const Math::Vector2& topRight, BlitMask blitMask) { - glBlitFramebuffer(bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), static_cast(blitMask), static_cast(AbstractTexture::Filter::NearestNeighbor)); - } - #endif - - /** - * @brief Read block of pixels from framebuffer to image - * @param offset Offset in the framebuffer - * @param dimensions Image dimensions - * @param components Color components - * @param type Data type - * @param image %Image where to put the data - * - * @requires_gl30 Extension @extension{EXT,framebuffer_object} - */ - static void read(const Math::Vector2& offset, const Math::Vector2& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image); - - #ifndef MAGNUM_TARGET_GLES - /** - * @brief Read block of pixels from framebuffer to buffered image - * @param offset Offset in the framebuffer - * @param dimensions Image dimensions - * @param components Color components - * @param type Data type - * @param image Buffered image where to put the data - * @param usage %Buffer usage - * - * @requires_gl - * @requires_gl30 Extension @extension{EXT,framebuffer_object} - */ - static void read(const Math::Vector2& offset, const Math::Vector2& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage); - #endif - - /** - * @brief Constructor - * - * Generates new OpenGL framebuffer. - * @requires_gl30 Extension @extension{EXT,framebuffer_object} - */ - inline Framebuffer() { glGenFramebuffers(1, &framebuffer); } - - /** - * @brief Destructor - * - * Deletes associated OpenGL framebuffer. - * @requires_gl30 Extension @extension{EXT,framebuffer_object} - */ - inline ~Framebuffer() { glDeleteFramebuffers(1, &framebuffer); } - - /** - * @brief Bind framebuffer - * - * @requires_gl30 Extension @extension{EXT,framebuffer_object} - */ - inline void bind(Target target) { - glBindFramebuffer(static_cast(target), framebuffer); - } - - #ifndef MAGNUM_TARGET_GLES /** * @brief Map given color attachments of current framebuffer for drawing * @param colorAttachments Color attachment IDs. If any value is -1, @@ -404,6 +281,21 @@ class MAGNUM_EXPORT Framebuffer { */ void mapForDraw(std::initializer_list colorAttachments); + /** + * @brief Map given attachment of default framebuffer for reading + * @param attachment Default attachment + * + * Each used attachment should have either renderbuffer or texture + * attached to work properly. + * @see mapForRead(), mapDefaultForDraw() + * @requires_gl + * @requires_gl30 Extension @extension{EXT,framebuffer_object} + */ + inline static void mapDefaultForRead(DefaultReadAttachment attachment) { + bindDefault(Target::Read); + glReadBuffer(static_cast(attachment)); + } + /** * @brief Map given color attachment of current framebuffer for reading * @param colorAttachment Color attachment ID @@ -420,6 +312,34 @@ class MAGNUM_EXPORT Framebuffer { } #endif + /*@}*/ + + /** @{ @name Attaching textures and renderbuffers */ + + /** + * @brief Attachment for depth/stencil part of fragment shader output + * + * @see attachRenderbuffer(Target, DepthStencilAttachment, Renderbuffer*), + * attachTexture1D(Target, DepthStencilAttachment, Texture1D*, GLint), + * attachTexture2D(Target, DepthStencilAttachment, Texture2D*, GLint), + * attachCubeMapTexture(Target, DepthStencilAttachment, CubeMapTexture*, CubeMapTexture::Coordinate, GLint), + * attachTexture3D(Target, DepthStencilAttachment, Texture3D*, GLint) + * @requires_gl30 Extension @extension{EXT,framebuffer_object} + */ + enum class DepthStencilAttachment: GLenum { + Depth = GL_DEPTH_ATTACHMENT, /**< Depth output only. */ + + Stencil = GL_STENCIL_ATTACHMENT /**< Stencil output only. */ + + #ifndef MAGNUM_TARGET_GLES + , + /** + * Both depth and stencil output. + */ + DepthStencil = GL_DEPTH_STENCIL_ATTACHMENT + #endif + }; + /** * @brief Attach renderbuffer to given framebuffer depth/stencil attachment * @param target %Target @@ -592,6 +512,106 @@ class MAGNUM_EXPORT Framebuffer { } #endif + /*@}*/ + + /** @{ @name Framebuffer blitting and reading */ + + #ifndef MAGNUM_TARGET_GLES + /** + * @brief Output mask for blitting + * + * Specifies which data are copied when performing blit operation + * using blit(). + * @see BlitMask + * @requires_gl + * @requires_gl30 Extension @extension{EXT,framebuffer_object} + */ + enum class Blit: GLbitfield { + Color = GL_COLOR_BUFFER_BIT, /**< Color */ + Depth = GL_DEPTH_BUFFER_BIT, /**< Depth value */ + Stencil = GL_STENCIL_BUFFER_BIT /**< Stencil value */ + }; + + /** + * @brief Output mask for blitting + * @requires_gl + * @requires_gl30 Extension @extension{EXT,framebuffer_object} + */ + typedef Corrade::Utility::Set BlitMask; + + /** + * @brief Copy block of pixels from read to draw framebuffer + * @param bottomLeft Bottom left coordinates of source rectangle + * @param topRight Top right coordinates of source rectangle + * @param destinationBottomLeft Bottom left coordinates of destination rectangle + * @param destinationTopRight Top right coordinates of destination + * rectangle + * @param blitMask Blit mask + * @param filter Interpolation applied if the image is + * stretched + * + * See mapForRead() / mapDefaultForRead() and mapForDraw() / + * mapDefaultForDraw() for binding particular framebuffer for reading + * and drawing. If multiple attachments are specified in mapForDraw() + * / mapDefaultForDraw(), the data are written to each of them. + * @requires_gl + * @requires_gl30 Extension @extension{EXT,framebuffer_blit} + */ + inline static void blit(const Math::Vector2& bottomLeft, const Math::Vector2& topRight, const Math::Vector2& destinationBottomLeft, const Math::Vector2& destinationTopRight, BlitMask blitMask, AbstractTexture::Filter filter) { + glBlitFramebuffer(bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), destinationBottomLeft.x(), destinationBottomLeft.y(), destinationTopRight.x(), destinationTopRight.y(), static_cast(blitMask), static_cast(filter)); + } + + /** + * @brief Copy block of pixels from read to draw framebuffer + * @param bottomLeft Bottom left coordinates of source and + * destination rectangle + * @param topRight Top right coordinates of source and + * destination rectangle + * @param blitMask Blit mask + * + * Convenience function when source rectangle is the same as + * destination rectangle. As the image is copied pixel-by-pixel, + * no interpolation is needed and thus + * AbstractTexture::Filter::NearestNeighbor filtering is used by + * default. + * @requires_gl + * @requires_gl30 Extension @extension{EXT,framebuffer_blit} + */ + inline static void blit(const Math::Vector2& bottomLeft, const Math::Vector2& topRight, BlitMask blitMask) { + glBlitFramebuffer(bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), static_cast(blitMask), static_cast(AbstractTexture::Filter::NearestNeighbor)); + } + #endif + + /** + * @brief Read block of pixels from framebuffer to image + * @param offset Offset in the framebuffer + * @param dimensions Image dimensions + * @param components Color components + * @param type Data type + * @param image %Image where to put the data + * + * @requires_gl30 Extension @extension{EXT,framebuffer_object} + */ + static void read(const Math::Vector2& offset, const Math::Vector2& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image); + + #ifndef MAGNUM_TARGET_GLES + /** + * @brief Read block of pixels from framebuffer to buffered image + * @param offset Offset in the framebuffer + * @param dimensions Image dimensions + * @param components Color components + * @param type Data type + * @param image Buffered image where to put the data + * @param usage %Buffer usage + * + * @requires_gl + * @requires_gl30 Extension @extension{EXT,framebuffer_object} + */ + static void read(const Math::Vector2& offset, const Math::Vector2& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage); + #endif + + /*@}*/ + private: static ClearMask clearMask;