diff --git a/doc/opengl-mapping.dox b/doc/opengl-mapping.dox index dcec0aff7..cea87b979 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::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::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 a8498f323..80a54eadb 100644 --- a/doc/opengl-support.dox +++ b/doc/opengl-support.dox @@ -252,6 +252,7 @@ supported. @es_extension2{EXT,blend_minmax,blend_minmax} | done @es_extension{EXT,shader_texture_lod} | done (shading language only) @es_extension{EXT,occlusion_query_boolean} | done +@es_extension{EXT,shadow_samplers} | done @es_extension{EXT,texture_rg} | done @es_extension{EXT,texture_storage} | done @es_extension{EXT,map_buffer_range} | done @@ -260,6 +261,8 @@ supported. @es_extension{NV,read_buffer} | done @es_extension{NV,framebuffer_blit} | done @es_extension{NV,framebuffer_multisample} | done +@es_extension{NV,shadow_samplers_array} | done (shading language only) +@es_extension{NV,shadow_samplers_cube} | done (shading language only) @es_extension{OES,depth24} | done @es_extension{OES,element_index_uint} | done @es_extension{OES,rgb8_rgba8} | done (desktop-compatible subset) diff --git a/src/Magnum/AbstractTexture.cpp b/src/Magnum/AbstractTexture.cpp index 1fb3143d4..34a30861f 100644 --- a/src/Magnum/AbstractTexture.cpp +++ b/src/Magnum/AbstractTexture.cpp @@ -286,6 +286,26 @@ void AbstractTexture::setMaxAnisotropy(const Float anisotropy) { (this->*Context::current()->state().texture->setMaxAnisotropyImplementation)(anisotropy); } +void AbstractTexture::setCompareMode(const Sampler::CompareMode mode) { + (this->*Context::current()->state().texture->parameteriImplementation)( + #ifndef MAGNUM_TARGET_GLES2 + GL_TEXTURE_COMPARE_MODE + #else + GL_TEXTURE_COMPARE_MODE_EXT + #endif + , GLenum(mode)); +} + +void AbstractTexture::setCompareFunction(const Sampler::CompareFunction function) { + (this->*Context::current()->state().texture->parameteriImplementation)( + #ifndef MAGNUM_TARGET_GLES2 + GL_TEXTURE_COMPARE_FUNC + #else + GL_TEXTURE_COMPARE_FUNC_EXT + #endif + , GLenum(function)); +} + #ifndef MAGNUM_TARGET_GLES void AbstractTexture::setDepthStencilMode(const Sampler::DepthStencilMode mode) { (this->*Context::current()->state().texture->parameteriImplementation)(GL_DEPTH_STENCIL_TEXTURE_MODE, GLenum(mode)); diff --git a/src/Magnum/AbstractTexture.h b/src/Magnum/AbstractTexture.h index 64d75591b..7420cf450 100644 --- a/src/Magnum/AbstractTexture.h +++ b/src/Magnum/AbstractTexture.h @@ -297,6 +297,8 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { void setBorderColor(const Vector4ui& color); #endif void setMaxAnisotropy(Float anisotropy); + void setCompareMode(Sampler::CompareMode mode); + void setCompareFunction(Sampler::CompareFunction function); #ifndef MAGNUM_TARGET_GLES void setDepthStencilMode(Sampler::DepthStencilMode mode); #endif diff --git a/src/Magnum/Context.cpp b/src/Magnum/Context.cpp index 9c607433f..8f67e33be 100644 --- a/src/Magnum/Context.cpp +++ b/src/Magnum/Context.cpp @@ -221,6 +221,7 @@ const std::vector& Extension::extensions(Version version) { _extension(GL,EXT,blend_minmax), _extension(GL,EXT,shader_texture_lod), _extension(GL,EXT,occlusion_query_boolean), + _extension(GL,EXT,shadow_samplers), _extension(GL,EXT,texture_rg), _extension(GL,EXT,texture_storage), _extension(GL,EXT,map_buffer_range), @@ -229,6 +230,8 @@ const std::vector& Extension::extensions(Version version) { _extension(GL,NV,read_buffer), _extension(GL,NV,framebuffer_blit), _extension(GL,NV,framebuffer_multisample), + _extension(GL,NV,shadow_samplers_array), + _extension(GL,NV,shadow_samplers_cube), _extension(GL,OES,depth24), _extension(GL,OES,element_index_uint), _extension(GL,OES,rgb8_rgba8), diff --git a/src/Magnum/CubeMapTexture.h b/src/Magnum/CubeMapTexture.h index b784d5104..5fa4f4734 100644 --- a/src/Magnum/CubeMapTexture.h +++ b/src/Magnum/CubeMapTexture.h @@ -188,6 +188,32 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { return *this; } + /** + * @copybrief Texture::setCompareMode() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setCompareMode() for more information. + * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} and + * @es_extension{NV,shadow_samplers_cube} + */ + CubeMapTexture& setCompareMode(Sampler::CompareMode mode) { + AbstractTexture::setCompareMode(mode); + return *this; + } + + /** + * @copybrief Texture::setCompareFunction() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setCompareFunction() for more information. + * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} and + * @es_extension{NV,shadow_samplers_cube} + */ + CubeMapTexture& setCompareFunction(Sampler::CompareFunction function) { + AbstractTexture::setCompareFunction(function); + return *this; + } + #ifndef MAGNUM_TARGET_GLES /** @copydoc Texture::setDepthStencilMode() */ CubeMapTexture& setDepthStencilMode(Sampler::DepthStencilMode mode) { diff --git a/src/Magnum/CubeMapTextureArray.h b/src/Magnum/CubeMapTextureArray.h index 771413391..3cf1da116 100644 --- a/src/Magnum/CubeMapTextureArray.h +++ b/src/Magnum/CubeMapTextureArray.h @@ -218,6 +218,28 @@ class CubeMapTextureArray: public AbstractTexture { return *this; } + /** + * @copybrief Texture::setCompareMode() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setCompareMode() for more information. + */ + CubeMapTextureArray& setCompareMode(Sampler::CompareMode mode) { + AbstractTexture::setCompareMode(mode); + return *this; + } + + /** + * @copybrief Texture::setCompareFunction() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setCompareFunction() for more information. + */ + CubeMapTextureArray& setCompareFunction(Sampler::CompareFunction function) { + AbstractTexture::setCompareFunction(function); + return *this; + } + /** * @copybrief Texture::setDepthStencilMode() * @return Reference to self (for method chaining) diff --git a/src/Magnum/Extensions.h b/src/Magnum/Extensions.h index 032fd4a90..4df94b3fa 100644 --- a/src/Magnum/Extensions.h +++ b/src/Magnum/Extensions.h @@ -242,6 +242,7 @@ namespace GL { #endif _extension(GL,EXT,separate_shader_objects, GLES200, None) // #101 #ifdef MAGNUM_TARGET_GLES2 + _extension(GL,EXT,shadow_samplers, GLES200, GLES300) // #102 _extension(GL,EXT,texture_rg, GLES200, GLES300) // #103 #endif _extension(GL,EXT,sRGB, GLES200, None) // #105 @@ -270,6 +271,8 @@ namespace GL { #ifdef MAGNUM_TARGET_GLES2 _extension(GL,NV,framebuffer_blit, GLES200, GLES300) // #142 _extension(GL,NV,framebuffer_multisample, GLES200, GLES300) // #143 + _extension(GL,NV,shadow_samplers_array, GLES200, GLES300) // #146 + _extension(GL,NV,shadow_samplers_cube, GLES200, GLES300) // #147 #endif _extension(GL,NV,texture_border_clamp, GLES200, None) // #149 } namespace OES { diff --git a/src/Magnum/RectangleTexture.h b/src/Magnum/RectangleTexture.h index 3f8ac4c49..55d052734 100644 --- a/src/Magnum/RectangleTexture.h +++ b/src/Magnum/RectangleTexture.h @@ -190,6 +190,28 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { return *this; } + /** + * @copybrief Texture::setCompareMode() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setCompareMode() for more information. + */ + RectangleTexture& setCompareMode(Sampler::CompareMode mode) { + AbstractTexture::setCompareMode(mode); + return *this; + } + + /** + * @copybrief Texture::setCompareFunction() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setCompareFunction() for more information. + */ + RectangleTexture& setCompareFunction(Sampler::CompareFunction function) { + AbstractTexture::setCompareFunction(function); + return *this; + } + /** * @copybrief Texture::setDepthStencilMode() * @return Reference to self (for method chaining) diff --git a/src/Magnum/Sampler.cpp b/src/Magnum/Sampler.cpp index 9a6138c72..7a886575b 100644 --- a/src/Magnum/Sampler.cpp +++ b/src/Magnum/Sampler.cpp @@ -100,6 +100,34 @@ Debug operator<<(Debug debug, const Sampler::Wrapping value) { return debug << "Sampler::Wrapping::(invalid)"; } +Debug operator<<(Debug debug, const Sampler::CompareMode value) { + switch(value) { + #define _c(value) case Sampler::CompareMode::value: return debug << "Sampler::CompareMode::" #value; + _c(None) + _c(CompareRefToTexture) + #undef _c + } + + return debug << "Sampler::CompareFunction::(invalid)"; +} + +Debug operator<<(Debug debug, const Sampler::CompareFunction value) { + switch(value) { + #define _c(value) case Sampler::CompareFunction::value: return debug << "Sampler::CompareFunction::" #value; + _c(Never) + _c(Always) + _c(Less) + _c(LessOrEqual) + _c(Equal) + _c(NotEqual) + _c(GreaterOrEqual) + _c(Greater) + #undef _c + } + + return debug << "Sampler::CompareFunction::(invalid)"; +} + #ifndef MAGNUM_TARGET_GLES Debug operator<<(Debug debug, const Sampler::DepthStencilMode value) { switch(value) { diff --git a/src/Magnum/Sampler.h b/src/Magnum/Sampler.h index 674e5a807..286c10fa1 100644 --- a/src/Magnum/Sampler.h +++ b/src/Magnum/Sampler.h @@ -136,6 +136,76 @@ class MAGNUM_EXPORT Sampler { #endif }; + /** + * @brief Depth texture comparison mode + * + * @see @ref CompareFunction, + * @ref Texture::setCompareMode() "*Texture::setCompareMode()" + * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} + */ + enum class CompareMode: GLenum { + /** Directly output the depth value */ + None = GL_NONE, + + /** Use output from specified @ref CompareFunction */ + CompareRefToTexture = + #ifndef MAGNUM_TARGET_GLES2 + GL_COMPARE_REF_TO_TEXTURE + #else + GL_COMPARE_REF_TO_TEXTURE_EXT + #endif + }; + + /** + * @brief Depth texture comparison function + * + * Comparison operator used when comparison mode is set to + * @ref CompareMode::CompareRefToTexture. + * @see @ref Texture::setCompareFunction() "*Texture::setCompareFunction()", + * @ref Texture::setCompareMode() "*Texture::setCompareMode()" + * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} + */ + enum class CompareFunction: GLenum { + Never = GL_NEVER, /**< Always `0.0` */ + Always = GL_ALWAYS, /**< Always `1.0` */ + + /** + * `1.0` when texture coordinate is less than depth value, `0.0` + * otherwise + */ + Less = GL_LESS, + + /** + * `1.0` when texture coordinate is less than or equal to depth + * value, `0.0` otherwise + */ + LessOrEqual = GL_LEQUAL, + + /** + * `1.0` when texture coordinate is equal to depth value, `0.0` + * otherwise + */ + Equal = GL_EQUAL, + + /** + * `0.0` when texture coordinate is equal to depth value, `1.0` + * otherwise + */ + NotEqual = GL_NOTEQUAL, + + /** + * `1.0` when texture coordinate is greater than or equal to depth + * value, `0.0` otherwise + */ + GreaterOrEqual = GL_GEQUAL, + + /** + * `1.0` when texture coordinate is greater than depth value, `0.0` + * otherwise + */ + Greater = GL_GREATER + }; + #ifndef MAGNUM_TARGET_GLES /** * @brief Depth/stencil texture mode @@ -182,6 +252,12 @@ Debug MAGNUM_EXPORT operator<<(Debug debug, Sampler::Mipmap value); /** @debugoperator{Magnum::Sampler} */ Debug MAGNUM_EXPORT operator<<(Debug debug, Sampler::Wrapping value); +/** @debugoperator{Magnum::Sampler} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, Sampler::CompareMode value); + +/** @debugoperator{Magnum::Sampler} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, Sampler::CompareFunction value); + #ifndef MAGNUM_TARGET_GLES /** @debugoperator{Magnum::Sampler} */ Debug MAGNUM_EXPORT operator<<(Debug debug, Sampler::DepthStencilMode value); diff --git a/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp b/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp index 847ffe9e3..41427ab05 100644 --- a/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp @@ -132,7 +132,9 @@ void CubeMapTextureArrayGLTest::sampling() { .setMaxLevel(750) .setWrapping(Sampler::Wrapping::ClampToBorder) .setBorderColor(Color3(0.5f)) - .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()) + .setCompareMode(Sampler::CompareMode::CompareRefToTexture) + .setCompareFunction(Sampler::CompareFunction::GreaterOrEqual); MAGNUM_VERIFY_NO_ERROR(); } diff --git a/src/Magnum/Test/CubeMapTextureGLTest.cpp b/src/Magnum/Test/CubeMapTextureGLTest.cpp index 892bc249c..5de0f2047 100644 --- a/src/Magnum/Test/CubeMapTextureGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureGLTest.cpp @@ -48,6 +48,7 @@ class CubeMapTextureGLTest: public AbstractOpenGLTester { void sampling(); #ifdef MAGNUM_TARGET_GLES2 void samplingMaxLevel(); + void samplingCompare(); #endif #ifndef MAGNUM_TARGET_GLES void samplingBorderInteger(); @@ -79,6 +80,7 @@ CubeMapTextureGLTest::CubeMapTextureGLTest() { &CubeMapTextureGLTest::sampling, #ifdef MAGNUM_TARGET_GLES2 &CubeMapTextureGLTest::samplingMaxLevel, + &CubeMapTextureGLTest::samplingCompare, #endif #ifndef MAGNUM_TARGET_GLES &CubeMapTextureGLTest::samplingBorderInteger, @@ -153,7 +155,12 @@ void CubeMapTextureGLTest::sampling() { #endif .setWrapping(Sampler::Wrapping::ClampToBorder) .setBorderColor(Color3(0.5f)) - .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()) + #ifndef MAGNUM_TARGET_GLES2 + .setCompareMode(Sampler::CompareMode::CompareRefToTexture) + .setCompareFunction(Sampler::CompareFunction::GreaterOrEqual) + #endif + ; MAGNUM_VERIFY_NO_ERROR(); } @@ -168,6 +175,18 @@ void CubeMapTextureGLTest::samplingMaxLevel() { MAGNUM_VERIFY_NO_ERROR(); } + +void CubeMapTextureGLTest::samplingCompare() { + if(!Context::current()->isExtensionSupported() || + !Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::NV::shadow_samplers_cube::string() + std::string(" is not supported.")); + + CubeMapTexture texture; + texture.setCompareMode(Sampler::CompareMode::CompareRefToTexture) + .setCompareFunction(Sampler::CompareFunction::GreaterOrEqual); + + MAGNUM_VERIFY_NO_ERROR(); +} #endif #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/Test/RectangleTextureGLTest.cpp b/src/Magnum/Test/RectangleTextureGLTest.cpp index ade0e0b03..d51b29fbc 100644 --- a/src/Magnum/Test/RectangleTextureGLTest.cpp +++ b/src/Magnum/Test/RectangleTextureGLTest.cpp @@ -128,7 +128,9 @@ void RectangleTextureGLTest::sampling() { .setMagnificationFilter(Sampler::Filter::Linear) .setWrapping(Sampler::Wrapping::ClampToBorder) .setBorderColor(Color3(0.5f)) - .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()) + .setCompareMode(Sampler::CompareMode::CompareRefToTexture) + .setCompareFunction(Sampler::CompareFunction::GreaterOrEqual); MAGNUM_VERIFY_NO_ERROR(); } diff --git a/src/Magnum/Test/SamplerTest.cpp b/src/Magnum/Test/SamplerTest.cpp index 812734c02..d7c241a9a 100644 --- a/src/Magnum/Test/SamplerTest.cpp +++ b/src/Magnum/Test/SamplerTest.cpp @@ -37,6 +37,8 @@ class SamplerTest: public TestSuite::Tester { void debugFilter(); void debugMipmap(); void debugWrapping(); + void debugCompareMode(); + void debugCompareFunction(); #ifndef MAGNUM_TARGET_GLES void debugDepthStencilMode(); #endif @@ -46,6 +48,8 @@ SamplerTest::SamplerTest() { addTests({&SamplerTest::debugFilter, &SamplerTest::debugMipmap, &SamplerTest::debugWrapping, + &SamplerTest::debugCompareMode, + &SamplerTest::debugCompareFunction, #ifndef MAGNUM_TARGET_GLES &SamplerTest::debugDepthStencilMode #endif @@ -73,6 +77,20 @@ void SamplerTest::debugWrapping() { CORRADE_COMPARE(out.str(), "Sampler::Wrapping::ClampToEdge\n"); } +void SamplerTest::debugCompareMode() { + std::ostringstream out; + + Debug(&out) << Sampler::CompareMode::CompareRefToTexture; + CORRADE_COMPARE(out.str(), "Sampler::CompareMode::CompareRefToTexture\n"); +} + +void SamplerTest::debugCompareFunction() { + std::ostringstream out; + + Debug(&out) << Sampler::CompareFunction::GreaterOrEqual; + CORRADE_COMPARE(out.str(), "Sampler::CompareFunction::GreaterOrEqual\n"); +} + #ifndef MAGNUM_TARGET_GLES void SamplerTest::debugDepthStencilMode() { std::ostringstream out; diff --git a/src/Magnum/Test/TextureArrayGLTest.cpp b/src/Magnum/Test/TextureArrayGLTest.cpp index 4dbc82dfa..d66ad6a33 100644 --- a/src/Magnum/Test/TextureArrayGLTest.cpp +++ b/src/Magnum/Test/TextureArrayGLTest.cpp @@ -57,6 +57,7 @@ class TextureArrayGLTest: public AbstractOpenGLTester { #ifdef MAGNUM_TARGET_GLES2 void samplingMaxLevel2D(); + void samplingCompare2D(); #endif #ifndef MAGNUM_TARGET_GLES @@ -274,7 +275,9 @@ void TextureArrayGLTest::sampling1D() { .setMaxLevel(750) .setWrapping(Sampler::Wrapping::ClampToBorder) .setBorderColor(Color3(0.5f)) - .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()) + .setCompareMode(Sampler::CompareMode::CompareRefToTexture) + .setCompareFunction(Sampler::CompareFunction::GreaterOrEqual); MAGNUM_VERIFY_NO_ERROR(); } @@ -328,7 +331,12 @@ void TextureArrayGLTest::sampling2D() { #else .setWrapping(Sampler::Wrapping::ClampToEdge) #endif - .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()) + #ifndef MAGNUM_TARGET_GLES + .setCompareMode(Sampler::CompareMode::CompareRefToTexture) + .setCompareFunction(Sampler::CompareFunction::GreaterOrEqual) + #endif + ; MAGNUM_VERIFY_NO_ERROR(); } @@ -343,6 +351,18 @@ void TextureArrayGLTest::samplingMaxLevel2D() { MAGNUM_VERIFY_NO_ERROR(); } + +void TextureArrayGLTest::samplingCompare2D() { + if(!Context::current()->isExtensionSupported() || + !Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::NV::shadow_samplers_array::string() + std::string(" is not supported.")); + + Texture2DArray texture; + texture.setCompareMode(Sampler::CompareMode::CompareRefToTexture) + .setCompareFunction(Sampler::CompareFunction::GreaterOrEqual); + + MAGNUM_VERIFY_NO_ERROR(); +} #endif #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/Test/TextureGLTest.cpp b/src/Magnum/Test/TextureGLTest.cpp index 2ef5f9f35..0cc5bd74f 100644 --- a/src/Magnum/Test/TextureGLTest.cpp +++ b/src/Magnum/Test/TextureGLTest.cpp @@ -63,6 +63,7 @@ class TextureGLTest: public AbstractOpenGLTester { #ifdef MAGNUM_TARGET_GLES2 void samplingMaxLevel2D(); void samplingMaxLevel3D(); + void samplingCompare2D(); #endif #ifndef MAGNUM_TARGET_GLES @@ -152,6 +153,7 @@ TextureGLTest::TextureGLTest() { #ifdef MAGNUM_TARGET_GLES2 &TextureGLTest::samplingMaxLevel2D, &TextureGLTest::samplingMaxLevel3D, + &TextureGLTest::samplingCompare2D, #endif #ifndef MAGNUM_TARGET_GLES @@ -346,7 +348,9 @@ void TextureGLTest::sampling1D() { .setMaxLevel(750) .setWrapping(Sampler::Wrapping::ClampToBorder) .setBorderColor(Color3(0.5f)) - .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()) + .setCompareMode(Sampler::CompareMode::CompareRefToTexture) + .setCompareFunction(Sampler::CompareFunction::GreaterOrEqual); MAGNUM_VERIFY_NO_ERROR(); } @@ -381,7 +385,9 @@ void TextureGLTest::sampling2D() { #else .setWrapping(Sampler::Wrapping::ClampToEdge) #endif - .setMaxAnisotropy(Sampler::maxMaxAnisotropy()); + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()) + .setCompareMode(Sampler::CompareMode::CompareRefToTexture) + .setCompareFunction(Sampler::CompareFunction::GreaterOrEqual); MAGNUM_VERIFY_NO_ERROR(); } @@ -396,6 +402,17 @@ void TextureGLTest::samplingMaxLevel2D() { MAGNUM_VERIFY_NO_ERROR(); } + +void TextureGLTest::samplingCompare2D() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::shadow_samplers::string() + std::string(" is not supported.")); + + Texture2D texture; + texture.setCompareMode(Sampler::CompareMode::CompareRefToTexture) + .setCompareFunction(Sampler::CompareFunction::GreaterOrEqual); + + MAGNUM_VERIFY_NO_ERROR(); +} #endif #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/Texture.h b/src/Magnum/Texture.h index af9d725e2..3190c70e5 100644 --- a/src/Magnum/Texture.h +++ b/src/Magnum/Texture.h @@ -442,6 +442,46 @@ template class Texture: public AbstractTexture { return *this; } + /** + * @brief Set depth texture comparison mode + * @return Reference to self (for method chaining) + * + * If @extension{EXT,direct_state_access} is not available, + * the texture is bound to some texture unit before the operation. + * Initial value is @ref Sampler::CompareMode::None. + * @note Depth textures can be only 1D or 2D. + * @see @ref setCompareFunction(), @fn_gl{ActiveTexture}, + * @fn_gl{BindTexture} and @fn_gl{TexParameter} or + * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with + * @def_gl{TEXTURE_COMPARE_MODE} + * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} + */ + Texture& setCompareMode(Sampler::CompareMode mode) { + AbstractTexture::setCompareMode(mode); + return *this; + } + + /** + * @brief Set depth texture comparison function + * @return Reference to self (for method chaining) + * + * Comparison operator used when comparison mode is set to + * @ref CompareMode::CompareRefToTexture. If + * @extension{EXT,direct_state_access} is not available, the texture is + * bound to some texture unit before the operation. + * @note Depth textures can be only 1D or 2D. + * @todoc initial value? + * @see @ref setCompareMode(), @fn_gl{ActiveTexture}, + * @fn_gl{BindTexture} and @fn_gl{TexParameter} or + * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with + * @def_gl{TEXTURE_COMPARE_FUNC} + * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} + */ + Texture& setCompareFunction(Sampler::CompareFunction function) { + AbstractTexture::setCompareFunction(function); + return *this; + } + #ifndef MAGNUM_TARGET_GLES /** * @brief Set depth/stencil texture mode diff --git a/src/Magnum/TextureArray.h b/src/Magnum/TextureArray.h index b1891d137..c8d94d0ef 100644 --- a/src/Magnum/TextureArray.h +++ b/src/Magnum/TextureArray.h @@ -196,6 +196,32 @@ template class TextureArray: public AbstractTexture { return *this; } + /** + * @copybrief Texture::setCompareMode() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setCompareMode() for more information. + * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} and + * @es_extension{NV,shadow_samplers_array} + */ + TextureArray& setCompareMode(Sampler::CompareMode mode) { + AbstractTexture::setCompareMode(mode); + return *this; + } + + /** + * @copybrief Texture::setCompareFunction() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setCompareFunction() for more information. + * @requires_gles30 %Extension @es_extension{EXT,shadow_samplers} and + * @es_extension{NV,shadow_samplers_array} + */ + TextureArray& setCompareFunction(Sampler::CompareFunction function) { + AbstractTexture::setCompareFunction(function); + return *this; + } + #ifndef MAGNUM_TARGET_GLES /** * @copybrief Texture::setDepthStencilMode()