mirror of https://github.com/mosra/magnum.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
371 lines
15 KiB
371 lines
15 KiB
|
14 years ago
|
#ifndef Magnum_AbstractFramebuffer_h
|
||
|
|
#define Magnum_AbstractFramebuffer_h
|
||
|
|
/*
|
||
|
|
This file is part of Magnum.
|
||
|
|
|
||
|
13 years ago
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
|
||
|
|
|
||
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||
|
|
copy of this software and associated documentation files (the "Software"),
|
||
|
|
to deal in the Software without restriction, including without limitation
|
||
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
||
|
|
Software is furnished to do so, subject to the following conditions:
|
||
|
|
|
||
|
|
The above copyright notice and this permission notice shall be included
|
||
|
|
in all copies or substantial portions of the Software.
|
||
|
14 years ago
|
|
||
|
13 years ago
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||
|
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||
|
|
DEALINGS IN THE SOFTWARE.
|
||
|
14 years ago
|
*/
|
||
|
|
|
||
|
|
/** @file
|
||
|
13 years ago
|
* @brief Class @ref Magnum::AbstractFramebuffer, enum @ref Magnum::FramebufferClear, @ref Magnum::FramebufferBlit, @ref Magnum::FramebufferBlitFilter, @ref Magnum::FramebufferTarget, enum set @ref Magnum::FramebufferClearMask
|
||
|
14 years ago
|
*/
|
||
|
|
|
||
|
|
#include <Containers/EnumSet.h>
|
||
|
|
|
||
|
13 years ago
|
#include "Math/Range.h"
|
||
|
13 years ago
|
#include "Magnum.h"
|
||
|
|
#include "OpenGL.h"
|
||
|
14 years ago
|
|
||
|
|
namespace Magnum {
|
||
|
|
|
||
|
13 years ago
|
/**
|
||
|
13 years ago
|
@brief Mask for framebuffer clearing
|
||
|
|
|
||
|
13 years ago
|
@see @ref AbstractFramebuffer, @ref FramebufferClearMask
|
||
|
13 years ago
|
*/
|
||
|
13 years ago
|
enum class FramebufferClear: GLbitfield {
|
||
|
|
Color = GL_COLOR_BUFFER_BIT, /**< Color */
|
||
|
|
Depth = GL_DEPTH_BUFFER_BIT, /**< Depth value */
|
||
|
|
Stencil = GL_STENCIL_BUFFER_BIT /**< Stencil value */
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
13 years ago
|
@brief Mask for clearing
|
||
|
|
|
||
|
13 years ago
|
@see @ref AbstractFramebuffer::clear()
|
||
|
13 years ago
|
*/
|
||
|
13 years ago
|
typedef Containers::EnumSet<FramebufferClear, GLbitfield,
|
||
|
13 years ago
|
GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT> FramebufferClearMask;
|
||
|
|
|
||
|
|
/**
|
||
|
13 years ago
|
@brief Mask for framebuffer blitting
|
||
|
|
|
||
|
13 years ago
|
@see @ref AbstractFramebuffer, @ref FramebufferBlitMask
|
||
|
13 years ago
|
@requires_gl30 %Extension @extension{ARB,framebuffer_object}
|
||
|
|
@requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
|
||
|
|
@es_extension{NV,framebuffer_blit}
|
||
|
13 years ago
|
@todo Remove redundant `%Buffer`
|
||
|
13 years ago
|
*/
|
||
|
13 years ago
|
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 */
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
13 years ago
|
@brief Mask for framebuffer blitting
|
||
|
|
|
||
|
13 years ago
|
@see @ref AbstractFramebuffer::blit()
|
||
|
13 years ago
|
@requires_gl30 %Extension @extension{ARB,framebuffer_object}
|
||
|
|
@requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
|
||
|
|
@es_extension{NV,framebuffer_blit}
|
||
|
|
*/
|
||
|
13 years ago
|
typedef Containers::EnumSet<FramebufferBlit, GLbitfield,
|
||
|
13 years ago
|
GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT> FramebufferBlitMask;
|
||
|
|
|
||
|
|
/**
|
||
|
13 years ago
|
@brief %Framebuffer blit filtering
|
||
|
|
|
||
|
13 years ago
|
@see @ref AbstractFramebuffer::blit()
|
||
|
13 years ago
|
@requires_gl30 %Extension @extension{ARB,framebuffer_object}
|
||
|
|
@requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
|
||
|
|
@es_extension{NV,framebuffer_blit}
|
||
|
|
*/
|
||
|
13 years ago
|
enum class FramebufferBlitFilter: GLenum {
|
||
|
|
Nearest = GL_NEAREST, /**< Nearest neighbor filtering */
|
||
|
|
Linear = GL_LINEAR /**< Linear interpolation filtering */
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
13 years ago
|
@brief Target for binding framebuffer
|
||
|
|
|
||
|
13 years ago
|
@see @ref DefaultFramebuffer::bind(), @ref Framebuffer::bind()
|
||
|
13 years ago
|
@requires_gl30 %Extension @extension{ARB,framebuffer_object}
|
||
|
|
*/
|
||
|
13 years ago
|
enum class FramebufferTarget: GLenum {
|
||
|
|
/**
|
||
|
|
* For reading only.
|
||
|
|
* @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_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. */
|
||
|
|
};
|
||
|
|
|
||
|
14 years ago
|
/**
|
||
|
|
@brief Base for default and named framebuffers
|
||
|
|
|
||
|
13 years ago
|
See @ref DefaultFramebuffer and @ref Framebuffer for more information.
|
||
|
14 years ago
|
|
||
|
13 years ago
|
@section AbstractFramebuffer-performance-optimization Performance optimizations and security
|
||
|
14 years ago
|
|
||
|
14 years ago
|
The engine tracks currently bound framebuffer and current viewport to avoid
|
||
|
|
unnecessary calls to @fn_gl{BindFramebuffer} and @fn_gl{Viewport} when
|
||
|
13 years ago
|
switching framebuffers. %Framebuffer limits and implementation-defined values
|
||
|
|
(such as @ref maxViewportSize()) are cached, so repeated queries don't result
|
||
|
|
in repeated @fn_gl{Get} calls.
|
||
|
14 years ago
|
|
||
|
13 years ago
|
If @extension{ARB,robustness} is available, @ref read() operations are
|
||
|
|
protected from buffer overflow.
|
||
|
13 years ago
|
@todo @extension{ARB,viewport_array} (and `GL_MAX_VIEWPORTS`)
|
||
|
14 years ago
|
*/
|
||
|
|
class MAGNUM_EXPORT AbstractFramebuffer {
|
||
|
14 years ago
|
friend class Context;
|
||
|
|
|
||
|
14 years ago
|
public:
|
||
|
13 years ago
|
/** @todo `GL_IMPLEMENTATION_COLOR_READ_FORMAT`, `GL_IMPLEMENTATION_COLOR_READ_TYPE`, seems to be depending on currently bound FB (aargh) (@extension{ARB,ES2_compatibility}). */
|
||
|
13 years ago
|
|
||
|
|
/**
|
||
|
|
* @brief Max supported viewport size
|
||
|
|
*
|
||
|
|
* The result is cached, repeated queries don't result in repeated
|
||
|
|
* OpenGL calls.
|
||
|
|
* @see @ref setViewport(), @fn_gl{Get} with @def_gl{MAX_VIEWPORT_DIMS}
|
||
|
|
*/
|
||
|
|
static Vector2i maxViewportSize();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Max supported draw buffer count
|
||
|
|
*
|
||
|
|
* The result is cached, repeated queries don't result in repeated
|
||
|
|
* OpenGL calls. If ES extension @extension{NV,draw_buffers} is not
|
||
|
|
* available, returns `0`.
|
||
|
|
* @see @ref DefaultFramebuffer::mapForDraw(), @ref Framebuffer::mapForDraw(),
|
||
|
|
* @fn_gl{Get} with @def_gl{MAX_DRAW_BUFFERS}
|
||
|
|
*/
|
||
|
|
static Int maxDrawBuffers();
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
/**
|
||
|
|
* @brief Max supported dual-source draw buffer count
|
||
|
|
*
|
||
|
|
* The result is cached, repeated queries don't result in repeated
|
||
|
|
* OpenGL calls. If extension @extension{ARB,blend_func_extended} is
|
||
|
|
* not available, returns `0`.
|
||
|
|
* @see @ref DefaultFramebuffer::mapForDraw(), @ref Framebuffer::mapForDraw(),
|
||
|
|
* @fn_gl{Get} with @def_gl{MAX_DUAL_SOURCE_DRAW_BUFFERS}
|
||
|
|
* @requires_gl Multiple blending inputs are not available in
|
||
|
|
* OpenGL ES.
|
||
|
|
*/
|
||
|
|
static Int maxDualSourceDrawBuffers();
|
||
|
|
#endif
|
||
|
|
|
||
|
14 years ago
|
/**
|
||
|
|
* @brief Copy block of pixels
|
||
|
|
* @param source Source framebuffer
|
||
|
|
* @param destination Destination framebuffer
|
||
|
14 years ago
|
* @param sourceRectangle Source rectangle
|
||
|
|
* @param destinationRectangle Destination rectangle
|
||
|
14 years ago
|
* @param mask Which buffers to perform blit operation on
|
||
|
|
* @param filter Interpolation filter
|
||
|
|
*
|
||
|
13 years ago
|
* Binds @p source framebuffer to @ref FramebufferTarget::Read and
|
||
|
|
* @p destination framebuffer to @ref FramebufferTarget::Draw and
|
||
|
|
* performs blitting operation. See @ref DefaultFramebuffer::mapForRead(),
|
||
|
|
* @ref Framebuffer::mapForRead(), @ref DefaultFramebuffer::mapForDraw()
|
||
|
|
* and @ref Framebuffer::mapForDraw() for specifying particular buffers
|
||
|
|
* for blitting operation.
|
||
|
14 years ago
|
* @see @fn_gl{BlitFramebuffer}
|
||
|
13 years ago
|
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
|
||
|
|
* @es_extension{NV,framebuffer_blit}
|
||
|
13 years ago
|
* @todo NaCl exports `BlitFramebufferEXT` (although no such extension
|
||
|
|
* exists for ES)
|
||
|
14 years ago
|
*/
|
||
|
13 years ago
|
static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
|
||
|
14 years ago
|
|
||
|
|
/**
|
||
|
|
* @brief Copy block of pixels
|
||
|
|
* @param source Source framebuffer
|
||
|
|
* @param destination Destination framebuffer
|
||
|
14 years ago
|
* @param rectangle Source and destination rectangle
|
||
|
14 years ago
|
* @param mask Which buffers to perform blit operation on
|
||
|
|
*
|
||
|
|
* Convenience alternative to above function when source rectangle is
|
||
|
|
* the same as destination rectangle. As the image is copied
|
||
|
|
* pixel-by-pixel, no interpolation is needed and thus
|
||
|
13 years ago
|
* @ref FramebufferBlitFilter::Nearest filtering is used by default.
|
||
|
14 years ago
|
* @see @fn_gl{BlitFramebuffer}
|
||
|
13 years ago
|
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
|
||
|
|
* @es_extension{NV,framebuffer_blit}
|
||
|
14 years ago
|
*/
|
||
|
13 years ago
|
static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& rectangle, FramebufferBlitMask mask) {
|
||
|
13 years ago
|
blit(source, destination, rectangle, rectangle, mask, FramebufferBlitFilter::Nearest);
|
||
|
14 years ago
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
14 years ago
|
* @brief Bind framebuffer for rendering
|
||
|
14 years ago
|
*
|
||
|
14 years ago
|
* Binds the framebuffer and updates viewport to saved dimensions.
|
||
|
13 years ago
|
* @see @ref setViewport(), @ref DefaultFramebuffer::mapForRead(),
|
||
|
|
* @ref Framebuffer::mapForRead(), @ref DefaultFramebuffer::mapForDraw(),
|
||
|
|
* @ref Framebuffer::mapForDraw(), @fn_gl{BindFramebuffer},
|
||
|
14 years ago
|
* @fn_gl{Viewport}
|
||
|
13 years ago
|
* @todo Bind internally to ReadDraw if separate binding points are not
|
||
|
|
* supported
|
||
|
14 years ago
|
*/
|
||
|
13 years ago
|
void bind(FramebufferTarget target);
|
||
|
14 years ago
|
|
||
|
14 years ago
|
/** @brief Viewport rectangle */
|
||
|
13 years ago
|
Range2Di viewport() const { return _viewport; }
|
||
|
14 years ago
|
|
||
|
14 years ago
|
/**
|
||
|
14 years ago
|
* @brief Set viewport
|
||
|
13 years ago
|
* @return Reference to self (for method chaining)
|
||
|
14 years ago
|
*
|
||
|
13 years ago
|
* Saves the viewport to be used at later time in @ref bind(). If the
|
||
|
14 years ago
|
* framebuffer is currently bound, updates the viewport to given
|
||
|
14 years ago
|
* rectangle.
|
||
|
13 years ago
|
* @see @ref maxViewportSize(), @fn_gl{Viewport}
|
||
|
14 years ago
|
*/
|
||
|
13 years ago
|
AbstractFramebuffer& setViewport(const Range2Di& rectangle);
|
||
|
14 years ago
|
|
||
|
|
/**
|
||
|
|
* @brief Clear specified buffers in framebuffer
|
||
|
|
* @param mask Which buffers to clear
|
||
|
|
*
|
||
|
14 years ago
|
* To improve performance you can also use
|
||
|
13 years ago
|
* @ref DefaultFramebuffer::invalidate() / @ref Framebuffer::invalidate()
|
||
|
|
* instead of clearing given buffer if you will not use it anymore or
|
||
|
|
* fully overwrite it later.
|
||
|
|
* @see @ref Renderer::setClearColor(), @ref Renderer::setClearDepth(),
|
||
|
|
* @ref Renderer::setClearStencil(), @fn_gl{BindFramebuffer},
|
||
|
14 years ago
|
* @fn_gl{Clear}
|
||
|
14 years ago
|
*/
|
||
|
13 years ago
|
void clear(FramebufferClearMask mask);
|
||
|
14 years ago
|
|
||
|
|
/**
|
||
|
|
* @brief Read block of pixels from framebuffer to image
|
||
|
|
* @param offset Offset in the framebuffer
|
||
|
|
* @param size %Image size
|
||
|
|
* @param image %Image where to put the data
|
||
|
|
*
|
||
|
13 years ago
|
* %Image parameters like format and type of pixel data are taken from
|
||
|
|
* given image.
|
||
|
|
*
|
||
|
13 years ago
|
* If @extension{ARB,robustness} is available, the operation is
|
||
|
|
* protected from buffer overflow.
|
||
|
|
* @see @fn_gl{BindFramebuffer}, @fn_gl{ReadPixels} or
|
||
|
|
* @fn_gl_extension{ReadnPixels,ARB,robustness}
|
||
|
14 years ago
|
*/
|
||
|
13 years ago
|
void read(const Vector2i& offset, const Vector2i& size, Image2D& image);
|
||
|
14 years ago
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES2
|
||
|
|
/**
|
||
|
|
* @brief Read block of pixels from framebuffer to buffer image
|
||
|
|
* @param offset Offset in the framebuffer
|
||
|
|
* @param size %Image size
|
||
|
|
* @param image %Buffer image where to put the data
|
||
|
|
* @param usage %Buffer usage
|
||
|
|
*
|
||
|
13 years ago
|
* See @ref read(const Vector2i&, const Vector2i&, Image2D&) for more
|
||
|
13 years ago
|
* information.
|
||
|
14 years ago
|
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES 2.0.
|
||
|
|
*/
|
||
|
13 years ago
|
void read(const Vector2i& offset, const Vector2i& size, BufferImage2D& image, BufferUsage usage);
|
||
|
14 years ago
|
#endif
|
||
|
|
|
||
|
13 years ago
|
#ifdef DOXYGEN_GENERATING_OUTPUT
|
||
|
|
private:
|
||
|
|
#else
|
||
|
14 years ago
|
protected:
|
||
|
13 years ago
|
#endif
|
||
|
13 years ago
|
explicit AbstractFramebuffer() = default;
|
||
|
13 years ago
|
~AbstractFramebuffer() = default;
|
||
|
|
|
||
|
13 years ago
|
void MAGNUM_LOCAL bindInternal(FramebufferTarget target);
|
||
|
|
FramebufferTarget MAGNUM_LOCAL bindInternal();
|
||
|
14 years ago
|
void MAGNUM_LOCAL setViewportInternal();
|
||
|
|
|
||
|
13 years ago
|
#ifdef MAGNUM_TARGET_GLES2
|
||
|
13 years ago
|
static MAGNUM_LOCAL FramebufferTarget readTarget;
|
||
|
|
static MAGNUM_LOCAL FramebufferTarget drawTarget;
|
||
|
13 years ago
|
#endif
|
||
|
14 years ago
|
|
||
|
13 years ago
|
typedef GLenum(AbstractFramebuffer::*CheckStatusImplementation)(FramebufferTarget);
|
||
|
|
static CheckStatusImplementation checkStatusImplementation;
|
||
|
|
|
||
|
14 years ago
|
typedef void(AbstractFramebuffer::*DrawBuffersImplementation)(GLsizei, const GLenum*);
|
||
|
|
static MAGNUM_LOCAL DrawBuffersImplementation drawBuffersImplementation;
|
||
|
|
|
||
|
|
typedef void(AbstractFramebuffer::*DrawBufferImplementation)(GLenum);
|
||
|
|
static DrawBufferImplementation drawBufferImplementation;
|
||
|
|
|
||
|
|
typedef void(AbstractFramebuffer::*ReadBufferImplementation)(GLenum);
|
||
|
|
static ReadBufferImplementation readBufferImplementation;
|
||
|
14 years ago
|
|
||
|
14 years ago
|
void MAGNUM_LOCAL invalidateImplementation(GLsizei count, GLenum* attachments);
|
||
|
13 years ago
|
void MAGNUM_LOCAL invalidateImplementation(GLsizei count, GLenum* attachments, const Range2Di& rectangle);
|
||
|
14 years ago
|
|
||
|
14 years ago
|
GLuint _id;
|
||
|
13 years ago
|
Range2Di _viewport;
|
||
|
14 years ago
|
|
||
|
|
private:
|
||
|
13 years ago
|
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context& context);
|
||
|
14 years ago
|
|
||
|
13 years ago
|
GLenum MAGNUM_LOCAL checkStatusImplementationDefault(FramebufferTarget target);
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
GLenum MAGNUM_LOCAL checkStatusImplementationDSA(FramebufferTarget target);
|
||
|
|
#endif
|
||
|
|
|
||
|
14 years ago
|
void MAGNUM_LOCAL drawBuffersImplementationDefault(GLsizei count, const GLenum* buffers);
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
void MAGNUM_LOCAL drawBuffersImplementationDSA(GLsizei count, const GLenum* buffers);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
void MAGNUM_LOCAL drawBufferImplementationDefault(GLenum buffer);
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
void MAGNUM_LOCAL drawBufferImplementationDSA(GLenum buffer);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
void MAGNUM_LOCAL readBufferImplementationDefault(GLenum buffer);
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
void MAGNUM_LOCAL readBufferImplementationDSA(GLenum buffer);
|
||
|
|
#endif
|
||
|
13 years ago
|
|
||
|
13 years ago
|
typedef void(*ReadImplementation)(const Vector2i&, const Vector2i&, ColorFormat, ColorType, std::size_t, GLvoid*);
|
||
|
|
static void MAGNUM_LOCAL readImplementationDefault(const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
|
||
|
|
static void MAGNUM_LOCAL readImplementationRobustness(const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
|
||
|
13 years ago
|
static ReadImplementation MAGNUM_LOCAL readImplementation;
|
||
|
14 years ago
|
};
|
||
|
|
|
||
|
13 years ago
|
CORRADE_ENUMSET_OPERATORS(FramebufferClearMask)
|
||
|
|
CORRADE_ENUMSET_OPERATORS(FramebufferBlitMask)
|
||
|
14 years ago
|
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|