diff --git a/src/AbstractFramebuffer.cpp b/src/AbstractFramebuffer.cpp index bc9b20eb5..73de50537 100644 --- a/src/AbstractFramebuffer.cpp +++ b/src/AbstractFramebuffer.cpp @@ -40,8 +40,10 @@ AbstractFramebuffer::DrawBuffersImplementation AbstractFramebuffer::drawBuffersI AbstractFramebuffer::DrawBufferImplementation AbstractFramebuffer::drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDefault; AbstractFramebuffer::ReadBufferImplementation AbstractFramebuffer::readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDefault; +#ifdef MAGNUM_TARGET_GLES2 FramebufferTarget AbstractFramebuffer::readTarget = FramebufferTarget::ReadDraw; FramebufferTarget AbstractFramebuffer::drawTarget = FramebufferTarget::ReadDraw; +#endif AbstractFramebuffer::~AbstractFramebuffer() {} @@ -81,10 +83,15 @@ FramebufferTarget AbstractFramebuffer::bindInternal() { /* Or bind it, if not already */ state->readBinding = _id; - if(readTarget == FramebufferTarget::ReadDraw) state->drawBinding = _id; + #ifndef MAGNUM_TARGET_GLES2 + glBindFramebuffer(GLenum(FramebufferTarget::Read), _id); + return FramebufferTarget::Read; + #else + if(readTarget == FramebufferTarget::ReadDraw) state->drawBinding = _id; glBindFramebuffer(GLenum(readTarget), _id); return readTarget; + #endif } void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& sourceRectangle, const Rectanglei& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter) { @@ -126,12 +133,20 @@ void AbstractFramebuffer::setViewportInternal() { } void AbstractFramebuffer::clear(FramebufferClearMask mask) { + #ifndef MAGNUM_TARGET_GLES2 + bindInternal(FramebufferTarget::Draw); + #else bindInternal(drawTarget); + #endif glClear(static_cast(mask)); } void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, Image2D* image) { + #ifndef MAGNUM_TARGET_GLES2 + bindInternal(FramebufferTarget::Read); + #else bindInternal(readTarget); + #endif const std::size_t dataSize = image->pixelSize()*size.product(); char* const data = new char[dataSize]; readImplementation(offset, size, image->format(), image->type(), dataSize, data); @@ -140,7 +155,11 @@ void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, Ima #ifndef MAGNUM_TARGET_GLES2 void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, BufferImage2D* image, Buffer::Usage usage) { + #ifndef MAGNUM_TARGET_GLES2 + bindInternal(FramebufferTarget::Read); + #else bindInternal(readTarget); + #endif /* If the buffer doesn't have sufficient size, resize it */ /** @todo Explicitly reset also when buffer usage changes */ if(image->size() != size) @@ -177,13 +196,6 @@ void AbstractFramebuffer::invalidateImplementation(GLsizei count, GLenum* attach void AbstractFramebuffer::initializeContextBasedFunctionality(Context* context) { #ifndef MAGNUM_TARGET_GLES - if(context->isExtensionSupported()) { - Debug() << "AbstractFramebuffer: using" << Extensions::GL::EXT::framebuffer_blit::string() << "features"; - - readTarget = FramebufferTarget::Read; - drawTarget = FramebufferTarget::Draw; - } - if(context->isExtensionSupported()) { Debug() << "AbstractFramebuffer: using" << Extensions::GL::EXT::direct_state_access::string() << "features"; @@ -193,6 +205,32 @@ void AbstractFramebuffer::initializeContextBasedFunctionality(Context* context) } #endif + #ifdef MAGNUM_TARGET_GLES2 + /* Optimistically set separate binding targets and check if one of the + extensions providing them is available */ + readTarget = FramebufferTarget::Read; + drawTarget = FramebufferTarget::Draw; + + if(context->isExtensionSupported()) + Debug() << "AbstractFramebuffer: using" << Extensions::GL::ANGLE::framebuffer_blit::string() << "features"; + + else if(context->isExtensionSupported()) + Debug() << "AbstractFramebuffer: using" << Extensions::GL::APPLE::framebuffer_multisample::string() << "features"; + + else if(context->isExtensionSupported()) + Debug() << "AbstractFramebuffer: using" << Extensions::GL::NV::framebuffer_blit::string() << "features"; + + /* NV_framebuffer_multisample requires NV_framebuffer_blit, which has these + enums. However, on my system only NV_framebuffer_multisample is + supported, but NV_framebuffer_blit isn't. I will hold my breath and + assume these enums are available. */ + else if(context->isExtensionSupported()) + Debug() << "AbstractFramebuffer: using" << Extensions::GL::NV::framebuffer_multisample::string() << "features"; + + /* If no such extension is available, reset back to unified target */ + else readTarget = drawTarget = FramebufferTarget::ReadDraw; + #endif + #ifndef MAGNUM_TARGET_GLES3 #ifndef MAGNUM_TARGET_GLES if(context->isExtensionSupported()) @@ -219,7 +257,11 @@ void AbstractFramebuffer::initializeContextBasedFunctionality(Context* context) void AbstractFramebuffer::drawBuffersImplementationDefault(GLsizei count, const GLenum* buffers) { /** @todo Re-enable when extension wrangler is available for ES2 */ #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES2 + bindInternal(FramebufferTarget::Draw); + #else bindInternal(drawTarget); + #endif glDrawBuffers(count, buffers); #else static_cast(count); @@ -236,7 +278,11 @@ void AbstractFramebuffer::drawBuffersImplementationDSA(GLsizei count, const GLen void AbstractFramebuffer::drawBufferImplementationDefault(GLenum buffer) { /** @todo Re-enable when extension wrangler is available for ES2 */ #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES2 + bindInternal(FramebufferTarget::Draw); + #else bindInternal(drawTarget); + #endif #ifndef MAGNUM_TARGET_GLES3 glDrawBuffer(buffer); #else @@ -256,7 +302,11 @@ void AbstractFramebuffer::drawBufferImplementationDSA(GLenum buffer) { void AbstractFramebuffer::readBufferImplementationDefault(GLenum buffer) { /** @todo Get some extension wrangler instead to avoid undeclared glReadBuffer() on ES2 */ #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES2 + bindInternal(FramebufferTarget::Read); + #else bindInternal(readTarget); + #endif glReadBuffer(buffer); #else static_cast(buffer); diff --git a/src/AbstractFramebuffer.h b/src/AbstractFramebuffer.h index 3e7916dda..cfa47d6be 100644 --- a/src/AbstractFramebuffer.h +++ b/src/AbstractFramebuffer.h @@ -36,10 +36,10 @@ namespace Magnum { /** - * @brief Mask for framebuffer clearing - * - * @see AbstractFramebuffer, FramebufferClearMask - */ +@brief Mask for framebuffer clearing + +@see AbstractFramebuffer, FramebufferClearMask +*/ enum class FramebufferClear: GLbitfield { Color = GL_COLOR_BUFFER_BIT, /**< Color */ Depth = GL_DEPTH_BUFFER_BIT, /**< Depth value */ @@ -47,21 +47,21 @@ enum class FramebufferClear: GLbitfield { }; /** - * @brief Mask for clearing - * - * @see AbstractFramebuffer::clear() - */ +@brief Mask for clearing + +@see AbstractFramebuffer::clear() +*/ typedef Containers::EnumSet FramebufferClearMask; /** - * @brief Mask for framebuffer blitting - * - * @see AbstractFramebuffer, FramebufferBlitMask - * @requires_gl30 %Extension @extension{EXT,framebuffer_object} - * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or - * @es_extension{NV,framebuffer_blit} - */ +@brief Mask for framebuffer blitting + +@see AbstractFramebuffer, FramebufferBlitMask +@requires_gl30 %Extension @extension{ARB,framebuffer_object} +@requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or + @es_extension{NV,framebuffer_blit} +*/ enum class FramebufferBlit: GLbitfield { ColorBuffer = GL_COLOR_BUFFER_BIT, /**< Color buffer */ DepthBuffer = GL_DEPTH_BUFFER_BIT, /**< Depth buffer */ @@ -69,36 +69,38 @@ enum class FramebufferBlit: GLbitfield { }; /** - * @brief Mask for framebuffer blitting - * - * @see AbstractFramebuffer::blit() - * @requires_gl30 %Extension @extension{EXT,framebuffer_object} - * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or - * @es_extension{NV,framebuffer_blit} - */ +@brief Mask for framebuffer blitting + +@see AbstractFramebuffer::blit() +@requires_gl30 %Extension @extension{ARB,framebuffer_object} +@requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or + @es_extension{NV,framebuffer_blit} +*/ typedef Containers::EnumSet FramebufferBlitMask; /** - * @brief %Framebuffer blit filtering - * - * @see AbstractFramebuffer::blit() - */ +@brief %Framebuffer blit filtering + +@see AbstractFramebuffer::blit() +@requires_gl30 %Extension @extension{ARB,framebuffer_object} +@requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or + @es_extension{NV,framebuffer_blit} +*/ enum class FramebufferBlitFilter: GLenum { Nearest = GL_NEAREST, /**< Nearest neighbor filtering */ Linear = GL_LINEAR /**< Linear interpolation filtering */ }; /** - * @brief Target for binding framebuffer - * - * @see DefaultFramebuffer::bind(), Framebuffer::bind() - * @requires_gl30 %Extension @extension{EXT,framebuffer_object} - */ +@brief Target for binding framebuffer + +@see DefaultFramebuffer::bind(), Framebuffer::bind() +@requires_gl30 %Extension @extension{ARB,framebuffer_object} +*/ enum class FramebufferTarget: GLenum { /** * For reading only. - * @requires_gl30 %Extension @extension{EXT,framebuffer_blit} * @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample}, * @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit} */ @@ -110,7 +112,6 @@ enum class FramebufferTarget: GLenum { /** * For drawing only. - * @requires_gl30 %Extension @extension{EXT,framebuffer_blit} * @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample}, * @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit} */ @@ -163,7 +164,6 @@ class MAGNUM_EXPORT AbstractFramebuffer { * Framebuffer::mapForDraw() for specifying particular buffers for * blitting operation. * @see @fn_gl{BlitFramebuffer} - * @requires_gl30 %Extension @extension{EXT,framebuffer_blit} * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or * @es_extension{NV,framebuffer_blit} */ @@ -182,7 +182,6 @@ class MAGNUM_EXPORT AbstractFramebuffer { * @ref FramebufferBlitFilter "FramebufferBlitFilter::Nearest" * filtering is used by default. * @see @fn_gl{BlitFramebuffer} - * @requires_gl30 %Extension @extension{EXT,framebuffer_blit} * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or * @es_extension{NV,framebuffer_blit} */ @@ -272,8 +271,10 @@ class MAGNUM_EXPORT AbstractFramebuffer { FramebufferTarget MAGNUM_LOCAL bindInternal(); void MAGNUM_LOCAL setViewportInternal(); + #ifdef MAGNUM_TARGET_GLES2 static MAGNUM_LOCAL FramebufferTarget readTarget; static MAGNUM_LOCAL FramebufferTarget drawTarget; + #endif typedef void(AbstractFramebuffer::*DrawBuffersImplementation)(GLsizei, const GLenum*); static MAGNUM_LOCAL DrawBuffersImplementation drawBuffersImplementation; diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index b447d1f6f..87179e638 100644 --- a/src/AbstractTexture.h +++ b/src/AbstractTexture.h @@ -253,7 +253,7 @@ class MAGNUM_EXPORT AbstractTexture { * @see setMinificationFilter(), @fn_gl{ActiveTexture}, * @fn_gl{BindTexture} and @fn_gl{GenerateMipmap} or * @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access} - * @requires_gl30 %Extension @extension{EXT,framebuffer_object} + * @requires_gl30 %Extension @extension{ARB,framebuffer_object} */ AbstractTexture* generateMipmap(); diff --git a/src/Context.cpp b/src/Context.cpp index 327b6ea22..2c1596aa3 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -97,14 +97,7 @@ const std::vector& Extension::extensions(Version version) { _extension(GL,ARB,texture_float), // done _extension(GL,ARB,depth_buffer_float), // done _extension(GL,ARB,texture_rg), // done - /** - * @todo Remove as it doesn't have the same functionality present in - * GL 3.0 and replace with ARB_framebuffer_object? - */ - _extension(GL,EXT,framebuffer_object), - _extension(GL,EXT,packed_depth_stencil), // done - _extension(GL,EXT,framebuffer_blit), // done - _extension(GL,EXT,framebuffer_multisample), + _extension(GL,ARB,framebuffer_object), _extension(GL,EXT,gpu_shader4), _extension(GL,EXT,packed_float), // done _extension(GL,EXT,texture_array), diff --git a/src/Extensions.h b/src/Extensions.h index a7980afc0..309c7b080 100644 --- a/src/Extensions.h +++ b/src/Extensions.h @@ -76,6 +76,7 @@ namespace GL { _extension(GL,ARB,texture_float, GL210, GL300) // #41 _extension(GL,ARB,depth_buffer_float, GL210, GL300) // #43 _extension(GL,ARB,draw_instanced, GL210, GL310) // #44 + _extension(GL,ARB,framebuffer_object, GL210, GL300) // #45 _extension(GL,ARB,geometry_shader4, GL210, GL320) // #47 _extension(GL,ARB,instanced_arrays, GL210, GL330) // #49 _extension(GL,ARB,map_buffer_range, GL210, GL300) // #50 @@ -154,10 +155,8 @@ namespace GL { _extension(GL,ARB,texture_storage_multisample, GL210, GL430) // #141 } namespace EXT { _extension(GL,EXT,texture_filter_anisotropic, GL210, None) // #187 - _extension(GL,EXT,framebuffer_object, GL210, GL300) // #310 - _extension(GL,EXT,packed_depth_stencil, GL210, GL300) // #312 - _extension(GL,EXT,framebuffer_blit, GL210, GL300) // #316 - _extension(GL,EXT,framebuffer_multisample, GL210, GL300) // #317 + /* EXT_framebuffer_object, EXT_packed_depth_stencil, EXT_framebuffer_blit, + EXT_framebuffer_multisample replaced with ARB_framebuffer_object */ _extension(GL,EXT,gpu_shader4, GL210, GL300) // #326 _extension(GL,EXT,packed_float, GL210, GL300) // #328 _extension(GL,EXT,texture_array, GL210, GL300) // #329 diff --git a/src/Framebuffer.h b/src/Framebuffer.h index e839d7488..975f96b14 100644 --- a/src/Framebuffer.h +++ b/src/Framebuffer.h @@ -94,7 +94,7 @@ attachTexture2D(), attachCubeMapTexture() and attachTexture3D() use DSA to avoid unnecessary calls to @fn_gl{BindFramebuffer}. See their respective documentation for more information. -@requires_gl30 %Extension @extension{EXT,framebuffer_object} +@requires_gl30 %Extension @extension{ARB,framebuffer_object} */ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer { friend class Context; diff --git a/src/ImageFormat.h b/src/ImageFormat.h index 9219dcc0a..2a358eca7 100644 --- a/src/ImageFormat.h +++ b/src/ImageFormat.h @@ -236,7 +236,7 @@ enum class ImageFormat: GLenum { /** * Depth and stencil. - * @requires_gl30 %Extension @extension{EXT,packed_depth_stencil} + * @requires_gl30 %Extension @extension{ARB,framebuffer_object} * @requires_gles30 For texture data only, extension @es_extension{OES,packed_depth_stencil}. * @requires_es_extension For framebuffer reading only, extension * @es_extension2{NV,read_depth_stencil,GL_NV_read_depth_stencil}. @@ -446,7 +446,7 @@ enum class ImageType: GLenum { /** * Unsigned int, depth component 24bit, stencil index 8bit. - * @requires_gl30 %Extension @extension{EXT,packed_depth_stencil} + * @requires_gl30 %Extension @extension{ARB,framebuffer_object} * @requires_gles30 For texture data only, extension @es_extension{OES,packed_depth_stencil}. */ #ifndef MAGNUM_TARGET_GLES2 diff --git a/src/Renderbuffer.h b/src/Renderbuffer.h index f35ac0bac..b4b425386 100644 --- a/src/Renderbuffer.h +++ b/src/Renderbuffer.h @@ -49,7 +49,7 @@ If extension @extension{EXT,direct_state_access} is available, function setStorage() uses DSA to avoid unnecessary calls to @fn_gl{BindFramebuffer}. See its documentation for more information. -@requires_gl30 %Extension @extension{EXT,framebuffer_object} +@requires_gl30 %Extension @extension{ARB,framebuffer_object} */ class MAGNUM_EXPORT Renderbuffer { friend class Context; @@ -105,7 +105,6 @@ class MAGNUM_EXPORT Renderbuffer { * operation. * @see @fn_gl{BindRenderbuffer}, @fn_gl{RenderbufferStorage} or * @fn_gl_extension{NamedRenderbufferStorage,EXT,direct_state_access} - * @requires_gl30 %Extension @extension{EXT,framebuffer_multisample} * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_multisample} * or @es_extension{NV,framebuffer_multisample} * @todo How about @es_extension{APPLE,framebuffer_multisample}? diff --git a/src/RenderbufferFormat.h b/src/RenderbufferFormat.h index f0d3de92f..fdb935ba1 100644 --- a/src/RenderbufferFormat.h +++ b/src/RenderbufferFormat.h @@ -36,6 +36,7 @@ namespace Magnum { @brief Internal renderbuffer format @see Renderbuffer +@requires_gl30 %Extension @extension{ARB,framebuffer_object} @todo RGB, RGB8 ES only (ES3 + @es_extension{OES,rgb8_rgba8}) */ enum class RenderbufferFormat: GLenum { @@ -481,7 +482,6 @@ enum class RenderbufferFormat: GLenum { /** * 24bit depth and 8bit stencil component. - * @requires_gl30 %Extension @extension{EXT,packed_depth_stencil} * @requires_gles30 %Extension @es_extension{OES,packed_depth_stencil} */ #ifdef MAGNUM_TARGET_GLES2 diff --git a/src/Renderer.h b/src/Renderer.h index 0053c78a3..e66e8311b 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -892,7 +892,7 @@ class MAGNUM_EXPORT Renderer { /** * The framebuffer object is not complete. * @see AbstractFramebuffer::checkStatus() - * @requires_gl30 %Extension @extension{EXT,framebuffer_object} + * @requires_gl30 %Extension @extension{ARB,framebuffer_object} */ InvalidFramebufferOperation = GL_INVALID_FRAMEBUFFER_OPERATION, diff --git a/src/TextureFormat.h b/src/TextureFormat.h index 2344cd7d7..86d68f36e 100644 --- a/src/TextureFormat.h +++ b/src/TextureFormat.h @@ -823,7 +823,7 @@ enum class TextureFormat: GLenum { /** * 24bit depth and 8bit stencil component. - * @requires_gl30 %Extension @extension{EXT,packed_depth_stencil} + * @requires_gl30 %Extension @extension{ARB,framebuffer_object} * @requires_gles30 %Extension @es_extension{OES,packed_depth_stencil} and * (@es_extension{OES,required_internalformat} or * (@es_extension{EXT,texture_storage} and @es_extension{ANGLE,depth_texture}))