Browse Source

Reorganized Framebuffer class and grouped its members.

Also marked everything related to blitting as unsupported in OpenGL ES
2.0.
vectorfields
Vladimír Vondruš 14 years ago
parent
commit
80cd503bbd
  1. 438
      src/Framebuffer.h

438
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<GLint>& position, const Math::Vector2<GLsizei>& size);
/*@}*/
/** @{ @name Clearing the framebuffer */
/**
* @brief Mask for clearing
*
@ -79,6 +96,61 @@ class MAGNUM_EXPORT Framebuffer {
typedef Corrade::Utility::Set<Clear, GLbitfield> 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<GLbitfield>(clearMask)); }
/**
* @brief Clear specified buffers in framebuffer
*
* @see clear()
*/
inline static void clear(ClearMask mask) { glClear(static_cast<GLbitfield>(mask)); }
/**
* @brief Set clear color
*
* Initial value is `{0.0f, 0.0f, 0.0f, 1.0f}`.
*/
inline static void setClearColor(const Color4<GLfloat>& 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<Blit, GLbitfield> 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<GLfloat>& color) {
glClearColor(color.r(), color.g(), color.b(), color.a());
inline static void bindDefault(Target target) {
glBindFramebuffer(static_cast<GLenum>(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<GLbitfield>(clearMask)); }
/**
* @brief Clear specified buffers in framebuffer
*
* @see clear()
*/
inline static void clear(ClearMask mask) { glClear(static_cast<GLbitfield>(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<GLint>& position, const Math::Vector2<GLsizei>& 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<GLenum>(target), 0);
inline void bind(Target target) {
glBindFramebuffer(static_cast<GLenum>(target), framebuffer);
}
#ifndef MAGNUM_TARGET_GLES
@ -274,120 +265,6 @@ class MAGNUM_EXPORT Framebuffer {
*/
static void mapDefaultForDraw(std::initializer_list<DefaultDrawAttachment> 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<GLenum>(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<GLint>& bottomLeft, const Math::Vector2<GLint>& topRight, const Math::Vector2<GLint>& destinationBottomLeft, const Math::Vector2<GLint>& 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<GLbitfield>(blitMask), static_cast<GLenum>(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<GLint>& bottomLeft, const Math::Vector2<GLint>& topRight, BlitMask blitMask) {
glBlitFramebuffer(bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), static_cast<GLbitfield>(blitMask), static_cast<GLenum>(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<GLint>& offset, const Math::Vector2<GLsizei>& 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<GLint>& offset, const Math::Vector2<GLsizei>& 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<GLenum>(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<int> 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<GLenum>(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<Blit, GLbitfield> 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<GLint>& bottomLeft, const Math::Vector2<GLint>& topRight, const Math::Vector2<GLint>& destinationBottomLeft, const Math::Vector2<GLint>& 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<GLbitfield>(blitMask), static_cast<GLenum>(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<GLint>& bottomLeft, const Math::Vector2<GLint>& topRight, BlitMask blitMask) {
glBlitFramebuffer(bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), static_cast<GLbitfield>(blitMask), static_cast<GLenum>(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<GLint>& offset, const Math::Vector2<GLsizei>& 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<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage);
#endif
/*@}*/
private:
static ClearMask clearMask;

Loading…
Cancel
Save