From 70cb1041aa519a851d10f5d13f3e870a396fd161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 6 Jul 2015 13:42:24 +0200 Subject: [PATCH] Implemented EXT_texture_buffer AEP extension. --- doc/opengl-support.dox | 2 +- src/Magnum/BufferTexture.cpp | 61 +++++++++++++++++++--- src/Magnum/BufferTexture.h | 61 ++++++++++++++++++---- src/Magnum/CMakeLists.txt | 11 ++-- src/Magnum/Implementation/TextureState.cpp | 4 +- src/Magnum/Implementation/TextureState.h | 10 ++-- src/Magnum/Magnum.h | 2 +- src/Magnum/Platform/magnum-info.cpp | 28 ++++++++-- src/Magnum/Test/BufferTextureGLTest.cpp | 25 +++++++++ src/Magnum/Test/CMakeLists.txt | 2 +- 10 files changed, 168 insertions(+), 38 deletions(-) diff --git a/doc/opengl-support.dox b/doc/opengl-support.dox index 701510dac..75d7c9142 100644 --- a/doc/opengl-support.dox +++ b/doc/opengl-support.dox @@ -367,7 +367,7 @@ Extension | Status @es_extension{EXT,shader_io_blocks} | done (shading language only) @es_extension{EXT,tessellation_shader} | | @es_extension{EXT,texture_border_clamp} | done -@es_extension{EXT,texture_buffer} | | +@es_extension{EXT,texture_buffer} | done @es_extension{EXT,texture_cube_map_array} | done @es_extension{EXT,primitive_bounding_box} | | @es_extension2{KHR,texture_compression_astc_ldr,texture_compression_astc_hdr} | | diff --git a/src/Magnum/BufferTexture.cpp b/src/Magnum/BufferTexture.cpp index a9fe6b9cb..742895fb1 100644 --- a/src/Magnum/BufferTexture.cpp +++ b/src/Magnum/BufferTexture.cpp @@ -25,7 +25,7 @@ #include "BufferTexture.h" -#ifndef MAGNUM_TARGET_GLES +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #include "Magnum/Buffer.h" #include "Magnum/Context.h" #include "Magnum/Extensions.h" @@ -36,26 +36,47 @@ namespace Magnum { Int BufferTexture::maxSize() { + #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) return 0; + #else + if(!Context::current()->isExtensionSupported()) + return 0; + #endif GLint& value = Context::current()->state().texture->maxBufferSize; - if(value == 0) - glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &value); + /* Get the value, if not already cached */ + if(value == 0) glGetIntegerv( + #ifndef MAGNUM_TARGET_GLES + GL_MAX_TEXTURE_BUFFER_SIZE, + #else + GL_MAX_TEXTURE_BUFFER_SIZE_EXT, + #endif + &value); return value; } Int BufferTexture::offsetAlignment() { + #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) return 1; + #else + if(!Context::current()->isExtensionSupported()) + return 0; + #endif GLint& value = Context::current()->state().texture->bufferOffsetAlignment; /* Get the value, if not already cached */ - if(value == 0) - glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &value); + if(value == 0) glGetIntegerv( + #ifndef MAGNUM_TARGET_GLES + GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, + #else + GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT, + #endif + &value); return value; } @@ -72,9 +93,21 @@ BufferTexture& BufferTexture::setBuffer(const BufferTextureFormat internalFormat void BufferTexture::setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer) { bindInternal(); - glTexBuffer(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id()); + #ifndef MAGNUM_TARGET_GLES + glTexBuffer + #else + glTexBufferEXT + #endif + ( + #ifndef MAGNUM_TARGET_GLES + GL_TEXTURE_BUFFER, + #else + GL_TEXTURE_BUFFER_EXT, + #endif + GLenum(internalFormat), buffer.id()); } +#ifndef MAGNUM_TARGET_GLES void BufferTexture::setBufferImplementationDSA(const BufferTextureFormat internalFormat, Buffer& buffer) { glTextureBuffer(id(), GLenum(internalFormat), buffer.id()); } @@ -82,12 +115,25 @@ void BufferTexture::setBufferImplementationDSA(const BufferTextureFormat interna void BufferTexture::setBufferImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer) { glTextureBufferEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id()); } +#endif void BufferTexture::setBufferRangeImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size) { bindInternal(); - glTexBufferRange(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id(), offset, size); + #ifndef MAGNUM_TARGET_GLES + glTexBufferRange + #else + glTexBufferRangeEXT + #endif + ( + #ifndef MAGNUM_TARGET_GLES + GL_TEXTURE_BUFFER, + #else + GL_TEXTURE_BUFFER_EXT, + #endif + GLenum(internalFormat), buffer.id(), offset, size); } +#ifndef MAGNUM_TARGET_GLES void BufferTexture::setBufferRangeImplementationDSA(const BufferTextureFormat internalFormat, Buffer& buffer, const GLintptr offset, const GLsizeiptr size) { glTextureBufferRange(id(), GLenum(internalFormat), buffer.id(), offset, size); } @@ -95,6 +141,7 @@ void BufferTexture::setBufferRangeImplementationDSA(const BufferTextureFormat in void BufferTexture::setBufferRangeImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size) { glTextureBufferRangeEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id(), offset, size); } +#endif } #endif diff --git a/src/Magnum/BufferTexture.h b/src/Magnum/BufferTexture.h index 2d05f87f0..a3ac61b33 100644 --- a/src/Magnum/BufferTexture.h +++ b/src/Magnum/BufferTexture.h @@ -25,7 +25,7 @@ DEALINGS IN THE SOFTWARE. */ -#ifndef MAGNUM_TARGET_GLES +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) /** @file * @brief Class @ref Magnum::BufferTexture, enum @ref Magnum::BufferTextureFormat */ @@ -33,13 +33,17 @@ #include "Magnum/AbstractTexture.h" -#ifndef MAGNUM_TARGET_GLES +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) namespace Magnum { /** @brief Internal buffer texture format @see @ref BufferTexture +@requires_gl31 Extension @extension{ARB,texture_buffer_object} +@requires_es_extension Extension @es_extension{ANDROID,extension_pack_es31a}/ + @es_extension{EXT,texture_buffer} +@requires_gles Texture buffers are not available in WebGL. */ enum class BufferTextureFormat: GLenum { /** Red component, normalized unsigned byte. */ @@ -51,14 +55,28 @@ enum class BufferTextureFormat: GLenum { /** RGBA, each component normalized unsigned byte. */ RGBA8 = GL_RGBA8, - /** Red component, normalized unsigned short. */ + #ifndef MAGNUM_TARGET_GLES + /** + * Red component, normalized unsigned short. + * @requires_gl Only @ref BufferTextureFormat::R8 is available in OpenGL + * ES. + */ R16 = GL_R16, - /** Red and green component, each normalized unsigned short. */ + /** + * Red and green component, each normalized unsigned short. + * @requires_gl Only @ref BufferTextureFormat::RG8 is available in OpenGL + * ES. + */ RG16 = GL_RG16, - /** RGBA, each component normalized unsigned short. */ + /** + * RGBA, each component normalized unsigned short. + * @requires_gl Only @ref BufferTextureFormat::RGBA8 is available in OpenGL + * ES. + */ RGBA16 = GL_RGBA16, + #endif /** Red component, non-normalized unsigned byte. */ R8UI = GL_R8UI, @@ -197,7 +215,10 @@ and respective function documentation for more information. @see @ref Texture, @ref TextureArray, @ref CubeMapTexture, @ref CubeMapTextureArray, @ref RectangleTexture, @ref MultisampleTexture @requires_gl31 Extension @extension{ARB,texture_buffer_object} -@requires_gl Texture buffers are not available in OpenGL ES or WebGL. +@requires_gles30 Not defined in OpenGL ES 2.0. +@requires_es_extension Extension @es_extension{ANDROID,extension_pack_es31a}/ + @es_extension{EXT,texture_buffer} +@requires_gles Texture buffers are not available in WebGL. */ class MAGNUM_EXPORT BufferTexture: public AbstractTexture { friend Implementation::TextureState; @@ -247,7 +268,12 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture { * @see @ref BufferTexture(NoCreateT), @ref wrap(), @fn_gl{CreateTextures} * with @def_gl{TEXTURE_BUFFER}, eventually @fn_gl{GenTextures} */ - explicit BufferTexture(): AbstractTexture(GL_TEXTURE_BUFFER) {} + explicit BufferTexture(): + #ifndef MAGNUM_TARGET_GLES + AbstractTexture(GL_TEXTURE_BUFFER) {} + #else + AbstractTexture(GL_TEXTURE_BUFFER_EXT) {} + #endif /** * @brief Construct without creating the underlying OpenGL object @@ -257,7 +283,12 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture { * another object over it to make it useful. * @see @ref BufferTexture(), @ref wrap() */ - explicit BufferTexture(NoCreateT) noexcept: AbstractTexture{NoCreate, GL_TEXTURE_BUFFER} {} + explicit BufferTexture(NoCreateT) noexcept: + #ifndef MAGNUM_TARGET_GLES + AbstractTexture{NoCreate, GL_TEXTURE_BUFFER} {} + #else + AbstractTexture{NoCreate, GL_TEXTURE_BUFFER_EXT} {} + #endif /** * @brief Set texture buffer @@ -313,20 +344,30 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture { #endif private: - explicit BufferTexture(GLuint id, ObjectFlags flags): AbstractTexture{id, GL_TEXTURE_BUFFER, flags} {} + explicit BufferTexture(GLuint id, ObjectFlags flags): AbstractTexture{id, + #ifndef MAGNUM_TARGET_GLES + GL_TEXTURE_BUFFER, + #else + GL_TEXTURE_BUFFER_EXT, + #endif + flags} {} void MAGNUM_LOCAL setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer); + #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL setBufferImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer); void MAGNUM_LOCAL setBufferImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer); + #endif void MAGNUM_LOCAL setBufferRangeImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); + #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL setBufferRangeImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); void MAGNUM_LOCAL setBufferRangeImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); + #endif }; } #else -#error this header is not available in OpenGL ES build +#error this header is not available in OpenGL ES 2.0 and WebGL build #endif #endif diff --git a/src/Magnum/CMakeLists.txt b/src/Magnum/CMakeLists.txt index ce6fabc0d..680a2c58a 100644 --- a/src/Magnum/CMakeLists.txt +++ b/src/Magnum/CMakeLists.txt @@ -131,13 +131,8 @@ set(Magnum_PRIVATE_HEADERS # Desktop-only stuff if(NOT TARGET_GLES) - list(APPEND Magnum_SRCS - BufferTexture.cpp - RectangleTexture.cpp) - - list(APPEND Magnum_HEADERS - BufferTexture.h - RectangleTexture.h) + list(APPEND Magnum_SRCS RectangleTexture.cpp) + list(APPEND Magnum_HEADERS RectangleTexture.h) endif() # OpenGL ES 3.0 and WebGL 2.0 stuff @@ -177,9 +172,11 @@ if(NOT TARGET_WEBGL) # Desktop and OpenGL ES 3.0 stuff that is not available in ES2 and WebGL if(NOT TARGET_GLES2) list(APPEND Magnum_SRCS + BufferTexture.cpp CubeMapTextureArray.cpp MultisampleTexture.cpp) list(APPEND Magnum_HEADERS + BufferTexture.h CubeMapTextureArray.h MultisampleTexture.h) endif() diff --git a/src/Magnum/Implementation/TextureState.cpp b/src/Magnum/Implementation/TextureState.cpp index 0622ec952..cfaee53d2 100644 --- a/src/Magnum/Implementation/TextureState.cpp +++ b/src/Magnum/Implementation/TextureState.cpp @@ -28,7 +28,7 @@ #include #include "Magnum/AbstractTexture.h" -#ifndef MAGNUM_TARGET_GLES +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #include "Magnum/BufferTexture.h" #endif #include "Magnum/Context.h" @@ -181,7 +181,7 @@ TextureState::TextureState(Context& context, std::vector& extension subImage3DImplementation = &AbstractTexture::subImageImplementationDefault; #endif - #ifndef MAGNUM_TARGET_GLES + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) setBufferImplementation = &BufferTexture::setBufferImplementationDefault; setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDefault; #endif diff --git a/src/Magnum/Implementation/TextureState.h b/src/Magnum/Implementation/TextureState.h index 3a8578f96..137435731 100644 --- a/src/Magnum/Implementation/TextureState.h +++ b/src/Magnum/Implementation/TextureState.h @@ -81,7 +81,7 @@ struct TextureState { void(AbstractTexture::*invalidateImageImplementation)(GLint); void(AbstractTexture::*invalidateSubImageImplementation)(GLint, const Vector3i&, const Vector3i&); - #ifndef MAGNUM_TARGET_GLES + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) void(BufferTexture::*setBufferImplementation)(BufferTextureFormat, Buffer&); void(BufferTexture::*setBufferRangeImplementation)(BufferTextureFormat, Buffer&, GLintptr, GLsizeiptr); #endif @@ -103,8 +103,10 @@ struct TextureState { GLint maxArrayLayers; #endif #ifndef MAGNUM_TARGET_GLES - GLint maxRectangleSize, - maxBufferSize; + GLint maxRectangleSize; + #endif + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + GLint maxBufferSize; #endif GLint maxTextureUnits; #ifndef MAGNUM_TARGET_GLES2 @@ -117,7 +119,7 @@ struct TextureState { maxDepthSamples, maxIntegerSamples; #endif - #ifndef MAGNUM_TARGET_GLES + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) GLint bufferOffsetAlignment; #endif diff --git a/src/Magnum/Magnum.h b/src/Magnum/Magnum.h index f48d81271..0b22f642a 100644 --- a/src/Magnum/Magnum.h +++ b/src/Magnum/Magnum.h @@ -441,7 +441,7 @@ typedef BufferImage<2> BufferImage2D; typedef BufferImage<3> BufferImage3D; #endif -#ifndef MAGNUM_TARGET_GLES +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) class BufferTexture; enum class BufferTextureFormat: GLenum; #endif diff --git a/src/Magnum/Platform/magnum-info.cpp b/src/Magnum/Platform/magnum-info.cpp index 7cecf300f..b5f0c3338 100644 --- a/src/Magnum/Platform/magnum-info.cpp +++ b/src/Magnum/Platform/magnum-info.cpp @@ -31,7 +31,7 @@ #include "Magnum/AbstractShaderProgram.h" #include "Magnum/Buffer.h" -#ifndef MAGNUM_TARGET_GLES +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #include "Magnum/BufferTexture.h" #endif #include "Magnum/Context.h" @@ -482,21 +482,39 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat _l(Shader::maxTessellationEvaluationInputComponents()) _l(Shader::maxTessellationEvaluationOutputComponents()) } + #endif - if(c->isExtensionSupported()) { + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + #ifndef MAGNUM_TARGET_GLES + if(c->isExtensionSupported()) + #else + if(c->isExtensionSupported()) + #endif + { + #ifndef MAGNUM_TARGET_GLES _h(ARB::texture_buffer_object) + #else + _h(EXT::texture_buffer) + #endif _l(BufferTexture::maxSize()) } - if(c->isExtensionSupported()) { + #ifndef MAGNUM_TARGET_GLES + if(c->isExtensionSupported()) + #else + if(c->isExtensionSupported()) + #endif + { + #ifndef MAGNUM_TARGET_GLES _h(ARB::texture_buffer_range) + #else + /* Header added above */ + #endif _l(BufferTexture::offsetAlignment()) } - #endif - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) #ifndef MAGNUM_TARGET_GLES if(c->isExtensionSupported()) #else diff --git a/src/Magnum/Test/BufferTextureGLTest.cpp b/src/Magnum/Test/BufferTextureGLTest.cpp index 1f0cc66ef..92f4e2992 100644 --- a/src/Magnum/Test/BufferTextureGLTest.cpp +++ b/src/Magnum/Test/BufferTextureGLTest.cpp @@ -54,8 +54,13 @@ BufferTextureGLTest::BufferTextureGLTest() { } void BufferTextureGLTest::construct() { + #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_buffer_object::string() + std::string(" is not supported.")); + #else + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_buffer::string() + std::string(" is not supported.")); + #endif { BufferTexture texture; @@ -79,8 +84,13 @@ void BufferTextureGLTest::constructNoCreate() { } void BufferTextureGLTest::wrap() { + #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_buffer_object::string() + std::string(" is not supported.")); + #else + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_buffer::string() + std::string(" is not supported.")); + #endif GLuint id; glGenTextures(1, &id); @@ -97,8 +107,13 @@ void BufferTextureGLTest::wrap() { } void BufferTextureGLTest::bind() { + #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_buffer_object::string() + std::string(" is not supported.")); + #else + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_buffer::string() + std::string(" is not supported.")); + #endif BufferTexture texture; texture.bind(15); @@ -119,8 +134,13 @@ void BufferTextureGLTest::bind() { } void BufferTextureGLTest::setBuffer() { + #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_buffer_object::string() + std::string(" is not supported.")); + #else + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_buffer::string() + std::string(" is not supported.")); + #endif BufferTexture texture; Buffer buffer; @@ -135,10 +155,15 @@ void BufferTextureGLTest::setBuffer() { } void BufferTextureGLTest::setBufferOffset() { + #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_buffer_object::string() + std::string(" is not supported.")); if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_buffer_range::string() + std::string(" is not supported.")); + #else + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_buffer::string() + std::string(" is not supported.")); + #endif /* Check that we have correct offset alignment */ CORRADE_INTERNAL_ASSERT(256 % BufferTexture::offsetAlignment() == 0); diff --git a/src/Magnum/Test/CMakeLists.txt b/src/Magnum/Test/CMakeLists.txt index 43eb3fa2c..f106fce0a 100644 --- a/src/Magnum/Test/CMakeLists.txt +++ b/src/Magnum/Test/CMakeLists.txt @@ -75,6 +75,7 @@ if(BUILD_GL_TESTS) if(NOT MAGNUM_TARGET_GLES2) corrade_add_test(BufferImageGLTest BufferImageGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) + corrade_add_test(BufferTextureGLTest BufferTextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(CubeMapTextureArrayGLTest CubeMapTextureArrayGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(MultisampleTextureGLTest MultisampleTextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(PrimitiveQueryGLTest PrimitiveQueryGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) @@ -83,7 +84,6 @@ if(BUILD_GL_TESTS) endif() if(NOT MAGNUM_TARGET_GLES) - corrade_add_test(BufferTextureGLTest BufferTextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(RectangleTextureGLTest RectangleTextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) endif() endif()