Browse Source

Moved framebuffer-related enums out of AbstractFramebuffer.

Removes another trivial choice issue.
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
6e1990132c
  1. 36
      src/AbstractFramebuffer.cpp
  2. 207
      src/AbstractFramebuffer.h
  3. 4
      src/Magnum.h
  4. 2
      src/TextureTools/DistanceField.cpp

36
src/AbstractFramebuffer.cpp

@ -40,25 +40,25 @@ AbstractFramebuffer::DrawBuffersImplementation AbstractFramebuffer::drawBuffersI
AbstractFramebuffer::DrawBufferImplementation AbstractFramebuffer::drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDefault; AbstractFramebuffer::DrawBufferImplementation AbstractFramebuffer::drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDefault;
AbstractFramebuffer::ReadBufferImplementation AbstractFramebuffer::readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDefault; AbstractFramebuffer::ReadBufferImplementation AbstractFramebuffer::readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDefault;
AbstractFramebuffer::Target AbstractFramebuffer::readTarget = AbstractFramebuffer::Target::ReadDraw; FramebufferTarget AbstractFramebuffer::readTarget = FramebufferTarget::ReadDraw;
AbstractFramebuffer::Target AbstractFramebuffer::drawTarget = AbstractFramebuffer::Target::ReadDraw; FramebufferTarget AbstractFramebuffer::drawTarget = FramebufferTarget::ReadDraw;
void AbstractFramebuffer::bind(Target target) { void AbstractFramebuffer::bind(FramebufferTarget target) {
bindInternal(target); bindInternal(target);
setViewportInternal(); setViewportInternal();
} }
void AbstractFramebuffer::bindInternal(Target target) { void AbstractFramebuffer::bindInternal(FramebufferTarget target) {
Implementation::FramebufferState* state = Context::current()->state()->framebuffer; Implementation::FramebufferState* state = Context::current()->state()->framebuffer;
/* If already bound, done, otherwise update tracked state */ /* If already bound, done, otherwise update tracked state */
if(target == Target::Read) { if(target == FramebufferTarget::Read) {
if(state->readBinding == _id) return; if(state->readBinding == _id) return;
state->readBinding = _id; state->readBinding = _id;
} else if(target == Target::Draw) { } else if(target == FramebufferTarget::Draw) {
if(state->drawBinding == _id) return; if(state->drawBinding == _id) return;
state->drawBinding = _id; state->drawBinding = _id;
} else if(target == Target::ReadDraw) { } else if(target == FramebufferTarget::ReadDraw) {
if(state->readBinding == _id && state->drawBinding == _id) return; if(state->readBinding == _id && state->drawBinding == _id) return;
state->readBinding = state->drawBinding = _id; state->readBinding = state->drawBinding = _id;
} else CORRADE_ASSERT_UNREACHABLE(); } else CORRADE_ASSERT_UNREACHABLE();
@ -66,28 +66,28 @@ void AbstractFramebuffer::bindInternal(Target target) {
glBindFramebuffer(static_cast<GLenum>(target), _id); glBindFramebuffer(static_cast<GLenum>(target), _id);
} }
AbstractFramebuffer::Target AbstractFramebuffer::bindInternal() { FramebufferTarget AbstractFramebuffer::bindInternal() {
Implementation::FramebufferState* state = Context::current()->state()->framebuffer; Implementation::FramebufferState* state = Context::current()->state()->framebuffer;
/* Return target to which the framebuffer is already bound */ /* Return target to which the framebuffer is already bound */
if(state->readBinding == _id && state->drawBinding == _id) if(state->readBinding == _id && state->drawBinding == _id)
return Target::ReadDraw; return FramebufferTarget::ReadDraw;
if(state->readBinding == _id) if(state->readBinding == _id)
return Target::Read; return FramebufferTarget::Read;
if(state->drawBinding == _id) if(state->drawBinding == _id)
return Target::Draw; return FramebufferTarget::Draw;
/* Or bind it, if not already */ /* Or bind it, if not already */
state->readBinding = _id; state->readBinding = _id;
if(readTarget == Target::ReadDraw) state->drawBinding = _id; if(readTarget == FramebufferTarget::ReadDraw) state->drawBinding = _id;
glBindFramebuffer(GLenum(readTarget), _id); glBindFramebuffer(GLenum(readTarget), _id);
return readTarget; return readTarget;
} }
void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& sourceRectangle, const Rectanglei& destinationRectangle, AbstractFramebuffer::BlitMask mask, AbstractFramebuffer::BlitFilter filter) { void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& sourceRectangle, const Rectanglei& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter) {
source.bindInternal(AbstractFramebuffer::Target::Read); source.bindInternal(FramebufferTarget::Read);
destination.bindInternal(AbstractFramebuffer::Target::Draw); destination.bindInternal(FramebufferTarget::Draw);
/** @todo Get some extension wrangler instead to avoid undeclared glBlitFramebuffer() on ES2 */ /** @todo Get some extension wrangler instead to avoid undeclared glBlitFramebuffer() on ES2 */
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
glBlitFramebuffer(sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), static_cast<GLbitfield>(mask), static_cast<GLenum>(filter)); glBlitFramebuffer(sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), static_cast<GLbitfield>(mask), static_cast<GLenum>(filter));
@ -123,7 +123,7 @@ void AbstractFramebuffer::setViewportInternal() {
glViewport(_viewport.left(), _viewport.bottom(), _viewport.width(), _viewport.height()); glViewport(_viewport.left(), _viewport.bottom(), _viewport.width(), _viewport.height());
} }
void AbstractFramebuffer::clear(ClearMask mask) { void AbstractFramebuffer::clear(FramebufferClearMask mask) {
bindInternal(drawTarget); bindInternal(drawTarget);
glClear(static_cast<GLbitfield>(mask)); glClear(static_cast<GLbitfield>(mask));
} }
@ -178,8 +178,8 @@ void AbstractFramebuffer::initializeContextBasedFunctionality(Context* context)
if(context->isExtensionSupported<Extensions::GL::EXT::framebuffer_blit>()) { if(context->isExtensionSupported<Extensions::GL::EXT::framebuffer_blit>()) {
Debug() << "AbstractFramebuffer: using" << Extensions::GL::EXT::framebuffer_blit::string() << "features"; Debug() << "AbstractFramebuffer: using" << Extensions::GL::EXT::framebuffer_blit::string() << "features";
readTarget = Target::Read; readTarget = FramebufferTarget::Read;
drawTarget = Target::Draw; drawTarget = FramebufferTarget::Draw;
} }
if(context->isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) { if(context->isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {

207
src/AbstractFramebuffer.h

@ -35,6 +35,94 @@
namespace Magnum { namespace Magnum {
/**
* @brief Mask for framebuffer clearing
*
* @see AbstractFramebuffer, FramebufferClearMask
*/
enum class FramebufferClear: GLbitfield {
Color = GL_COLOR_BUFFER_BIT, /**< Color */
Depth = GL_DEPTH_BUFFER_BIT, /**< Depth value */
Stencil = GL_STENCIL_BUFFER_BIT /**< Stencil value */
};
/**
* @brief Mask for clearing
*
* @see AbstractFramebuffer::clear()
*/
typedef Corrade::Containers::EnumSet<FramebufferClear, GLbitfield,
GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT> FramebufferClearMask;
/**
* @brief Mask for framebuffer blitting
*
* @see AbstractFramebuffer, FramebufferBlitMask
* @requires_gl30 %Extension @extension{EXT,framebuffer_object}
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit}
*/
enum class FramebufferBlit: GLbitfield {
ColorBuffer = GL_COLOR_BUFFER_BIT, /**< Color buffer */
DepthBuffer = GL_DEPTH_BUFFER_BIT, /**< Depth buffer */
StencilBuffer = GL_STENCIL_BUFFER_BIT /**< Stencil buffer */
};
/**
* @brief Mask for framebuffer blitting
*
* @see AbstractFramebuffer::blit()
* @requires_gl30 %Extension @extension{EXT,framebuffer_object}
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit}
*/
typedef Corrade::Containers::EnumSet<FramebufferBlit, GLbitfield,
GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT> FramebufferBlitMask;
/**
* @brief %Framebuffer blit filtering
*
* @see AbstractFramebuffer::blit()
*/
enum class FramebufferBlitFilter: GLenum {
Nearest = GL_NEAREST, /**< Nearest neighbor filtering */
Linear = GL_LINEAR /**< Linear interpolation filtering */
};
/**
* @brief Target for binding framebuffer
*
* @see DefaultFramebuffer::bind(), Framebuffer::bind()
* @requires_gl30 %Extension @extension{EXT,framebuffer_object}
*/
enum class FramebufferTarget: GLenum {
/**
* For reading only.
* @requires_gl30 %Extension @extension{EXT,framebuffer_blit}
* @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample},
* @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit}
*/
#ifndef MAGNUM_TARGET_GLES2
Read = GL_READ_FRAMEBUFFER,
#else
Read = GL_READ_FRAMEBUFFER_APPLE,
#endif
/**
* For drawing only.
* @requires_gl30 %Extension @extension{EXT,framebuffer_blit}
* @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample},
* @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit}
*/
#ifndef MAGNUM_TARGET_GLES2
Draw = GL_DRAW_FRAMEBUFFER,
#else
Draw = GL_DRAW_FRAMEBUFFER_APPLE,
#endif
ReadDraw = GL_FRAMEBUFFER /**< For both reading and drawing. */
};
/** /**
@brief Base for default and named framebuffers @brief Base for default and named framebuffers
@ -59,94 +147,6 @@ class MAGNUM_EXPORT AbstractFramebuffer {
AbstractFramebuffer& operator=(AbstractFramebuffer&&) = delete; AbstractFramebuffer& operator=(AbstractFramebuffer&&) = delete;
public: public:
/**
* @brief Mask for clearing
*
* @see ClearMask
*/
enum class Clear: GLbitfield {
Color = GL_COLOR_BUFFER_BIT, /**< Color */
Depth = GL_DEPTH_BUFFER_BIT, /**< Depth value */
Stencil = GL_STENCIL_BUFFER_BIT /**< Stencil value */
};
/**
* @brief Mask for clearing
*
* @see clear()
*/
typedef Corrade::Containers::EnumSet<Clear, GLbitfield,
GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT> ClearMask;
/**
* @brief Mask for blitting
*
* @see BlitMask
* @requires_gl30 %Extension @extension{EXT,framebuffer_object}
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit}
*/
enum class Blit: GLbitfield {
ColorBuffer = GL_COLOR_BUFFER_BIT, /**< Color buffer */
DepthBuffer = GL_DEPTH_BUFFER_BIT, /**< Depth buffer */
StencilBuffer = GL_STENCIL_BUFFER_BIT /**< Stencil buffer */
};
/**
* @brief Mask for blitting
*
* @see blit()
* @requires_gl30 %Extension @extension{EXT,framebuffer_object}
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit}
*/
typedef Corrade::Containers::EnumSet<Blit, GLbitfield,
GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT> BlitMask;
/**
* @brief Blit filtering
*
* @see blit()
*/
enum class BlitFilter: GLenum {
Nearest = GL_NEAREST, /**< Nearest neighbor filtering */
Linear = GL_LINEAR /**< Linear interpolation filtering */
};
/**
* @brief Target for binding framebuffer
*
* @see DefaultFramebuffer::bind(), Framebuffer::bind()
* @requires_gl30 %Extension @extension{EXT,framebuffer_object}
*/
enum class Target: GLenum {
/**
* For reading only.
* @requires_gl30 %Extension @extension{EXT,framebuffer_blit}
* @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample},
* @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit}
*/
#ifndef MAGNUM_TARGET_GLES2
Read = GL_READ_FRAMEBUFFER,
#else
Read = GL_READ_FRAMEBUFFER_APPLE,
#endif
/**
* For drawing only.
* @requires_gl30 %Extension @extension{EXT,framebuffer_blit}
* @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample},
* @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit}
*/
#ifndef MAGNUM_TARGET_GLES2
Draw = GL_DRAW_FRAMEBUFFER,
#else
Draw = GL_DRAW_FRAMEBUFFER_APPLE,
#endif
ReadDraw = GL_FRAMEBUFFER /**< For both reading and drawing. */
};
/** /**
* @brief Copy block of pixels * @brief Copy block of pixels
* @param source Source framebuffer * @param source Source framebuffer
@ -156,9 +156,9 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @param mask Which buffers to perform blit operation on * @param mask Which buffers to perform blit operation on
* @param filter Interpolation filter * @param filter Interpolation filter
* *
* Binds @p source framebuffer to @ref Target "Target::Read" and * Binds @p source framebuffer to @ref FramebufferTarget "FramebufferTarget::Read"
* @p destination framebuffer to @ref Target "Target::Draw" and * and @p destination framebuffer to @ref FramebufferTarget "FramebufferTarget::Draw"
* performs blitting operation. See DefaultFramebuffer::mapForRead(), * and performs blitting operation. See DefaultFramebuffer::mapForRead(),
* Framebuffer::mapForRead(), DefaultFramebuffer::mapForDraw() and * Framebuffer::mapForRead(), DefaultFramebuffer::mapForDraw() and
* Framebuffer::mapForDraw() for specifying particular buffers for * Framebuffer::mapForDraw() for specifying particular buffers for
* blitting operation. * blitting operation.
@ -167,7 +167,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit} * @es_extension{NV,framebuffer_blit}
*/ */
static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& sourceRectangle, const Rectanglei& destinationRectangle, BlitMask mask, BlitFilter filter); static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& sourceRectangle, const Rectanglei& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
/** /**
* @brief Copy block of pixels * @brief Copy block of pixels
@ -179,14 +179,15 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* Convenience alternative to above function when source rectangle is * Convenience alternative to above function when source rectangle is
* the same as destination rectangle. As the image is copied * the same as destination rectangle. As the image is copied
* pixel-by-pixel, no interpolation is needed and thus * pixel-by-pixel, no interpolation is needed and thus
* @ref BlitFilter "BlitFilter::Nearest" filtering is used by default. * @ref FramebufferBlitFilter "FramebufferBlitFilter::Nearest"
* filtering is used by default.
* @see @fn_gl{BlitFramebuffer} * @see @fn_gl{BlitFramebuffer}
* @requires_gl30 %Extension @extension{EXT,framebuffer_blit} * @requires_gl30 %Extension @extension{EXT,framebuffer_blit}
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit} * @es_extension{NV,framebuffer_blit}
*/ */
inline static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& rectangle, BlitMask mask) { inline static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& rectangle, FramebufferBlitMask mask) {
blit(source, destination, rectangle, rectangle, mask, BlitFilter::Nearest); blit(source, destination, rectangle, rectangle, mask, FramebufferBlitFilter::Nearest);
} }
explicit AbstractFramebuffer() = default; explicit AbstractFramebuffer() = default;
@ -201,7 +202,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* Framebuffer::mapForDraw(), @fn_gl{BindFramebuffer}, * Framebuffer::mapForDraw(), @fn_gl{BindFramebuffer},
* @fn_gl{Viewport} * @fn_gl{Viewport}
*/ */
void bind(Target target); void bind(FramebufferTarget target);
/** @brief Viewport rectangle */ /** @brief Viewport rectangle */
inline Rectanglei viewport() const { return _viewport; } inline Rectanglei viewport() const { return _viewport; }
@ -229,7 +230,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* Renderer::setClearStencil(), @fn_gl{BindFramebuffer}, * Renderer::setClearStencil(), @fn_gl{BindFramebuffer},
* @fn_gl{Clear} * @fn_gl{Clear}
*/ */
void clear(ClearMask mask); void clear(FramebufferClearMask mask);
/** /**
* @brief Read block of pixels from framebuffer to image * @brief Read block of pixels from framebuffer to image
@ -267,12 +268,12 @@ class MAGNUM_EXPORT AbstractFramebuffer {
#else #else
protected: protected:
#endif #endif
void MAGNUM_LOCAL bindInternal(Target target); void MAGNUM_LOCAL bindInternal(FramebufferTarget target);
Target MAGNUM_LOCAL bindInternal(); FramebufferTarget MAGNUM_LOCAL bindInternal();
void MAGNUM_LOCAL setViewportInternal(); void MAGNUM_LOCAL setViewportInternal();
static MAGNUM_LOCAL Target readTarget; static MAGNUM_LOCAL FramebufferTarget readTarget;
static MAGNUM_LOCAL Target drawTarget; static MAGNUM_LOCAL FramebufferTarget drawTarget;
typedef void(AbstractFramebuffer::*DrawBuffersImplementation)(GLsizei, const GLenum*); typedef void(AbstractFramebuffer::*DrawBuffersImplementation)(GLsizei, const GLenum*);
static MAGNUM_LOCAL DrawBuffersImplementation drawBuffersImplementation; static MAGNUM_LOCAL DrawBuffersImplementation drawBuffersImplementation;
@ -317,8 +318,8 @@ class MAGNUM_EXPORT AbstractFramebuffer {
inline AbstractFramebuffer::~AbstractFramebuffer() {} inline AbstractFramebuffer::~AbstractFramebuffer() {}
CORRADE_ENUMSET_OPERATORS(AbstractFramebuffer::ClearMask) CORRADE_ENUMSET_OPERATORS(FramebufferClearMask)
CORRADE_ENUMSET_OPERATORS(AbstractFramebuffer::BlitMask) CORRADE_ENUMSET_OPERATORS(FramebufferBlitMask)
} }

4
src/Magnum.h

@ -329,7 +329,11 @@ using Math::operator "" _radf;
/** @todoc Remove `ifndef` when Doxygen is sane again */ /** @todoc Remove `ifndef` when Doxygen is sane again */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* Forward declarations for all types in root namespace */ /* Forward declarations for all types in root namespace */
/* FramebufferClear[Mask], FramebufferBlit[Mask], FramebufferBlitFilter,
FramebufferTarget enums used only directly with framebuffer instance */
class AbstractFramebuffer; class AbstractFramebuffer;
class AbstractImage; class AbstractImage;
class AbstractShaderProgram; class AbstractShaderProgram;
class AbstractTexture; class AbstractTexture;

2
src/TextureTools/DistanceField.cpp

@ -89,7 +89,7 @@ void distanceField(Texture2D* input, Texture2D* output, const Rectanglei& rectan
Framebuffer framebuffer(rectangle); Framebuffer framebuffer(rectangle);
framebuffer.attachTexture2D(Framebuffer::ColorAttachment(0), output, 0); framebuffer.attachTexture2D(Framebuffer::ColorAttachment(0), output, 0);
framebuffer.bind(Framebuffer::Target::Draw); framebuffer.bind(FramebufferTarget::Draw);
DistanceFieldShader shader; DistanceFieldShader shader;
shader.setRadius(radius) shader.setRadius(radius)

Loading…
Cancel
Save