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