From 86dbd86e74b98330797990e191d98863f03a4209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 27 Jan 2020 12:26:50 +0100 Subject: [PATCH] GL: added BufferTexture::resetBuffer(). --- doc/changelog.dox | 2 + src/Magnum/GL/BufferTexture.cpp | 22 +++++++---- src/Magnum/GL/BufferTexture.h | 25 ++++++++---- src/Magnum/GL/Implementation/TextureState.h | 2 +- src/Magnum/GL/Test/BufferTextureGLTest.cpp | 43 ++++++++++++++++++++- 5 files changed, 78 insertions(+), 16 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index 1249ceab7..f650c210c 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -129,6 +129,8 @@ See also: @ref Corrade::Containers::ArrayView instead of @ref std::initializer_list in order to allow passing runtime-sized lists (see [mosra/magnum#403](https://github.com/mosra/magnum/pull/403)) +- Added an ability to remove a buffer from a @ref GL::BufferTexture using + @ref GL::BufferTexture::resetBuffer() "resetBuffer()" @subsubsection changelog-latest-changes-math Math library diff --git a/src/Magnum/GL/BufferTexture.cpp b/src/Magnum/GL/BufferTexture.cpp index b38a0c262..6df6c1398 100644 --- a/src/Magnum/GL/BufferTexture.cpp +++ b/src/Magnum/GL/BufferTexture.cpp @@ -27,6 +27,7 @@ #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #include "Magnum/GL/Buffer.h" +#include "Magnum/GL/BufferTextureFormat.h" #include "Magnum/GL/Context.h" #include "Magnum/GL/Extensions.h" #include "Magnum/GL/Implementation/State.h" @@ -80,7 +81,7 @@ Int BufferTexture::size() { BufferTexture& BufferTexture::setBuffer(const BufferTextureFormat internalFormat, Buffer& buffer) { buffer.createIfNotAlready(); - (this->*Context::current().state().texture->setBufferImplementation)(internalFormat, buffer); + (this->*Context::current().state().texture->setBufferImplementation)(internalFormat, &buffer); return *this; } @@ -90,21 +91,21 @@ BufferTexture& BufferTexture::setBuffer(const BufferTextureFormat internalFormat return *this; } -void BufferTexture::setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer) { +void BufferTexture::setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer* buffer) { bindInternal(); - glTexBuffer(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id()); + glTexBuffer(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer ? buffer->id() : 0); } #ifdef MAGNUM_TARGET_GLES -void BufferTexture::setBufferImplementationEXT(BufferTextureFormat internalFormat, Buffer& buffer) { +void BufferTexture::setBufferImplementationEXT(BufferTextureFormat internalFormat, Buffer* buffer) { bindInternal(); - glTexBufferEXT(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id()); + glTexBufferEXT(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer ? buffer->id() : 0); } #endif #ifndef MAGNUM_TARGET_GLES -void BufferTexture::setBufferImplementationDSA(const BufferTextureFormat internalFormat, Buffer& buffer) { - glTextureBuffer(id(), GLenum(internalFormat), buffer.id()); +void BufferTexture::setBufferImplementationDSA(const BufferTextureFormat internalFormat, Buffer* buffer) { + glTextureBuffer(id(), GLenum(internalFormat), buffer ? buffer->id() : 0); } #endif @@ -126,5 +127,12 @@ void BufferTexture::setBufferRangeImplementationDSA(const BufferTextureFormat in } #endif +BufferTexture& BufferTexture::resetBuffer() { + /* R8 is the default state according to ARB_texture_buffer_object, so use + that */ + (this->*Context::current().state().texture->setBufferImplementation)(BufferTextureFormat::R8, nullptr); + return *this; +} + }} #endif diff --git a/src/Magnum/GL/BufferTexture.h b/src/Magnum/GL/BufferTexture.h index 04e44d390..eec3d9fe7 100644 --- a/src/Magnum/GL/BufferTexture.h +++ b/src/Magnum/GL/BufferTexture.h @@ -209,8 +209,9 @@ class MAGNUM_GL_EXPORT BufferTexture: public AbstractTexture { * own data setting functions. If @gl_extension{ARB,direct_state_access} * (part of OpenGL 4.5) is not available, the texture is bound before * the operation (if not already). - * @see @ref maxSize(), @fn_gl2_keyword{TextureBuffer,TexBuffer}, - * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @see @ref maxSize(), @ref resetBuffer(), + * @fn_gl2_keyword{TextureBuffer,TexBuffer}, eventually + * @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and * @fn_gl_keyword{TexBuffer} */ BufferTexture& setBuffer(BufferTextureFormat internalFormat, Buffer& buffer); @@ -228,13 +229,23 @@ class MAGNUM_GL_EXPORT BufferTexture: public AbstractTexture { * own data setting functions. If @gl_extension{ARB,direct_state_access} * (part of OpenGL 4.5) is not available, the texture is bound before * the operation (if not already). - * @see @ref maxSize(), @fn_gl2_keyword{TextureBufferRange,TexBufferRange}, - * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @see @ref maxSize(), @ref resetBuffer(), + * @fn_gl2_keyword{TextureBufferRange,TexBufferRange}, eventually + * @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and * @fn_gl_keyword{TexBufferRange} * @requires_gl43 Extension @gl_extension{ARB,texture_buffer_range} */ BufferTexture& setBuffer(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); + /** + * @brief Remove existing buffer from the texture + * @return Reference to self (for method chaining) + * @m_since_latest + * + * @see @ref setBuffer() + */ + BufferTexture& resetBuffer(); + /* Overloads to remove WTF-factor from method chaining order */ #ifndef DOXYGEN_GENERATING_OUTPUT BufferTexture& setLabel(const std::string& label) { @@ -250,12 +261,12 @@ class MAGNUM_GL_EXPORT BufferTexture: public AbstractTexture { private: explicit BufferTexture(GLuint id, ObjectFlags flags): AbstractTexture{id, GL_TEXTURE_BUFFER, flags} {} - void MAGNUM_GL_LOCAL setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer); + void MAGNUM_GL_LOCAL setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer* buffer); #ifdef MAGNUM_TARGET_GLES - void MAGNUM_GL_LOCAL setBufferImplementationEXT(BufferTextureFormat internalFormat, Buffer& buffer); + void MAGNUM_GL_LOCAL setBufferImplementationEXT(BufferTextureFormat internalFormat, Buffer* buffer); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_GL_LOCAL setBufferImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer); + void MAGNUM_GL_LOCAL setBufferImplementationDSA(BufferTextureFormat internalFormat, Buffer* buffer); #endif void MAGNUM_GL_LOCAL setBufferRangeImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); diff --git a/src/Magnum/GL/Implementation/TextureState.h b/src/Magnum/GL/Implementation/TextureState.h index 9e3f9a4cd..3064478d0 100644 --- a/src/Magnum/GL/Implementation/TextureState.h +++ b/src/Magnum/GL/Implementation/TextureState.h @@ -105,7 +105,7 @@ struct TextureState { void(AbstractTexture::*invalidateSubImageImplementation)(GLint, const Vector3i&, const Vector3i&); #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - void(BufferTexture::*setBufferImplementation)(BufferTextureFormat, Buffer&); + void(BufferTexture::*setBufferImplementation)(BufferTextureFormat, Buffer*); void(BufferTexture::*setBufferRangeImplementation)(BufferTextureFormat, Buffer&, GLintptr, GLsizeiptr); #endif diff --git a/src/Magnum/GL/Test/BufferTextureGLTest.cpp b/src/Magnum/GL/Test/BufferTextureGLTest.cpp index 29d95d90d..21f99013b 100644 --- a/src/Magnum/GL/Test/BufferTextureGLTest.cpp +++ b/src/Magnum/GL/Test/BufferTextureGLTest.cpp @@ -47,6 +47,8 @@ struct BufferTextureGLTest: OpenGLTester { void setBuffer(); void setBufferEmptyFirst(); void setBufferOffset(); + + void resetBuffer(); }; BufferTextureGLTest::BufferTextureGLTest() { @@ -58,7 +60,9 @@ BufferTextureGLTest::BufferTextureGLTest() { &BufferTextureGLTest::setBuffer, &BufferTextureGLTest::setBufferEmptyFirst, - &BufferTextureGLTest::setBufferOffset}); + &BufferTextureGLTest::setBufferOffset, + + &BufferTextureGLTest::resetBuffer}); } void BufferTextureGLTest::construct() { @@ -271,6 +275,43 @@ void BufferTextureGLTest::setBufferOffset() { MAGNUM_VERIFY_NO_GL_ERROR(); } +void BufferTextureGLTest::resetBuffer() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current().isExtensionSupported()) + CORRADE_SKIP(Extensions::ARB::texture_buffer_object::string() + std::string(" is not supported.")); + #else + if(!Context::current().isExtensionSupported()) + CORRADE_SKIP(Extensions::EXT::texture_buffer::string() + std::string(" is not supported.")); + #endif + + BufferTexture texture; + Buffer buffer; + buffer.setData({nullptr, 16}); + texture.setBuffer(BufferTextureFormat::RG8UI, buffer); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + #ifdef MAGNUM_TARGET_GLES + if(Context::current().isVersionSupported(Version::GLES310)) + #endif + { + CORRADE_COMPARE(texture.size(), 8); + } + + texture.resetBuffer(); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + #ifdef MAGNUM_TARGET_GLES + if(!Context::current().isVersionSupported(Version::GLES310)) + CORRADE_SKIP("OpenGL ES 3.1 not supported, skipping image size testing."); + #endif + + CORRADE_COMPARE(texture.size(), 0); + + MAGNUM_VERIFY_NO_GL_ERROR(); +} + }}}} CORRADE_TEST_MAIN(Magnum::GL::Test::BufferTextureGLTest)