Browse Source

First-class WebGL support, part 5: reduced framebuffer functionality.

pull/107/head
Vladimír Vondruš 11 years ago
parent
commit
c77848ffac
  1. 27
      src/Magnum/AbstractFramebuffer.cpp
  2. 51
      src/Magnum/AbstractFramebuffer.h
  3. 4
      src/Magnum/DefaultFramebuffer.cpp
  4. 122
      src/Magnum/DefaultFramebuffer.h
  5. 24
      src/Magnum/Framebuffer.cpp
  6. 156
      src/Magnum/Framebuffer.h
  7. 46
      src/Magnum/Implementation/FramebufferState.cpp
  8. 13
      src/Magnum/Implementation/FramebufferState.h
  9. 10
      src/Magnum/Renderbuffer.cpp
  10. 32
      src/Magnum/Renderbuffer.h

27
src/Magnum/AbstractFramebuffer.cpp

@ -49,9 +49,14 @@ Vector2i AbstractFramebuffer::maxViewportSize() {
Int AbstractFramebuffer::maxDrawBuffers() {
#ifdef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_WEBGL
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::draw_buffers>() &&
!Context::current()->isExtensionSupported<Extensions::GL::NV::draw_buffers>())
return 0;
#else
if(!Context::current()->isExtensionSupported<Extensions::GL::WEBGL::draw_buffers>())
return 0;
#endif
#endif
GLint& value = Context::current()->state().framebuffer->maxDrawBuffers;
@ -187,9 +192,11 @@ FramebufferTarget AbstractFramebuffer::bindImplementationDefault() {
return FramebufferTarget::Read;
}
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) {
Context::current()->state().framebuffer->blitImplementation(source, destination, sourceRectangle, destinationRectangle, mask, filter);
}
#endif
#ifndef MAGNUM_TARGET_GLES2
void AbstractFramebuffer::blitImplementationDefault(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) {
@ -204,9 +211,9 @@ void AbstractFramebuffer::blitImplementationDSA(AbstractFramebuffer& source, Abs
}
#endif
#else
#elif !defined(MAGNUM_TARGET_WEBGL)
void AbstractFramebuffer::blitImplementationANGLE(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
source.bindInternal(FramebufferTarget::Read);
destination.bindInternal(FramebufferTarget::Draw);
glBlitFramebufferANGLE(sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), GLbitfield(mask), GLenum(filter));
@ -222,7 +229,7 @@ void AbstractFramebuffer::blitImplementationANGLE(AbstractFramebuffer& source, A
}
void AbstractFramebuffer::blitImplementationNV(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
source.bindInternal(FramebufferTarget::Read);
destination.bindInternal(FramebufferTarget::Draw);
glBlitFramebufferNV(sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), GLbitfield(mask), GLenum(filter));
@ -380,7 +387,7 @@ void AbstractFramebuffer::drawBuffersImplementationDSAEXT(GLsizei count, const G
void AbstractFramebuffer::drawBuffersImplementationEXT(GLsizei count, const GLenum* buffers) {
bindInternal(FramebufferTarget::Draw);
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
glDrawBuffersEXT(count, buffers);
#else
static_cast<void>(count);
@ -389,10 +396,11 @@ void AbstractFramebuffer::drawBuffersImplementationEXT(GLsizei count, const GLen
#endif
}
#ifndef MAGNUM_TARGET_WEBGL
void AbstractFramebuffer::drawBuffersImplementationNV(GLsizei count, const GLenum* buffers) {
bindInternal(FramebufferTarget::Draw);
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
glDrawBuffersNV(count, buffers);
#else
static_cast<void>(count);
@ -401,6 +409,7 @@ void AbstractFramebuffer::drawBuffersImplementationNV(GLsizei count, const GLenu
#endif
}
#endif
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::drawBufferImplementationDefault(GLenum buffer) {
@ -419,18 +428,20 @@ void AbstractFramebuffer::drawBufferImplementationDSAEXT(GLenum buffer) {
}
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void AbstractFramebuffer::readBufferImplementationDefault(GLenum buffer) {
bindInternal(FramebufferTarget::Read);
#ifndef MAGNUM_TARGET_GLES2
glReadBuffer(buffer);
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#elif !defined(CORRADE_TARGET_NACL)
glReadBufferNV(buffer);
#else
static_cast<void>(buffer);
CORRADE_ASSERT_UNREACHABLE();
#endif
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::readBufferImplementationDSA(const GLenum buffer) {
@ -447,10 +458,11 @@ void AbstractFramebuffer::readImplementationDefault(const Range2Di& rectangle, c
glReadPixels(rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY(), GLenum(format), GLenum(type), data);
}
#ifndef MAGNUM_TARGET_WEBGL
void AbstractFramebuffer::readImplementationRobustness(const Range2Di& rectangle, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) {
#ifndef MAGNUM_TARGET_GLES
glReadnPixelsARB(rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY(), GLenum(format), GLenum(type), dataSize, data);
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#elif !defined(CORRADE_TARGET_NACL)
glReadnPixelsEXT(rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY(), GLenum(format), GLenum(type), dataSize, data);
#else
static_cast<void>(rectangle);
@ -461,5 +473,6 @@ void AbstractFramebuffer::readImplementationRobustness(const Range2Di& rectangle
CORRADE_ASSERT_UNREACHABLE();
#endif
}
#endif
}

51
src/Magnum/AbstractFramebuffer.h

@ -61,13 +61,15 @@ typedef Containers::EnumSet<FramebufferClear,
typedef Containers::EnumSet<FramebufferClear> FramebufferClearMask;
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
@brief Mask for framebuffer blitting
@see @ref AbstractFramebuffer, @ref FramebufferBlitMask
@requires_gl30 Extension @extension{ARB,framebuffer_object}
@requires_gles30 Extension @es_extension{ANGLE,framebuffer_blit} or
@es_extension{NV,framebuffer_blit} in OpenGL ES 2.0
@es_extension{NV,framebuffer_blit} in OpenGL ES 2.0.
@requires_webgl20 Framebuffer blit is not available in WebGL 1.0.
*/
enum class FramebufferBlit: GLbitfield {
#ifdef MAGNUM_BUILD_DEPRECATED
@ -98,7 +100,8 @@ enum class FramebufferBlit: GLbitfield {
@see @ref AbstractFramebuffer::blit()
@requires_gl30 Extension @extension{ARB,framebuffer_object}
@requires_gles30 Extension @es_extension{ANGLE,framebuffer_blit} or
@es_extension{NV,framebuffer_blit} in OpenGL ES 2.0
@es_extension{NV,framebuffer_blit} in OpenGL ES 2.0.
@requires_webgl20 Framebuffer blit is not available in WebGL 1.0.
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
typedef Containers::EnumSet<FramebufferBlit,
@ -113,12 +116,14 @@ typedef Containers::EnumSet<FramebufferBlit> FramebufferBlitMask;
@see @ref AbstractFramebuffer::blit()
@requires_gl30 Extension @extension{ARB,framebuffer_object}
@requires_gles30 Extension @es_extension{ANGLE,framebuffer_blit} or
@es_extension{NV,framebuffer_blit} in OpenGL ES 2.0
@es_extension{NV,framebuffer_blit} in OpenGL ES 2.0.
@requires_webgl20 Framebuffer blit is not available in WebGL 1.0.
*/
enum class FramebufferBlitFilter: GLenum {
Nearest = GL_NEAREST, /**< Nearest neighbor filtering */
Linear = GL_LINEAR /**< Linear interpolation filtering */
};
#endif
/**
@brief Framebuffer target
@ -130,15 +135,19 @@ enum class FramebufferTarget: GLenum {
/** Frambebuffer reading target */
#ifndef MAGNUM_TARGET_GLES2
Read = GL_READ_FRAMEBUFFER,
#else
#elif !defined(MAGNUM_TARGET_WEBGL)
Read = GL_READ_FRAMEBUFFER_APPLE,
#else
Read,
#endif
/** Framebuffer drawing target */
#ifndef MAGNUM_TARGET_GLES2
Draw = GL_DRAW_FRAMEBUFFER,
#else
#elif !defined(MAGNUM_TARGET_WEBGL)
Draw = GL_DRAW_FRAMEBUFFER_APPLE,
#else
Draw,
#endif
#ifdef MAGNUM_BUILD_DEPRECATED
@ -149,8 +158,10 @@ enum class FramebufferTarget: GLenum {
ReadDraw CORRADE_DEPRECATED_ENUM("use FramebufferTarget::Draw instead") =
#ifndef MAGNUM_TARGET_GLES2
GL_DRAW_FRAMEBUFFER
#else
#elif !defined(MAGNUM_TARGET_WEBGL)
GL_DRAW_FRAMEBUFFER_APPLE
#else
1
#endif
#endif
};
@ -197,8 +208,10 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @brief Max supported draw buffer count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. In OpenGL ES 2.0, if neither @es_extension{EXT,draw_buffers}
* nor @es_extension{NV,draw_buffers} is available, returns `0`.
* OpenGL calls. If neither @es_extension{EXT,draw_buffers} nor
* @es_extension{NV,draw_buffers} is available in OpenGL ES 2.0 and
* @webgl_extension{WEBGL,draw_buffers} is not available in WebGL 1.0,
* returns `0`.
* @see @ref DefaultFramebuffer::mapForDraw(), @ref Framebuffer::mapForDraw(),
* @fn_gl{Get} with @def_gl{MAX_DRAW_BUFFERS}
*/
@ -214,11 +227,12 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @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.
* OpenGL ES or WebGL.
*/
static Int maxDualSourceDrawBuffers();
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Copy block of pixels
* @param source Source framebuffer
@ -238,7 +252,8 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @see @fn_gl2{BlitNamedFramebuffer,BlitFramebuffer}, eventually
* @fn_gl{BlitFramebuffer}
* @requires_gles30 Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit} in OpenGL ES 2.0
* @es_extension{NV,framebuffer_blit} in OpenGL ES 2.0.
* @requires_webgl20 Framebuffer blit is not available in WebGL 1.0.
* @todo NaCl exports `BlitFramebufferEXT` (although no such extension
* exists for ES)
*/
@ -255,6 +270,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& rectangle, FramebufferBlitMask mask) {
blit(source, destination, rectangle, rectangle, mask, FramebufferBlitFilter::Nearest);
}
#endif
/**
* @brief Bind framebuffer for drawing
@ -352,7 +368,10 @@ class MAGNUM_EXPORT AbstractFramebuffer {
*
* See @ref read(const Vector2i&, const Vector2i&, Image2D&) for more
* information.
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES 2.0.
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @requires_webgl20 Pixel buffer objects are not available in WebGL
* 1.0.
* @todo Make it more flexible (usable with
* @extension{ARB,buffer_storage}, avoiding relocations...)
*/
@ -403,7 +422,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
#ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL blitImplementationDSA(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
#endif
#else
#elif !defined(MAGNUM_TARGET_WEBGL)
static void MAGNUM_LOCAL blitImplementationANGLE(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
static void MAGNUM_LOCAL blitImplementationNV(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
#endif
@ -432,8 +451,10 @@ class MAGNUM_EXPORT AbstractFramebuffer {
#endif
#else
void MAGNUM_LOCAL drawBuffersImplementationEXT(GLsizei count, const GLenum* buffers);
#ifndef MAGNUM_TARGET_WEBGL
void MAGNUM_LOCAL drawBuffersImplementationNV(GLsizei count, const GLenum* buffers);
#endif
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL drawBufferImplementationDefault(GLenum buffer);
@ -441,14 +462,18 @@ class MAGNUM_EXPORT AbstractFramebuffer {
void MAGNUM_LOCAL drawBufferImplementationDSAEXT(GLenum buffer);
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void MAGNUM_LOCAL readBufferImplementationDefault(GLenum buffer);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL readBufferImplementationDSA(GLenum buffer);
void MAGNUM_LOCAL readBufferImplementationDSAEXT(GLenum buffer);
#endif
static void MAGNUM_LOCAL readImplementationDefault(const Range2Di& rectangle, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
#ifndef MAGNUM_TARGET_WEBGL
static void MAGNUM_LOCAL readImplementationRobustness(const Range2Di& rectangle, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
#endif
void MAGNUM_LOCAL invalidateImplementationNoOp(GLsizei, const GLenum*);
void MAGNUM_LOCAL invalidateImplementationDefault(GLsizei count, const GLenum* attachments);
@ -466,7 +491,9 @@ class MAGNUM_EXPORT AbstractFramebuffer {
};
CORRADE_ENUMSET_OPERATORS(FramebufferClearMask)
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
CORRADE_ENUMSET_OPERATORS(FramebufferBlitMask)
#endif
}

4
src/Magnum/DefaultFramebuffer.cpp

@ -71,6 +71,7 @@ DefaultFramebuffer& DefaultFramebuffer::mapForDraw(const DrawAttachment attachme
return *this;
}
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
DefaultFramebuffer& DefaultFramebuffer::mapForRead(const ReadAttachment attachment) {
(this->*Context::current()->state().framebuffer->readBufferImplementation)(GLenum(attachment));
return *this;
@ -84,6 +85,7 @@ void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment
(this->*Context::current()->state().framebuffer->invalidateImplementation)(attachments.size(), _attachments);
}
#endif
#ifndef MAGNUM_TARGET_GLES2
void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle) {
@ -117,7 +119,9 @@ Debug operator<<(Debug debug, const DefaultFramebuffer::Status value) {
switch(value) {
#define _c(value) case DefaultFramebuffer::Status::value: return debug << "DefaultFramebuffer::Status::" #value;
_c(Complete)
#ifndef MAGNUM_TARGET_WEBGL
_c(Undefined)
#endif
#undef _c
}

122
src/Magnum/DefaultFramebuffer.h

@ -73,8 +73,8 @@ more involved usage, usage of non-default or multiple framebuffers.
See also @ref AbstractFramebuffer-performance-optimization "relevant section in AbstractFramebuffer".
If on desktop GL and either @extension{ARB,direct_state_access} (part of OpenGL
4.5) or @extension{EXT,direct_state_access} is available, functions
If either @extension{ARB,direct_state_access} (part of OpenGL 4.5) or
@extension{EXT,direct_state_access} desktop extension is available, functions
@ref checkStatus(), @ref mapForDraw(), @ref mapForRead() and @ref invalidate()
use DSA to avoid unnecessary calls to @fn_gl{BindFramebuffer}. See their
respective documentation for more information.
@ -93,16 +93,19 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/** The framebuffer is complete */
Complete = GL_FRAMEBUFFER_COMPLETE,
#ifndef MAGNUM_TARGET_WEBGL
/**
* The default framebuffer does not exist.
* @requires_gles30 Extension @es_extension{OES,surfaceless_context}
* in OpenGL ES 2.0
* in OpenGL ES 2.0.
* @requires_gles Surfaceless context is not available in WebGL.
*/
#ifndef MAGNUM_TARGET_GLES2
Undefined = GL_FRAMEBUFFER_UNDEFINED
#else
Undefined = GL_FRAMEBUFFER_UNDEFINED_OES
#endif
#endif
};
/**
@ -111,6 +114,8 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @see @ref mapForDraw()
* @requires_gles30 Extension @es_extension{EXT,draw_buffers} in OpenGL
* ES 2.0.
* @requires_webgl20 Extension @webgl_extension{WEBGL,draw_buffers} in
* WebGL 1.0.
*/
enum class DrawAttachment: GLenum {
/** Don't use the output. */
@ -119,25 +124,29 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
#ifndef MAGNUM_TARGET_GLES
/**
* Write output to front left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES
* or WebGL.
*/
FrontLeft = GL_FRONT_LEFT,
/**
* Write output to front right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES
* or WebGL.
*/
FrontRight = GL_FRONT_RIGHT,
/**
* Write output to back left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES
* or WebGL.
*/
BackLeft = GL_BACK_LEFT,
/**
* Write output to back right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES
* or WebGL.
*/
BackRight = GL_BACK_RIGHT,
#endif
@ -145,8 +154,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/**
* Write output to back buffer.
*
* On desktop OpenGL, this is equal to
* @ref DrawAttachment::BackLeft.
* On desktop OpenGL this is equal to @ref DrawAttachment::BackLeft.
*/
#ifdef MAGNUM_TARGET_GLES
Back = GL_BACK
@ -155,12 +163,15 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
#endif
};
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Read attachment
*
* @see @ref mapForRead()
* @requires_gles30 Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
* in OpenGL ES 2.0
* in OpenGL ES 2.0.
* @requires_webgl20 Framebuffer read mapping is not available in WebGL
* 1.0.
*/
enum class ReadAttachment: GLenum {
/** Don't read from any buffer */
@ -169,37 +180,43 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
#ifndef MAGNUM_TARGET_GLES
/**
* Read from front left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES or
* WebGL.
*/
FrontLeft = GL_FRONT_LEFT,
/**
* Read from front right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES or
* WebGL.
*/
FrontRight = GL_FRONT_RIGHT,
/**
* Read from back left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES or
* WebGL.
*/
BackLeft = GL_BACK_LEFT,
/**
* Read from back right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES or
* WebGL.
*/
BackRight = GL_BACK_RIGHT,
/**
* Read from left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES or
* WebGL.
*/
Left = GL_LEFT,
/**
* Read from right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES or
* WebGL.
*/
Right = GL_RIGHT,
#endif
@ -210,6 +227,8 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/**
* Read from front buffer.
* @requires_es_extension Extension @es_extension2{NV,read_buffer_front,GL_NV_read_buffer}
* @requires_gles Reading from front buffer is not available in
* WebGL.
*/
Front = GL_FRONT
@ -219,7 +238,8 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/**
* Read from front and back buffer.
* @requires_gl In OpenGL ES you must specify either
* @ref ReadAttachment::Front or @ref ReadAttachment::Back.
* @ref ReadAttachment::Front or @ref ReadAttachment::Back. In
* WebGL there is only @ref ReadAttachment::Back.
*/
FrontAndBack = GL_FRONT_AND_BACK
#endif
@ -230,32 +250,38 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
*
* @see @ref invalidate()
* @requires_gl43 Extension @extension{ARB,invalidate_subdata}
* @requires_gles30 Extension @es_extension{EXT,discard_framebuffer}
* in OpenGL ES 2.0
* @requires_gles30 Extension @es_extension{EXT,discard_framebuffer} in
* OpenGL ES 2.0.
* @requires_webgl20 Framebuffer invalidation is not available in WebGL
* 1.0.
*/
enum class InvalidationAttachment: GLenum {
#ifndef MAGNUM_TARGET_GLES
/**
* Invalidate front left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES
* or WebGL.
*/
FrontLeft = GL_FRONT_LEFT,
/**
* Invalidate front right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES
* or WebGL.
*/
FrontRight = GL_FRONT_RIGHT,
/**
* Invalidate back left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES
* or WebGL.
*/
BackLeft = GL_BACK_LEFT,
/**
* Invalidate back right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
* @requires_gl Stereo rendering is not available in OpenGL ES
* or WebGL.
*/
BackRight = GL_BACK_RIGHT,
#endif
@ -281,6 +307,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
Stencil = GL_STENCIL_EXT
#endif
};
#endif
explicit MAGNUM_LOCAL DefaultFramebuffer();
@ -300,13 +327,15 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @brief Check framebuffer status
* @param target Target for which to check the status
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
*
* On OpenGL ES 2.0, if none of @es_extension{APPLE,framebuffer_multisample},
* @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit}
* is available, the @p target parameter is ignored.
* The @p target parameter is ignored on OpenGL ES 2.0 if none of
* @es_extension{APPLE,framebuffer_multisample}, @es_extension{ANGLE,framebuffer_blit}
* or @es_extension{NV,framebuffer_blit} is available and also on WebGL
* 1.0.
* @see @fn_gl2{CheckNamedFramebufferStatus,CheckFramebufferStatus},
* @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{CheckFramebufferStatus}
@ -327,15 +356,18 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* {MyShader::NormalOutput, DefaultFramebuffer::DrawAttachment::None}});
* @endcode
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref maxDrawBuffers(), @ref maxDualSourceDrawBuffers(),
* @ref mapForRead(), @fn_gl2{NamedFramebufferDrawBuffers,DrawBuffers},
* @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{DrawBuffers}
* @requires_gles30 Extension @es_extension{EXT,draw_buffers} in OpenGL
* ES 2.0.
* @requires_webgl20 Extension @webgl_extension{WEBGL,draw_buffers} in
* WebGL 1.0.
*/
DefaultFramebuffer& mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments);
@ -347,31 +379,38 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* Similar to above function, can be used in cases when shader has
* only one (unnamed) output.
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref mapForRead(), @fn_gl2{NamedFramebufferDrawBuffer,DrawBuffer},
* @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{DrawBuffer} or
* @fn_gl{DrawBuffers} in OpenGL ES 3.0
* @requires_gles30 Extension @es_extension{EXT,draw_buffers} in OpenGL
* ES 2.0.
* @requires_webgl20 Extension @webgl_extension{WEBGL,draw_buffers} in
* WebGL 1.0.
*/
DefaultFramebuffer& mapForDraw(DrawAttachment attachment);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Map given attachment for reading
* @param attachment Buffer attachment
* @return Reference to self (for method chaining)
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref mapForDraw(), @fn_gl2{NamedFramebufferReadBuffer,ReadBuffer},
* @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{ReadBuffer}
* @requires_gles30 Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
* in OpenGL ES 2.0
* in OpenGL ES 2.0.
* @requires_webgl20 Framebuffer read mapping is not available in WebGL
* 1.0.
*/
DefaultFramebuffer& mapForRead(ReadAttachment attachment);
@ -389,8 +428,11 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* eventually @fn_gl{InvalidateFramebuffer} or
* @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer}
* on OpenGL ES 2.0
* @requires_webgl20 Framebuffer invalidation is not available in WebGL
* 1.0.
*/
void invalidate(std::initializer_list<InvalidationAttachment> attachments);
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
@ -408,6 +450,8 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* eventually @fn_gl{InvalidateSubFramebuffer}
* @requires_gles30 Use @ref invalidate(std::initializer_list<InvalidationAttachment>)
* in OpenGL ES 2.0 instead.
* @requires_webgl20 Framebuffer invalidation is not available in WebGL
* 1.0.
*/
void invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle);
#endif

24
src/Magnum/Framebuffer.cpp

@ -36,7 +36,9 @@
#ifndef MAGNUM_TARGET_GLES2
#include "Magnum/BufferImage.h"
#ifndef MAGNUM_TARGET_WEBGL
#include "Magnum/MultisampleTexture.h"
#endif
#include "Magnum/TextureArray.h"
#endif
@ -56,17 +58,27 @@ namespace Magnum {
const Framebuffer::DrawAttachment Framebuffer::DrawAttachment::None = Framebuffer::DrawAttachment(GL_NONE);
const Framebuffer::BufferAttachment Framebuffer::BufferAttachment::Depth = Framebuffer::BufferAttachment(GL_DEPTH_ATTACHMENT);
const Framebuffer::BufferAttachment Framebuffer::BufferAttachment::Stencil = Framebuffer::BufferAttachment(GL_STENCIL_ATTACHMENT);
/** @todo where to get GL_DEPTH_STENCIL_ATTACHMENT for WebGL? */
#ifndef MAGNUM_TARGET_GLES2
const Framebuffer::BufferAttachment Framebuffer::BufferAttachment::DepthStencil = Framebuffer::BufferAttachment(GL_DEPTH_STENCIL_ATTACHMENT);
#elif defined(MAGNUM_TARGET_WEBGL)
const Framebuffer::BufferAttachment Framebuffer::BufferAttachment::DepthStencil = Framebuffer::BufferAttachment(0x821A);
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
const Framebuffer::InvalidationAttachment Framebuffer::InvalidationAttachment::Depth = Framebuffer::InvalidationAttachment(GL_DEPTH_ATTACHMENT);
const Framebuffer::InvalidationAttachment Framebuffer::InvalidationAttachment::Stencil = Framebuffer::InvalidationAttachment(GL_STENCIL_ATTACHMENT);
#endif
Int Framebuffer::maxColorAttachments() {
#ifdef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_WEBGL
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::draw_buffers>() &&
!Context::current()->isExtensionSupported<Extensions::GL::NV::fbo_color_attachments>())
return 0;
#else
if(!Context::current()->isExtensionSupported<Extensions::GL::WEBGL::draw_buffers>())
return 0;
#endif
#endif
GLint& value = Context::current()->state().framebuffer->maxColorAttachments;
@ -166,6 +178,7 @@ Framebuffer& Framebuffer::mapForDraw(const DrawAttachment attachment) {
return *this;
}
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
Framebuffer& Framebuffer::mapForRead(const ColorAttachment attachment) {
(this->*Context::current()->state().framebuffer->readBufferImplementation)(GLenum(attachment));
return *this;
@ -190,6 +203,7 @@ void Framebuffer::invalidate(std::initializer_list<InvalidationAttachment> attac
(this->*Context::current()->state().framebuffer->invalidateSubImplementation)(attachments.size(), _attachments, rectangle);
}
#endif
#endif
Framebuffer& Framebuffer::attachRenderbuffer(const BufferAttachment attachment, Renderbuffer& renderbuffer) {
(this->*Context::current()->state().framebuffer->renderbufferImplementation)(attachment, renderbuffer);
@ -215,7 +229,7 @@ Framebuffer& Framebuffer::attachTexture(const BufferAttachment attachment, Recta
}
#endif
#ifndef MAGNUM_TARGET_GLES2
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
Framebuffer& Framebuffer::attachTexture(const BufferAttachment attachment, MultisampleTexture2D& texture) {
(this->*Context::current()->state().framebuffer->texture2DImplementation)(attachment, GL_TEXTURE_2D_MULTISAMPLE, texture.id(), 0);
return *this;
@ -227,10 +241,12 @@ Framebuffer& Framebuffer::attachCubeMapTexture(const BufferAttachment attachment
return *this;
}
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
Framebuffer& Framebuffer::attachTextureLayer(Framebuffer::BufferAttachment attachment, Texture3D& texture, Int level, Int layer) {
(this->*Context::current()->state().framebuffer->textureLayerImplementation)(attachment, texture.id(), level, layer);
return *this;
}
#endif
#ifndef MAGNUM_TARGET_GLES
Framebuffer& Framebuffer::attachTextureLayer(Framebuffer::BufferAttachment attachment, Texture1DArray& texture, Int level, Int layer) {
@ -322,10 +338,11 @@ void Framebuffer::texture2DImplementationDSAEXT(BufferAttachment attachment, GLe
}
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void Framebuffer::textureLayerImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint mipLevel, GLint layer) {
#ifndef MAGNUM_TARGET_GLES2
glFramebufferTextureLayer(GLenum(bindInternal()), GLenum(attachment), textureId, mipLevel, layer);
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#elif !defined(CORRADE_TARGET_NACL)
glFramebufferTexture3DOES(GLenum(bindInternal()), GLenum(attachment), GL_TEXTURE_3D_OES, textureId, mipLevel, layer);
#else
static_cast<void>(attachment);
@ -335,6 +352,7 @@ void Framebuffer::textureLayerImplementationDefault(BufferAttachment attachment,
CORRADE_ASSERT_UNREACHABLE();
#endif
}
#endif
#ifndef MAGNUM_TARGET_GLES
void Framebuffer::textureLayerImplementationDSA(const BufferAttachment attachment, const GLuint textureId, const GLint mipLevel, const GLint layer) {
@ -359,7 +377,9 @@ Debug operator<<(Debug debug, const Framebuffer::Status value) {
_c(IncompleteReadBuffer)
#endif
_c(Unsupported)
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
_c(IncompleteMultisample)
#endif
#ifndef MAGNUM_TARGET_GLES
_c(IncompleteLayerTargets)
#endif

156
src/Magnum/Framebuffer.h

@ -93,8 +93,8 @@ void drawEvent() {
See also @ref AbstractFramebuffer-performance-optimization "relevant section in AbstractFramebuffer".
If on desktop GL and either @extension{ARB,direct_state_access} (part of OpenGL
4.5) or @extension{EXT,direct_state_access} is available, functions
If either @extension{ARB,direct_state_access} (part of OpenGL 4.5) or
@extension{EXT,direct_state_access} desktop extension is available, functions
@ref checkStatus(), @ref mapForDraw(), @ref mapForRead(), @ref invalidate(),
@ref attachRenderbuffer(), @ref attachTexture(), @ref attachCubeMapTexture()
and @ref attachTextureLayer() use DSA to avoid unnecessary calls to
@ -117,6 +117,8 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @es_extension{NV,draw_buffers} for @ref mapForDraw() and
* extension @es_extension{NV,fbo_color_attachments} for `attach*()`
* in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{WEBGL,draw_buffers} in
* WebGL 1.0.
*/
class ColorAttachment {
friend Framebuffer;
@ -142,6 +144,8 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @see @ref mapForDraw()
* @requires_gles30 Extension @es_extension{EXT,draw_buffers} or
* @es_extension{NV,draw_buffers} in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{WEBGL,draw_buffers} in
* WebGL 1.0.
*/
class DrawAttachment {
public:
@ -168,6 +172,8 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @ref attachCubeMapTexture(), @ref attachTextureLayer()
* @requires_gles30 Extension @es_extension{EXT,draw_buffers} or
* @es_extension{NV,fbo_color_attachments} in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{WEBGL,draw_buffers} in
* WebGL 1.0.
*/
class MAGNUM_EXPORT BufferAttachment {
public:
@ -177,7 +183,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
/** @brief Stencil buffer */
static const BufferAttachment Stencil;
#ifndef MAGNUM_TARGET_GLES2
#if !defined(MAGNUM_TARGET_GLES2) || defined(MAGNUM_TARGET_WEBGL)
/**
* @brief Both depth and stencil buffer
*
@ -203,13 +209,16 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
GLenum attachment;
};
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Invalidation attachment
*
* @see @ref invalidate()
* @requires_gl43 Extension @extension{ARB,invalidate_subdata}
* @requires_gles30 Extension @es_extension{EXT,discard_framebuffer}
* in OpenGL ES 2.0
* @requires_gles30 Extension @es_extension{EXT,discard_framebuffer} in
* OpenGL ES 2.0.
* @requires_webgl20 Framebuffer invalidation is not available in WebGL
* 1.0.
*/
class InvalidationAttachment {
public:
@ -231,6 +240,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
GLenum attachment;
};
#endif
/**
* @brief Status
@ -251,13 +261,13 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
/** @todo Why exactly this is not needed? */
/**
* No object attached to any draw color attachment points
* @requires_gl Not available in OpenGL ES.
* @requires_gl Not available in OpenGL ES or WebGL.
*/
IncompleteDrawBuffer = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER,
/**
* No object attached to read color attachment point
* @requires_gl Not available in OpenGL ES.
* @requires_gl Not available in OpenGL ES or WebGL.
*/
IncompleteReadBuffer = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER,
#endif
@ -274,18 +284,21 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @requires_gles30 Extension @es_extension{ANGLE,framebuffer_multisample},
* @es_extension{APPLE,framebuffer_multisample},
* @es_extension{EXT,multisampled_render_to_texture} or
* @es_extension{NV,framebuffer_multisample} in OpenGL ES 2.0
* @es_extension{NV,framebuffer_multisample} in OpenGL ES 2.0.
* @requires_webgl20 Multisample framebuffers are not available in
* WebGL 1.0.
*/
#ifndef MAGNUM_TARGET_GLES2
IncompleteMultisample = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
#else
#elif !defined(MAGNUM_TARGET_WEBGL)
IncompleteMultisample = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE,
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* Mismatched layered color attachments
* @requires_gl Geometry shaders are not available in OpenGL ES.
* @requires_gl Geometry shaders are not available in OpenGL ES or
* WebGL.
*/
IncompleteLayerTargets = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS
#endif
@ -297,9 +310,10 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @brief Max supported color attachment count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. In OpenGL ES 2.0, if neither @es_extension{EXT,draw_buffers}
* nor @es_extension{NV,fbo_color_attachments} extension is available,
* returns `0`.
* OpenGL calls. If neither @es_extension{EXT,draw_buffers} nor
* @es_extension{NV,fbo_color_attachments} extension is available in
* OpenGL ES 2.0 and @webgl_extension{WEBGL,draw_buffers} is not
* available in WebGL 1.0, returns `0`.
* @see @ref mapForDraw(), @fn_gl{Get} with @def_gl{MAX_COLOR_ATTACHMENTS}
*/
static Int maxColorAttachments();
@ -308,7 +322,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @brief Constructor
*
* Generates new OpenGL framebuffer object. If @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) is not supported, the framebuffer is created on
* (part of OpenGL 4.5) is not available, the framebuffer is created on
* first use.
* @see @ref setViewport(), @fn_gl{CreateFramebuffers}, eventually
* @fn_gl{GenFramebuffers}
@ -379,13 +393,15 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @brief Check framebuffer status
* @param target Target for which check the status
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
*
* On OpenGL ES 2.0, if none of @es_extension{APPLE,framebuffer_multisample},
* @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit}
* is available, the @p target parameter is ignored.
* The @p target parameter is ignored on OpenGL ES 2.0 if none of
* @es_extension{APPLE,framebuffer_multisample}, @es_extension{ANGLE,framebuffer_blit}
* or @es_extension{NV,framebuffer_blit} is available and also on WebGL
* 1.0.
* @see @fn_gl2{CheckNamedFramebufferStatus,CheckFramebufferStatus},
* @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{CheckFramebufferStatus}
@ -405,9 +421,10 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* {MyShader::NormalOutput, Framebuffer::DrawAttachment::None}});
* @endcode
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref maxDrawBuffers(), @ref maxDualSourceDrawBuffers(),
* @ref maxColorAttachments(), @ref mapForRead(),
* @fn_gl2{NamedFramebufferDrawBuffers,DrawBuffers},
@ -415,6 +432,8 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* eventually @fn_gl{BindFramebuffer} and @fn_gl{DrawBuffers}
* @requires_gles30 Extension @es_extension{EXT,draw_buffers} or
* @es_extension{NV,draw_buffers} in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{WEBGL,draw_buffers} in
* WebGL 1.0.
*/
Framebuffer& mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments);
@ -426,9 +445,10 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* Similar to above function, can be used in cases when shader has
* only one (unnamed) output.
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref maxColorAttachments(), @ref mapForRead(),
* @fn_gl2{NamedFramebufferDrawBuffer,DrawBuffer},
* @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access},
@ -436,22 +456,28 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @fn_gl{DrawBuffers} in OpenGL ES)
* @requires_gles30 Extension @es_extension{EXT,draw_buffers} or
* @es_extension{NV,draw_buffers} in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{WEBGL,draw_buffers} in
* WebGL 1.0.
*/
Framebuffer& mapForDraw(DrawAttachment attachment);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Map given color attachment for reading
* @param attachment Color attachment
* @return Reference to self (for method chaining)
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref mapForDraw(), @fn_gl2{NamedFramebufferReadBuffer,ReadBuffer},
* @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{ReadBuffer}
* @requires_gles30 Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
* in OpenGL ES 2.0
* in OpenGL ES 2.0.
* @requires_webgl20 Framebuffer read mapping is not available in WebGL
* 1.0.
*/
Framebuffer& mapForRead(ColorAttachment attachment);
@ -469,8 +495,11 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* eventually @fn_gl{InvalidateFramebuffer} or
* @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer}
* on OpenGL ES 2.0
* @requires_webgl20 Framebuffer invalidation is not available in WebGL
* 1.0.
*/
void invalidate(std::initializer_list<InvalidationAttachment> attachments);
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
@ -488,6 +517,8 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* eventually @fn_gl{InvalidateSubFramebuffer}
* @requires_gles30 Use @ref invalidate(std::initializer_list<InvalidationAttachment>)
* in OpenGL ES 2.0 instead.
* @requires_webgl20 Framebuffer invalidation is not available in WebGL
* 1.0.
*/
void invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle);
#endif
@ -498,9 +529,10 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @param renderbuffer Renderbuffer
* @return Reference to self (for method chaining)
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
* @see @fn_gl2{NamedFramebufferRenderbuffer,FramebufferRenderbuffer},
* @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{FramebufferRenderbuffer}
@ -515,14 +547,16 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @param level Mip level
* @return Reference to self (for method chaining)
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref attachCubeMapTexture(), @fn_gl2{NamedFramebufferTexture,FramebufferTexture},
* @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and
* @fn_gl2{FramebufferTexture1D,FramebufferTexture}
* @requires_gl Only 2D and 3D textures are available in OpenGL ES.
* @requires_gl Only 2D and 3D textures are available in OpenGL ES and
* WebGL.
*/
Framebuffer& attachTexture(BufferAttachment attachment, Texture1D& texture, Int level);
#endif
@ -534,9 +568,10 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @param level Mip level
* @return Reference to self (for method chaining)
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref attachCubeMapTexture(), @fn_gl2{NamedFramebufferTexture,FramebufferTexture},
* @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and
@ -547,16 +582,18 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
#ifndef MAGNUM_TARGET_GLES
/** @overload
* @requires_gl31 Extension @extension{ARB,texture_rectangle}
* @requires_gl Rectangle textures are not available in OpenGL ES.
* @requires_gl Rectangle textures are not available in OpenGL ES and
* WebGL.
*/
Framebuffer& attachTexture(BufferAttachment attachment, RectangleTexture& texture);
#endif
#ifndef MAGNUM_TARGET_GLES2
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/** @overload
* @requires_gl32 Extension @extension{ARB,texture_multisample}
* @requires_gles31 Multisample textures are not available in OpenGL ES
* 3.0 and older.
* @requires_gles Multisample textures are not available in WebGL.
*/
Framebuffer& attachTexture(BufferAttachment attachment, MultisampleTexture2D& texture);
#endif
@ -569,15 +606,17 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @param level Mip level
* @return Reference to self (for method chaining)
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref attachTexture2D(), @fn_gl2{NamedFramebufferTexture,FramebufferTexture},
* @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl2{FramebufferTexture2D,FramebufferTexture}
*/
Framebuffer& attachCubeMapTexture(BufferAttachment attachment, CubeMapTexture& texture, CubeMapTexture::Coordinate coordinate, Int level);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Attach texture layer to given buffer
* @param attachment Buffer attachment
@ -586,23 +625,27 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @param layer Layer
* @return Reference to self (for method chaining)
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the framebuffer is bound before the operation (if not
* already).
* @see @fn_gl2{NamedFramebufferTextureLayer,FramebufferTextureLayer},
* @fn_gl_extension{NamedFramebufferTextureLayer,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl2{FramebufferTextureLayer,FramebufferTexture}
* or @fn_gles_extension{FramebufferTexture3D,OES,texture_3D} in
* OpenGL ES 2.0
* @requires_gles30 Extension @es_extension{OES,texture_3D} in OpenGL
* ES 2.0
* ES 2.0.
* @requires_webgl20 Only 2D textures are available in WebGL 1.0.
*/
Framebuffer& attachTextureLayer(BufferAttachment attachment, Texture3D& texture, Int level, Int layer);
#endif
#ifndef MAGNUM_TARGET_GLES
/** @overload
* @requires_gl30 Extension @extension{EXT,texture_array}
* @requires_gl Only 2D array textures are available in OpenGL ES.
* @requires_gl Only 2D array textures are available in OpenGL ES and
* WebGL.
*/
Framebuffer& attachTextureLayer(BufferAttachment attachment, Texture1DArray& texture, Int level, Int layer);
#endif
@ -610,7 +653,8 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
#ifndef MAGNUM_TARGET_GLES2
/** @overload
* @requires_gl30 Extension @extension{EXT,texture_array}
* @requires_gles30 Array textures are not available in OpenGL ES 2.0
* @requires_gles30 Array textures are not available in OpenGL ES 2.0.
* @requires_webgl20 Array textures are not available in WebGL 1.0.
*/
Framebuffer& attachTextureLayer(BufferAttachment attachment, Texture2DArray& texture, Int level, Int layer);
#endif
@ -618,13 +662,15 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
#ifndef MAGNUM_TARGET_GLES
/** @overload
* @requires_gl40 Extension @extension{ARB,texture_cube_map_array}
* @requires_gl Cube map texture arrays are not available in OpenGL ES.
* @requires_gl Cube map texture arrays are not available in OpenGL ES
* or WebGL.
*/
Framebuffer& attachTextureLayer(BufferAttachment attachment, CubeMapTextureArray& texture, Int level, Int layer);
/** @overload
* @requires_gl32 Extension @extension{ARB,texture_multisample}
* @requires_gl Multisample array textures are not available in OpenGL ES.
* @requires_gl Multisample array textures are not available in OpenGL
* ES or WebGL.
*/
Framebuffer& attachTextureLayer(BufferAttachment attachment, MultisampleTexture2DArray& texture, Int layer);
#endif
@ -646,6 +692,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
*/
CORRADE_DEPRECATED("use one of attachTexture() overloads instead") Framebuffer& attachTexture2D(BufferAttachment attachment, Texture2D& texture, Int level);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @copybrief attachTextureLayer()
* @deprecated Use one of @ref attachTextureLayer() overloads instead.
@ -654,6 +701,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
return attachTextureLayer(attachment, texture, level, layer);
}
#endif
#endif
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
@ -695,7 +743,9 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
void MAGNUM_LOCAL texture2DImplementationDSAEXT(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level);
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void MAGNUM_LOCAL textureLayerImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL textureLayerImplementationDSA(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer);
void MAGNUM_LOCAL textureLayerImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer);

46
src/Magnum/Implementation/FramebufferState.cpp

@ -35,7 +35,10 @@ namespace Magnum { namespace Implementation {
constexpr const Range2Di FramebufferState::DisengagedViewport;
FramebufferState::FramebufferState(Context& context, std::vector<std::string>& extensions): readBinding{0}, drawBinding{0}, renderbufferBinding{0}, maxDrawBuffers{0}, maxColorAttachments{0}, maxRenderbufferSize{0}, maxSamples{0},
FramebufferState::FramebufferState(Context& context, std::vector<std::string>& extensions): readBinding{0}, drawBinding{0}, renderbufferBinding{0}, maxDrawBuffers{0}, maxColorAttachments{0}, maxRenderbufferSize{0},
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
maxSamples{0},
#endif
#ifndef MAGNUM_TARGET_GLES
maxDualSourceDrawBuffers{0},
#endif
@ -96,14 +99,18 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
#ifndef MAGNUM_TARGET_GLES
drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDefault;
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDefault;
#endif
renderbufferImplementation = &Framebuffer::renderbufferImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
texture1DImplementation = &Framebuffer::texture1DImplementationDefault;
#endif
texture2DImplementation = &Framebuffer::texture2DImplementationDefault;
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
textureLayerImplementation = &Framebuffer::textureLayerImplementationDefault;
#endif
renderbufferStorageImplementation = &Renderbuffer::storageImplementationDefault;
}
@ -112,10 +119,13 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Framebuffer binding and checking on ES2 */
/* Optimistically set separate binding targets and check if one of the
extensions providing them is available */
#ifndef MAGNUM_TARGET_WEBGL
bindImplementation = &Framebuffer::bindImplementationDefault;
bindInternalImplementation = &Framebuffer::bindImplementationDefault;
#endif
checkStatusImplementation = &Framebuffer::checkStatusImplementationDefault;
#ifndef MAGNUM_TARGET_WEBGL
if(context.isExtensionSupported<Extensions::GL::ANGLE::framebuffer_blit>()) {
extensions.push_back(Extensions::GL::ANGLE::framebuffer_blit::string());
@ -138,7 +148,9 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
bindInternalImplementation = &Framebuffer::bindImplementationSingle;
checkStatusImplementation = &Framebuffer::checkStatusImplementationSingle;
}
#endif
#ifndef MAGNUM_TARGET_WEBGL
/* Framebuffer draw mapping on ES2 */
if(context.isExtensionSupported<Extensions::GL::EXT::draw_buffers>()) {
extensions.push_back(Extensions::GL::EXT::draw_buffers::string());
@ -149,9 +161,17 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationNV;
} else drawBuffersImplementation = nullptr;
#else
if(context.isExtensionSupported<Extensions::GL::WEBGL::draw_buffers>()) {
extensions.push_back(Extensions::GL::WEBGL::draw_buffers::string());
/* The EXT implementation is exposed in Emscripten */
drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationEXT;
} else drawBuffersImplementation = nullptr;
#endif
#endif
/* Framebuffer reading implementation */
/* Framebuffer reading implementation in desktop/ES */
#ifndef MAGNUM_TARGET_WEBGL
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::robustness>())
#else
@ -167,6 +187,11 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
readImplementation = &AbstractFramebuffer::readImplementationRobustness;
} else readImplementation = &AbstractFramebuffer::readImplementationDefault;
/* Framebuffer reading in WebGL */
#else
readImplementation = &AbstractFramebuffer::readImplementationDefault;
#endif
/* Multisample renderbuffer storage implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
@ -181,7 +206,7 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
} else
#endif
{
#ifdef MAGNUM_TARGET_GLES2
#if defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(context.isExtensionSupported<Extensions::GL::ANGLE::framebuffer_multisample>()) {
extensions.push_back(Extensions::GL::ANGLE::framebuffer_multisample::string());
@ -191,7 +216,7 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationNV;
} else renderbufferStorageMultisampleImplementation = nullptr;
#else
#elif !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationDefault;
#endif
}
@ -216,7 +241,7 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
}
/* Framebuffer invalidation implementation on ES2 */
#elif defined(MAGNUM_TARGET_GLES2)
#elif defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(context.isExtensionSupported<Extensions::GL::EXT::discard_framebuffer>()) {
extensions.push_back(Extensions::GL::EXT::discard_framebuffer::string());
@ -226,7 +251,7 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
}
/* Always available on ES3 */
#else
#elif !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
invalidateImplementation = &AbstractFramebuffer::invalidateImplementationDefault;
invalidateSubImplementation = &AbstractFramebuffer::invalidateImplementationDefault;
#endif
@ -240,7 +265,7 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
} else blitImplementation = &AbstractFramebuffer::blitImplementationDefault;
/* Blit implementation on ES2 */
#elif defined(MAGNUM_TARGET_GLES2)
#elif defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(context.isExtensionSupported<Extensions::GL::ANGLE::framebuffer_blit>()) {
extensions.push_back(Extensions::GL::ANGLE::framebuffer_blit::string());
blitImplementation = &AbstractFramebuffer::blitImplementationANGLE;
@ -252,9 +277,14 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
} else blitImplementation = nullptr;
/* Always available on ES3 */
#else
#elif !defined(MAGNUM_TARGET_WEBGL)
blitImplementation = &AbstractFramebuffer::blitImplementationDefault;
#endif
#if defined(MAGNUM_TARGET_WEBGL) && !defined(MAGNUM_TARGET_GLES2)
static_cast<void>(context);
static_cast<void>(extensions);
#endif
}
void FramebufferState::reset() {

13
src/Magnum/Implementation/FramebufferState.h

@ -39,14 +39,18 @@ struct FramebufferState {
void reset();
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void(*blitImplementation)(AbstractFramebuffer&, AbstractFramebuffer&, const Range2Di&, const Range2Di&, FramebufferBlitMask, FramebufferBlitFilter);
#endif
GLenum(AbstractFramebuffer::*checkStatusImplementation)(FramebufferTarget);
void(AbstractFramebuffer::*drawBuffersImplementation)(GLsizei, const GLenum*);
#ifndef MAGNUM_TARGET_GLES
void(AbstractFramebuffer::*drawBufferImplementation)(GLenum);
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void(AbstractFramebuffer::*readBufferImplementation)(GLenum);
void(AbstractFramebuffer::*invalidateImplementation)(GLsizei, const GLenum*);
#endif
#ifndef MAGNUM_TARGET_GLES2
void(AbstractFramebuffer::*invalidateSubImplementation)(GLsizei, const GLenum*, const Range2Di&);
#endif
@ -61,16 +65,23 @@ struct FramebufferState {
void(Framebuffer::*texture1DImplementation)(Framebuffer::BufferAttachment, GLuint, GLint);
#endif
void(Framebuffer::*texture2DImplementation)(Framebuffer::BufferAttachment, GLenum, GLuint, GLint);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void(Framebuffer::*textureLayerImplementation)(Framebuffer::BufferAttachment, GLuint, GLint, GLint);
#endif
void(Renderbuffer::*createRenderbufferImplementation)();
void(Renderbuffer::*renderbufferStorageImplementation)(RenderbufferFormat, const Vector2i&);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void(Renderbuffer::*renderbufferStorageMultisampleImplementation)(GLsizei, RenderbufferFormat, const Vector2i&);
#endif
void(*readImplementation)(const Range2Di&, ColorFormat, ColorType, std::size_t, GLvoid*);
GLuint readBinding, drawBinding, renderbufferBinding;
GLint maxDrawBuffers, maxColorAttachments, maxRenderbufferSize, maxSamples;
GLint maxDrawBuffers, maxColorAttachments, maxRenderbufferSize;
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
GLint maxSamples;
#endif
#ifndef MAGNUM_TARGET_GLES
GLint maxDualSourceDrawBuffers;
#endif

10
src/Magnum/Renderbuffer.cpp

@ -46,6 +46,7 @@ Int Renderbuffer::maxSize() {
return value;
}
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
Int Renderbuffer::maxSamples() {
#ifdef MAGNUM_TARGET_GLES2
if(!Context::current()->isExtensionSupported<Extensions::GL::ANGLE::framebuffer_multisample>() && !Context::current()->isExtensionSupported<Extensions::GL::NV::framebuffer_multisample>())
@ -65,6 +66,7 @@ Int Renderbuffer::maxSamples() {
return value;
}
#endif
Renderbuffer::Renderbuffer() {
(this->*Context::current()->state().framebuffer->createRenderbufferImplementation)();
@ -121,9 +123,11 @@ void Renderbuffer::setStorage(const RenderbufferFormat internalFormat, const Vec
(this->*Context::current()->state().framebuffer->renderbufferStorageImplementation)(internalFormat, size);
}
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void Renderbuffer::setStorageMultisample(const Int samples, const RenderbufferFormat internalFormat, const Vector2i& size) {
(this->*Context::current()->state().framebuffer->renderbufferStorageMultisampleImplementation)(samples, internalFormat, size);
}
#endif
void Renderbuffer::bind() {
GLuint& binding = Context::current()->state().framebuffer->renderbufferBinding;
@ -157,9 +161,9 @@ void Renderbuffer::storageMultisampleImplementationDefault(const GLsizei samples
bind();
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GLenum(internalFormat), size.x(), size.y());
}
#else
#elif !defined(MAGNUM_TARGET_WEBGL)
void Renderbuffer::storageMultisampleImplementationANGLE(const GLsizei samples, const RenderbufferFormat internalFormat, const Vector2i& size) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
bind();
glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, samples, GLenum(internalFormat), size.x(), size.y());
#else
@ -171,7 +175,7 @@ void Renderbuffer::storageMultisampleImplementationANGLE(const GLsizei samples,
}
void Renderbuffer::storageMultisampleImplementationNV(const GLsizei samples, const RenderbufferFormat internalFormat, const Vector2i& size) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
#ifndef CORRADE_TARGET_NACL
bind();
glRenderbufferStorageMultisampleNV(GL_RENDERBUFFER, samples, GLenum(internalFormat), size.x(), size.y());
#else

32
src/Magnum/Renderbuffer.h

@ -51,8 +51,8 @@ The engine tracks currently bound renderbuffer to avoid unnecessary calls to
implementation-defined values (such as @ref maxSize()) are cached, so repeated
queries don't result in repeated @fn_gl{Get} calls.
If not on OpenGL ES and either @extension{ARB,direct_state_access} (part of
OpenGL 4.5) or @extension{EXT,direct_state_access} is available, functions
If either @extension{ARB,direct_state_access} (part of OpenGL 4.5) or
@extension{EXT,direct_state_access} desktop extension is available, functions
@ref setStorage() and @ref setStorageMultisample() use DSA to avoid unnecessary
calls to @fn_gl{BindRenderbuffer}. See their respective documentation for more
information.
@ -73,6 +73,7 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
*/
static Int maxSize();
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Max supported sample count
*
@ -81,14 +82,17 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
* @es_extension{ANGLE,framebuffer_multisample} /
* @es_extension{NV,framebuffer_multisample} is available, returns `0`.
* @see @ref setStorageMultisample(), @fn_gl{Get} with @def_gl{MAX_SAMPLES}
* @requires_webgl20 Multisample framebuffers are not available in
* WebGL 1.0.
*/
static Int maxSamples();
#endif
/**
* @brief Constructor
*
* Generates new OpenGL renderbuffer object. If @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) is not supported, the renderbuffer is created
* (part of OpenGL 4.5) is not available, the renderbuffer is created
* on first use.
* @see @fn_gl{CreateRenderbuffers}, eventually @fn_gl{GenRenderbuffers}
*/
@ -159,34 +163,40 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
* @param internalFormat Internal format
* @param size Renderbuffer size
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the renderbuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the renderbuffer is bound before the operation (if not
* already).
* @see @ref maxSize(), @fn_gl2{NamedRenderbufferStorage,RenderbufferStorage},
* @fn_gl_extension{NamedRenderbufferStorage,EXT,direct_state_access},
* eventually @fn_gl{BindRenderbuffer} and @fn_gl{RenderbufferStorage}
*/
void setStorage(RenderbufferFormat internalFormat, const Vector2i& size);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Set multisample renderbuffer storage
* @param samples Sample count
* @param internalFormat Internal format
* @param size Renderbuffer size
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the renderbuffer is bound before the operation (if not already).
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the renderbuffer is bound before the operation (if not
* already).
* @see @ref maxSize(), @ref maxSamples(),
* @fn_gl2{NamedRenderbufferStorageMultisample,RenderbufferStorageMultisample},
* @fn_gl_extension{NamedRenderbufferStorageMultisample,EXT,direct_state_access},
* eventually @fn_gl{BindRenderbuffer} and @fn_gl{RenderbufferStorageMultisample}
* @requires_gles30 Extension @es_extension{ANGLE,framebuffer_multisample}
* or @es_extension{NV,framebuffer_multisample} in OpenGL ES 2.0
* or @es_extension{NV,framebuffer_multisample} in OpenGL ES 2.0.
* @requires_webgl20 Multisample framebuffers are not available in
* WebGL 1.0.
* @todo How about @es_extension{APPLE,framebuffer_multisample}?
* @todo NaCl has @fn_gl_extension{RenderbufferStorageMultisample,EXT,multisampled_render_to_texture}
*/
void setStorageMultisample(Int samples, RenderbufferFormat internalFormat, const Vector2i& size);
#endif
private:
void MAGNUM_LOCAL createImplementationDefault();
@ -212,7 +222,7 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size);
#endif
#else
#elif !defined(MAGNUM_TARGET_WEBGL)
void MAGNUM_LOCAL storageMultisampleImplementationANGLE(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageMultisampleImplementationNV(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size);
#endif

Loading…
Cancel
Save