From 959d40a02d0ff3adeef3fc62b663db10bd2977b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 27 Jan 2014 15:38:56 +0100 Subject: [PATCH] Split Texture into TextureArray, MultisampleTexture and RectangleTexture. Each texture has slightly different usage requirements and having everything under one generic class is not worth the additional runtime checks and whatnot. The current way with Texture::Target enum (hopefully not too widely used) is now deprecated and will be removed in some future release. However general Texture1D/2D/3D usage is not changed in any way. --- doc/opengl-mapping.dox | 8 +- src/Magnum/AbstractTexture.cpp | 25 +- src/Magnum/AbstractTexture.h | 143 +-- src/Magnum/BufferTexture.h | 9 +- src/Magnum/CMakeLists.txt | 7 +- src/Magnum/CubeMapTexture.h | 63 +- src/Magnum/CubeMapTextureArray.h | 65 +- src/Magnum/Magnum.h | 18 +- src/Magnum/MultisampleTexture.h | 116 ++ src/Magnum/RectangleTexture.h | 323 +++++ src/Magnum/Test/CMakeLists.txt | 3 + src/Magnum/Test/CubeMapTextureArrayGLTest.cpp | 3 +- src/Magnum/Test/CubeMapTextureGLTest.cpp | 3 +- src/Magnum/Test/MeshGLTest.cpp | 1 + src/Magnum/Test/MultisampleTextureGLTest.cpp | 212 ++++ src/Magnum/Test/RectangleTextureGLTest.cpp | 250 ++++ src/Magnum/Test/TextureArrayGLTest.cpp | 683 +++++++++++ src/Magnum/Test/TextureGLTest.cpp | 1061 +---------------- src/Magnum/Text/AbstractFont.cpp | 1 + src/Magnum/Text/Renderer.cpp | 1 + src/Magnum/Text/Test/AbstractFontTest.cpp | 1 + src/Magnum/Texture.h | 369 +++--- src/Magnum/TextureArray.h | 302 +++++ 23 files changed, 2230 insertions(+), 1437 deletions(-) create mode 100644 src/Magnum/MultisampleTexture.h create mode 100644 src/Magnum/RectangleTexture.h create mode 100644 src/Magnum/Test/MultisampleTextureGLTest.cpp create mode 100644 src/Magnum/Test/RectangleTextureGLTest.cpp create mode 100644 src/Magnum/Test/TextureArrayGLTest.cpp create mode 100644 src/Magnum/TextureArray.h diff --git a/doc/opengl-mapping.dox b/doc/opengl-mapping.dox index c1ab1a932..98d1c6a4a 100644 --- a/doc/opengl-mapping.dox +++ b/doc/opengl-mapping.dox @@ -137,7 +137,7 @@ OpenGL function | Matching API @fn_gl{GenTextures}, @fn_gl{DeleteTextures} | @ref AbstractTexture constructor and destructor @fn_gl{GenTransformFeedbacks}, @fn_gl{DeleteTransformFeedbacks} | | @fn_gl{GenVertexArrays}, @fn_gl{DeleteVertexArrays} | @ref Mesh constructor and destructor -@fn_gl{GenerateMipmap}, \n @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access} | @ref AbstractTexture::generateMipmap() +@fn_gl{GenerateMipmap}, \n @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access} | @ref Texture::generateMipmap(), \n @ref TextureArray::generateMipmap(), \n @ref CubeMapTexture::generateMipmap(), \n @ref CubeMapTextureArray::generateMipmap() @fn_gl{Get} | see @ref opengl-mapping-state "table below" @fn_gl2{GetActiveAtomicCounterBuffer,GetActiveAtomicCounterBufferiv} | not queryable @fn_gl{GetActiveAttrib}, \n @fn_gl{GetActiveSubroutineName}, \n @fn_gl{GetActiveSubroutineUniform}, \n @fn_gl{GetActiveSubroutineUniformName}, \n @fn_gl{GetActiveUniform}, \n @fn_gl{GetActiveUniformBlock}, \n @fn_gl{GetActiveUniformBlockName}, \n @fn_gl{GetActiveUniformName}, \n @fn_gl{GetActiveUniforms} | not queryable @@ -193,8 +193,8 @@ OpenGL function | Matching API @fn_gl{InvalidateBufferSubData} | @ref Buffer::invalidateSubData() @fn_gl{InvalidateFramebuffer}, \n @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer} | @ref DefaultFramebuffer::invalidate(), \n @ref Framebuffer::invalidate() @fn_gl{InvalidateSubFramebuffer}, \n @fn_gles_extension{DiscardSubFramebuffer,EXT,discard_framebuffer} | @ref DefaultFramebuffer::invalidate(), \n @ref Framebuffer::invalidate() -@fn_gl{InvalidateTexImage} | @ref AbstractTexture::invalidateImage() -@fn_gl{InvalidateTexSubImage} | @ref Texture::invalidateSubImage(),\n @ref CubeMapTexture::invalidateSubImage(), \n @ref CubeMapTextureArray::invalidateSubImage() +@fn_gl{InvalidateTexImage} | @ref Texture::invalidateImage(), \n @ref TextureArray::invalidateImage(), \n @ref CubeMapTexture::invalidateImage(), \n @ref CubeMapTextureArray::invalidateImage(), \n @ref MultisampleTexture::invalidateImage(), \n @ref RectangleTexture::invalidateImage() +@fn_gl{InvalidateTexSubImage} | @ref Texture::invalidateSubImage(), \n @ref TextureArray::invalidateSubImage(), \n @ref CubeMapTexture::invalidateSubImage(), \n @ref CubeMapTextureArray::invalidateSubImage(), \n @ref MultisampleTexture::invalidateSubImage(), \n @ref RectangleTexture::invalidateSubImage() @fn_gl{IsBuffer}, \n @fn_gl{IsFramebuffer}, \n @fn_gl{IsProgram}, \n @fn_gl{IsProgramPipeline}, \n @fn_gl{IsQuery}, \n @fn_gl{IsRenderbuffer}, \n @fn_gl{IsSampler}, \n @fn_gl{IsShader}, \n @fn_gl{IsSync}, \n @fn_gl{IsTexture}, \n @fn_gl{IsTransformFeedback}, \n @fn_gl{IsVertexArray} | not needed, objects are strongly typed @fn_gl{IsEnabled} | not queryable, @ref Renderer::setFeature() setter only @fn_gl{LineWidth} | @ref Renderer::setLineWidth() @@ -239,7 +239,7 @@ OpenGL function | Matching API @fn_gl{TexBuffer}, \n @fn_gl_extension{TextureBuffer,EXT,direct_state_access}, \n @fn_gl{TexBufferRange}, \n @fn_gl_extension{TextureBufferRange,EXT,direct_state_access} | @ref BufferTexture::setBuffer() @fn_gl{TexImage1D}, \n @fn_gl_extension{TextureImage1D,EXT,direct_state_access} \n @fn_gl{TexImage2D}, \n @fn_gl_extension{TextureImage2D,EXT,direct_state_access}, \n @fn_gl{TexImage3D}, \n @fn_gl_extension{TextureImage3D,EXT,direct_state_access} | @ref Texture::setImage(), \n @ref CubeMapTexture::setImage(), \n @ref CubeMapTextureArray::setImage() @fn_gl{TexImage2DMultisample}, \n @fn_gl{TexImage3DMultisample} | | -@fn_gl{TexParameter}, \n @fn_gl_extension{TextureParameter,EXT,direct_state_access} | @ref AbstractTexture::setMinificationFilter(), \n @ref AbstractTexture::setMagnificationFilter(), \n @ref AbstractTexture::setBorderColor(), \n @ref AbstractTexture::setMaxAnisotropy(), \n @ref Texture::setWrapping(), \n @ref CubeMapTexture::setWrapping(), \n @ref CubeMapTextureArray::setWrapping() +@fn_gl{TexParameter}, \n @fn_gl_extension{TextureParameter,EXT,direct_state_access} | @ref Texture::setMinificationFilter(), \n @ref TextureArray::setMinificationFilter(), \n @ref CubeMapTexture::setMinificationFilter(), \n @ref CubeMapTextureArray::setMinificationFilter(), \n @ref RectangleTexture::setMinificationFilter(), \n @ref Texture::setMagnificationFilter(), \n @ref TextureArray::setMagnificationFilter(), \n @ref CubeMapTexture::setMagnificationFilter(), \n @ref CubeMapTextureArray::setMagnificationFilter(), \n @ref RectangleTexture::setMagnificationFilter(), \n @ref Texture::setBorderColor(), \n @ref TextureArray::setBorderColor(), \n @ref CubeMapTexture::setBorderColor(), \n @ref CubeMapTextureArray::setBorderColor(), \n @ref RectangleTexture::setBorderColor(), \n @ref Texture::setMaxAnisotropy(), \n @ref TextureArray::setMaxAnisotropy(), \n @ref CubeMapTexture::setMaxAnisotropy(), \n @ref CubeMapTextureArray::setMaxAnisotropy(), \n @ref RectangleTexture::setMaxAnisotropy(), \n @ref Texture::setWrapping(), \n @ref TextureArray::setWrapping(), \n @ref CubeMapTexture::setWrapping(), \n @ref CubeMapTextureArray::setWrapping(), \n @ref RectangleTexture::setWrapping() @fn_gl{TexStorage1D}, \n @fn_gl_extension{TextureStorage1D,EXT,direct_state_access}, \n @fn_gl{TexStorage2D}, \n @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}, \n @fn_gl{TexStorage3D}, \n @fn_gl_extension{TextureStorage3D,EXT,direct_state_access} | @ref Texture::setStorage(), \n @ref CubeMapTexture::setStorage(), \n @ref CubeMapTextureArray::setStorage() @fn_gl{TexStorage2DMultisample}, \n @fn_gl{TexStorage3DMultisample} | | @fn_gl{TexSubImage1D}, \n @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}, \n @fn_gl{TexSubImage2D}, \n @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}, \n @fn_gl{TexSubImage3D}, \n @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} | @ref Texture::setSubImage(), \n @ref CubeMapTexture::setSubImage(), \n @ref CubeMapTextureArray::setSubImage() diff --git a/src/Magnum/AbstractTexture.cpp b/src/Magnum/AbstractTexture.cpp index 5742d3e87..4d2dd9d40 100644 --- a/src/Magnum/AbstractTexture.cpp +++ b/src/Magnum/AbstractTexture.cpp @@ -28,6 +28,8 @@ #ifndef MAGNUM_TARGET_GLES2 #include "Magnum/BufferImage.h" #endif +#include "Magnum/Array.h" +#include "Magnum/Color.h" #include "Magnum/ColorFormat.h" #include "Magnum/Context.h" #include "Magnum/Extensions.h" @@ -134,45 +136,32 @@ void AbstractTexture::bindImplementationDSA(GLint layer) { } #endif -AbstractTexture& AbstractTexture::setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap) { - #ifndef MAGNUM_TARGET_GLES - CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Sampler::Mipmap::Base, "AbstractTexture: rectangle textures cannot have mipmaps", *this); - #endif - +void AbstractTexture::setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap) { (this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_MIN_FILTER, GLint(filter)|GLint(mipmap)); - return *this; } -AbstractTexture& AbstractTexture::setMagnificationFilter(const Sampler::Filter filter) { +void AbstractTexture::setMagnificationFilter(const Sampler::Filter filter) { (this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_MAG_FILTER, GLint(filter)); - return *this; } -AbstractTexture& AbstractTexture::setBorderColor(const Color4& color) { +void AbstractTexture::setBorderColor(const Color4& color) { #ifndef MAGNUM_TARGET_GLES (this->*Context::current()->state().texture->parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR, color.data()); #else (this->*Context::current()->state().texture->parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR_NV, color.data()); #endif - return *this; } -AbstractTexture& AbstractTexture::setMaxAnisotropy(const Float anisotropy) { +void AbstractTexture::setMaxAnisotropy(const Float anisotropy) { (this->*Context::current()->state().texture->setMaxAnisotropyImplementation)(anisotropy); - return *this; } void AbstractTexture::invalidateImage(const Int level) { (this->*Context::current()->state().texture->invalidateImageImplementation)(level); } -AbstractTexture& AbstractTexture::generateMipmap() { - #ifndef MAGNUM_TARGET_GLES - CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", *this); - #endif - +void AbstractTexture::generateMipmap() { (this->*Context::current()->state().texture->mipmapImplementation)(); - return *this; } void AbstractTexture::mipmapImplementationDefault() { diff --git a/src/Magnum/AbstractTexture.h b/src/Magnum/AbstractTexture.h index a234e6887..8a10eede1 100644 --- a/src/Magnum/AbstractTexture.h +++ b/src/Magnum/AbstractTexture.h @@ -29,8 +29,6 @@ * @brief Class @ref Magnum::AbstractTexture */ -#include "Magnum/Array.h" -#include "Magnum/Color.h" #include "Magnum/Sampler.h" #include "Magnum/AbstractObject.h" @@ -81,7 +79,7 @@ OpenGL ES 3.0 or @es_extension{EXT,texture_storage} in OpenGL ES 2.0 is not available, the feature is emulated with sequence of @ref Texture::setImage() "setImage()" calls. -You can use functions @ref invalidateImage() and +You can use functions @ref Texture::invalidateImage() and @ref Texture::invalidateSubImage() "invalidateSubImage()" if you don't need texture data anymore to avoid unnecessary memory operations performed by OpenGL in order to preserve the data. If running on OpenGL ES or extension @@ -158,6 +156,14 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { static Int maxIntegerSamples(); #endif + /** + * @brief Destructor + * + * Deletes associated OpenGL texture. + * @see @fn_gl{DeleteTextures} + */ + ~AbstractTexture(); + /** @brief Copying is not allowed */ AbstractTexture(const AbstractTexture&) = delete; @@ -211,116 +217,6 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { */ void bind(Int layer); - /** - * @brief Set minification filter - * @param filter Filter - * @param mipmap Mipmap filtering. If set to anything else than - * @ref Sampler::Mipmap::Base, make sure textures for all mip - * levels are set or call @ref generateMipmap(). - * @return Reference to self (for method chaining) - * - * Sets filter used when the object pixel size is smaller than the - * texture size. If @extension{EXT,direct_state_access} is not - * available, the texture is bound to some layer before the operation. - * Initial value is (@ref Sampler::Filter::Nearest, @ref Sampler::Mipmap::Linear). - * @attention For rectangle textures only some modes are supported, - * see @ref Sampler::Filter and @ref Sampler::Mipmap documentation - * for more information. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_MIN_FILTER} - */ - AbstractTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base); - - /** - * @brief Set magnification filter - * @param filter Filter - * @return Reference to self (for method chaining) - * - * Sets filter used when the object pixel size is larger than largest - * texture size. If @extension{EXT,direct_state_access} is not - * available, the texture is bound to some layer before the operation. - * Initial value is @ref Sampler::Filter::Linear. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_MAG_FILTER} - */ - AbstractTexture& setMagnificationFilter(Sampler::Filter filter); - - /** - * @brief Set border color - * @return Reference to self (for method chaining) - * - * Border color when wrapping is set to @ref Sampler::Wrapping::ClampToBorder. - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some layer before the operation. Initial value is - * `{0.0f, 0.0f, 0.0f, 0.0f}`. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_BORDER_COLOR} - * @requires_es_extension %Extension @es_extension{NV,texture_border_clamp} - */ - AbstractTexture& setBorderColor(const Color4& color); - - /** - * @brief Set max anisotropy - * @return Reference to self (for method chaining) - * - * Default value is `1.0f`, which means no anisotropy. Set to value - * greater than `1.0f` for anisotropic filtering. If extension - * @extension{EXT,texture_filter_anisotropic} (desktop or ES) is not - * available, this function does nothing. If - * @extension{EXT,direct_state_access} is not available, the texture is - * bound to some layer before the operation. - * @see @ref Sampler::maxMaxAnisotropy(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_MAX_ANISOTROPY_EXT} - */ - AbstractTexture& setMaxAnisotropy(Float anisotropy); - - /** - * @brief Invalidate texture image - * @param level Mip level - * - * If running on OpenGL ES or extension @extension{ARB,invalidate_subdata} - * (part of OpenGL 4.3) is not available, this function does nothing. - * @see @ref Texture::invalidateSubImage() "invalidateSubImage()", - * @fn_gl{InvalidateTexImage} - */ - void invalidateImage(Int level); - - /** - * @brief Generate mipmap - * @return Reference to self (for method chaining) - * - * Can not be used for rectangle textures. If - * @extension{EXT,direct_state_access} is not available, the texture - * is bound to some layer before the operation. - * @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{ARB,framebuffer_object} - */ - AbstractTexture& generateMipmap(); - - protected: - /** - * @brief Constructor - * - * Creates new OpenGL texture. - * @see @fn_gl{GenTextures} - */ - explicit AbstractTexture(GLenum target); - - /** - * @brief Destructor - * - * Deletes assigned OpenGL texture. - * @see @fn_gl{DeleteTextures} - */ - ~AbstractTexture(); - #ifdef DOXYGEN_GENERATING_OUTPUT private: #else @@ -328,9 +224,18 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { #endif template struct DataHelper {}; + explicit AbstractTexture(GLenum target); + /* Unlike bind() this also sets the binding layer as active */ void MAGNUM_LOCAL bindInternal(); + void setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap); + void setMagnificationFilter(Sampler::Filter filter); + void setBorderColor(const Color4& color); + void setMaxAnisotropy(Float anisotropy); + void invalidateImage(Int level); + void generateMipmap(); + #ifndef MAGNUM_TARGET_GLES template void image(GLenum target, GLint level, Image& image); template void image(GLenum target, GLint level, BufferImage& image, BufferUsage usage); @@ -445,11 +350,11 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { #ifndef DOXYGEN_GENERATING_OUTPUT #ifndef MAGNUM_TARGET_GLES template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<1> { + #ifdef MAGNUM_BUILD_DEPRECATED enum class Target: GLenum { Texture1D = GL_TEXTURE_1D }; - - constexpr static Target target() { return Target::Texture1D; } + #endif static Math::Vector<1, GLint> imageSize(AbstractTexture& texture, GLenum target, GLint level); @@ -467,6 +372,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<1> { }; #endif template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> { + #ifdef MAGNUM_BUILD_DEPRECATED enum class Target: GLenum { Texture2D = GL_TEXTURE_2D, #ifndef MAGNUM_TARGET_GLES @@ -475,8 +381,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> { Rectangle = GL_TEXTURE_RECTANGLE #endif }; - - constexpr static Target target() { return Target::Texture2D; } + #endif #ifndef MAGNUM_TARGET_GLES static Vector2i imageSize(AbstractTexture& texture, GLenum target, GLint level); @@ -499,6 +404,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> { static void invalidateSubImage(AbstractTexture& texture, GLint level, const Vector2i& offset, const Vector2i& size); }; template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> { + #ifdef MAGNUM_BUILD_DEPRECATED enum class Target: GLenum { #ifndef MAGNUM_TARGET_GLES2 Texture3D = GL_TEXTURE_3D, @@ -510,8 +416,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> { Texture3D = GL_TEXTURE_3D_OES #endif }; - - constexpr static Target target() { return Target::Texture3D; } + #endif #ifndef MAGNUM_TARGET_GLES static Vector3i imageSize(AbstractTexture& texture, GLenum target, GLint level); diff --git a/src/Magnum/BufferTexture.h b/src/Magnum/BufferTexture.h index d30e4f4c0..67d9931ee 100644 --- a/src/Magnum/BufferTexture.h +++ b/src/Magnum/BufferTexture.h @@ -195,7 +195,8 @@ functions use DSA to avoid unnecessary calls to @fn_gl{ActiveTexture} and @ref AbstractTexture-performance-optimization "relevant section in AbstractTexture documentation" and respective function documentation for more information. -@see @ref Texture, @ref CubeMapTexture, @ref CubeMapTextureArray +@see @ref Texture, @ref TextureArray, @ref CubeMapTexture, + @ref CubeMapTextureArray, @ref MultisampleTexture, @ref RectangleTexture @requires_gl31 %Extension @extension{ARB,texture_buffer_object} @requires_gl Texture buffers are not available in OpenGL ES. */ @@ -216,6 +217,12 @@ class MAGNUM_EXPORT BufferTexture: private AbstractTexture { */ static Int offsetAlignment(); + /** + * @brief Constructor + * + * Creates new OpenGL texture object. + * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_BUFFER} + */ explicit BufferTexture(): AbstractTexture(GL_TEXTURE_BUFFER) {} /** @copydoc AbstractTexture::id() */ diff --git a/src/Magnum/CMakeLists.txt b/src/Magnum/CMakeLists.txt index 9b619b6f9..359fa3301 100644 --- a/src/Magnum/CMakeLists.txt +++ b/src/Magnum/CMakeLists.txt @@ -138,14 +138,17 @@ endif() if(NOT TARGET_GLES) set(Magnum_HEADERS ${Magnum_HEADERS} BufferTexture.h - CubeMapTextureArray.h) + CubeMapTextureArray.h + MultisampleTexture.h + RectangleTexture.h) set(Magnum_SRCS ${Magnum_SRCS} $) endif() # Not-ES2 headers if(NOT TARGET_GLES2) set(Magnum_HEADERS ${Magnum_HEADERS} - BufferImage.h) + BufferImage.h + TextureArray.h) endif() # Files shared between main library and math unit test library diff --git a/src/Magnum/CubeMapTexture.h b/src/Magnum/CubeMapTexture.h index 1cd6401cd..8db6acaf7 100644 --- a/src/Magnum/CubeMapTexture.h +++ b/src/Magnum/CubeMapTexture.h @@ -30,6 +30,8 @@ */ #include "Magnum/AbstractTexture.h" +#include "Magnum/Array.h" +#include "Magnum/Math/Vector2.h" namespace Magnum { @@ -92,21 +94,41 @@ class CubeMapTexture: public AbstractTexture { /** * @brief Constructor * - * Creates one cube map OpenGL texture. + * Creates new OpenGL texture object. * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP} */ explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {} - /** - * @brief Set wrapping - * - * See @ref Texture::setWrapping() for more information. - */ + /** @copydoc Texture::setMinificationFilter() */ + CubeMapTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { + AbstractTexture::setMinificationFilter(filter, mipmap); + return *this; + } + + /** @copydoc Texture::setMagnificationFilter() */ + CubeMapTexture& setMagnificationFilter(Sampler::Filter filter) { + AbstractTexture::setMagnificationFilter(filter); + return *this; + } + + /** @copydoc Texture::setWrapping() */ CubeMapTexture& setWrapping(const Array3D& wrapping) { DataHelper<3>::setWrapping(*this, wrapping); return *this; } + /** @copydoc Texture::setBorderColor() */ + CubeMapTexture& setBorderColor(const Color4& color) { + AbstractTexture::setBorderColor(color); + return *this; + } + + /** @copydoc Texture::setMaxAnisotropy() */ + CubeMapTexture& setMaxAnisotropy(Float anisotropy) { + AbstractTexture::setMaxAnisotropy(anisotropy); + return *this; + } + #ifndef MAGNUM_TARGET_GLES /** * @brief %Image size in given mip level @@ -220,6 +242,15 @@ class CubeMapTexture: public AbstractTexture { } #endif + /** @copydoc Texture::generateMipmap() */ + CubeMapTexture& generateMipmap() { + AbstractTexture::generateMipmap(); + return *this; + } + + /** @copydoc Texture::invalidateImage() */ + void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } + /** * @brief Invalidate texture subimage * @param level Mip level @@ -242,26 +273,6 @@ class CubeMapTexture: public AbstractTexture { AbstractTexture::setLabel(label); return *this; } - CubeMapTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { - AbstractTexture::setMinificationFilter(filter, mipmap); - return *this; - } - CubeMapTexture& setMagnificationFilter(Sampler::Filter filter) { - AbstractTexture::setMagnificationFilter(filter); - return *this; - } - CubeMapTexture& setBorderColor(const Color4& color) { - AbstractTexture::setBorderColor(color); - return *this; - } - CubeMapTexture& setMaxAnisotropy(Float anisotropy) { - AbstractTexture::setMaxAnisotropy(anisotropy); - return *this; - } - CubeMapTexture& generateMipmap() { - AbstractTexture::generateMipmap(); - return *this; - } #endif }; diff --git a/src/Magnum/CubeMapTextureArray.h b/src/Magnum/CubeMapTextureArray.h index 4767d67a7..a22b89ece 100644 --- a/src/Magnum/CubeMapTextureArray.h +++ b/src/Magnum/CubeMapTextureArray.h @@ -32,6 +32,8 @@ #endif #include "Magnum/AbstractTexture.h" +#include "Magnum/Array.h" +#include "Magnum/Math/Vector2.h" #ifndef MAGNUM_TARGET_GLES namespace Magnum { @@ -83,21 +85,41 @@ class CubeMapTextureArray: public AbstractTexture { /** * @brief Constructor * - * Creates one cube map OpenGL texture. - * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP} + * Creates new OpenGL texture object. + * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP_ARRAY} */ explicit CubeMapTextureArray(): AbstractTexture(GL_TEXTURE_CUBE_MAP_ARRAY) {} - /** - * @brief Set wrapping - * - * See @ref Texture::setWrapping() for more information. - */ + /** @copydoc Texture::setMinificationFilter() */ + CubeMapTextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { + AbstractTexture::setMinificationFilter(filter, mipmap); + return *this; + } + + /** @copydoc Texture::setMagnificationFilter() */ + CubeMapTextureArray& setMagnificationFilter(Sampler::Filter filter) { + AbstractTexture::setMagnificationFilter(filter); + return *this; + } + + /** @copydoc Texture::setWrapping() */ CubeMapTextureArray& setWrapping(const Array3D& wrapping) { DataHelper<3>::setWrapping(*this, wrapping); return *this; } + /** @copydoc Texture::setBorderColor() */ + CubeMapTextureArray& setBorderColor(const Color4& color) { + AbstractTexture::setBorderColor(color); + return *this; + } + + /** @copydoc Texture::setMaxAnisotropy() */ + CubeMapTextureArray& setMaxAnisotropy(Float anisotropy) { + AbstractTexture::setMaxAnisotropy(anisotropy); + return *this; + } + /** * @brief %Image size in given mip level * @param level Mip level @@ -207,6 +229,15 @@ class CubeMapTextureArray: public AbstractTexture { return setSubImage(level, offset, image); } + /** @copydoc Texture::generateMipmap() */ + CubeMapTextureArray& generateMipmap() { + AbstractTexture::generateMipmap(); + return *this; + } + + /** @copydoc Texture::invalidateImage() */ + void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } + /** * @brief Invalidate texture subimage * @param level Mip level @@ -228,26 +259,6 @@ class CubeMapTextureArray: public AbstractTexture { AbstractTexture::setLabel(label); return *this; } - CubeMapTextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { - AbstractTexture::setMinificationFilter(filter, mipmap); - return *this; - } - CubeMapTextureArray& setMagnificationFilter(Sampler::Filter filter) { - AbstractTexture::setMagnificationFilter(filter); - return *this; - } - CubeMapTextureArray& setBorderColor(const Color4& color) { - AbstractTexture::setBorderColor(color); - return *this; - } - CubeMapTextureArray& setMaxAnisotropy(Float anisotropy) { - AbstractTexture::setMaxAnisotropy(anisotropy); - return *this; - } - CubeMapTextureArray& generateMipmap() { - AbstractTexture::generateMipmap(); - return *this; - } #endif }; diff --git a/src/Magnum/Magnum.h b/src/Magnum/Magnum.h index 5166cd1dd..969b9b4f4 100644 --- a/src/Magnum/Magnum.h +++ b/src/Magnum/Magnum.h @@ -560,8 +560,8 @@ typedef ColorFormat ImageFormat; typedef ColorType ColorType; class Context; -class CubeMapTexture; +class CubeMapTexture; #ifndef MAGNUM_TARGET_GLES class CubeMapTextureArray; #endif @@ -588,11 +588,19 @@ enum class MeshPrimitive: GLenum; class Mesh; class MeshView; +#ifndef MAGNUM_TARGET_GLES +template class MultisampleTexture; +typedef MultisampleTexture<2> MultisampleTexture2D; +typedef MultisampleTexture<3> MultisampleTexture2DArray; +#endif + /* AbstractQuery is not used directly */ class PrimitiveQuery; class SampleQuery; class TimeQuery; +class RectangleTexture; + class Renderbuffer; enum class RenderbufferFormat: GLenum; @@ -613,6 +621,14 @@ typedef Texture<1> Texture1D; typedef Texture<2> Texture2D; typedef Texture<3> Texture3D; +#ifndef MAGNUM_TARGET_GLES2 +template class TextureArray; +#ifndef MAGNUM_TARGET_GLES +typedef TextureArray<1> Texture1DArray; +#endif +typedef TextureArray<2> Texture2DArray; +#endif + enum class TextureFormat: GLenum; class Timeline; diff --git a/src/Magnum/MultisampleTexture.h b/src/Magnum/MultisampleTexture.h new file mode 100644 index 000000000..cff1c1d2b --- /dev/null +++ b/src/Magnum/MultisampleTexture.h @@ -0,0 +1,116 @@ +#ifndef Magnum_MultisampleTexture_h +#define Magnum_MultisampleTexture_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef MAGNUM_TARGET_GLES +/** @file + * @brief Class @ref Magnum::MultisampleTexture, typedef @ref Magnum::MultisampleTexture2D, @ref Magnum::MultisampleTexture2DArray + */ +#endif + +#include "Magnum/AbstractTexture.h" +#include "Magnum/DimensionTraits.h" +#include "Magnum/Math/Vector3.h" + +#ifndef MAGNUM_TARGET_GLES +namespace Magnum { + +namespace Implementation { + template constexpr GLenum multisampleTextureTarget(); + template<> inline constexpr GLenum multisampleTextureTarget<2>() { return GL_TEXTURE_2D_MULTISAMPLE; } + template<> inline constexpr GLenum multisampleTextureTarget<3>() { return GL_TEXTURE_2D_MULTISAMPLE_ARRAY; } +} + +/** +@brief Mulitsample texture + +Template class for 2D mulitsample texture and 2D multisample texture array. See +also @ref AbstractTexture documentation for more information. + +@todoc Finish when fully implemented + +The texture is bound to layer specified by shader via @ref bind(). In shader, +the texture is used via `sampler2DMS`/`sampler2DMSArray`, +`isampler2DMS`/`isampler2DMSArray` or `usampler2DMS`/`usampler2DMSArray`. See +@ref AbstractShaderProgram documentation for more information about usage in +shaders. + +@requires_gl32 %Extension @extension{ARB,texture_multisample} +@requires_gl Multisample textures are not available in OpenGL ES. + +@see @ref MultisampleTexture2D, @ref MultisampleTexture2DArray, @ref Texture, + @ref TextureArray, @ref BufferTexture, @ref CubeMapTexture, + @ref CubeMapTextureArray, @ref RectangleTexture + */ +template class MultisampleTexture: public AbstractTexture { + public: + static const UnsignedInt Dimensions = dimensions; /**< @brief %Texture dimension count */ + + /** + * @brief Constructor + * + * Creates new OpenGL texture object. + * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_2D_MULTISAMPLE} or + * @def_gl{TEXTURE_2D_MULTISAMPLE_ARRAY} + */ + explicit MultisampleTexture(): AbstractTexture(Implementation::multisampleTextureTarget()) {} + + #ifndef MAGNUM_TARGET_GLES + /** @copydoc Texture::imageSize() */ + typename DimensionTraits::VectorType imageSize(Int level) { + return DataHelper::imageSize(*this, _target, level); + } + #endif + + /** @copydoc Texture::invalidateImage() */ + void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } + + /** @copydoc Texture::invalidateSubImage() */ + void invalidateSubImage(Int level, const typename DimensionTraits::VectorType& offset, const typename DimensionTraits::VectorType& size) { + DataHelper::invalidateSubImage(*this, level, offset, size); + } + + /* Overloads to remove WTF-factor from method chaining order */ + #ifndef DOXYGEN_GENERATING_OUTPUT + MultisampleTexture& setLabel(const std::string& label) { + AbstractTexture::setLabel(label); + return *this; + } + #endif +}; + +/** @brief Two-dimensional multisample texture */ +typedef MultisampleTexture<2> MultisampleTexture2D; + +/** @brief Two-dimensional multisample texture array */ +typedef MultisampleTexture<3> MultisampleTexture2DArray; + +} +#else +#error this header is available only on desktop OpenGL build +#endif + +#endif diff --git a/src/Magnum/RectangleTexture.h b/src/Magnum/RectangleTexture.h new file mode 100644 index 000000000..d226bc9c8 --- /dev/null +++ b/src/Magnum/RectangleTexture.h @@ -0,0 +1,323 @@ +#ifndef Magnum_RectangleTexture_h +#define Magnum_RectangleTexture_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef MAGNUM_TARGET_GLES +/** @file + * @brief Class @ref Magnum::RectangleTexture + */ +#endif + +#include "Magnum/AbstractTexture.h" +#include "Magnum/Array.h" +#include "Magnum/Math/Vector2.h" + +#ifndef MAGNUM_TARGET_GLES +namespace Magnum { + +/** +@brief Rectangle texture + +See also @ref AbstractTexture documentation for more information. + +@section RectangleTexture-usage Usage + +Common usage is to fully configure all texture parameters and then set the +data from e.g. @ref Image2D. Example configuration: +@code +Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte, {526, 137}, data); + +RectangleTexture texture; +texture.setMagnificationFilter(Sampler::Filter::Linear) + .setMinificationFilter(Sampler::Filter::Linear) + .setWrapping(Sampler::Wrapping::ClampToEdge) + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()) + .setStorage(TextureFormat::RGBA8, {526, 137}) + .setSubImage({}, image); +@endcode + +The texture is bound to layer specified by shader via @ref bind(). In shader, +the texture is used via sampler2DRect`, `sampler2DRectShadow`, `isampler2DRect` +or `usampler2DRect`. See @ref AbstractShaderProgram documentation for more +information about usage in shaders. + +@requires_gl31 %Extension @extension{ARB,texture_rectangle} +@requires_gl Rectangle textures are not available in OpenGL ES. + +@see @ref Texture, @ref TextureArray, @ref BufferTexture, @ref CubeMapTexture, + @ref CubeMapTextureArray, @ref MultisampleTexture + */ +class RectangleTexture: public AbstractTexture { + public: + /** + * @brief Constructor + * + * Creates new OpenGL texture object. + * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_RECTANGLE} + */ + explicit RectangleTexture(): AbstractTexture(GL_TEXTURE_RECTANGLE) {} + + /** + * @brief Set minification filter + * @param filter Filter + * @return Reference to self (for method chaining) + * + * Sets filter used when the object pixel size is smaller than the + * texture size. If @extension{EXT,direct_state_access} is not + * available, the texture is bound to some layer before the operation. + * Initial value is @ref Sampler::Filter::Linear. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} + * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} + * with @def_gl{TEXTURE_MIN_FILTER} + */ + RectangleTexture& setMinificationFilter(Sampler::Filter filter) { + AbstractTexture::setMinificationFilter(filter, Sampler::Mipmap::Base); + return *this; + } + + /** @copydoc Texture::setMagnificationFilter() */ + RectangleTexture& setMagnificationFilter(Sampler::Filter filter) { + AbstractTexture::setMagnificationFilter(filter); + return *this; + } + + #ifndef MAGNUM_TARGET_GLES + /** + * @brief %Image size + * + * The result is not cached in any way. If + * @extension{EXT,direct_state_access} is not available, the texture + * is bound to some layer before the operation. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} + * with @def_gl{TEXTURE_WIDTH} and @def_gl{TEXTURE_HEIGHT} + * @requires_gl %Texture image queries are not available in OpenGL ES. + */ + Vector2i imageSize() { return DataHelper<2>::imageSize(*this, _target, 0); } + #endif + + /** + * @brief Set wrapping + * @param wrapping Wrapping type for all texture dimensions + * @return Reference to self (for method chaining) + * + * Sets wrapping type for coordinates out of (0, textureSizeInGivenDirection-1) + * range for rectangle textures. If @extension{EXT,direct_state_access} + * is not available, the texture is bound to some layer before the + * operation. Initial value is @ref Sampler::Wrapping::ClampToEdge. + * @attention Only @ref Sampler::Wrapping::ClampToEdge and + * @ref Sampler::Wrapping::ClampToBorder is supported on this + * texture type. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} + * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} + * with @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T}, + * @def_gl{TEXTURE_WRAP_R} + */ + RectangleTexture& setWrapping(const Array2D& wrapping) { + DataHelper<2>::setWrapping(*this, wrapping); + return *this; + } + + /** @copydoc Texture::setBorderColor() */ + RectangleTexture& setBorderColor(const Color4& color) { + AbstractTexture::setBorderColor(color); + return *this; + } + + /** @copydoc Texture::setMaxAnisotropy() */ + RectangleTexture& setMaxAnisotropy(Float anisotropy) { + AbstractTexture::setMaxAnisotropy(anisotropy); + return *this; + } + + /** + * @brief Set storage + * @param internalFormat Internal format + * @param size Size + * @return Reference to self (for method chaining) + * + * Specifies entire structure of a texture at once, removing the need + * for additional consistency checks and memory reallocations when + * updating the data later. After calling this function the texture + * is immutable and calling @ref setStorage() or @ref setImage() is not + * allowed. + * + * If @extension{EXT,direct_state_access} is not available, the texture + * is bound to some layer before the operation. If OpenGL 4.2, + * @extension{ARB,texture_storage}, OpenGL ES 3.0 or + * @es_extension{EXT,texture_storage} in OpenGL ES 2.0 is not + * available, the feature is emulated with @ref setImage() call. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexStorage2D} + * or @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}, + * eventually @fn_gl{TexImage2D} or + * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}. + */ + RectangleTexture& setStorage(TextureFormat internalFormat, const Vector2i& size) { + DataHelper<2>::setStorage(*this, _target, 1, internalFormat, size); + return *this; + } + + #ifndef MAGNUM_TARGET_GLES + /** + * @brief Read texture to image + * @param image %Image where to put the data + * + * %Image parameters like format and type of pixel data are taken from + * given image, image size is taken from the texture using + * @ref imageSize(). + * + * If @extension{EXT,direct_state_access} is not available, the + * texture is bound to some layer before the operation. If + * @extension{ARB,robustness} is available, the operation is protected + * from buffer overflow. However, if both @extension{EXT,direct_state_access} + * and @extension{ARB,robustness} are available, the DSA version is + * used, because it is better for performance and there isn't any + * function combining both features. + * @requires_gl %Texture image queries are not available in OpenGL ES. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} + * with @def_gl{TEXTURE_WIDTH} and @def_gl{TEXTURE_HEIGHT}, then + * @fn_gl{GetTexImage}, @fn_gl_extension{GetTextureImage,EXT,direct_state_access} + * or @fn_gl_extension{GetnTexImage,ARB,robustness} + */ + void image(Image2D& image) { + AbstractTexture::image<2>(_target, 0, image); + } + + /** + * @brief Read given mip level of texture to buffer image + * @param image %Buffer image where to put the data + * @param usage %Buffer usage + * + * See @ref image(Image2D&) for more information. + * @requires_gl %Texture image queries are not available in OpenGL ES. + */ + void image(BufferImage2D& image, BufferUsage usage) { + AbstractTexture::image<2>(_target, 0, image, usage); + } + #endif + + /** + * @brief Set image data + * @param internalFormat Internal format + * @param image @ref Image2D, @ref ImageReference2D or + * @ref Trade::ImageData2D + * @return Reference to self (for method chaining) + * + * For better performance when calling @ref setImage() more than once + * use @ref setStorage() and @ref setSubImage() instead. + * + * If @extension{EXT,direct_state_access} is not available, the + * texture is bound to some layer before the operation. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexImage2D} + * or @fn_gl_extension{TextureImage2D,EXT,direct_state_access} + */ + RectangleTexture& setImage(TextureFormat internalFormat, const ImageReference2D& image) { + DataHelper<2>::setImage(*this, _target, 0, internalFormat, image); + return *this; + } + + #ifndef MAGNUM_TARGET_GLES2 + /** @overload */ + RectangleTexture& setImage(TextureFormat internalFormat, BufferImage2D& image) { + DataHelper<2>::setImage(*this, _target, 0, internalFormat, image); + return *this; + } + + /** @overload */ + RectangleTexture& setImage(TextureFormat internalFormat, BufferImage2D&& image) { + return setImage(internalFormat, image); + } + #endif + + /** + * @brief Set image subdata + * @param offset Offset where to put data in the texture + * @param image @ref Image2D, @ref ImageReference2D or + * @ref Trade::ImageData2D + * @return Reference to self (for method chaining) + * + * If @extension{EXT,direct_state_access} is not available, the + * texture is bound to some layer before the operation. + * @see @ref setStorage(), @ref setImage(), @fn_gl{ActiveTexture}, + * @fn_gl{BindTexture} and @fn_gl{TexSubImage2D} or + * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access} + */ + RectangleTexture& setSubImage(const Vector2i& offset, const ImageReference2D& image) { + DataHelper<2>::setSubImage(*this, _target, 0, offset, image); + return *this; + } + + #ifndef MAGNUM_TARGET_GLES2 + /** @overload */ + RectangleTexture& setSubImage(const Vector2i& offset, BufferImage2D& image) { + DataHelper<2>::setSubImage(*this, _target, 0, offset, image); + return *this; + } + + /** @overload */ + RectangleTexture& setSubImage(const Vector2i& offset, BufferImage2D&& image) { + return setSubImage(offset, image); + } + #endif + + /** + * @brief Invalidate texture image + * + * If running on OpenGL ES or extension @extension{ARB,invalidate_subdata} + * (part of OpenGL 4.3) is not available, this function does nothing. + * @see @ref invalidateSubImage(), @fn_gl{InvalidateTexImage} + */ + void invalidateImage() { AbstractTexture::invalidateImage(0); } + + /** + * @brief Invalidate texture subimage + * @param offset Offset into the texture + * @param size Size of invalidated data + * + * If running on OpenGL ES or extension @extension{ARB,invalidate_subdata} + * (part of OpenGL 4.3) is not available, this function does nothing. + * @see @ref invalidateImage(), @fn_gl{InvalidateTexSubImage} + */ + void invalidateSubImage(const Vector2i& offset, const Vector2i& size) { + DataHelper<2>::invalidateSubImage(*this, 0, offset, size); + } + + /* Overloads to remove WTF-factor from method chaining order */ + #ifndef DOXYGEN_GENERATING_OUTPUT + RectangleTexture& setLabel(const std::string& label) { + AbstractTexture::setLabel(label); + return *this; + } + #endif +}; + +} +#else +#error this header is available only on desktop OpenGL build +#endif + +#endif diff --git a/src/Magnum/Test/CMakeLists.txt b/src/Magnum/Test/CMakeLists.txt index 04ccc8a94..76f3eafa3 100644 --- a/src/Magnum/Test/CMakeLists.txt +++ b/src/Magnum/Test/CMakeLists.txt @@ -77,12 +77,15 @@ if(BUILD_GL_TESTS) corrade_add_test(ShaderGLTest ShaderGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) if(NOT MAGNUM_TARGET_GLES2) + corrade_add_test(TextureArrayGLTest TextureArrayGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(BufferImageGLTest BufferImageGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) endif() if(NOT MAGNUM_TARGET_GLES) 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(RectangleTextureGLTest RectangleTextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) endif() endif() diff --git a/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp b/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp index c04774c45..e3da6a916 100644 --- a/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp @@ -26,9 +26,10 @@ #include #include "Magnum/BufferImage.h" +#include "Magnum/Color.h" #include "Magnum/ColorFormat.h" -#include "Magnum/Image.h" #include "Magnum/CubeMapTextureArray.h" +#include "Magnum/Image.h" #include "Magnum/TextureFormat.h" #include "Magnum/Test/AbstractOpenGLTester.h" diff --git a/src/Magnum/Test/CubeMapTextureGLTest.cpp b/src/Magnum/Test/CubeMapTextureGLTest.cpp index a7ba9d9e8..6e4d75a77 100644 --- a/src/Magnum/Test/CubeMapTextureGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureGLTest.cpp @@ -29,9 +29,10 @@ #ifndef MAGNUM_TARGET_GLES2 #include "Magnum/BufferImage.h" #endif +#include "Magnum/Color.h" #include "Magnum/ColorFormat.h" -#include "Magnum/Image.h" #include "Magnum/CubeMapTexture.h" +#include "Magnum/Image.h" #include "Magnum/TextureFormat.h" #include "Magnum/Test/AbstractOpenGLTester.h" diff --git a/src/Magnum/Test/MeshGLTest.cpp b/src/Magnum/Test/MeshGLTest.cpp index dcc412b86..8ec197adf 100644 --- a/src/Magnum/Test/MeshGLTest.cpp +++ b/src/Magnum/Test/MeshGLTest.cpp @@ -24,6 +24,7 @@ */ #include "Magnum/Buffer.h" +#include "Magnum/Color.h" #include "Magnum/ColorFormat.h" #include "Magnum/Framebuffer.h" #include "Magnum/Image.h" diff --git a/src/Magnum/Test/MultisampleTextureGLTest.cpp b/src/Magnum/Test/MultisampleTextureGLTest.cpp new file mode 100644 index 000000000..6c5e959cc --- /dev/null +++ b/src/Magnum/Test/MultisampleTextureGLTest.cpp @@ -0,0 +1,212 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Magnum/MultisampleTexture.h" +#include "Magnum/Test/AbstractOpenGLTester.h" + +namespace Magnum { namespace Test { + +class MultisampleTextureGLTest: public AbstractOpenGLTester { + public: + explicit MultisampleTextureGLTest(); + + void construct2D(); + void construct2DArray(); + + void storage2D(); + void storage2DArray(); + + void image2D(); + void image2DBuffer(); + void image2DArray(); + void image2DArrayBuffer(); + + void subImage2D(); + void subImage2DBuffer(); + void subImage2DArray(); + void subImage2DArrayBuffer(); + + void invalidateImage2D(); + void invalidateImage2DArray(); + + void invalidateSubImage2D(); + void invalidateSubImage2DArray(); +}; + +MultisampleTextureGLTest::MultisampleTextureGLTest() { + addTests({&MultisampleTextureGLTest::construct2D, + &MultisampleTextureGLTest::construct2DArray, + + &MultisampleTextureGLTest::storage2D, + &MultisampleTextureGLTest::storage2DArray, + + &MultisampleTextureGLTest::image2D, + &MultisampleTextureGLTest::image2DBuffer, + &MultisampleTextureGLTest::image2DArray, + &MultisampleTextureGLTest::image2DArrayBuffer, + + &MultisampleTextureGLTest::subImage2D, + &MultisampleTextureGLTest::subImage2DBuffer, + &MultisampleTextureGLTest::subImage2DArray, + &MultisampleTextureGLTest::subImage2DArrayBuffer, + + &MultisampleTextureGLTest::invalidateImage2D, + &MultisampleTextureGLTest::invalidateImage2DArray, + + &MultisampleTextureGLTest::invalidateSubImage2D, + &MultisampleTextureGLTest::invalidateSubImage2DArray}); +} + +void MultisampleTextureGLTest::construct2D() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + { + MultisampleTexture2D texture; + + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_VERIFY(texture.id() > 0); + } + + MAGNUM_VERIFY_NO_ERROR(); +} + +void MultisampleTextureGLTest::construct2DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + { + MultisampleTexture2DArray texture; + + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_VERIFY(texture.id() > 0); + } + + MAGNUM_VERIFY_NO_ERROR(); +} + +void MultisampleTextureGLTest::storage2D() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Not implemented yet."); +} + +void MultisampleTextureGLTest::storage2DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Not implemented yet."); +} + +void MultisampleTextureGLTest::image2D() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Not implemented yet."); +} + +void MultisampleTextureGLTest::image2DBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Not implemented yet."); +} + +void MultisampleTextureGLTest::image2DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Not implemented yet."); +} + +void MultisampleTextureGLTest::image2DArrayBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Not implemented yet."); +} + +void MultisampleTextureGLTest::subImage2D() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Not implemented yet."); +} + +void MultisampleTextureGLTest::subImage2DBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Not implemented yet."); +} + +void MultisampleTextureGLTest::subImage2DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Not implemented yet."); +} + +void MultisampleTextureGLTest::subImage2DArrayBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Not implemented yet."); +} + +void MultisampleTextureGLTest::invalidateImage2D() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Multisample storage is not implemented yet."); +} + +void MultisampleTextureGLTest::invalidateImage2DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Multisample storage is not implemented yet."); +} + +void MultisampleTextureGLTest::invalidateSubImage2D() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Multisample storage is not implemented yet."); +} + +void MultisampleTextureGLTest::invalidateSubImage2DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); + + CORRADE_SKIP("Multisample storage is not implemented yet."); +} + +}} + +CORRADE_TEST_MAIN(Magnum::Test::MultisampleTextureGLTest) diff --git a/src/Magnum/Test/RectangleTextureGLTest.cpp b/src/Magnum/Test/RectangleTextureGLTest.cpp new file mode 100644 index 000000000..e4ff02c4e --- /dev/null +++ b/src/Magnum/Test/RectangleTextureGLTest.cpp @@ -0,0 +1,250 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Magnum/configure.h" +#include "Magnum/BufferImage.h" +#include "Magnum/Color.h" +#include "Magnum/ColorFormat.h" +#include "Magnum/Image.h" +#include "Magnum/RectangleTexture.h" +#include "Magnum/TextureFormat.h" +#include "Magnum/Test/AbstractOpenGLTester.h" + +namespace Magnum { namespace Test { + +class TextureGLTest: public AbstractOpenGLTester { + public: + explicit TextureGLTest(); + + void construct(); + void sampling(); + void storage(); + + void image(); + void imageBuffer(); + + void subImage(); + void subImageBuffer(); + + void invalidateImage(); + void invalidateSubImage(); +}; + +TextureGLTest::TextureGLTest() { + addTests({&TextureGLTest::construct, + &TextureGLTest::sampling, + &TextureGLTest::storage, + + &TextureGLTest::image, + &TextureGLTest::imageBuffer, + + &TextureGLTest::subImage, + &TextureGLTest::subImageBuffer, + + &TextureGLTest::invalidateImage, + &TextureGLTest::invalidateSubImage}); +} + +void TextureGLTest::construct() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); + + { + RectangleTexture texture; + + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_VERIFY(texture.id() > 0); + } + + MAGNUM_VERIFY_NO_ERROR(); +} + +void TextureGLTest::sampling() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); + + RectangleTexture texture; + texture.setMinificationFilter(Sampler::Filter::Linear) + .setMagnificationFilter(Sampler::Filter::Linear) + .setWrapping(Sampler::Wrapping::ClampToBorder) + .setBorderColor(Color3(0.5f)) + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); + + MAGNUM_VERIFY_NO_ERROR(); +} + +void TextureGLTest::storage() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); + + RectangleTexture texture; + texture.setStorage(TextureFormat::RGBA8, Vector2i(32)); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(texture.imageSize(), Vector2i(32)); + + MAGNUM_VERIFY_NO_ERROR(); +} + +void TextureGLTest::image() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); + + constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }; + RectangleTexture texture; + texture.setImage(TextureFormat::RGBA8, + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data)); + + MAGNUM_VERIFY_NO_ERROR(); + + Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); + texture.image(image); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector2i(2)); + CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), + std::vector(data, data + 16), TestSuite::Compare::Container); +} + +void TextureGLTest::imageBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); + + constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }; + RectangleTexture texture; + texture.setImage(TextureFormat::RGBA8, + BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data, BufferUsage::StaticDraw)); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); + texture.image(image, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector2i(2)); + CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), + std::vector(data, data+16), TestSuite::Compare::Container); +} + +void TextureGLTest::subImage() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); + + constexpr UnsignedByte zero[4*4*4] = {}; + constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }; + RectangleTexture texture; + texture.setImage(TextureFormat::RGBA8, + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); + texture.setSubImage(Vector2i(1), + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData)); + + MAGNUM_VERIFY_NO_ERROR(); + + Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); + texture.image(image); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector2i(4)); + CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, + 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }), TestSuite::Compare::Container); +} + +void TextureGLTest::subImageBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); + + constexpr UnsignedByte zero[4*4*4] = {}; + constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }; + RectangleTexture texture; + texture.setImage(TextureFormat::RGBA8, + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); + texture.setSubImage(Vector2i(1), + BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData, BufferUsage::StaticDraw)); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); + texture.image(image, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector2i(4)); + CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, + 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }), TestSuite::Compare::Container); +} + +void TextureGLTest::invalidateImage() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); + + RectangleTexture texture; + texture.setStorage(TextureFormat::RGBA8, Vector2i(32)); + texture.invalidateImage(); + + MAGNUM_VERIFY_NO_ERROR(); +} + +void TextureGLTest::invalidateSubImage() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); + + RectangleTexture texture; + texture.setStorage(TextureFormat::RGBA8, Vector2i(32)); + texture.invalidateSubImage(Vector2i(4), Vector2i(16)); + + MAGNUM_VERIFY_NO_ERROR(); +} + +}} + +CORRADE_TEST_MAIN(Magnum::Test::TextureGLTest) diff --git a/src/Magnum/Test/TextureArrayGLTest.cpp b/src/Magnum/Test/TextureArrayGLTest.cpp new file mode 100644 index 000000000..2c2eccfde --- /dev/null +++ b/src/Magnum/Test/TextureArrayGLTest.cpp @@ -0,0 +1,683 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Magnum/configure.h" +#include "Magnum/BufferImage.h" +#include "Magnum/Color.h" +#include "Magnum/ColorFormat.h" +#include "Magnum/Image.h" +#include "Magnum/TextureArray.h" +#include "Magnum/TextureFormat.h" +#include "Magnum/Test/AbstractOpenGLTester.h" + +namespace Magnum { namespace Test { + +class TextureGLTest: public AbstractOpenGLTester { + public: + explicit TextureGLTest(); + + #ifndef MAGNUM_TARGET_GLES + void construct1DArray(); + #endif + void construct2DArray(); + + #ifndef MAGNUM_TARGET_GLES + void sampling1DArray(); + #endif + void sampling2DArray(); + + #ifdef MAGNUM_TARGET_GLES + void samplingBorder2DArray(); + #endif + + #ifndef MAGNUM_TARGET_GLES + void storage1DArray(); + #endif + void storage2DArray(); + + #ifndef MAGNUM_TARGET_GLES + void image1DArray(); + void image1DArrayBuffer(); + #endif + #ifndef MAGNUM_TARGET_GLES2 + void image2DArray(); + void image2DArrayBuffer(); + #endif + + #ifndef MAGNUM_TARGET_GLES + void subImage1DArray(); + void subImage1DArrayBuffer(); + #endif + void subImage2DArray(); + void subImage2DArrayBuffer(); + + #ifndef MAGNUM_TARGET_GLES + void generateMipmap1DArray(); + #endif + void generateMipmap2DArray(); + + #ifndef MAGNUM_TARGET_GLES + void invalidateImage1DArray(); + #endif + void invalidateImage2DArray(); + + #ifndef MAGNUM_TARGET_GLES + void invalidateSubImage1DArray(); + #endif + void invalidateSubImage2DArray(); +}; + +TextureGLTest::TextureGLTest() { + addTests({ + #ifndef MAGNUM_TARGET_GLES + &TextureGLTest::construct1DArray, + #endif + &TextureGLTest::construct2DArray, + + #ifndef MAGNUM_TARGET_GLES + &TextureGLTest::sampling1DArray, + #endif + &TextureGLTest::sampling2DArray, + + #ifdef MAGNUM_TARGET_GLES + &TextureGLTest::samplingBorder2DArray, + #endif + + #ifndef MAGNUM_TARGET_GLES + &TextureGLTest::storage1DArray, + #endif + &TextureGLTest::storage2DArray, + + #ifndef MAGNUM_TARGET_GLES + &TextureGLTest::image1DArray, + &TextureGLTest::image1DArrayBuffer, + #endif + &TextureGLTest::image2DArray, + &TextureGLTest::image2DArrayBuffer, + + #ifndef MAGNUM_TARGET_GLES + &TextureGLTest::subImage1DArray, + &TextureGLTest::subImage1DArrayBuffer, + #endif + &TextureGLTest::subImage2DArray, + &TextureGLTest::subImage2DArrayBuffer, + + #ifndef MAGNUM_TARGET_GLES + &TextureGLTest::generateMipmap1DArray, + #endif + &TextureGLTest::generateMipmap2DArray, + + #ifndef MAGNUM_TARGET_GLES + &TextureGLTest::invalidateImage1DArray, + #endif + &TextureGLTest::invalidateImage2DArray, + + #ifndef MAGNUM_TARGET_GLES + &TextureGLTest::invalidateSubImage1DArray, + #endif + &TextureGLTest::invalidateSubImage2DArray + }); +} + +#ifndef MAGNUM_TARGET_GLES +void TextureGLTest::construct1DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + + { + Texture1DArray texture; + + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_VERIFY(texture.id() > 0); + } + + MAGNUM_VERIFY_NO_ERROR(); +} +#endif + +void TextureGLTest::construct2DArray() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + #endif + + { + Texture2DArray texture; + + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_VERIFY(texture.id() > 0); + } + + MAGNUM_VERIFY_NO_ERROR(); +} + +#ifndef MAGNUM_TARGET_GLES +void TextureGLTest::sampling1DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + + Texture1DArray texture; + texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) + .setMagnificationFilter(Sampler::Filter::Linear) + .setWrapping(Sampler::Wrapping::ClampToBorder) + .setBorderColor(Color3(0.5f)) + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); + + MAGNUM_VERIFY_NO_ERROR(); +} +#endif + +void TextureGLTest::sampling2DArray() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + #endif + + Texture2DArray texture; + texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) + .setMagnificationFilter(Sampler::Filter::Linear) + #ifndef MAGNUM_TARGET_GLES + .setWrapping(Sampler::Wrapping::ClampToBorder) + .setBorderColor(Color3(0.5f)) + #else + .setWrapping(Sampler::Wrapping::ClampToEdge) + #endif + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); + + MAGNUM_VERIFY_NO_ERROR(); +} + +#ifdef MAGNUM_TARGET_GLES +void TextureGLTest::samplingBorder2DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::NV::texture_border_clamp::string() + std::string(" is not supported.")); + + Texture2DArray texture; + texture.setWrapping(Sampler::Wrapping::ClampToBorder) + .setBorderColor(Color3(0.5f)); + + MAGNUM_VERIFY_NO_ERROR(); +} +#endif + +#ifndef MAGNUM_TARGET_GLES +void TextureGLTest::storage1DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + + Texture1DArray texture; + texture.setStorage(5, TextureFormat::RGBA8, Vector2i(32)); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(texture.imageSize(0), Vector2i(32, 32)); + CORRADE_COMPARE(texture.imageSize(1), Vector2i(16, 32)); + CORRADE_COMPARE(texture.imageSize(2), Vector2i( 8, 32)); + CORRADE_COMPARE(texture.imageSize(3), Vector2i( 4, 32)); + CORRADE_COMPARE(texture.imageSize(4), Vector2i( 2, 32)); + CORRADE_COMPARE(texture.imageSize(5), Vector2i( 0, 0)); /* not available */ + + MAGNUM_VERIFY_NO_ERROR(); +} +#endif + +void TextureGLTest::storage2DArray() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + #endif + + Texture2DArray texture; + texture.setStorage(5, TextureFormat::RGBA8, Vector3i(32)); + + MAGNUM_VERIFY_NO_ERROR(); + + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES + CORRADE_COMPARE(texture.imageSize(0), Vector3i(32, 32, 32)); + CORRADE_COMPARE(texture.imageSize(1), Vector3i(16, 16, 32)); + CORRADE_COMPARE(texture.imageSize(2), Vector3i( 8, 8, 32)); + CORRADE_COMPARE(texture.imageSize(3), Vector3i( 4, 4, 32)); + CORRADE_COMPARE(texture.imageSize(4), Vector3i( 2, 2, 32)); + CORRADE_COMPARE(texture.imageSize(5), Vector3i( 0, 0, 0)); /* not available */ + + MAGNUM_VERIFY_NO_ERROR(); + #endif +} + +#ifndef MAGNUM_TARGET_GLES +void TextureGLTest::image1DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + + constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }; + Texture1DArray texture; + texture.setImage(0, TextureFormat::RGBA8, + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data)); + + MAGNUM_VERIFY_NO_ERROR(); + + Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); + texture.image(0, image); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector2i(2)); + CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), + std::vector(data, data + 16), TestSuite::Compare::Container); +} + +void TextureGLTest::image1DArrayBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + + constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }; + Texture1DArray texture; + texture.setImage(0, TextureFormat::RGBA8, + BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data, BufferUsage::StaticDraw)); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); + texture.image(0, image, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector2i(2)); + CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), + std::vector(data, data + 16), TestSuite::Compare::Container); +} +#endif + +void TextureGLTest::image2DArray() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + #endif + + constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f }; + Texture2DArray texture; + texture.setImage(0, TextureFormat::RGBA8, + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), data)); + + MAGNUM_VERIFY_NO_ERROR(); + + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES + Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte); + texture.image(0, image); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(2)); + CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), + std::vector(data, data + 32), TestSuite::Compare::Container); + #endif +} + +void TextureGLTest::image2DArrayBuffer() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + #endif + + constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f }; + Texture2DArray texture; + texture.setImage(0, TextureFormat::RGBA8, + BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), data, BufferUsage::StaticDraw)); + + MAGNUM_VERIFY_NO_ERROR(); + + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES + BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); + texture.image(0, image, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(2)); + CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), + std::vector(data, data + 32), TestSuite::Compare::Container); + #endif +} + +#ifndef MAGNUM_TARGET_GLES +void TextureGLTest::subImage1DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + + constexpr UnsignedByte zero[4*4*4] = {}; + constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }; + Texture1DArray texture; + texture.setImage(0, TextureFormat::RGBA8, + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); + texture.setSubImage(0, Vector2i(1), + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData)); + + MAGNUM_VERIFY_NO_ERROR(); + + Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); + texture.image(0, image); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector2i(4)); + CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, + 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }), TestSuite::Compare::Container); +} + +void TextureGLTest::subImage1DArrayBuffer() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + + constexpr UnsignedByte zero[4*4*4] = {}; + constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }; + Texture1DArray texture; + texture.setImage(0, TextureFormat::RGBA8, + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); + texture.setSubImage(0, Vector2i(1), + BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData, BufferUsage::StaticDraw)); + + MAGNUM_VERIFY_NO_ERROR(); + + BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); + texture.image(0, image, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector2i(4)); + CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, + 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }), TestSuite::Compare::Container); +} +#endif + +void TextureGLTest::subImage2DArray() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + #endif + + constexpr UnsignedByte zero[4*4*4*4] = {}; + constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f }; + Texture2DArray texture; + texture.setImage(0, TextureFormat::RGBA8, + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), zero)); + texture.setSubImage(0, Vector3i(1), + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), subData)); + + MAGNUM_VERIFY_NO_ERROR(); + + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES + Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte); + texture.image(0, image); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(4)); + CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, + 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0, 0, 0, 0, + 0, 0, 0, 0, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }), TestSuite::Compare::Container); + #endif +} + +void TextureGLTest::subImage2DArrayBuffer() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + #endif + + constexpr UnsignedByte zero[4*4*4*4] = {}; + constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f }; + Texture2DArray texture; + texture.setImage(0, TextureFormat::RGBA8, + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), zero)); + texture.setSubImage(0, Vector3i(1), + BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), subData, BufferUsage::StaticDraw)); + + MAGNUM_VERIFY_NO_ERROR(); + + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES + BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); + texture.image(0, image, BufferUsage::StaticRead); + const auto imageData = image.buffer().data(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(image.size(), Vector3i(4)); + CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, + 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0, 0, 0, 0, + 0, 0, 0, 0, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }), TestSuite::Compare::Container); + #endif +} + +#ifndef MAGNUM_TARGET_GLES +void TextureGLTest::generateMipmap1DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported.")); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + + Texture1DArray texture; + texture.setImage(0, TextureFormat::RGBA8, + ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(32))); + + CORRADE_COMPARE(texture.imageSize(0), Vector2i(32)); + CORRADE_COMPARE(texture.imageSize(1), Vector2i( 0)); + + texture.generateMipmap(); + + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(texture.imageSize(0), Vector2i(32, 32)); + CORRADE_COMPARE(texture.imageSize(1), Vector2i(16, 32)); + CORRADE_COMPARE(texture.imageSize(2), Vector2i( 8, 32)); + CORRADE_COMPARE(texture.imageSize(3), Vector2i( 4, 32)); + CORRADE_COMPARE(texture.imageSize(4), Vector2i( 2, 32)); + CORRADE_COMPARE(texture.imageSize(5), Vector2i( 1, 32)); + + MAGNUM_VERIFY_NO_ERROR(); +} +#endif + +void TextureGLTest::generateMipmap2DArray() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported.")); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + #endif + + Texture2DArray texture; + texture.setImage(0, TextureFormat::RGBA8, + ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(32))); + + /** @todo How to test this on ES? */ + #ifndef MAGNUM_TARGET_GLES + CORRADE_COMPARE(texture.imageSize(0), Vector3i(32)); + CORRADE_COMPARE(texture.imageSize(1), Vector3i( 0)); + #endif + + texture.generateMipmap(); + + MAGNUM_VERIFY_NO_ERROR(); + + #ifndef MAGNUM_TARGET_GLES + CORRADE_COMPARE(texture.imageSize(0), Vector3i(32, 32, 32)); + CORRADE_COMPARE(texture.imageSize(1), Vector3i(16, 16, 32)); + CORRADE_COMPARE(texture.imageSize(2), Vector3i( 8, 8, 32)); + CORRADE_COMPARE(texture.imageSize(3), Vector3i( 4, 4, 32)); + CORRADE_COMPARE(texture.imageSize(4), Vector3i( 2, 2, 32)); + CORRADE_COMPARE(texture.imageSize(5), Vector3i( 1, 1, 32)); + + MAGNUM_VERIFY_NO_ERROR(); + #endif +} + +#ifndef MAGNUM_TARGET_GLES +void TextureGLTest::invalidateImage1DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + + Texture1DArray texture; + texture.setStorage(2, TextureFormat::RGBA8, Vector2i(32)); + texture.invalidateImage(1); + + MAGNUM_VERIFY_NO_ERROR(); +} +#endif + +void TextureGLTest::invalidateImage2DArray() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + #endif + + Texture2DArray texture; + texture.setStorage(2, TextureFormat::RGBA8, Vector3i(32)); + texture.invalidateImage(1); + + MAGNUM_VERIFY_NO_ERROR(); +} + +#ifndef MAGNUM_TARGET_GLES +void TextureGLTest::invalidateSubImage1DArray() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + + Texture1DArray texture; + texture.setStorage(2, TextureFormat::RGBA8, Vector2i(32)); + texture.invalidateSubImage(1, Vector2i(2), Vector2i(8)); + + MAGNUM_VERIFY_NO_ERROR(); +} +#endif + +void TextureGLTest::invalidateSubImage2DArray() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); + #endif + + Texture2DArray texture; + texture.setStorage(2, TextureFormat::RGBA8, Vector3i(32)); + texture.invalidateSubImage(1, Vector3i(2), Vector3i(8)); + + MAGNUM_VERIFY_NO_ERROR(); +} + +}} + +CORRADE_TEST_MAIN(Magnum::Test::TextureGLTest) diff --git a/src/Magnum/Test/TextureGLTest.cpp b/src/Magnum/Test/TextureGLTest.cpp index 1da5b1264..79a9368ae 100644 --- a/src/Magnum/Test/TextureGLTest.cpp +++ b/src/Magnum/Test/TextureGLTest.cpp @@ -29,6 +29,7 @@ #ifndef MAGNUM_TARGET_GLES2 #include "Magnum/BufferImage.h" #endif +#include "Magnum/Color.h" #include "Magnum/ColorFormat.h" #include "Magnum/Image.h" #include "Magnum/Texture.h" @@ -46,39 +47,16 @@ class TextureGLTest: public AbstractOpenGLTester { #endif void construct2D(); void construct3D(); - #ifndef MAGNUM_TARGET_GLES - void construct1DArray(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void construct2DArray(); - #endif - #ifndef MAGNUM_TARGET_GLES - void construct2DMultisample(); - void construct2DMultisampleArray(); - void constructRectangle(); - #endif #ifndef MAGNUM_TARGET_GLES void sampling1D(); #endif void sampling2D(); void sampling3D(); - #ifndef MAGNUM_TARGET_GLES - void sampling1DArray(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void sampling2DArray(); - #endif - #ifndef MAGNUM_TARGET_GLES - void samplingRectangle(); - #endif #ifdef MAGNUM_TARGET_GLES void samplingBorder2D(); void samplingBorder3D(); - #ifndef MAGNUM_TARGET_GLES2 - void samplingBorder2DArray(); - #endif #endif #ifndef MAGNUM_TARGET_GLES @@ -86,17 +64,6 @@ class TextureGLTest: public AbstractOpenGLTester { #endif void storage2D(); void storage3D(); - #ifndef MAGNUM_TARGET_GLES - void storage1DArray(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void storage2DArray(); - #endif - #ifndef MAGNUM_TARGET_GLES - void storage2DMultisample(); - void storage2DMultisampleArray(); - void storageRectangle(); - #endif #ifndef MAGNUM_TARGET_GLES void image1D(); @@ -112,22 +79,6 @@ class TextureGLTest: public AbstractOpenGLTester { #ifndef MAGNUM_TARGET_GLES2 void image3DBuffer(); #endif - #ifndef MAGNUM_TARGET_GLES - void image1DArray(); - void image1DArrayBuffer(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void image2DArray(); - void image2DArrayBuffer(); - #endif - #ifndef MAGNUM_TARGET_GLES - void image2DMultisample(); - void image2DMultisampleBuffer(); - void image2DMultisampleArray(); - void image2DMultisampleArrayBuffer(); - void imageRectangle(); - void imageRectangleBuffer(); - #endif #ifndef MAGNUM_TARGET_GLES void subImage1D(); @@ -141,68 +92,24 @@ class TextureGLTest: public AbstractOpenGLTester { #ifndef MAGNUM_TARGET_GLES2 void subImage3DBuffer(); #endif - #ifndef MAGNUM_TARGET_GLES - void subImage1DArray(); - void subImage1DArrayBuffer(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void subImage2DArray(); - void subImage2DArrayBuffer(); - #endif - #ifndef MAGNUM_TARGET_GLES - void subImage2DMultisample(); - void subImage2DMultisampleBuffer(); - void subImage2DMultisampleArray(); - void subImage2DMultisampleArrayBuffer(); - void subImageRectangle(); - void subImageRectangleBuffer(); - #endif #ifndef MAGNUM_TARGET_GLES void generateMipmap1D(); #endif void generateMipmap2D(); void generateMipmap3D(); - #ifndef MAGNUM_TARGET_GLES - void generateMipmap1DArray(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void generateMipmap2DArray(); - #endif #ifndef MAGNUM_TARGET_GLES void invalidateImage1D(); #endif void invalidateImage2D(); void invalidateImage3D(); - #ifndef MAGNUM_TARGET_GLES - void invalidateImage1DArray(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void invalidateImage2DArray(); - #endif - #ifndef MAGNUM_TARGET_GLES - void invalidateImage2DMultisample(); - void invalidateImage2DMultisampleArray(); - void invalidateImageRectangle(); - #endif #ifndef MAGNUM_TARGET_GLES void invalidateSubImage1D(); #endif void invalidateSubImage2D(); void invalidateSubImage3D(); - #ifndef MAGNUM_TARGET_GLES - void invalidateSubImage1DArray(); - #endif - #ifndef MAGNUM_TARGET_GLES2 - void invalidateSubImage2DArray(); - #endif - #ifndef MAGNUM_TARGET_GLES - void invalidateSubImage2DMultisample(); - void invalidateSubImage2DMultisampleArray(); - void invalidateSubImageRectangle(); - #endif }; TextureGLTest::TextureGLTest() { @@ -212,39 +119,16 @@ TextureGLTest::TextureGLTest() { #endif &TextureGLTest::construct2D, &TextureGLTest::construct3D, - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::construct1DArray, - #endif - #ifndef MAGNUM_TARGET_GLES2 - &TextureGLTest::construct2DArray, - #endif - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::construct2DMultisample, - &TextureGLTest::construct2DMultisampleArray, - &TextureGLTest::constructRectangle, - #endif #ifndef MAGNUM_TARGET_GLES &TextureGLTest::sampling1D, #endif &TextureGLTest::sampling2D, &TextureGLTest::sampling3D, - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::sampling1DArray, - #endif - #ifndef MAGNUM_TARGET_GLES2 - &TextureGLTest::sampling2DArray, - #endif - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::samplingRectangle, - #endif #ifdef MAGNUM_TARGET_GLES &TextureGLTest::samplingBorder2D, &TextureGLTest::samplingBorder3D, - #ifndef MAGNUM_TARGET_GLES2 - &TextureGLTest::samplingBorder2DArray, - #endif #endif #ifndef MAGNUM_TARGET_GLES @@ -252,17 +136,6 @@ TextureGLTest::TextureGLTest() { #endif &TextureGLTest::storage2D, &TextureGLTest::storage3D, - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::storage1DArray, - #endif - #ifndef MAGNUM_TARGET_GLES2 - &TextureGLTest::storage2DArray, - #endif - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::storage2DMultisample, - &TextureGLTest::storage2DMultisampleArray, - &TextureGLTest::storageRectangle, - #endif #ifndef MAGNUM_TARGET_GLES &TextureGLTest::image1D, @@ -276,22 +149,6 @@ TextureGLTest::TextureGLTest() { #ifndef MAGNUM_TARGET_GLES2 &TextureGLTest::image3DBuffer, #endif - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::image1DArray, - &TextureGLTest::image1DArrayBuffer, - #endif - #ifndef MAGNUM_TARGET_GLES2 - &TextureGLTest::image2DArray, - &TextureGLTest::image2DArrayBuffer, - #endif - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::image2DMultisample, - &TextureGLTest::image2DMultisampleBuffer, - &TextureGLTest::image2DMultisampleArray, - &TextureGLTest::image2DMultisampleArrayBuffer, - &TextureGLTest::imageRectangle, - &TextureGLTest::imageRectangleBuffer, - #endif #ifndef MAGNUM_TARGET_GLES &TextureGLTest::subImage1D, @@ -305,68 +162,24 @@ TextureGLTest::TextureGLTest() { #ifndef MAGNUM_TARGET_GLES2 &TextureGLTest::subImage3DBuffer, #endif - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::subImage1DArray, - &TextureGLTest::subImage1DArrayBuffer, - #endif - #ifndef MAGNUM_TARGET_GLES2 - &TextureGLTest::subImage2DArray, - &TextureGLTest::subImage2DArrayBuffer, - #endif - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::subImage2DMultisample, - &TextureGLTest::subImage2DMultisampleBuffer, - &TextureGLTest::subImage2DMultisampleArray, - &TextureGLTest::subImage2DMultisampleArrayBuffer, - &TextureGLTest::subImageRectangle, - &TextureGLTest::subImageRectangleBuffer, - #endif #ifndef MAGNUM_TARGET_GLES &TextureGLTest::generateMipmap1D, #endif &TextureGLTest::generateMipmap2D, &TextureGLTest::generateMipmap3D, - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::generateMipmap1DArray, - #endif - #ifndef MAGNUM_TARGET_GLES2 - &TextureGLTest::generateMipmap2DArray, - #endif #ifndef MAGNUM_TARGET_GLES &TextureGLTest::invalidateImage1D, #endif &TextureGLTest::invalidateImage2D, &TextureGLTest::invalidateImage3D, - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::invalidateImage1DArray, - #endif - #ifndef MAGNUM_TARGET_GLES2 - &TextureGLTest::invalidateImage2DArray, - #endif - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::invalidateImage2DMultisample, - &TextureGLTest::invalidateImage2DMultisampleArray, - &TextureGLTest::invalidateImageRectangle, - #endif #ifndef MAGNUM_TARGET_GLES &TextureGLTest::invalidateSubImage1D, #endif &TextureGLTest::invalidateSubImage2D, &TextureGLTest::invalidateSubImage3D, - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::invalidateSubImage1DArray, - #endif - #ifndef MAGNUM_TARGET_GLES2 - &TextureGLTest::invalidateSubImage2DArray, - #endif - #ifndef MAGNUM_TARGET_GLES - &TextureGLTest::invalidateSubImage2DMultisample, - &TextureGLTest::invalidateSubImage2DMultisampleArray, - &TextureGLTest::invalidateSubImageRectangle - #endif }); } @@ -410,84 +223,6 @@ void TextureGLTest::construct3D() { MAGNUM_VERIFY_NO_ERROR(); } -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::construct1DArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - - { - Texture2D texture(Texture2D::Target::Texture1DArray); - - MAGNUM_VERIFY_NO_ERROR(); - CORRADE_VERIFY(texture.id() > 0); - } - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - -#ifndef MAGNUM_TARGET_GLES2 -void TextureGLTest::construct2DArray() { - #ifndef MAGNUM_TARGET_GLES - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - #endif - - { - Texture3D texture(Texture3D::Target::Texture2DArray); - - MAGNUM_VERIFY_NO_ERROR(); - CORRADE_VERIFY(texture.id() > 0); - } - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::construct2DMultisample() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - { - Texture2D texture(Texture2D::Target::Texture2DMultisample); - - MAGNUM_VERIFY_NO_ERROR(); - CORRADE_VERIFY(texture.id() > 0); - } - - MAGNUM_VERIFY_NO_ERROR(); -} - -void TextureGLTest::construct2DMultisampleArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - { - Texture3D texture(Texture3D::Target::Texture2DMultisampleArray); - - MAGNUM_VERIFY_NO_ERROR(); - CORRADE_VERIFY(texture.id() > 0); - } - - MAGNUM_VERIFY_NO_ERROR(); -} - -void TextureGLTest::constructRectangle() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - - { - Texture2D texture(Texture2D::Target::Rectangle); - - MAGNUM_VERIFY_NO_ERROR(); - CORRADE_VERIFY(texture.id() > 0); - } - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - #ifndef MAGNUM_TARGET_GLES void TextureGLTest::sampling1D() { Texture1D texture; @@ -567,73 +302,6 @@ void TextureGLTest::samplingBorder3D() { } #endif -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::sampling1DArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - - Texture2D texture(Texture2D::Target::Texture1DArray); - texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) - .setMagnificationFilter(Sampler::Filter::Linear) - .setWrapping(Sampler::Wrapping::ClampToBorder) - .setBorderColor(Color3(0.5f)) - .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - -#ifndef MAGNUM_TARGET_GLES2 -void TextureGLTest::sampling2DArray() { - #ifndef MAGNUM_TARGET_GLES - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - #endif - - Texture3D texture(Texture3D::Target::Texture2DArray); - texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) - .setMagnificationFilter(Sampler::Filter::Linear) - #ifndef MAGNUM_TARGET_GLES - .setWrapping(Sampler::Wrapping::ClampToBorder) - .setBorderColor(Color3(0.5f)) - #else - .setWrapping(Sampler::Wrapping::ClampToEdge) - #endif - .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); - - MAGNUM_VERIFY_NO_ERROR(); -} - -#ifdef MAGNUM_TARGET_GLES -void TextureGLTest::samplingBorder2DArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::NV::texture_border_clamp::string() + std::string(" is not supported.")); - - Texture3D texture(Texture3D::Target::Texture2DArray); - texture.setWrapping(Sampler::Wrapping::ClampToBorder) - .setBorderColor(Color3(0.5f)); - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif -#endif - -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::samplingRectangle() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - - Texture2D texture(Texture2D::Target::Rectangle); - texture.setMinificationFilter(Sampler::Filter::Linear) - .setMagnificationFilter(Sampler::Filter::Linear) - .setWrapping(Sampler::Wrapping::ClampToBorder) - .setBorderColor(Color3(0.5f)) - .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - #ifndef MAGNUM_TARGET_GLES void TextureGLTest::storage1D() { Texture1D texture; @@ -695,87 +363,6 @@ void TextureGLTest::storage3D() { #endif } -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::storage1DArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - - Texture2D texture(Texture2D::Target::Texture1DArray); - texture.setStorage(5, TextureFormat::RGBA8, Vector2i(32)); - - MAGNUM_VERIFY_NO_ERROR(); - - /** @todo How to test this on ES? */ - #ifndef MAGNUM_TARGET_GLES - CORRADE_COMPARE(texture.imageSize(0), Vector2i(32, 32)); - CORRADE_COMPARE(texture.imageSize(1), Vector2i(16, 32)); - CORRADE_COMPARE(texture.imageSize(2), Vector2i( 8, 32)); - CORRADE_COMPARE(texture.imageSize(3), Vector2i( 4, 32)); - CORRADE_COMPARE(texture.imageSize(4), Vector2i( 2, 32)); - CORRADE_COMPARE(texture.imageSize(5), Vector2i( 0, 0)); /* not available */ - - MAGNUM_VERIFY_NO_ERROR(); - #endif -} -#endif - -#ifndef MAGNUM_TARGET_GLES2 -void TextureGLTest::storage2DArray() { - #ifndef MAGNUM_TARGET_GLES - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - #endif - - Texture3D texture(Texture3D::Target::Texture2DArray); - texture.setStorage(5, TextureFormat::RGBA8, Vector3i(32)); - - MAGNUM_VERIFY_NO_ERROR(); - - /** @todo How to test this on ES? */ - #ifndef MAGNUM_TARGET_GLES - CORRADE_COMPARE(texture.imageSize(0), Vector3i(32, 32, 32)); - CORRADE_COMPARE(texture.imageSize(1), Vector3i(16, 16, 32)); - CORRADE_COMPARE(texture.imageSize(2), Vector3i( 8, 8, 32)); - CORRADE_COMPARE(texture.imageSize(3), Vector3i( 4, 4, 32)); - CORRADE_COMPARE(texture.imageSize(4), Vector3i( 2, 2, 32)); - CORRADE_COMPARE(texture.imageSize(5), Vector3i( 0, 0, 0)); /* not available */ - - MAGNUM_VERIFY_NO_ERROR(); - #endif -} -#endif - -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::storage2DMultisample() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Not implemented yet."); -} - -void TextureGLTest::storage2DMultisampleArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Not implemented yet."); -} - -void TextureGLTest::storageRectangle() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - - Texture2D texture(Texture2D::Target::Rectangle); - texture.setStorage(1, TextureFormat::RGBA8, Vector2i(32)); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(texture.imageSize(0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(1), Vector2i( 0)); /* not available */ - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - #ifndef MAGNUM_TARGET_GLES void TextureGLTest::image1D() { constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, @@ -932,205 +519,6 @@ void TextureGLTest::image3DBuffer() { } #endif -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::image1DArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; - Texture2D texture(Texture2D::Target::Texture1DArray); - texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data)); - - MAGNUM_VERIFY_NO_ERROR(); - - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(image.size(), Vector2i(2)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), - std::vector(data, data + 16), TestSuite::Compare::Container); -} - -void TextureGLTest::image1DArrayBuffer() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; - Texture2D texture(Texture2D::Target::Texture1DArray); - texture.setImage(0, TextureFormat::RGBA8, - BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data, BufferUsage::StaticDraw)); - - MAGNUM_VERIFY_NO_ERROR(); - - BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); - const auto imageData = image.buffer().data(); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(image.size(), Vector2i(2)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), - std::vector(data, data + 16), TestSuite::Compare::Container); -} -#endif - -#ifndef MAGNUM_TARGET_GLES2 -void TextureGLTest::image2DArray() { - #ifndef MAGNUM_TARGET_GLES - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - #endif - - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f }; - Texture3D texture(Texture3D::Target::Texture2DArray); - texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), data)); - - MAGNUM_VERIFY_NO_ERROR(); - - /** @todo How to test this on ES? */ - #ifndef MAGNUM_TARGET_GLES - Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(image.size(), Vector3i(2)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), - std::vector(data, data + 32), TestSuite::Compare::Container); - #endif -} - -void TextureGLTest::image2DArrayBuffer() { - #ifndef MAGNUM_TARGET_GLES - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - #endif - - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f }; - Texture3D texture(Texture3D::Target::Texture2DArray); - texture.setImage(0, TextureFormat::RGBA8, - BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), data, BufferUsage::StaticDraw)); - - MAGNUM_VERIFY_NO_ERROR(); - - /** @todo How to test this on ES? */ - #ifndef MAGNUM_TARGET_GLES - BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); - const auto imageData = image.buffer().data(); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(image.size(), Vector3i(2)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), - std::vector(data, data + 32), TestSuite::Compare::Container); - #endif -} -#endif - -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::image2DMultisample() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Not implemented yet."); -} - -void TextureGLTest::image2DMultisampleBuffer() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Not implemented yet."); -} - -void TextureGLTest::image2DMultisampleArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Not implemented yet."); -} - -void TextureGLTest::image2DMultisampleArrayBuffer() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Not implemented yet."); -} - -void TextureGLTest::imageRectangle() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; - Texture2D texture(Texture2D::Target::Rectangle); - texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data)); - - MAGNUM_VERIFY_NO_ERROR(); - - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(image.size(), Vector2i(2)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), - std::vector(data, data + 16), TestSuite::Compare::Container); -} - -void TextureGLTest::imageRectangleBuffer() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - - constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; - Texture2D texture; - texture.setImage(0, TextureFormat::RGBA8, - BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data, BufferUsage::StaticDraw)); - - MAGNUM_VERIFY_NO_ERROR(); - - BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); - const auto imageData = image.buffer().data(); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(image.size(), Vector2i(2)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), - std::vector(data, data+16), TestSuite::Compare::Container); -} -#endif - #ifndef MAGNUM_TARGET_GLES void TextureGLTest::subImage1D() { constexpr UnsignedByte zero[4*4] = {}; @@ -1353,277 +741,6 @@ void TextureGLTest::subImage3DBuffer() { } #endif -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::subImage1DArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - - constexpr UnsignedByte zero[4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; - Texture2D texture(Texture2D::Target::Texture1DArray); - texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); - texture.setSubImage(0, Vector2i(1), - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData)); - - MAGNUM_VERIFY_NO_ERROR(); - - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(image.size(), Vector2i(4)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); -} - -void TextureGLTest::subImage1DArrayBuffer() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - - constexpr UnsignedByte zero[4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; - Texture2D texture(Texture2D::Target::Texture1DArray); - texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); - texture.setSubImage(0, Vector2i(1), - BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData, BufferUsage::StaticDraw)); - - MAGNUM_VERIFY_NO_ERROR(); - - BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); - const auto imageData = image.buffer().data(); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(image.size(), Vector2i(4)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); -} -#endif - -#ifndef MAGNUM_TARGET_GLES2 -void TextureGLTest::subImage2DArray() { - #ifndef MAGNUM_TARGET_GLES - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - #endif - - constexpr UnsignedByte zero[4*4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f }; - Texture3D texture(Texture3D::Target::Texture2DArray); - texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), zero)); - texture.setSubImage(0, Vector3i(1), - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), subData)); - - MAGNUM_VERIFY_NO_ERROR(); - - /** @todo How to test this on ES? */ - #ifndef MAGNUM_TARGET_GLES - Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(image.size(), Vector3i(4)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0, 0, 0, 0, - 0, 0, 0, 0, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); - #endif -} - -void TextureGLTest::subImage2DArrayBuffer() { - #ifndef MAGNUM_TARGET_GLES - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - #endif - - constexpr UnsignedByte zero[4*4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f }; - Texture3D texture(Texture3D::Target::Texture2DArray); - texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), zero)); - texture.setSubImage(0, Vector3i(1), - BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), subData, BufferUsage::StaticDraw)); - - MAGNUM_VERIFY_NO_ERROR(); - - /** @todo How to test this on ES? */ - #ifndef MAGNUM_TARGET_GLES - BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); - const auto imageData = image.buffer().data(); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(image.size(), Vector3i(4)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0, 0, 0, 0, - 0, 0, 0, 0, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); - #endif -} -#endif - -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::subImage2DMultisample() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Not implemented yet."); -} - -void TextureGLTest::subImage2DMultisampleBuffer() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Not implemented yet."); -} - -void TextureGLTest::subImage2DMultisampleArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Not implemented yet."); -} - -void TextureGLTest::subImage2DMultisampleArrayBuffer() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Not implemented yet."); -} - -void TextureGLTest::subImageRectangle() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - - constexpr UnsignedByte zero[4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; - Texture2D texture(Texture2D::Target::Rectangle); - texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); - texture.setSubImage(0, Vector2i(1), - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData)); - - MAGNUM_VERIFY_NO_ERROR(); - - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(image.size(), Vector2i(4)); - CORRADE_COMPARE_AS(std::vector(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); -} - -void TextureGLTest::subImageRectangleBuffer() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - - constexpr UnsignedByte zero[4*4*4] = {}; - constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }; - Texture2D texture(Texture2D::Target::Rectangle); - texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero)); - texture.setSubImage(0, Vector2i(1), - BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData, BufferUsage::StaticDraw)); - - MAGNUM_VERIFY_NO_ERROR(); - - BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte); - texture.image(0, image, BufferUsage::StaticRead); - const auto imageData = image.buffer().data(); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(image.size(), Vector2i(4)); - CORRADE_COMPARE_AS(std::vector(imageData.begin(), imageData.end()), (std::vector{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0, - 0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }), TestSuite::Compare::Container); -} -#endif - #ifndef MAGNUM_TARGET_GLES void TextureGLTest::generateMipmap1D() { if(!Context::current()->isExtensionSupported()) @@ -1720,72 +837,6 @@ void TextureGLTest::generateMipmap3D() { #endif } -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::generateMipmap1DArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported.")); - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - - Texture2D texture(Texture2D::Target::Texture1DArray); - texture.setImage(0, TextureFormat::RGBA8, - ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(32))); - - CORRADE_COMPARE(texture.imageSize(0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(1), Vector2i( 0)); - - texture.generateMipmap(); - - MAGNUM_VERIFY_NO_ERROR(); - - CORRADE_COMPARE(texture.imageSize(0), Vector2i(32, 32)); - CORRADE_COMPARE(texture.imageSize(1), Vector2i(16, 32)); - CORRADE_COMPARE(texture.imageSize(2), Vector2i( 8, 32)); - CORRADE_COMPARE(texture.imageSize(3), Vector2i( 4, 32)); - CORRADE_COMPARE(texture.imageSize(4), Vector2i( 2, 32)); - CORRADE_COMPARE(texture.imageSize(5), Vector2i( 1, 32)); - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - -#ifndef MAGNUM_TARGET_GLES2 -void TextureGLTest::generateMipmap2DArray() { - #ifndef MAGNUM_TARGET_GLES - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported.")); - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - #endif - - Texture3D texture(Texture3D::Target::Texture2DArray); - texture.setImage(0, TextureFormat::RGBA8, - ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(32))); - - /** @todo How to test this on ES? */ - #ifndef MAGNUM_TARGET_GLES - CORRADE_COMPARE(texture.imageSize(0), Vector3i(32)); - CORRADE_COMPARE(texture.imageSize(1), Vector3i( 0)); - #endif - - texture.generateMipmap(); - - MAGNUM_VERIFY_NO_ERROR(); - - /** @todo How to test this on ES? */ - #ifndef MAGNUM_TARGET_GLES - CORRADE_COMPARE(texture.imageSize(0), Vector3i(32, 32, 32)); - CORRADE_COMPARE(texture.imageSize(1), Vector3i(16, 16, 32)); - CORRADE_COMPARE(texture.imageSize(2), Vector3i( 8, 8, 32)); - CORRADE_COMPARE(texture.imageSize(3), Vector3i( 4, 4, 32)); - CORRADE_COMPARE(texture.imageSize(4), Vector3i( 2, 2, 32)); - CORRADE_COMPARE(texture.imageSize(5), Vector3i( 1, 1, 32)); - - MAGNUM_VERIFY_NO_ERROR(); - #endif -} -#endif - #ifndef MAGNUM_TARGET_GLES void TextureGLTest::invalidateImage1D() { Texture1D texture; @@ -1817,61 +868,6 @@ void TextureGLTest::invalidateImage3D() { MAGNUM_VERIFY_NO_ERROR(); } -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::invalidateImage1DArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - - Texture2D texture(Texture2D::Target::Texture1DArray); - texture.setStorage(2, TextureFormat::RGBA8, Vector2i(32)); - texture.invalidateImage(1); - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - -#ifndef MAGNUM_TARGET_GLES2 -void TextureGLTest::invalidateImage2DArray() { - #ifndef MAGNUM_TARGET_GLES - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - #endif - - Texture3D texture(Texture3D::Target::Texture2DArray); - texture.setStorage(2, TextureFormat::RGBA8, Vector3i(32)); - texture.invalidateImage(1); - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::invalidateImage2DMultisample() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Multisample storage is not implemented yet."); -} - -void TextureGLTest::invalidateImage2DMultisampleArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Multisample storage is not implemented yet."); -} - -void TextureGLTest::invalidateImageRectangle() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - - Texture2D texture(Texture2D::Target::Rectangle); - texture.setStorage(1, TextureFormat::RGBA8, Vector2i(32)); - texture.invalidateImage(0); - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - #ifndef MAGNUM_TARGET_GLES void TextureGLTest::invalidateSubImage1D() { Texture1D texture; @@ -1903,61 +899,6 @@ void TextureGLTest::invalidateSubImage3D() { MAGNUM_VERIFY_NO_ERROR(); } -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::invalidateSubImage1DArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - - Texture2D texture(Texture2D::Target::Texture1DArray); - texture.setStorage(2, TextureFormat::RGBA8, Vector2i(32)); - texture.invalidateSubImage(1, Vector2i(2), Vector2i(8)); - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - -#ifndef MAGNUM_TARGET_GLES2 -void TextureGLTest::invalidateSubImage2DArray() { - #ifndef MAGNUM_TARGET_GLES - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); - #endif - - Texture3D texture(Texture3D::Target::Texture2DArray); - texture.setStorage(2, TextureFormat::RGBA8, Vector3i(32)); - texture.invalidateSubImage(1, Vector3i(2), Vector3i(8)); - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - -#ifndef MAGNUM_TARGET_GLES -void TextureGLTest::invalidateSubImage2DMultisample() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Multisample storage is not implemented yet."); -} - -void TextureGLTest::invalidateSubImage2DMultisampleArray() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); - - CORRADE_SKIP("Multisample storage is not implemented yet."); -} - -void TextureGLTest::invalidateSubImageRectangle() { - if(!Context::current()->isExtensionSupported()) - CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); - - Texture2D texture(Texture2D::Target::Rectangle); - texture.setStorage(1, TextureFormat::RGBA8, Vector2i(32)); - texture.invalidateSubImage(0, Vector2i(4), Vector2i(16)); - - MAGNUM_VERIFY_NO_ERROR(); -} -#endif - }} CORRADE_TEST_MAIN(Magnum::Test::TextureGLTest) diff --git a/src/Magnum/Text/AbstractFont.cpp b/src/Magnum/Text/AbstractFont.cpp index fc9410116..f0db13818 100644 --- a/src/Magnum/Text/AbstractFont.cpp +++ b/src/Magnum/Text/AbstractFont.cpp @@ -29,6 +29,7 @@ #include #include +#include "Magnum/Math/Functions.h" #include "Magnum/Text/GlyphCache.h" namespace Magnum { namespace Text { diff --git a/src/Magnum/Text/Renderer.cpp b/src/Magnum/Text/Renderer.cpp index c8b83e93f..2256ecd9c 100644 --- a/src/Magnum/Text/Renderer.cpp +++ b/src/Magnum/Text/Renderer.cpp @@ -28,6 +28,7 @@ #include "Magnum/Context.h" #include "Magnum/Extensions.h" #include "Magnum/Mesh.h" +#include "Magnum/Math/Functions.h" #include "Magnum/Shaders/AbstractVector.h" #include "Magnum/Text/AbstractFont.h" diff --git a/src/Magnum/Text/Test/AbstractFontTest.cpp b/src/Magnum/Text/Test/AbstractFontTest.cpp index 484762172..0bc52a7a6 100644 --- a/src/Magnum/Text/Test/AbstractFontTest.cpp +++ b/src/Magnum/Text/Test/AbstractFontTest.cpp @@ -27,6 +27,7 @@ #include #include +#include "Magnum/Math/Vector2.h" #include "Magnum/Text/AbstractFont.h" #include "configure.h" diff --git a/src/Magnum/Texture.h b/src/Magnum/Texture.h index 18dbe6e98..3beb01e88 100644 --- a/src/Magnum/Texture.h +++ b/src/Magnum/Texture.h @@ -29,11 +29,30 @@ * @brief Class @ref Magnum::Texture, typedef @ref Magnum::Texture1D, @ref Magnum::Texture2D, @ref Magnum::Texture3D */ +#include + #include "Magnum/AbstractTexture.h" +#include "Magnum/Array.h" #include "Magnum/DimensionTraits.h" +#include "Magnum/Math/Vector3.h" namespace Magnum { +namespace Implementation { + template constexpr GLenum textureTarget(); + #ifndef MAGNUM_TARGET_GLES + template<> inline constexpr GLenum textureTarget<1>() { return GL_TEXTURE_1D; } + #endif + template<> inline constexpr GLenum textureTarget<2>() { return GL_TEXTURE_2D; } + template<> inline constexpr GLenum textureTarget<3>() { + #ifndef MAGNUM_TARGET_GLES2 + return GL_TEXTURE_3D; + #else + return GL_TEXTURE_3D_OES; + #endif + } +} + /** @brief %Texture @@ -58,180 +77,95 @@ texture.setMagnificationFilter(Sampler::Filter::Linear) .generateMipmap(); @endcode -@attention Don't forget to fully configure the texture before use. Note that - default configuration (if @ref setMinificationFilter() is not called with - another value) is to use mipmaps, so be sure to either call @ref setMinificationFilter(), - explicitly specify all mip levels with @ref setStorage() and @ref setImage() - or call @ref generateMipmap(). If using rectangle texture, you must also - call @ref setWrapping(), because the initial value is not supported on - rectangle textures. See also @ref setMagnificationFilter() and - @ref setBorderColor(). +@attention Note that default configuration (if @ref setMinificationFilter() is + not called with another value) is to use mipmaps, so be sure to either call + @ref setMinificationFilter(), explicitly specify all mip levels with + @ref setStorage() and @ref setImage() or call @ref generateMipmap(). The texture is bound to layer specified by shader via @ref bind(). In shader, -the texture is used via `sampler2D` and friends, see @ref Target enum -documentation for more information. See also AbstractShaderProgram -documentation for more information about usage in shaders. - -@section Texture-array Texture arrays - -You can create texture arrays by passing -@ref Target::Texture1DArray "Texture2D::Target::Texture1DArray" or -@ref Target::Texture2DArray "Texture3D::Target::Texture2DArray" to constructor. - -It is possible to specify each layer separately using @ref setSubImage(), but -you have to allocate the memory for all layers first by calling @ref setStorage(). -Example: 2D texture array with 16 layers of 64x64 images: -@code -Texture3D texture(Texture3D::Target::Texture2DArray); -texture.setMagnificationFilter(Sampler::Filter::Linear) - // ... - .setStorage(levels, TextureFormat::RGBA8, {64, 64,16}); - -for(std::size_t i = 0; i != 16; ++i) { - // ... - Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte, {64, 64}, data[i]); - texture.setSubImage(0, Vector3i::zAxis(i), image); -} - -// ... -@endcode - -Similar approach can be used for any other texture types (e.g. setting -@ref Texture3D data using 2D layers, @ref Texture2D data using one-dimensional -chunks etc.). - -@requires_gl30 %Extension @extension{EXT,texture_array} for texture arrays. -@requires_gles30 %Array textures are not available in OpenGL ES 2.0. - -@section Texture-multisample Multisample textures - -You can create multisample textures by passing -@ref Target::Texture2DMultisample "Texture2D::Target::Texture2DMultisample" or -@ref Target::Texture2DMultisampleArray "Texture3D::Target::Texture2DMultisampleArray" -to constructor. - -@todoc finish this when fully implemented - -@requires_gl32 %Extension @extension{ARB,texture_multisample} for multisample - textures. -@requires_gl Multisample textures are not available in OpenGL ES. - -@section Texture-rectangle Rectangle textures - -Rectangle texture is created by passing @ref Target::Rectangle "Texture2D::Target::Rectangle" -to constructor. In shader, the texture is used via `sampler2DRect` and friends. -Unlike `sampler2D`, which accepts coordinates between 0 and 1, `sampler2DRect` -accepts coordinates between 0 and `textureSizeInGivenDirection-1`. Note that -rectangle textures don't support mipmapping and repeating wrapping modes, see -@ref Sampler::Filter, @ref Sampler::Mipmap and @ref generateMipmap() -documentation for more information. - -@requires_gl31 %Extension @extension{ARB,texture_rectangle} for rectangle - textures. -@requires_gl Rectangle textures are not available in OpenGL ES. - -@see @ref Texture1D, @ref Texture2D, @ref Texture3D, @ref CubeMapTexture, - @ref CubeMapTextureArray, @ref BufferTexture -@todo @extension{AMD,sparse_texture} -@todo Separate multisample, array and rectangle texture classes to avoid confusion, then remove Target enum +the texture is used via `sampler1D`/`sampler2D`/`sampler3D`, +`sampler1DShadow`/`sampler2DShadow`/`sampler3DShadow`, +`isampler1D`/`isampler2D`/`isampler3D` or `usampler1D`/`usampler2D`/`usampler3D`. +See @ref AbstractShaderProgram documentation for more information about usage +in shaders. + +@requires_gles30 %Extension @es_extension{OES,texture_3D} for 3D textures. +@requires_gl 1D textures are not available in OpenGL ES, only 2D and 3D ones. + +@see @ref Texture1D, @ref Texture2D, @ref Texture3D, @ref TextureArray, + @ref BufferTexture, @ref CubeMapTexture, @ref CubeMapTextureArray, + @ref MultisampleTexture, @ref RectangleTexture */ template class Texture: public AbstractTexture { public: static const UnsignedInt Dimensions = dimensions; /**< @brief %Texture dimension count */ - #ifdef DOXYGEN_GENERATING_OUTPUT + #ifdef MAGNUM_BUILD_DEPRECATED /** * @brief %Texture target * - * Each dimension has its own unique subset of these targets. + * @deprecated Use dedicated classes instead, see documentation of + * particular enum value for more information. */ + #ifdef DOXYGEN_GENERATING_OUTPUT enum class Target: GLenum { - /** - * One-dimensional texture. Use `sampler1D`, `sampler1DShadow`, - * `isampler1D` or `usampler1D` in shader. - * @requires_gl Only 2D and 3D textures are available in OpenGL - * ES. - */ + /** @deprecated Used implicitly in @ref Magnum::Texture1D "Texture1D" class. */ Texture1D = GL_TEXTURE_1D, - /** - * Two-dimensional texture. Use `sampler2D`, `sampler2DShadow`, - * `isampler2D` or `usampler2D` in shader. - */ + /** @deprecated Used implicitly in @ref Magnum::Texture2D "Texture2D" class. */ Texture2D = GL_TEXTURE_2D, - /** - * Three-dimensional texture. Use `sampler3D`, `isampler3D` or - * `usampler3D` in shader. - * @requires_gles30 %Extension @es_extension{OES,texture_3D} - */ + /** @deprecated Used implicitly in @ref Magnum::Texture3D "Texture3D" class. */ Texture3D = GL_TEXTURE_3D, - /** - * One-dimensional texture array (i.e. two dimensions in total). - * Use `sampler1DArray`, `sampler1DArrayShadow`, `isampler1DArray` - * or `usampler1DArray` in shader. - * @requires_gl30 %Extension @extension{EXT,texture_array} - * @requires_gl Only 2D and 3D textures are available in OpenGL - * ES. - */ + /** @deprecated Use @ref Magnum::Texture1DArray "Texture1DArray" class instead. */ Texture1DArray = GL_TEXTURE_1D_ARRAY, - /** - * Two-dimensional texture array (i.e. three dimensions in total). - * Use `sampler2DArray`, `sampler2DArrayShadow`, `isampler2DArray` - * or `usampler2DArray` in shader. - * @requires_gl30 %Extension @extension{EXT,texture_array} - * @requires_gles30 %Array textures are not available in OpenGL ES - * 2.0. - */ + /** @deprecated Use @ref Magnum::Texture2DArray "Texture2DArray" class instead. */ Texture2DArray = GL_TEXTURE_2D_ARRAY, - /** - * Multisampled two-dimensional texture. Use `sampler2DMS`, - * `isampler2DMS` or `usampler2DMS` in shader. - * @requires_gl32 %Extension @extension{ARB,texture_multisample} - * @requires_gl Multisample textures are not available in OpenGL - * ES. - */ + /** @deprecated Use @ref Magnum::MultisampleTexture2D "MultisampleTexture2D" class instead. */ Texture2DMultisample = GL_TEXTURE_2D_MULTISAMPLE, - /** - * Multisampled two-dimensional texture array (i.e. three - * dimensions in total). Use `sampler2DMSArray`, - * `isampler2DMSArray` or `usampler2DMSArray` in shader. - * @requires_gl32 %Extension @extension{ARB,texture_multisample} - * @requires_gl Multisample textures are not available in OpenGL - * ES. - */ + /** @deprecated Use @ref Magnum::MultisampleTexture2DArray "MultisampleTexture2DArray" class instead. */ Texture2DMultisampleArray = GL_TEXTURE_2D_MULTISAMPLE_ARRAY, - /** - * Rectangle texture (i.e. two dimensions). Use `sampler2DRect`, - * `sampler2DRectShadow`, `isampler2DRect` or `usampler2DRect` in - * shader. - * @requires_gl31 %Extension @extension{ARB,texture_rectangle} - * @requires_gl Rectangle textures are not available in OpenGL ES. - */ + /** @deprecated Use @ref Magnum::RectangleTexture "RectangleTexture" class instead. */ Rectangle = GL_TEXTURE_RECTANGLE }; #else - typedef typename DataHelper::Target Target; /**< @brief %Texture target */ + typedef typename DataHelper::Target Target; + #endif #endif /** * @brief Constructor - * @param target %Texture target. If not set, default value - * is `Target::Texture1D`, `Target::Texture2D` or - * `Target::Texture3D` based on dimension count. * - * Creates new OpenGL texture. - * @see @fn_gl{GenTextures} + * Creates new OpenGL texture object. + * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_1D}, @def_gl{TEXTURE_2D} + * or @def_gl{TEXTURE_3D} */ - explicit Texture(Target target = DataHelper::target()): AbstractTexture(GLenum(target)) {} - - /** @brief %Texture target */ - constexpr Target target() const { return static_cast(_target); } + explicit Texture(): AbstractTexture(Implementation::textureTarget()) {} + + #ifdef MAGNUM_BUILD_DEPRECATED + /** @copybrief Texture() + * @deprecated Use the parameterless @ref Magnum::Texture::Texture() "Texture()" + * constructor or dedicated @ref Magnum::TextureArray "TextureArray", + * @ref Magnum::MultisampleTexture "MultisampleTexture", + * @ref Magnum::RectangleTexture "RectangleTexture" classes + * instead. + */ + explicit CORRADE_DEPRECATED("use the parameterless constructor or dedicated TextureArray, MultisampleTexture, RectangleTexture classes instead") Texture(Target target): AbstractTexture(GLenum(target)) {} + + /** @brief %Texture target + * @deprecated Use dedicated @ref Magnum::Texture "Texture", + * @ref Magnum::TextureArray "TextureArray", + * @ref Magnum::MultisampleTexture "MultisampleTexture", + * @ref Magnum::RectangleTexture "RectangleTexture" classes + * instead. + */ + constexpr CORRADE_DEPRECATED("use dedicated Texture, TextureArray, MultisampleTexture, RectangleTexture classes instead") Target target() const { return static_cast(_target); } + #endif #ifndef MAGNUM_TARGET_GLES /** @@ -245,11 +179,50 @@ template class Texture: public AbstractTexture { * with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or @def_gl{TEXTURE_DEPTH}. * @requires_gl %Texture image queries are not available in OpenGL ES. */ - typename DimensionTraits::VectorType imageSize(Int level) { - return DataHelper::imageSize(*this, _target, level); + typename DimensionTraits::VectorType imageSize(Int level) { + return DataHelper::imageSize(*this, _target, level); } #endif + /** + * @brief Set minification filter + * @param filter Filter + * @param mipmap Mipmap filtering. If set to anything else than + * @ref Sampler::Mipmap::Base, make sure textures for all mip + * levels are set or call @ref generateMipmap(). + * @return Reference to self (for method chaining) + * + * Sets filter used when the object pixel size is smaller than the + * texture size. If @extension{EXT,direct_state_access} is not + * available, the texture is bound to some layer before the operation. + * Initial value is (@ref Sampler::Filter::Nearest, @ref Sampler::Mipmap::Linear). + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} + * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} + * with @def_gl{TEXTURE_MIN_FILTER} + */ + Texture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { + AbstractTexture::setMinificationFilter(filter, mipmap); + return *this; + } + + /** + * @brief Set magnification filter + * @param filter Filter + * @return Reference to self (for method chaining) + * + * Sets filter used when the object pixel size is larger than largest + * texture size. If @extension{EXT,direct_state_access} is not + * available, the texture is bound to some layer before the operation. + * Initial value is @ref Sampler::Filter::Linear. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} + * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} + * with @def_gl{TEXTURE_MAG_FILTER} + */ + Texture& setMagnificationFilter(Sampler::Filter filter) { + AbstractTexture::setMagnificationFilter(filter); + return *this; + } + /** * @brief Set wrapping * @param wrapping Wrapping type for all texture dimensions @@ -260,15 +233,51 @@ template class Texture: public AbstractTexture { * textures. If @extension{EXT,direct_state_access} is not available, * the texture is bound to some layer before the operation. Initial * value is @ref Sampler::Wrapping::Repeat. - * @attention For rectangle textures only some modes are supported, - * see @ref Sampler::Wrapping documentation for more information. * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} * with @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T}, * @def_gl{TEXTURE_WRAP_R} */ - Texture& setWrapping(const Array& wrapping) { - DataHelper::setWrapping(*this, wrapping); + Texture& setWrapping(const Array& wrapping) { + DataHelper::setWrapping(*this, wrapping); + return *this; + } + + /** + * @brief Set border color + * @return Reference to self (for method chaining) + * + * Border color when wrapping is set to @ref Sampler::Wrapping::ClampToBorder. + * If @extension{EXT,direct_state_access} is not available, the texture + * is bound to some layer before the operation. Initial value is + * `{0.0f, 0.0f, 0.0f, 0.0f}`. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} + * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} + * with @def_gl{TEXTURE_BORDER_COLOR} + * @requires_es_extension %Extension @es_extension{NV,texture_border_clamp} + */ + Texture& setBorderColor(const Color4& color) { + AbstractTexture::setBorderColor(color); + return *this; + } + + /** + * @brief Set max anisotropy + * @return Reference to self (for method chaining) + * + * Default value is `1.0f`, which means no anisotropy. Set to value + * greater than `1.0f` for anisotropic filtering. If extension + * @extension{EXT,texture_filter_anisotropic} (desktop or ES) is not + * available, this function does nothing. If + * @extension{EXT,direct_state_access} is not available, the texture is + * bound to some layer before the operation. + * @see @ref Sampler::maxMaxAnisotropy(), @fn_gl{ActiveTexture}, + * @fn_gl{BindTexture} and @fn_gl{TexParameter} or + * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with + * @def_gl{TEXTURE_MAX_ANISOTROPY_EXT} + */ + Texture& setMaxAnisotropy(Float anisotropy) { + AbstractTexture::setMaxAnisotropy(anisotropy); return *this; } @@ -301,8 +310,8 @@ template class Texture: public AbstractTexture { * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureImage3D,EXT,direct_state_access}. */ - Texture& setStorage(Int levels, TextureFormat internalFormat, const typename DimensionTraits::VectorType& size) { - DataHelper::setStorage(*this, _target, levels, internalFormat, size); + Texture& setStorage(Int levels, TextureFormat internalFormat, const typename DimensionTraits::VectorType& size) { + DataHelper::setStorage(*this, _target, levels, internalFormat, size); return *this; } @@ -368,20 +377,20 @@ template class Texture: public AbstractTexture { * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureImage3D,EXT,direct_state_access} */ - Texture& setImage(Int level, TextureFormat internalFormat, const ImageReference& image) { - DataHelper::setImage(*this, _target, level, internalFormat, image); + Texture& setImage(Int level, TextureFormat internalFormat, const ImageReference& image) { + DataHelper::setImage(*this, _target, level, internalFormat, image); return *this; } #ifndef MAGNUM_TARGET_GLES2 /** @overload */ - Texture& setImage(Int level, TextureFormat internalFormat, BufferImage& image) { - DataHelper::setImage(*this, _target, level, internalFormat, image); + Texture& setImage(Int level, TextureFormat internalFormat, BufferImage& image) { + DataHelper::setImage(*this, _target, level, internalFormat, image); return *this; } /** @overload */ - Texture& setImage(Int level, TextureFormat internalFormat, BufferImage&& image) { + Texture& setImage(Int level, TextureFormat internalFormat, BufferImage&& image) { return setImage(level, internalFormat, image); } #endif @@ -403,24 +412,50 @@ template class Texture: public AbstractTexture { * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} */ - Texture& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, const ImageReference& image) { + Texture& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, const ImageReference& image) { DataHelper::setSubImage(*this, _target, level, offset, image); return *this; } #ifndef MAGNUM_TARGET_GLES2 /** @overload */ - Texture& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, BufferImage& image) { + Texture& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, BufferImage& image) { DataHelper::setSubImage(*this, _target, level, offset, image); return *this; } /** @overload */ - Texture& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, BufferImage&& image) { + Texture& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, BufferImage&& image) { return setSubImage(level, offset, image); } #endif + /** + * @brief Generate mipmap + * @return Reference to self (for method chaining) + * + * If @extension{EXT,direct_state_access} is not available, the texture + * is bound to some layer before the operation. + * @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{ARB,framebuffer_object} + */ + Texture& generateMipmap() { + AbstractTexture::generateMipmap(); + return *this; + } + + /** + * @brief Invalidate texture image + * @param level Mip level + * + * If running on OpenGL ES or extension @extension{ARB,invalidate_subdata} + * (part of OpenGL 4.3) is not available, this function does nothing. + * @see @ref invalidateSubImage(), @fn_gl{InvalidateTexImage} + */ + void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } + /** * @brief Invalidate texture subimage * @param level Mip level @@ -431,36 +466,16 @@ template class Texture: public AbstractTexture { * (part of OpenGL 4.3) is not available, this function does nothing. * @see @ref invalidateImage(), @fn_gl{InvalidateTexSubImage} */ - void invalidateSubImage(Int level, const typename DimensionTraits::VectorType& offset, const typename DimensionTraits::VectorType& size) { + void invalidateSubImage(Int level, const typename DimensionTraits::VectorType& offset, const typename DimensionTraits::VectorType& size) { DataHelper::invalidateSubImage(*this, level, offset, size); } /* Overloads to remove WTF-factor from method chaining order */ #ifndef DOXYGEN_GENERATING_OUTPUT - Texture& setLabel(const std::string& label) { + Texture& setLabel(const std::string& label) { AbstractTexture::setLabel(label); return *this; } - Texture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { - AbstractTexture::setMinificationFilter(filter, mipmap); - return *this; - } - Texture& setMagnificationFilter(Sampler::Filter filter) { - AbstractTexture::setMagnificationFilter(filter); - return *this; - } - Texture& setBorderColor(const Color4& color) { - AbstractTexture::setBorderColor(color); - return *this; - } - Texture& setMaxAnisotropy(Float anisotropy) { - AbstractTexture::setMaxAnisotropy(anisotropy); - return *this; - } - Texture& generateMipmap() { - AbstractTexture::generateMipmap(); - return *this; - } #endif }; diff --git a/src/Magnum/TextureArray.h b/src/Magnum/TextureArray.h new file mode 100644 index 000000000..e4653dae6 --- /dev/null +++ b/src/Magnum/TextureArray.h @@ -0,0 +1,302 @@ +#ifndef Magnum_TextureArray_h +#define Magnum_TextureArray_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef MAGNUM_TARGET_GLES2 +/** @file + * @brief Class @ref Magnum::TextureArray, typedef @ref Magnum::Texture1DArray, @ref Magnum::Texture2DArray + */ +#endif + +#include "Magnum/AbstractTexture.h" +#include "Magnum/Array.h" +#include "Magnum/DimensionTraits.h" +#include "Magnum/Math/Vector3.h" + +#ifndef MAGNUM_TARGET_GLES2 +namespace Magnum { + +namespace Implementation { + template constexpr GLenum textureArrayTarget(); + #ifndef MAGNUM_TARGET_GLES + template<> inline constexpr GLenum textureArrayTarget<1>() { return GL_TEXTURE_1D_ARRAY; } + #endif + template<> inline constexpr GLenum textureArrayTarget<2>() { return GL_TEXTURE_2D_ARRAY; } +} + +/** +@brief %Texture array + +Template class for one- and two-dimensional texture arrays. See also +@ref AbstractTexture documentation for more information. + +@section Texture-usage Usage + +Common usage is to fully configure all texture parameters and then set the +data. Example configuration: +@code +Texture2DArray texture; +texture.setMagnificationFilter(Sampler::Filter::Linear) + .setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) + .setWrapping(Sampler::Wrapping::ClampToEdge) + .setMaxAnisotropy(Sampler::maxMaxAnisotropy());; +@endcode + +It is often more convenient to first allocate the memory for all layers by +calling @ref setStorage() and then specify each layer separately using +@ref setSubImage(): +@code +texture.setStorage(levels, TextureFormat::RGBA8, {64, 64, 16}); + +for(std::size_t i = 0; i != 16; ++i) { + Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte, {64, 64, 1}, ...); + texture.setSubImage(0, Vector3i::zAxis(i), image); +} +@endcode + +@attention Note that default configuration (if @ref setMinificationFilter() is + not called with another value) is to use mipmaps, so be sure to either call + @ref setMinificationFilter(), explicitly specify all mip levels with + @ref setStorage() and @ref setImage() or call @ref generateMipmap(). + +The texture is bound to layer specified by shader via @ref bind(). In shader, +the texture is used via `sampler1DArray`/`sampler2DArray`, +`sampler1DArrayShadow`/`sampler1DArrayShadow`, `isampler1DArray`/`isampler2DArray` +or `usampler1DArray`/`usampler2DArray`. See @ref AbstractShaderProgram +documentation for more information about usage in shaders. + +@requires_gl30 %Extension @extension{EXT,texture_array} +@requires_gles30 %Array textures are not available in OpenGL ES 2.0. +@requires_gl 1D array textures are not available in OpenGL ES, only 2D ones. + +@see @ref Texture1DArray, @ref Texture2DArray, @ref Texture, @ref BufferTexture, + @ref CubeMapTexture, @ref CubeMapTextureArray, @ref MultisampleTexture, + @ref RectangleTexture + */ +template class TextureArray: public AbstractTexture { + public: + static const UnsignedInt Dimensions = dimensions; /**< @brief %Texture dimension count */ + + /** + * @brief Constructor + * + * Creates new OpenGL texture object. + * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_1D_ARRAY} or @def_gl{TEXTURE_2D_ARRAY} + */ + explicit TextureArray(): AbstractTexture(Implementation::textureArrayTarget()) {} + + /** @copydoc Texture::setMinificationFilter() */ + TextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { + AbstractTexture::setMinificationFilter(filter, mipmap); + return *this; + } + + /** @copydoc Texture::setMagnificationFilter() */ + TextureArray& setMagnificationFilter(Sampler::Filter filter) { + AbstractTexture::setMagnificationFilter(filter); + return *this; + } + + /** @copydoc Texture::setWrapping() */ + TextureArray& setWrapping(const Array& wrapping) { + DataHelper::setWrapping(*this, wrapping); + return *this; + } + + /** @copydoc Texture::setBorderColor() */ + TextureArray& setBorderColor(const Color4& color) { + AbstractTexture::setBorderColor(color); + return *this; + } + + /** @copydoc Texture::setMaxAnisotropy() */ + TextureArray& setMaxAnisotropy(Float anisotropy) { + AbstractTexture::setMaxAnisotropy(anisotropy); + return *this; + } + + #ifndef MAGNUM_TARGET_GLES + /** @copydoc Texture::imageSize() */ + typename DimensionTraits::VectorType imageSize(Int level) { + return DataHelper::imageSize(*this, _target, level); + } + #endif + + /** + * @brief Set storage + * @param levels Mip level count + * @param internalFormat Internal format + * @param size Size of largest mip level + * @return Reference to self (for method chaining) + * + * Specifies entire structure of a texture at once, removing the need + * for additional consistency checks and memory reallocations when + * updating the data later. After calling this function the texture + * is immutable and calling @ref setStorage() or @ref setImage() is not + * allowed. + * + * If @extension{EXT,direct_state_access} is not available, the texture + * is bound to some layer before the operation. If + * @extension{ARB,texture_storage} (part of OpenGL 4.2) or OpenGL ES + * 3.0 is not available, the feature is emulated with sequence of + * @ref setImage() calls. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexStorage2D}/@fn_gl{TexStorage3D} or + * @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}/ + * @fn_gl_extension{TextureStorage3D,EXT,direct_state_access}, + * eventually @fn_gl{TexImage2D}/@fn_gl{TexImage3D} or + * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ + * @fn_gl_extension{TextureImage3D,EXT,direct_state_access}. + */ + TextureArray& setStorage(Int levels, TextureFormat internalFormat, const typename DimensionTraits::VectorType& size) { + DataHelper::setStorage(*this, _target, levels, internalFormat, size); + return *this; + } + + #ifndef MAGNUM_TARGET_GLES + /** @copydoc Texture::image(Int, Image&) */ + void image(Int level, Image& image) { + AbstractTexture::image(_target, level, image); + } + + /** @copydoc Texture::imate(Int, BufferImage&, BufferUsage) */ + void image(Int level, BufferImage& image, BufferUsage usage) { + AbstractTexture::image(_target, level, image, usage); + } + #endif + + /** + * @brief Set image data + * @param level Mip level + * @param internalFormat Internal format + * @param image @ref Image, @ref ImageReference or + * @ref Trade::ImageData of the same dimension count + * @return Reference to self (for method chaining) + * + * For better performance when generating mipmaps using + * @ref generateMipmap() or calling @ref setImage() more than once use + * @ref setStorage() and @ref setSubImage() instead. + * + * If @extension{EXT,direct_state_access} is not available, the + * texture is bound to some layer before the operation. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexImage2D}/@fn_gl{TexImage3D} or + * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ + * @fn_gl_extension{TextureImage3D,EXT,direct_state_access} + */ + TextureArray& setImage(Int level, TextureFormat internalFormat, const ImageReference& image) { + DataHelper::setImage(*this, _target, level, internalFormat, image); + return *this; + } + + #ifndef MAGNUM_TARGET_GLES2 + /** @overload */ + TextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage& image) { + DataHelper::setImage(*this, _target, level, internalFormat, image); + return *this; + } + + /** @overload */ + TextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage&& image) { + return setImage(level, internalFormat, image); + } + #endif + + /** + * @brief Set image subdata + * @param level Mip level + * @param offset Offset where to put data in the texture + * @param image @ref Image, @ref ImageReference or + * @ref Trade::ImageData of the same dimension count + * @return Reference to self (for method chaining) + * + * If @extension{EXT,direct_state_access} is not available, the + * texture is bound to some layer before the operation. + * @see @ref setStorage(), @ref setImage(), @fn_gl{ActiveTexture}, + * @fn_gl{BindTexture} and @fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D} + * or @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ + * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} + */ + TextureArray& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, const ImageReference& image) { + DataHelper::setSubImage(*this, _target, level, offset, image); + return *this; + } + + #ifndef MAGNUM_TARGET_GLES2 + /** @overload */ + TextureArray& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, BufferImage& image) { + DataHelper::setSubImage(*this, _target, level, offset, image); + return *this; + } + + /** @overload */ + TextureArray& setSubImage(Int level, const typename DimensionTraits::VectorType& offset, BufferImage&& image) { + return setSubImage(level, offset, image); + } + #endif + + /** @copydoc Texture::generateMipmap() */ + TextureArray& generateMipmap() { + AbstractTexture::generateMipmap(); + return *this; + } + + /** @copydoc Texture::invalidateImage() */ + void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } + + /** @copydoc Texture::invalidateSubImage() */ + void invalidateSubImage(Int level, const typename DimensionTraits::VectorType& offset, const typename DimensionTraits::VectorType& size) { + DataHelper::invalidateSubImage(*this, level, offset, size); + } + + /* Overloads to remove WTF-factor from method chaining order */ + #ifndef DOXYGEN_GENERATING_OUTPUT + TextureArray& setLabel(const std::string& label) { + AbstractTexture::setLabel(label); + return *this; + } + #endif +}; + +#ifndef MAGNUM_TARGET_GLES +/** +@brief One-dimensional texture array + +@requires_gl Only @ref Magnum::Texture2DArray "Texture2DArray" is available in + OpenGL ES. +*/ +typedef TextureArray<1> Texture1DArray; +#endif + +/** @brief Two-dimensional texture array */ +typedef TextureArray<2> Texture2DArray; + +} +#else +#error this header is not available on OpenGL ES 2.0 build +#endif + +#endif