diff --git a/doc/opengl-mapping.dox b/doc/opengl-mapping.dox index cea87b979..2f5ad439d 100644 --- a/doc/opengl-mapping.dox +++ b/doc/opengl-mapping.dox @@ -234,7 +234,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 TextureArray::setImage(), \n @ref CubeMapTexture::setImage(), \n @ref CubeMapTextureArray::setImage(), \n @ref RectangleTexture::setImage() @fn_gl{TexImage2DMultisample}, \n @fn_gl{TexImage3DMultisample} | @ref MultisampleTexture::setStorage() -@fn_gl{TexParameter}, \n @fn_gl_extension{TextureParameter,EXT,direct_state_access} | @ref Texture::setBaseLevel() "*Texture::setBaseLevel()", \n @ref Texture::setMaxLevel() "*Texture::setMaxLevel()", \n @ref Texture::setMinificationFilter() "*Texture::setMinificationFilter()", \n @ref Texture::setMagnificationFilter() "*Texture::setMagnificationFilter()", \n @ref Texture::setMinLod() "*Texture::setMinLod()", \n @ref Texture::setMaxLod() "*Texture::setMaxLod()", \n @ref Texture::setLodBias() "*Texture::setLodBias()", \n @ref Texture::setWrapping() "*Texture::setWrapping()", \n @ref Texture::setBorderColor() "*Texture::setBorderColor()", \n @ref Texture::setMaxAnisotropy() "*Texture::setMaxAnisotropy()", \n @ref Texture::setCompareMode() "*Texture::setCompareMode()", \n @ref Texture::setCompareFunction() "*Texture::setCompareFunction()", \n @ref Texture::setDepthStencilMode() "*Texture::setDepthStencilMode()" +@fn_gl{TexParameter}, \n @fn_gl_extension{TextureParameter,EXT,direct_state_access} | @ref Texture::setBaseLevel() "*Texture::setBaseLevel()", \n @ref Texture::setMaxLevel() "*Texture::setMaxLevel()", \n @ref Texture::setMinificationFilter() "*Texture::setMinificationFilter()", \n @ref Texture::setMagnificationFilter() "*Texture::setMagnificationFilter()", \n @ref Texture::setMinLod() "*Texture::setMinLod()", \n @ref Texture::setMaxLod() "*Texture::setMaxLod()", \n @ref Texture::setLodBias() "*Texture::setLodBias()", \n @ref Texture::setWrapping() "*Texture::setWrapping()", \n @ref Texture::setBorderColor() "*Texture::setBorderColor()", \n @ref Texture::setMaxAnisotropy() "*Texture::setMaxAnisotropy()", \n @ref Texture::setSwizzle() "*Texture::setSwizzle()", \n @ref Texture::setCompareMode() "*Texture::setCompareMode()", \n @ref Texture::setCompareFunction() "*Texture::setCompareFunction()", \n @ref Texture::setDepthStencilMode() "*Texture::setDepthStencilMode()" @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 TextureArray::setStorage(), \n @ref CubeMapTexture::setStorage(), \n @ref CubeMapTextureArray::setStorage(), \n @ref RectangleTexture::setStorage() @fn_gl{TexStorage2DMultisample}, \n @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access}, \n @fn_gl{TexStorage3DMultisample}, \n @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access} | @ref MultisampleTexture::setStorage() @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 TextureArray::setSubImage(), \n @ref CubeMapTexture::setSubImage(), \n @ref CubeMapTextureArray::setSubImage(), \n @ref RectangleTexture::setSubImage() diff --git a/doc/opengl-support.dox b/doc/opengl-support.dox index 80a54eadb..25ba6a715 100644 --- a/doc/opengl-support.dox +++ b/doc/opengl-support.dox @@ -114,7 +114,7 @@ following: @extension{ARB,sampler_objects} | | @extension{ARB,shader_bit_encoding} | done (shading language only) @extension{ARB,texture_rgb10_a2ui} | done -@extension{ARB,texture_swizzle} | | +@extension{ARB,texture_swizzle} | done @extension{ARB,timer_query} | missing direct query @extension{ARB,vertex_type_2_10_10_10_rev} | done diff --git a/src/Magnum/AbstractTexture.cpp b/src/Magnum/AbstractTexture.cpp index 7492a4028..6e9049a4f 100644 --- a/src/Magnum/AbstractTexture.cpp +++ b/src/Magnum/AbstractTexture.cpp @@ -286,6 +286,20 @@ void AbstractTexture::setMaxAnisotropy(const Float anisotropy) { (this->*Context::current()->state().texture->setMaxAnisotropyImplementation)(anisotropy); } +#ifndef MAGNUM_TARGET_GLES2 +void AbstractTexture::setSwizzleInternal(const GLint r, const GLint g, const GLint b, const GLint a) { + #ifndef MAGNUM_TARGET_GLES + const GLint rgba[] = {r, g, b, a}; + (this->*Context::current()->state().texture->parameterivImplementation)(GL_TEXTURE_SWIZZLE_RGBA, rgba); + #else + (this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_SWIZZLE_R, r); + (this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_SWIZZLE_G, g); + (this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_SWIZZLE_B, b); + (this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_SWIZZLE_A, a); + #endif +} +#endif + void AbstractTexture::setCompareMode(const Sampler::CompareMode mode) { (this->*Context::current()->state().texture->parameteriImplementation)( #ifndef MAGNUM_TARGET_GLES2 @@ -745,6 +759,19 @@ void AbstractTexture::parameterImplementationDSA(GLenum parameter, GLfloat value } #endif +#ifndef MAGNUM_TARGET_GLES2 +void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLint* values) { + bindInternal(); + glTexParameteriv(_target, parameter, values); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractTexture::parameterImplementationDSA(GLenum parameter, const GLint* values) { + glTextureParameterivEXT(_id, _target, parameter, values); +} +#endif +#endif + void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLfloat* values) { bindInternal(); glTexParameterfv(_target, parameter, values); diff --git a/src/Magnum/AbstractTexture.h b/src/Magnum/AbstractTexture.h index 78f51ab76..68e377828 100644 --- a/src/Magnum/AbstractTexture.h +++ b/src/Magnum/AbstractTexture.h @@ -34,7 +34,19 @@ namespace Magnum { -namespace Implementation { struct TextureState; } +namespace Implementation { + struct TextureState; + + #ifndef MAGNUM_TARGET_GLES2 + template struct TextureSwizzle; + template<> struct TextureSwizzle<'r'> { enum: GLint { Value = GL_RED }; }; + template<> struct TextureSwizzle<'g'> { enum: GLint { Value = GL_GREEN }; }; + template<> struct TextureSwizzle<'b'> { enum: GLint { Value = GL_BLUE }; }; + template<> struct TextureSwizzle<'a'> { enum: GLint { Value = GL_ALPHA }; }; + template<> struct TextureSwizzle<'0'> { enum: GLint { Value = GL_ZERO }; }; + template<> struct TextureSwizzle<'1'> { enum: GLint { Value = GL_ONE }; }; + #endif +} /** @brief Base for textures @@ -297,6 +309,17 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { void setBorderColor(const Vector4ui& color); #endif void setMaxAnisotropy(Float anisotropy); + + #ifndef MAGNUM_TARGET_GLES2 + template void setSwizzle() { + setSwizzleInternal(Implementation::TextureSwizzle::Value, + Implementation::TextureSwizzle::Value, + Implementation::TextureSwizzle::Value, + Implementation::TextureSwizzle::Value); + } + void setSwizzleInternal(GLint r, GLint g, GLint b, GLint a); + #endif + void setCompareMode(Sampler::CompareMode mode); void setCompareFunction(Sampler::CompareFunction function); #ifndef MAGNUM_TARGET_GLES @@ -332,6 +355,9 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { void MAGNUM_LOCAL parameterImplementationDefault(GLenum parameter, GLint value); void MAGNUM_LOCAL parameterImplementationDefault(GLenum parameter, GLfloat value); + #ifndef MAGNUM_TARGET_GLES2 + void MAGNUM_LOCAL parameterImplementationDefault(GLenum parameter, const GLint* values); + #endif void MAGNUM_LOCAL parameterImplementationDefault(GLenum parameter, const GLfloat* values); #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL parameterIImplementationDefault(GLenum parameter, const GLuint* values); @@ -340,6 +366,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLint value); void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLfloat value); + void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, const GLint* values); void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, const GLfloat* values); void MAGNUM_LOCAL parameterIImplementationDSA(GLenum parameter, const GLuint* values); void MAGNUM_LOCAL parameterIImplementationDSA(GLenum parameter, const GLint* values); diff --git a/src/Magnum/CubeMapTexture.h b/src/Magnum/CubeMapTexture.h index 5fa4f4734..45372823f 100644 --- a/src/Magnum/CubeMapTexture.h +++ b/src/Magnum/CubeMapTexture.h @@ -188,6 +188,14 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { return *this; } + #ifndef MAGNUM_TARGET_GLES2 + /** @copydoc Texture::setSwizzle() */ + template CubeMapTexture& setSwizzle() { + AbstractTexture::setSwizzle(); + return *this; + } + #endif + /** * @copybrief Texture::setCompareMode() * @return Reference to self (for method chaining) diff --git a/src/Magnum/CubeMapTextureArray.h b/src/Magnum/CubeMapTextureArray.h index 3cf1da116..ab24ca357 100644 --- a/src/Magnum/CubeMapTextureArray.h +++ b/src/Magnum/CubeMapTextureArray.h @@ -218,6 +218,17 @@ class CubeMapTextureArray: public AbstractTexture { return *this; } + /** + * @copybrief Texture::setSwizzle() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSwizzle() for more information. + */ + template CubeMapTextureArray& setSwizzle() { + AbstractTexture::setSwizzle(); + return *this; + } + /** * @copybrief Texture::setCompareMode() * @return Reference to self (for method chaining) diff --git a/src/Magnum/Implementation/TextureState.cpp b/src/Magnum/Implementation/TextureState.cpp index b08899058..864e64716 100644 --- a/src/Magnum/Implementation/TextureState.cpp +++ b/src/Magnum/Implementation/TextureState.cpp @@ -72,6 +72,7 @@ TextureState::TextureState(Context& context, std::vector& extension parameteriImplementation = &AbstractTexture::parameterImplementationDSA; parameterfImplementation = &AbstractTexture::parameterImplementationDSA; + parameterivImplementation = &AbstractTexture::parameterImplementationDSA; parameterfvImplementation = &AbstractTexture::parameterImplementationDSA; parameterIuivImplementation = &AbstractTexture::parameterIImplementationDSA; parameterIivImplementation = &AbstractTexture::parameterIImplementationDSA; @@ -92,6 +93,9 @@ TextureState::TextureState(Context& context, std::vector& extension { parameteriImplementation = &AbstractTexture::parameterImplementationDefault; parameterfImplementation = &AbstractTexture::parameterImplementationDefault; + #ifndef MAGNUM_TARGET_GLES2 + parameterivImplementation = &AbstractTexture::parameterImplementationDefault; + #endif parameterfvImplementation = &AbstractTexture::parameterImplementationDefault; #ifndef MAGNUM_TARGET_GLES parameterIuivImplementation = &AbstractTexture::parameterIImplementationDefault; diff --git a/src/Magnum/Implementation/TextureState.h b/src/Magnum/Implementation/TextureState.h index 9e44a68aa..e33d21ae3 100644 --- a/src/Magnum/Implementation/TextureState.h +++ b/src/Magnum/Implementation/TextureState.h @@ -42,6 +42,9 @@ struct TextureState { void(AbstractTexture::*bindImplementation)(GLint); void(AbstractTexture::*parameteriImplementation)(GLenum, GLint); void(AbstractTexture::*parameterfImplementation)(GLenum, GLfloat); + #ifndef MAGNUM_TARGET_GLES2 + void(AbstractTexture::*parameterivImplementation)(GLenum, const GLint*); + #endif void(AbstractTexture::*parameterfvImplementation)(GLenum, const GLfloat*); void(AbstractTexture::*parameterIuivImplementation)(GLenum, const GLuint*); void(AbstractTexture::*parameterIivImplementation)(GLenum, const GLint*); diff --git a/src/Magnum/RectangleTexture.h b/src/Magnum/RectangleTexture.h index 55d052734..3b5e4c5f9 100644 --- a/src/Magnum/RectangleTexture.h +++ b/src/Magnum/RectangleTexture.h @@ -190,6 +190,17 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { return *this; } + /** + * @copybrief Texture::setSwizzle() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSwizzle() for more information. + */ + template RectangleTexture& setSwizzle() { + AbstractTexture::setSwizzle(); + return *this; + } + /** * @copybrief Texture::setCompareMode() * @return Reference to self (for method chaining) diff --git a/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp b/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp index 41427ab05..5fadb807a 100644 --- a/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp @@ -44,6 +44,7 @@ class CubeMapTextureArrayGLTest: public AbstractOpenGLTester { void sampling(); void samplingBorderInteger(); + void samplingSwizzle(); void samplingDepthStencilMode(); void storage(); @@ -65,6 +66,7 @@ CubeMapTextureArrayGLTest::CubeMapTextureArrayGLTest() { &CubeMapTextureArrayGLTest::sampling, &CubeMapTextureArrayGLTest::samplingBorderInteger, + &CubeMapTextureArrayGLTest::samplingSwizzle, &CubeMapTextureArrayGLTest::samplingDepthStencilMode, &CubeMapTextureArrayGLTest::storage, @@ -155,6 +157,18 @@ void CubeMapTextureArrayGLTest::samplingBorderInteger() { MAGNUM_VERIFY_NO_ERROR(); } +void CubeMapTextureArrayGLTest::samplingSwizzle() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_swizzle::string() + std::string(" is not supported.")); + + CubeMapTextureArray texture; + texture.setSwizzle<'b', 'g', 'r', '0'>(); + + MAGNUM_VERIFY_NO_ERROR(); +} + void CubeMapTextureArrayGLTest::samplingDepthStencilMode() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); diff --git a/src/Magnum/Test/CubeMapTextureGLTest.cpp b/src/Magnum/Test/CubeMapTextureGLTest.cpp index 5de0f2047..7f5d12d9d 100644 --- a/src/Magnum/Test/CubeMapTextureGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureGLTest.cpp @@ -46,7 +46,9 @@ class CubeMapTextureGLTest: public AbstractOpenGLTester { void bind(); void sampling(); - #ifdef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES2 + void samplingSwizzle(); + #else void samplingMaxLevel(); void samplingCompare(); #endif @@ -78,7 +80,9 @@ CubeMapTextureGLTest::CubeMapTextureGLTest() { &CubeMapTextureGLTest::bind, &CubeMapTextureGLTest::sampling, - #ifdef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES2 + &CubeMapTextureGLTest::samplingSwizzle, + #else &CubeMapTextureGLTest::samplingMaxLevel, &CubeMapTextureGLTest::samplingCompare, #endif @@ -165,7 +169,19 @@ void CubeMapTextureGLTest::sampling() { MAGNUM_VERIFY_NO_ERROR(); } -#ifdef MAGNUM_TARGET_GLES2 +#ifndef MAGNUM_TARGET_GLES2 +void CubeMapTextureGLTest::samplingSwizzle() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_swizzle::string() + std::string(" is not supported.")); + #endif + + CubeMapTexture texture; + texture.setSwizzle<'b', 'g', 'r', '0'>(); + + MAGNUM_VERIFY_NO_ERROR(); +} +#else void CubeMapTextureGLTest::samplingMaxLevel() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::APPLE::texture_max_level::string() + std::string(" is not supported.")); diff --git a/src/Magnum/Test/RectangleTextureGLTest.cpp b/src/Magnum/Test/RectangleTextureGLTest.cpp index d51b29fbc..7a925626f 100644 --- a/src/Magnum/Test/RectangleTextureGLTest.cpp +++ b/src/Magnum/Test/RectangleTextureGLTest.cpp @@ -45,6 +45,7 @@ class RectangleTextureGLTest: public AbstractOpenGLTester { void sampling(); void samplingBorderInteger(); + void samplingSwizzle(); void samplingDepthStencilMode(); void storage(); @@ -64,6 +65,7 @@ RectangleTextureGLTest::RectangleTextureGLTest() { &RectangleTextureGLTest::sampling, &RectangleTextureGLTest::samplingBorderInteger, + &RectangleTextureGLTest::samplingSwizzle, &RectangleTextureGLTest::samplingDepthStencilMode, &RectangleTextureGLTest::storage, @@ -151,6 +153,18 @@ void RectangleTextureGLTest::samplingBorderInteger() { MAGNUM_VERIFY_NO_ERROR(); } +void RectangleTextureGLTest::samplingSwizzle() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_swizzle::string() + std::string(" is not supported.")); + + RectangleTexture texture; + texture.setSwizzle<'b', 'g', 'r', '0'>(); + + MAGNUM_VERIFY_NO_ERROR(); +} + void RectangleTextureGLTest::samplingDepthStencilMode() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); diff --git a/src/Magnum/Test/TextureArrayGLTest.cpp b/src/Magnum/Test/TextureArrayGLTest.cpp index d66ad6a33..495bcc392 100644 --- a/src/Magnum/Test/TextureArrayGLTest.cpp +++ b/src/Magnum/Test/TextureArrayGLTest.cpp @@ -55,7 +55,12 @@ class TextureArrayGLTest: public AbstractOpenGLTester { #endif void sampling2D(); - #ifdef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES + void samplingSwizzle1D(); + #endif + void samplingSwizzle2D(); + #else void samplingMaxLevel2D(); void samplingCompare2D(); #endif @@ -123,7 +128,12 @@ TextureArrayGLTest::TextureArrayGLTest() { #endif &TextureArrayGLTest::sampling2D, - #ifdef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES + &TextureArrayGLTest::samplingSwizzle1D, + #endif + &TextureArrayGLTest::samplingSwizzle2D, + #else &TextureArrayGLTest::samplingMaxLevel2D, #endif @@ -282,6 +292,16 @@ void TextureArrayGLTest::sampling1D() { MAGNUM_VERIFY_NO_ERROR(); } +void TextureArrayGLTest::samplingSwizzle1D() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_swizzle::string() + std::string(" is not supported.")); + + Texture1DArray texture; + texture.setSwizzle<'b', 'g', 'r', '0'>(); + + MAGNUM_VERIFY_NO_ERROR(); +} + void TextureArrayGLTest::samplingBorderInteger1D() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::EXT::texture_integer::string() + std::string(" is not supported.")); @@ -341,7 +361,19 @@ void TextureArrayGLTest::sampling2D() { MAGNUM_VERIFY_NO_ERROR(); } -#ifdef MAGNUM_TARGET_GLES2 +#ifndef MAGNUM_TARGET_GLES2 +void TextureArrayGLTest::samplingSwizzle2D() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_swizzle::string() + std::string(" is not supported.")); + #endif + + Texture2DArray texture; + texture.setSwizzle<'b', 'g', 'r', '0'>(); + + MAGNUM_VERIFY_NO_ERROR(); +} +#else void TextureArrayGLTest::samplingMaxLevel2D() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::APPLE::texture_max_level::string() + std::string(" is not supported.")); diff --git a/src/Magnum/Test/TextureGLTest.cpp b/src/Magnum/Test/TextureGLTest.cpp index 0cc5bd74f..8f6b6fead 100644 --- a/src/Magnum/Test/TextureGLTest.cpp +++ b/src/Magnum/Test/TextureGLTest.cpp @@ -60,7 +60,13 @@ class TextureGLTest: public AbstractOpenGLTester { void sampling2D(); void sampling3D(); - #ifdef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES + void samplingSwizzle1D(); + #endif + void samplingSwizzle2D(); + void samplingSwizzle3D(); + #else void samplingMaxLevel2D(); void samplingMaxLevel3D(); void samplingCompare2D(); @@ -150,7 +156,13 @@ TextureGLTest::TextureGLTest() { &TextureGLTest::sampling2D, &TextureGLTest::sampling3D, - #ifdef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES + &TextureGLTest::samplingSwizzle1D, + #endif + &TextureGLTest::samplingSwizzle2D, + &TextureGLTest::samplingSwizzle3D, + #else &TextureGLTest::samplingMaxLevel2D, &TextureGLTest::samplingMaxLevel3D, &TextureGLTest::samplingCompare2D, @@ -355,6 +367,16 @@ void TextureGLTest::sampling1D() { MAGNUM_VERIFY_NO_ERROR(); } +void TextureGLTest::samplingSwizzle1D() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_swizzle::string() + std::string(" is not supported.")); + + Texture1D texture; + texture.setSwizzle<'b', 'g', 'r', '0'>(); + + MAGNUM_VERIFY_NO_ERROR(); +} + void TextureGLTest::samplingDepthStencilMode1D() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::stencil_texturing::string() + std::string(" is not supported.")); @@ -392,7 +414,19 @@ void TextureGLTest::sampling2D() { MAGNUM_VERIFY_NO_ERROR(); } -#ifdef MAGNUM_TARGET_GLES2 +#ifndef MAGNUM_TARGET_GLES2 +void TextureGLTest::samplingSwizzle2D() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_swizzle::string() + std::string(" is not supported.")); + #endif + + Texture2D texture; + texture.setSwizzle<'b', 'g', 'r', '0'>(); + + MAGNUM_VERIFY_NO_ERROR(); +} +#else void TextureGLTest::samplingMaxLevel2D() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::APPLE::texture_max_level::string() + std::string(" is not supported.")); @@ -481,7 +515,19 @@ void TextureGLTest::sampling3D() { MAGNUM_VERIFY_NO_ERROR(); } -#ifdef MAGNUM_TARGET_GLES2 +#ifndef MAGNUM_TARGET_GLES2 +void TextureGLTest::samplingSwizzle3D() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::texture_swizzle::string() + std::string(" is not supported.")); + #endif + + Texture3D texture; + texture.setSwizzle<'b', 'g', 'r', '0'>(); + + MAGNUM_VERIFY_NO_ERROR(); +} +#else void TextureGLTest::samplingMaxLevel3D() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::OES::texture_3D::string() + std::string(" is not supported.")); diff --git a/src/Magnum/Texture.h b/src/Magnum/Texture.h index 7a96de6a2..c1de9599b 100644 --- a/src/Magnum/Texture.h +++ b/src/Magnum/Texture.h @@ -442,6 +442,35 @@ template class Texture: public AbstractTexture { return *this; } + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Set component swizzle + * @return Reference to self (for method chaining) + * + * You can use letters `r`, `g`, `b`, `a` for addressing components or + * letters `0` and `1` for zero and one, similarly as in + * @ref Math::swizzle() function. Example usage: + * @code + * texture.setSwizzle<'b', 'g', 'r', '0'>(); + * @endcode + * If @extension{EXT,direct_state_access} is not available, + * the texture is bound to some texture unit before the operation. + * Initial value is `rgba`. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} or + * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with + * @def_gl{TEXTURE_SWIZZLE_RGBA} (or @def_gl{TEXTURE_SWIZZLE_R}, + * @def_gl{TEXTURE_SWIZZLE_G}, @def_gl{TEXTURE_SWIZZLE_B} and + * @def_gl{TEXTURE_SWIZZLE_A} separately in OpenGL ES) + * @requires_gl33 %Extension @extension{ARB,texture_swizzle} + * @requires_gles30 %Texture swizzle is not available in OpenGL ES 2.0. + */ + template Texture& setSwizzle() { + AbstractTexture::setSwizzle(); + return *this; + } + #endif + /** * @brief Set depth texture comparison mode * @return Reference to self (for method chaining) diff --git a/src/Magnum/TextureArray.h b/src/Magnum/TextureArray.h index c8d94d0ef..0a671dbd7 100644 --- a/src/Magnum/TextureArray.h +++ b/src/Magnum/TextureArray.h @@ -196,6 +196,14 @@ template class TextureArray: public AbstractTexture { return *this; } + #ifndef MAGNUM_TARGET_GLES2 + /** @copydoc Texture::setSwizzle() */ + template TextureArray& setSwizzle() { + AbstractTexture::setSwizzle(); + return *this; + } + #endif + /** * @copybrief Texture::setCompareMode() * @return Reference to self (for method chaining)