From 4f4131b320c1225b8a234edc2c8e9c5bbb519002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 10 Apr 2014 17:52:17 +0200 Subject: [PATCH] Implemented texture LOD parameters. --- doc/opengl-mapping.dox | 4 +- src/Magnum/AbstractTexture.cpp | 28 ++++++++ src/Magnum/AbstractTexture.h | 21 +++++- src/Magnum/CubeMapTexture.h | 22 +++++++ src/Magnum/CubeMapTextureArray.h | 33 ++++++++++ src/Magnum/Implementation/TextureState.cpp | 2 +- src/Magnum/Implementation/TextureState.h | 3 +- src/Magnum/Test/CubeMapTextureArrayGLTest.cpp | 3 + src/Magnum/Test/CubeMapTextureGLTest.cpp | 5 ++ src/Magnum/Test/TextureArrayGLTest.cpp | 8 +++ src/Magnum/Test/TextureGLTest.cpp | 13 ++++ src/Magnum/Texture.h | 64 +++++++++++++++++++ src/Magnum/TextureArray.h | 22 +++++++ 13 files changed, 223 insertions(+), 5 deletions(-) diff --git a/doc/opengl-mapping.dox b/doc/opengl-mapping.dox index 44fe71cd8..d06fdef20 100644 --- a/doc/opengl-mapping.dox +++ b/doc/opengl-mapping.dox @@ -241,7 +241,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::setWrapping() "*Texture::setWrapping()", \n @ref Texture::setBorderColor() "*Texture::setBorderColor()", \n @ref Texture::setMaxAnisotropy() "*Texture::setMaxAnisotropy()" +@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()" @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() @@ -340,7 +340,7 @@ OpenGL function | Matching API @def_gl{MAX_SHADER_STORAGE_BUFFER_BINDINGS} | @ref Buffer::maxShaderStorageBindings() @def_gl{MAX_TEXTURE_BUFFER_SIZE} | | @def_gl_extension{MAX_TEXTURE_MAX_ANISOTROPY,EXT,texture_filter_anisotropic} | @ref Sampler::maxMaxAnisotropy() -@def_gl{MAX_TEXTURE_LOD_BIAS} | | +@def_gl{MAX_TEXTURE_LOD_BIAS} | @ref AbstractTexture::maxLodBias() @def_gl{MAX_UNIFORM_BLOCK_SIZE} | @ref AbstractShaderProgram::maxUniformBlockSize() @def_gl{MAX_UNIFORM_BUFFER_BINDINGS} | @ref Buffer::maxUniformBindings() @def_gl{MAX_UNIFORM_LOCATIONS} | @ref AbstractShaderProgram::maxUniformLocations() diff --git a/src/Magnum/AbstractTexture.cpp b/src/Magnum/AbstractTexture.cpp index 81c71fe9c..c7921e411 100644 --- a/src/Magnum/AbstractTexture.cpp +++ b/src/Magnum/AbstractTexture.cpp @@ -50,6 +50,18 @@ namespace Magnum { Int AbstractTexture::maxLayers() { return Shader::maxCombinedTextureImageUnits(); } #endif +#ifndef MAGNUM_TARGET_GLES2 +Float AbstractTexture::maxLodBias() { + GLfloat& value = Context::current()->state().texture->maxLodBias; + + /* Get the value, if not already cached */ + if(value == 0.0f) + glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &value); + + return value; +} +#endif + #ifndef MAGNUM_TARGET_GLES Int AbstractTexture::maxColorSamples() { if(!Context::current()->isExtensionSupported()) @@ -236,6 +248,22 @@ void AbstractTexture::setMagnificationFilter(const Sampler::Filter filter) { (this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_MAG_FILTER, GLint(filter)); } +#ifndef MAGNUM_TARGET_GLES2 +void AbstractTexture::setMinLod(const Float lod) { + (this->*Context::current()->state().texture->parameterfImplementation)(GL_TEXTURE_MIN_LOD, lod); +} + +void AbstractTexture::setMaxLod(const Float lod) { + (this->*Context::current()->state().texture->parameterfImplementation)(GL_TEXTURE_MAX_LOD, lod); +} +#endif + +#ifndef MAGNUM_TARGET_GLES +void AbstractTexture::setLodBias(const Float bias) { + (this->*Context::current()->state().texture->parameterfImplementation)(GL_TEXTURE_LOD_BIAS, bias); +} +#endif + void AbstractTexture::setBorderColor(const Color4& color) { #ifndef MAGNUM_TARGET_GLES (this->*Context::current()->state().texture->parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR, color.data()); diff --git a/src/Magnum/AbstractTexture.h b/src/Magnum/AbstractTexture.h index 8ab0ea12b..0054b1294 100644 --- a/src/Magnum/AbstractTexture.h +++ b/src/Magnum/AbstractTexture.h @@ -105,7 +105,6 @@ functions do nothing. then deleting it immediately? @todo ES2 - proper support for pixel unpack buffer when extension is in headers @todo `GL_MAX_3D_TEXTURE_SIZE`, `GL_MAX_ARRAY_TEXTURE_LAYERS`, `GL_MAX_CUBE_MAP_TEXTURE_SIZE`, `GL_MAX_RECTANGLE_TEXTURE_SIZE`, `GL_MAX_TEXTURE_SIZE`, `GL_MAX_TEXTURE_BUFFER_SIZE` enable them only where it makes sense? -@todo `GL_MAX_TEXTURE_LOD_BIAS` when `TEXTURE_LOD_BIAS` is implemented @todo `GL_NUM_COMPRESSED_TEXTURE_FORMATS` when compressed textures are implemented @todo `GL_MAX_SAMPLE_MASK_WORDS` when @extension{ARB,texture_multisample} is done @todo Query for immutable levels (@extension{ARB,ES3_compatibility}) @@ -127,6 +126,19 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { static CORRADE_DEPRECATED("use Shader::maxCombinedTextureImageUnits() instead") Int maxLayers(); #endif + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Max level-of-detail bias + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. + * @see @fn_gl{Get} with @def_gl{MAX_TEXTURE_LOD_BIAS} + * @requires_gles30 %Texture LOD bias doesn't have + * implementation-defined range in OpenGL ES 2.0. + */ + static Float maxLodBias(); + #endif + #ifndef MAGNUM_TARGET_GLES /** * @brief Max supported color sample count @@ -273,6 +285,13 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { void setMaxLevel(Int level); void setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap); void setMagnificationFilter(Sampler::Filter filter); + #ifndef MAGNUM_TARGET_GLES2 + void setMinLod(Float lod); + void setMaxLod(Float lod); + #endif + #ifndef MAGNUM_TARGET_GLES + void setLodBias(Float bias); + #endif void setBorderColor(const Color4& color); void setBorderColor(const Vector4i& color); void setBorderColor(const Vector4ui& color); diff --git a/src/Magnum/CubeMapTexture.h b/src/Magnum/CubeMapTexture.h index 2714e8970..b23da70f3 100644 --- a/src/Magnum/CubeMapTexture.h +++ b/src/Magnum/CubeMapTexture.h @@ -125,6 +125,28 @@ class CubeMapTexture: public AbstractTexture { return *this; } + #ifndef MAGNUM_TARGET_GLES2 + /** @copydoc Texture::setMinLod() */ + CubeMapTexture& setMinLod(Float lod) { + AbstractTexture::setMinLod(lod); + return *this; + } + + /** @copydoc Texture::setMaxLod() */ + CubeMapTexture& setMaxLod(Float lod) { + AbstractTexture::setMaxLod(lod); + return *this; + } + #endif + + #ifndef MAGNUM_TARGET_GLES + /** @copydoc Texture::setLodBias() */ + CubeMapTexture& setLodBias(Float bias) { + AbstractTexture::setLodBias(bias); + return *this; + } + #endif + /** @copydoc Texture::setWrapping() */ CubeMapTexture& setWrapping(const Array3D& wrapping) { DataHelper<3>::setWrapping(*this, wrapping); diff --git a/src/Magnum/CubeMapTextureArray.h b/src/Magnum/CubeMapTextureArray.h index 8529886bd..2c64085cc 100644 --- a/src/Magnum/CubeMapTextureArray.h +++ b/src/Magnum/CubeMapTextureArray.h @@ -126,6 +126,39 @@ class CubeMapTextureArray: public AbstractTexture { return *this; } + /** + * @brief Set minimum level-of-detail parameter + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMinLod() for more information. + */ + CubeMapTextureArray& setMinLod(Float lod) { + AbstractTexture::setMinLod(lod); + return *this; + } + + /** + * @brief Set maximum level-of-detail parameter + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxLod() for more information. + */ + CubeMapTextureArray& setMaxLod(Float lod) { + AbstractTexture::setMaxLod(lod); + return *this; + } + + /** + * @brief Set level-of-detail bias + * @return Reference to self (for method chaining) + * + * See @ref Texture::setLodBias() for more information. + */ + CubeMapTextureArray& setLodBias(Float bias) { + AbstractTexture::setLodBias(bias); + return *this; + } + /** @copydoc Texture::setWrapping() */ CubeMapTextureArray& setWrapping(const Array3D& wrapping) { DataHelper<3>::setWrapping(*this, wrapping); diff --git a/src/Magnum/Implementation/TextureState.cpp b/src/Magnum/Implementation/TextureState.cpp index 60d362f43..1463be29d 100644 --- a/src/Magnum/Implementation/TextureState.cpp +++ b/src/Magnum/Implementation/TextureState.cpp @@ -36,7 +36,7 @@ namespace Magnum { namespace Implementation { -TextureState::TextureState(Context& context, std::vector& extensions): maxTextureUnits(0), maxMaxAnisotropy(0.0f), currentTextureUnit(0) +TextureState::TextureState(Context& context, std::vector& extensions): maxTextureUnits(0), maxLodBias(0.0f), maxMaxAnisotropy(0.0f), currentTextureUnit(0) #ifndef MAGNUM_TARGET_GLES , maxColorSamples(0), maxDepthSamples(0), maxIntegerSamples(0), bufferOffsetAlignment(0) #endif diff --git a/src/Magnum/Implementation/TextureState.h b/src/Magnum/Implementation/TextureState.h index a3057eca4..28b5335d5 100644 --- a/src/Magnum/Implementation/TextureState.h +++ b/src/Magnum/Implementation/TextureState.h @@ -75,7 +75,8 @@ struct TextureState { #endif GLint maxTextureUnits; - GLfloat maxMaxAnisotropy; + GLfloat maxLodBias, + maxMaxAnisotropy; GLint currentTextureUnit; #ifndef MAGNUM_TARGET_GLES GLint maxColorSamples, diff --git a/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp b/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp index e6f9fdf63..3b0c6fb50 100644 --- a/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp @@ -123,6 +123,9 @@ void CubeMapTextureArrayGLTest::sampling() { CubeMapTextureArray texture; texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) .setMagnificationFilter(Sampler::Filter::Linear) + .setMinLod(-750.0f) + .setMaxLod(750.0f) + .setLodBias(0.5f) .setBaseLevel(1) .setMaxLevel(750) .setWrapping(Sampler::Wrapping::ClampToBorder) diff --git a/src/Magnum/Test/CubeMapTextureGLTest.cpp b/src/Magnum/Test/CubeMapTextureGLTest.cpp index c820d365c..b55e7b252 100644 --- a/src/Magnum/Test/CubeMapTextureGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureGLTest.cpp @@ -141,6 +141,11 @@ void CubeMapTextureGLTest::sampling() { texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) .setMagnificationFilter(Sampler::Filter::Linear) #ifndef MAGNUM_TARGET_GLES2 + .setMinLod(-750.0f) + .setMaxLod(750.0f) + #ifndef MAGNUM_TARGET_GLES + .setLodBias(0.5f) + #endif .setBaseLevel(1) .setMaxLevel(750) #endif diff --git a/src/Magnum/Test/TextureArrayGLTest.cpp b/src/Magnum/Test/TextureArrayGLTest.cpp index d7c2d2f68..b3caf3532 100644 --- a/src/Magnum/Test/TextureArrayGLTest.cpp +++ b/src/Magnum/Test/TextureArrayGLTest.cpp @@ -263,6 +263,9 @@ void TextureArrayGLTest::sampling1D() { Texture1DArray texture; texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) .setMagnificationFilter(Sampler::Filter::Linear) + .setMinLod(-750.0f) + .setMaxLod(750.0f) + .setLodBias(0.5f) .setBaseLevel(1) .setMaxLevel(750) .setWrapping(Sampler::Wrapping::ClampToBorder) @@ -297,6 +300,11 @@ void TextureArrayGLTest::sampling2D() { texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) .setMagnificationFilter(Sampler::Filter::Linear) #ifndef MAGNUM_TARGET_GLES2 + .setMinLod(-750.0f) + .setMaxLod(750.0f) + #ifndef MAGNUM_TARGET_GLES + .setLodBias(0.5f) + #endif .setBaseLevel(1) .setMaxLevel(750) #endif diff --git a/src/Magnum/Test/TextureGLTest.cpp b/src/Magnum/Test/TextureGLTest.cpp index ee23b0316..e8aaccf72 100644 --- a/src/Magnum/Test/TextureGLTest.cpp +++ b/src/Magnum/Test/TextureGLTest.cpp @@ -333,6 +333,9 @@ void TextureGLTest::sampling1D() { Texture1D texture; texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) .setMagnificationFilter(Sampler::Filter::Linear) + .setMinLod(-750.0f) + .setMaxLod(750.0f) + .setLodBias(0.5f) .setBaseLevel(1) .setMaxLevel(750) .setWrapping(Sampler::Wrapping::ClampToBorder) @@ -348,6 +351,11 @@ void TextureGLTest::sampling2D() { texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) .setMagnificationFilter(Sampler::Filter::Linear) #ifndef MAGNUM_TARGET_GLES2 + .setMinLod(-750.0f) + .setMaxLod(750.0f) + #ifndef MAGNUM_TARGET_GLES + .setLodBias(0.5f) + #endif .setBaseLevel(1) .setMaxLevel(750) #endif @@ -411,6 +419,11 @@ void TextureGLTest::sampling3D() { texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) .setMagnificationFilter(Sampler::Filter::Linear) #ifndef MAGNUM_TARGET_GLES2 + .setMinLod(-750.0f) + .setMaxLod(750.0f) + #ifndef MAGNUM_TARGET_GLES + .setLodBias(0.5f) + #endif .setBaseLevel(1) .setMaxLevel(750) #endif diff --git a/src/Magnum/Texture.h b/src/Magnum/Texture.h index 0c278b022..e7eebf850 100644 --- a/src/Magnum/Texture.h +++ b/src/Magnum/Texture.h @@ -270,6 +270,70 @@ template class Texture: public AbstractTexture { return *this; } + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Set minimum level-of-detail parameter + * @return Reference to self (for method chaining) + * + * Limits selection of highest resolution mipmap. If + * @extension{EXT,direct_state_access} is not available, the texture is + * bound to some texture unit before the operation. Initial value is + * `-1000.0f`. + * @see @ref setMaxLod(), @ref setLodBias(), @fn_gl{ActiveTexture}, + * @fn_gl{BindTexture} and @fn_gl{TexParameter} or + * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with + * @def_gl{TEXTURE_MIN_LOD} + * @requires_gles30 %Texture LOD parameters are not available in OpenGL + * ES 2.0. + */ + Texture& setMinLod(Float lod) { + AbstractTexture::setMinLod(lod); + return *this; + } + + /** + * @brief Set maximum level-of-detail parameter + * @return Reference to self (for method chaining) + * + * Limits selection of lowest resolution mipmap. If + * @extension{EXT,direct_state_access} is not available, the texture is + * bound to some texture unit before the operation. Initial value is + * `1000.0f`. + * @see @ref setMinLod(), @ref setLodBias(), @fn_gl{ActiveTexture}, + * @fn_gl{BindTexture} and @fn_gl{TexParameter} or + * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with + * @def_gl{TEXTURE_MAX_LOD} + * @requires_gles30 %Texture LOD parameters are not available in OpenGL + * ES 2.0. + */ + Texture& setMaxLod(Float lod) { + AbstractTexture::setMaxLod(lod); + return *this; + } + #endif + + #ifndef MAGNUM_TARGET_GLES + /** + * @brief Set level-of-detail bias + * @return Reference to self (for method chaining) + * + * Fixed bias value that is added to the level-of-detail parameter. If + * @extension{EXT,direct_state_access} is not available, the texture is + * bound to some texture unit before the operation. Initial value is + * `0.0f`. + * @see @ref maxLodBias(), @ref setMinLod(), @ref setMaxLod(), + * @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} + * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} + * with @def_gl{TEXTURE_LOD_BIAS} + * @requires_gl %Texture LOD bias can be specified only directly in + * fragment shader in OpenGL ES. + */ + Texture& setLodBias(Float bias) { + AbstractTexture::setLodBias(bias); + return *this; + } + #endif + /** * @brief Set wrapping * @param wrapping Wrapping type for all texture dimensions diff --git a/src/Magnum/TextureArray.h b/src/Magnum/TextureArray.h index 6e38ce3ac..e21fba8f1 100644 --- a/src/Magnum/TextureArray.h +++ b/src/Magnum/TextureArray.h @@ -130,6 +130,28 @@ template class TextureArray: public AbstractTexture { return *this; } + #ifndef MAGNUM_TARGET_GLES2 + /** @copydoc Texture::setMinLod() */ + TextureArray& setMinLod(Float lod) { + AbstractTexture::setMinLod(lod); + return *this; + } + + /** @copydoc Texture::setMaxLod() */ + TextureArray& setMaxLod(Float lod) { + AbstractTexture::setMaxLod(lod); + return *this; + } + #endif + + #ifndef MAGNUM_TARGET_GLES + /** @copydoc Texture::setLodBias() */ + TextureArray& setLodBias(Float bias) { + AbstractTexture::setLodBias(bias); + return *this; + } + #endif + /** @copydoc Texture::setWrapping() */ TextureArray& setWrapping(const Array& wrapping) { DataHelper::setWrapping(*this, wrapping);