diff --git a/doc/changelog.dox b/doc/changelog.dox index 997d9d3ed..ce80dd54f 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -449,6 +449,12 @@ See also: upload/download where needed. The compressed variant is still only GL 4.5+, as that needs the @ref CompressedImageView APIs to be aware of compression format properties, which isn't implemented yet. +- Added @ref GL::DefaultFramebuffer::mapForDraw(), + @ref GL::Framebuffer::mapForDraw(), + @ref GL::DefaultFramebuffer::invalidate() and + @ref GL::Framebuffer::invalidate() overloads taking a + @relativeref{Corrade,Containers::ArrayView} instead of a + @ref std::initializer_list - Added @ref GL::Framebuffer::Status::IncompleteDimensions for ES2. This enum isn't available on ES3 or desktop GL, but NVidia drivers are known to emit it, which is why it got added. diff --git a/src/Magnum/GL/DefaultFramebuffer.cpp b/src/Magnum/GL/DefaultFramebuffer.cpp index 7203ddc9d..24f34b361 100644 --- a/src/Magnum/GL/DefaultFramebuffer.cpp +++ b/src/Magnum/GL/DefaultFramebuffer.cpp @@ -60,23 +60,27 @@ DefaultFramebuffer& DefaultFramebuffer::clearColor(const Vector4ui& color) { } #endif -DefaultFramebuffer& DefaultFramebuffer::mapForDraw(std::initializer_list> attachments) { +DefaultFramebuffer& DefaultFramebuffer::mapForDraw(const Containers::ArrayView> attachments) { /* Max attachment location */ std::size_t max = 0; for(const auto& attachment: attachments) - if(attachment.first > max) max = attachment.first; + if(attachment.first() > max) max = attachment.first(); /* Create linear array from associative */ /** @todo C++14: use VLA to avoid heap allocation */ static_assert(GL_NONE == 0, "Expecting zero GL_NONE for zero-initialization"); Containers::Array _attachments{ValueInit, max+1}; for(const auto& attachment: attachments) - _attachments[attachment.first] = GLenum(attachment.second); + _attachments[attachment.first()] = GLenum(attachment.second()); (this->*Context::current().state().framebuffer.drawBuffersImplementation)(max+1, _attachments); return *this; } +DefaultFramebuffer& DefaultFramebuffer::mapForDraw(std::initializer_list> attachments) { + return mapForDraw(Containers::arrayView(attachments)); +} + DefaultFramebuffer& DefaultFramebuffer::mapForDraw(const DrawAttachment attachment) { #ifndef MAGNUM_TARGET_GLES (this->*Context::current().state().framebuffer.drawBufferImplementation)(GLenum(attachment)); @@ -92,7 +96,7 @@ DefaultFramebuffer& DefaultFramebuffer::mapForRead(const ReadAttachment attachme return *this; } -void DefaultFramebuffer::invalidate(std::initializer_list attachments) { +void DefaultFramebuffer::invalidate(Containers::ArrayView attachments) { /** @todo C++14: use VLA to avoid heap allocation */ Containers::Array _attachments(attachments.size()); for(std::size_t i = 0; i != attachments.size(); ++i) @@ -100,10 +104,14 @@ void DefaultFramebuffer::invalidate(std::initializer_list*Context::current().state().framebuffer.invalidateImplementation)(attachments.size(), _attachments); } + +void DefaultFramebuffer::invalidate(std::initializer_list attachments) { + invalidate(Containers::arrayView(attachments)); +} #endif #ifndef MAGNUM_TARGET_GLES2 -void DefaultFramebuffer::invalidate(std::initializer_list attachments, const Range2Di& rectangle) { +void DefaultFramebuffer::invalidate(const Containers::ArrayView attachments, const Range2Di& rectangle) { /** @todo C++14: use VLA to avoid heap allocation */ Containers::Array _attachments(attachments.size()); for(std::size_t i = 0; i != attachments.size(); ++i) @@ -111,6 +119,10 @@ void DefaultFramebuffer::invalidate(std::initializer_list*Context::current().state().framebuffer.invalidateSubImplementation)(attachments.size(), _attachments, rectangle); } + +void DefaultFramebuffer::invalidate(std::initializer_list attachments, const Range2Di& rectangle) { + invalidate(Containers::arrayView(attachments), rectangle); +} #endif #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Magnum/GL/DefaultFramebuffer.h b/src/Magnum/GL/DefaultFramebuffer.h index e177c8bfe..4daa98f09 100644 --- a/src/Magnum/GL/DefaultFramebuffer.h +++ b/src/Magnum/GL/DefaultFramebuffer.h @@ -31,6 +31,11 @@ #include "Magnum/GL/AbstractFramebuffer.h" +#ifdef MAGNUM_BUILD_DEPRECATED +/* For mapForDraw(), which used to take a std::pair */ +#include +#endif + namespace Magnum { namespace GL { /** @@ -366,6 +371,7 @@ class MAGNUM_GL_EXPORT DefaultFramebuffer: public AbstractFramebuffer { /** * @brief Map shader outputs to buffer attachment * @return Reference to self (for method chaining) + * @m_since_latest * * @p attachments is list of shader outputs mapped to buffer * attachments. Shader outputs which are not listed are not used, you @@ -385,7 +391,10 @@ class MAGNUM_GL_EXPORT DefaultFramebuffer: public AbstractFramebuffer { * @requires_webgl20 Extension @webgl_extension{WEBGL,draw_buffers} in * WebGL 1.0. */ - DefaultFramebuffer& mapForDraw(std::initializer_list> attachments); + DefaultFramebuffer& mapForDraw(Containers::ArrayView> attachments); + + /** @overload */ + DefaultFramebuffer& mapForDraw(std::initializer_list> attachments); /** * @brief Map shader output to buffer attachment @@ -429,6 +438,7 @@ class MAGNUM_GL_EXPORT DefaultFramebuffer: public AbstractFramebuffer { /** * @brief Invalidate framebuffer * @param attachments Attachments to invalidate + * @m_since_latest * * If extension @gl_extension{ARB,invalidate_subdata} (part of OpenGL * 4.3), extension @gl_extension{EXT,discard_framebuffer} in OpenGL ES @@ -443,6 +453,9 @@ class MAGNUM_GL_EXPORT DefaultFramebuffer: public AbstractFramebuffer { * @requires_webgl20 Framebuffer invalidation is not available in WebGL * 1.0. */ + void invalidate(Containers::ArrayView attachments); + + /** @overload */ void invalidate(std::initializer_list attachments); #endif @@ -451,20 +464,24 @@ class MAGNUM_GL_EXPORT DefaultFramebuffer: public AbstractFramebuffer { * @brief Invalidate framebuffer rectangle * @param attachments Attachments to invalidate * @param rectangle Rectangle to invalidate + * @m_since_latest * * If extension @gl_extension{ARB,invalidate_subdata} (part of OpenGL * 4.3) is not available, this function does nothing. If * @gl_extension{ARB,direct_state_access} (part of OpenGL 4.5) is not * available, the framebuffer is bound before the operation (if not * already). - * @see @ref invalidate(std::initializer_list), + * @see @ref invalidate(Containers::ArrayView), * @fn_gl2_keyword{InvalidateNamedFramebufferSubData,InvalidateSubFramebuffer}, * eventually @fn_gl_keyword{InvalidateSubFramebuffer} - * @requires_gles30 Use @ref invalidate(std::initializer_list) + * @requires_gles30 Use @ref invalidate(Containers::ArrayView) * in OpenGL ES 2.0 instead. * @requires_webgl20 Framebuffer invalidation is not available in WebGL * 1.0. */ + void invalidate(Containers::ArrayView attachments, const Range2Di& rectangle); + + /** @overload */ void invalidate(std::initializer_list attachments, const Range2Di& rectangle); #endif diff --git a/src/Magnum/GL/Framebuffer.cpp b/src/Magnum/GL/Framebuffer.cpp index 5c8476503..b067ebd37 100644 --- a/src/Magnum/GL/Framebuffer.cpp +++ b/src/Magnum/GL/Framebuffer.cpp @@ -27,6 +27,7 @@ #include "Framebuffer.h" #include +#include #ifndef MAGNUM_TARGET_WEBGL #include #endif @@ -182,23 +183,27 @@ Framebuffer& Framebuffer::clearColor(const Int attachment, const Vector4ui& colo } #endif -Framebuffer& Framebuffer::mapForDraw(std::initializer_list> attachments) { +Framebuffer& Framebuffer::mapForDraw(const Containers::ArrayView> attachments) { /* Max attachment location */ std::size_t max = 0; for(const auto& attachment: attachments) - if(attachment.first > max) max = attachment.first; + if(attachment.first() > max) max = attachment.first(); /* Create linear array from associative */ /** @todo C++14: use VLA to avoid heap allocation */ static_assert(GL_NONE == 0, "Expecting zero GL_NONE for zero-initialization"); Containers::Array _attachments{ValueInit, max+1}; for(const auto& attachment: attachments) - _attachments[attachment.first] = GLenum(attachment.second); + _attachments[attachment.first()] = GLenum(attachment.second()); (this->*Context::current().state().framebuffer.drawBuffersImplementation)(max+1, _attachments); return *this; } +Framebuffer& Framebuffer::mapForDraw(std::initializer_list> attachments) { + return mapForDraw(Containers::arrayView(attachments)); +} + Framebuffer& Framebuffer::mapForDraw(const DrawAttachment attachment) { #ifndef MAGNUM_TARGET_GLES (this->*Context::current().state().framebuffer.drawBufferImplementation)(GLenum(attachment)); @@ -214,7 +219,7 @@ Framebuffer& Framebuffer::mapForRead(const ColorAttachment attachment) { return *this; } -void Framebuffer::invalidate(std::initializer_list attachments) { +void Framebuffer::invalidate(const Containers::ArrayView attachments) { /** @todo C++14: use VLA to avoid heap allocation */ Containers::Array _attachments(attachments.size()); for(std::size_t i = 0; i != attachments.size(); ++i) @@ -223,8 +228,12 @@ void Framebuffer::invalidate(std::initializer_list attac (this->*Context::current().state().framebuffer.invalidateImplementation)(attachments.size(), _attachments); } +void Framebuffer::invalidate(const std::initializer_list attachments) { + invalidate(Containers::arrayView(attachments)); +} + #ifndef MAGNUM_TARGET_GLES2 -void Framebuffer::invalidate(std::initializer_list attachments, const Range2Di& rectangle) { +void Framebuffer::invalidate(const Containers::ArrayView attachments, const Range2Di& rectangle) { /** @todo C++14: use VLA to avoid heap allocation */ Containers::Array _attachments(attachments.size()); for(std::size_t i = 0; i != attachments.size(); ++i) @@ -232,6 +241,10 @@ void Framebuffer::invalidate(std::initializer_list attac (this->*Context::current().state().framebuffer.invalidateSubImplementation)(attachments.size(), _attachments, rectangle); } + +void Framebuffer::invalidate(const std::initializer_list attachments, const Range2Di& rectangle) { + invalidate(Containers::arrayView(attachments), rectangle); +} #endif #endif diff --git a/src/Magnum/GL/Framebuffer.h b/src/Magnum/GL/Framebuffer.h index 26864e82c..3b926e9d4 100644 --- a/src/Magnum/GL/Framebuffer.h +++ b/src/Magnum/GL/Framebuffer.h @@ -41,6 +41,8 @@ /* For label() / setLabel(), which used to be a std::string. Not ideal for the return type, but at least something. */ #include +/* For mapForDraw(), which used to take a std::pair */ +#include #endif namespace Magnum { namespace GL { @@ -526,6 +528,7 @@ class MAGNUM_GL_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractO /** * @brief Map shader output to attachments * @return Reference to self (for method chaining) + * @m_since_latest * * @p attachments is list of shader outputs mapped to framebuffer * color attachment IDs. Shader outputs which are not listed are not @@ -546,7 +549,10 @@ class MAGNUM_GL_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractO * @requires_webgl20 Extension @webgl_extension{WEBGL,draw_buffers} in * WebGL 1.0. */ - Framebuffer& mapForDraw(std::initializer_list> attachments); + Framebuffer& mapForDraw(Containers::ArrayView> attachments); + + /** @overload */ + Framebuffer& mapForDraw(std::initializer_list> attachments); /** * @brief Map shader output to an attachment @@ -591,6 +597,7 @@ class MAGNUM_GL_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractO /** * @brief Invalidate framebuffer * @param attachments Attachments to invalidate + * @m_since_latest * * If extension @gl_extension{ARB,invalidate_subdata} (part of OpenGL * 4.3), extension @gl_extension{EXT,discard_framebuffer} in OpenGL ES @@ -605,6 +612,13 @@ class MAGNUM_GL_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractO * @requires_webgl20 Framebuffer invalidation is not available in WebGL * 1.0. */ + void invalidate(Containers::ArrayView attachments); + + /** + * @overload + * @requires_webgl20 Framebuffer invalidation is not available in WebGL + * 1.0. + */ void invalidate(std::initializer_list attachments); #endif @@ -613,20 +627,28 @@ class MAGNUM_GL_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractO * @brief Invalidate framebuffer rectangle * @param attachments Attachments to invalidate * @param rectangle Rectangle to invalidate + * @m_since_latest * * If extension @gl_extension{ARB,invalidate_subdata} (part of OpenGL * 4.3) is not available, this function does nothing. If * @gl_extension{ARB,direct_state_access} (part of OpenGL 4.5) is not * available, the framebuffer is bound before the operation (if not * already). - * @see @ref invalidate(std::initializer_list), + * @see @ref invalidate(Containers::ArrayView), * @fn_gl2_keyword{InvalidateNamedFramebufferSubData,InvalidateSubFramebuffer}, * eventually @fn_gl_keyword{InvalidateSubFramebuffer} - * @requires_gles30 Use @ref invalidate(std::initializer_list) + * @requires_gles30 Use @ref invalidate(Containers::ArrayView) * in OpenGL ES 2.0 instead. * @requires_webgl20 Framebuffer invalidation is not available in WebGL * 1.0. */ + void invalidate(Containers::ArrayView attachments, const Range2Di& rectangle); + + /** + * @overload + * @requires_webgl20 Framebuffer invalidation is not available in WebGL + * 1.0. + */ void invalidate(std::initializer_list attachments, const Range2Di& rectangle); #endif