From c77848ffac63ba69878d9a56ecb1fe0178640ffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 18 May 2015 23:38:33 +0200 Subject: [PATCH] First-class WebGL support, part 5: reduced framebuffer functionality. --- src/Magnum/AbstractFramebuffer.cpp | 27 ++- src/Magnum/AbstractFramebuffer.h | 51 ++++-- src/Magnum/DefaultFramebuffer.cpp | 4 + src/Magnum/DefaultFramebuffer.h | 122 +++++++++----- src/Magnum/Framebuffer.cpp | 24 ++- src/Magnum/Framebuffer.h | 156 ++++++++++++------ .../Implementation/FramebufferState.cpp | 46 +++++- src/Magnum/Implementation/FramebufferState.h | 13 +- src/Magnum/Renderbuffer.cpp | 10 +- src/Magnum/Renderbuffer.h | 32 ++-- 10 files changed, 349 insertions(+), 136 deletions(-) diff --git a/src/Magnum/AbstractFramebuffer.cpp b/src/Magnum/AbstractFramebuffer.cpp index e63d66cae..ca59de6f5 100644 --- a/src/Magnum/AbstractFramebuffer.cpp +++ b/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() && !Context::current()->isExtensionSupported()) return 0; + #else + if(!Context::current()->isExtensionSupported()) + 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(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(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(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(rectangle); @@ -461,5 +473,6 @@ void AbstractFramebuffer::readImplementationRobustness(const Range2Di& rectangle CORRADE_ASSERT_UNREACHABLE(); #endif } +#endif } diff --git a/src/Magnum/AbstractFramebuffer.h b/src/Magnum/AbstractFramebuffer.h index 0e3c1dfbc..574c3d41b 100644 --- a/src/Magnum/AbstractFramebuffer.h +++ b/src/Magnum/AbstractFramebuffer.h @@ -61,13 +61,15 @@ typedef Containers::EnumSet 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 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 } diff --git a/src/Magnum/DefaultFramebuffer.cpp b/src/Magnum/DefaultFramebuffer.cpp index 3ec5a2d88..649bcac99 100644 --- a/src/Magnum/DefaultFramebuffer.cpp +++ b/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*Context::current()->state().framebuffer->invalidateImplementation)(attachments.size(), _attachments); } +#endif #ifndef MAGNUM_TARGET_GLES2 void DefaultFramebuffer::invalidate(std::initializer_list 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 } diff --git a/src/Magnum/DefaultFramebuffer.h b/src/Magnum/DefaultFramebuffer.h index 83d9d942c..104567fae 100644 --- a/src/Magnum/DefaultFramebuffer.h +++ b/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> 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 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) * in OpenGL ES 2.0 instead. + * @requires_webgl20 Framebuffer invalidation is not available in WebGL + * 1.0. */ void invalidate(std::initializer_list attachments, const Range2Di& rectangle); #endif diff --git a/src/Magnum/Framebuffer.cpp b/src/Magnum/Framebuffer.cpp index 81d7313c1..964b087df 100644 --- a/src/Magnum/Framebuffer.cpp +++ b/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() && !Context::current()->isExtensionSupported()) return 0; + #else + if(!Context::current()->isExtensionSupported()) + 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 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(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 diff --git a/src/Magnum/Framebuffer.h b/src/Magnum/Framebuffer.h index e3c9966f8..95523eea0 100644 --- a/src/Magnum/Framebuffer.h +++ b/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> 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 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) * in OpenGL ES 2.0 instead. + * @requires_webgl20 Framebuffer invalidation is not available in WebGL + * 1.0. */ void invalidate(std::initializer_list 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); diff --git a/src/Magnum/Implementation/FramebufferState.cpp b/src/Magnum/Implementation/FramebufferState.cpp index 8be1483b3..ddb99de72 100644 --- a/src/Magnum/Implementation/FramebufferState.cpp +++ b/src/Magnum/Implementation/FramebufferState.cpp @@ -35,7 +35,10 @@ namespace Magnum { namespace Implementation { constexpr const Range2Di FramebufferState::DisengagedViewport; -FramebufferState::FramebufferState(Context& context, std::vector& extensions): readBinding{0}, drawBinding{0}, renderbufferBinding{0}, maxDrawBuffers{0}, maxColorAttachments{0}, maxRenderbufferSize{0}, maxSamples{0}, +FramebufferState::FramebufferState(Context& context, std::vector& 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& 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& 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.push_back(Extensions::GL::ANGLE::framebuffer_blit::string()); @@ -138,7 +148,9 @@ FramebufferState::FramebufferState(Context& context, std::vector& e bindInternalImplementation = &Framebuffer::bindImplementationSingle; checkStatusImplementation = &Framebuffer::checkStatusImplementationSingle; } + #endif + #ifndef MAGNUM_TARGET_WEBGL /* Framebuffer draw mapping on ES2 */ if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::EXT::draw_buffers::string()); @@ -149,9 +161,17 @@ FramebufferState::FramebufferState(Context& context, std::vector& e drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationNV; } else drawBuffersImplementation = nullptr; + #else + if(context.isExtensionSupported()) { + 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()) #else @@ -167,6 +187,11 @@ FramebufferState::FramebufferState(Context& context, std::vector& 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()) { @@ -181,7 +206,7 @@ FramebufferState::FramebufferState(Context& context, std::vector& e } else #endif { - #ifdef MAGNUM_TARGET_GLES2 + #if defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::ANGLE::framebuffer_multisample::string()); @@ -191,7 +216,7 @@ FramebufferState::FramebufferState(Context& context, std::vector& 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& e } /* Framebuffer invalidation implementation on ES2 */ - #elif defined(MAGNUM_TARGET_GLES2) + #elif defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::EXT::discard_framebuffer::string()); @@ -226,7 +251,7 @@ FramebufferState::FramebufferState(Context& context, std::vector& 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& 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.push_back(Extensions::GL::ANGLE::framebuffer_blit::string()); blitImplementation = &AbstractFramebuffer::blitImplementationANGLE; @@ -252,9 +277,14 @@ FramebufferState::FramebufferState(Context& context, std::vector& 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(context); + static_cast(extensions); + #endif } void FramebufferState::reset() { diff --git a/src/Magnum/Implementation/FramebufferState.h b/src/Magnum/Implementation/FramebufferState.h index 50d612254..a98341de6 100644 --- a/src/Magnum/Implementation/FramebufferState.h +++ b/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 diff --git a/src/Magnum/Renderbuffer.cpp b/src/Magnum/Renderbuffer.cpp index 627454d1d..6e82490e9 100644 --- a/src/Magnum/Renderbuffer.cpp +++ b/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() && !Context::current()->isExtensionSupported()) @@ -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 diff --git a/src/Magnum/Renderbuffer.h b/src/Magnum/Renderbuffer.h index 63d8d2dd4..6bbab41f4 100644 --- a/src/Magnum/Renderbuffer.h +++ b/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