Browse Source

Ability to set base and max mip level on textures.

Curiously this functionality is not available on ES2, just the max limit
is supported by APPLE_texture_max_level extension.
pull/51/head
Vladimír Vondruš 12 years ago
parent
commit
a24ea3ce25
  1. 1
      doc/opengl-support.dox
  2. 16
      src/Magnum/AbstractTexture.cpp
  3. 4
      src/Magnum/AbstractTexture.h
  4. 1
      src/Magnum/Context.cpp
  5. 14
      src/Magnum/CubeMapTexture.h
  6. 14
      src/Magnum/CubeMapTextureArray.h
  7. 3
      src/Magnum/Extensions.h
  8. 2
      src/Magnum/Test/CubeMapTextureArrayGLTest.cpp
  9. 22
      src/Magnum/Test/CubeMapTextureGLTest.cpp
  10. 26
      src/Magnum/Test/TextureArrayGLTest.cpp
  11. 46
      src/Magnum/Test/TextureGLTest.cpp
  12. 62
      src/Magnum/Texture.h
  13. 21
      src/Magnum/TextureArray.h

1
doc/opengl-support.dox

@ -245,6 +245,7 @@ supported.
@es_extension{ANGLE,framebuffer_multisample} | done
@es_extension{ANGLE,depth_texture} | done
@es_extension{APPLE,framebuffer_multisample} | done (ES 3.0 subset)
@es_extension{APPLE,texture_max_level} | done
@es_extension{ARM,rgba8} | done
@es_extension{EXT,texture_type_2_10_10_10_REV} | done
@es_extension{EXT,discard_framebuffer} | done

16
src/Magnum/AbstractTexture.cpp

@ -146,6 +146,22 @@ void AbstractTexture::bindImplementationDSA(GLint textureUnit) {
}
#endif
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::setBaseLevel(Int level) {
(this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_BASE_LEVEL, level);
}
#endif
void AbstractTexture::setMaxLevel(Int level) {
(this->*Context::current()->state().texture->parameteriImplementation)(
#ifndef MAGNUM_TARGET_GLES2
GL_TEXTURE_MAX_LEVEL
#else
GL_TEXTURE_MAX_LEVEL_APPLE
#endif
, level);
}
void AbstractTexture::setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap) {
(this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_MIN_FILTER, GLint(filter)|GLint(mipmap));
}

4
src/Magnum/AbstractTexture.h

@ -242,6 +242,10 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
/* Unlike bind() this also sets the texture binding unit as active */
void MAGNUM_LOCAL bindInternal();
#ifndef MAGNUM_TARGET_GLES2
void setBaseLevel(Int level);
#endif
void setMaxLevel(Int level);
void setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap);
void setMagnificationFilter(Sampler::Filter filter);
void setBorderColor(const Color4& color);

1
src/Magnum/Context.cpp

@ -214,6 +214,7 @@ const std::vector<Extension>& Extension::extensions(Version version) {
_extension(GL,ANGLE,framebuffer_multisample),
_extension(GL,ANGLE,depth_texture),
_extension(GL,APPLE,framebuffer_multisample),
_extension(GL,APPLE,texture_max_level),
_extension(GL,ARM,rgba8),
_extension(GL,EXT,texture_type_2_10_10_10_REV),
_extension(GL,EXT,discard_framebuffer),

14
src/Magnum/CubeMapTexture.h

@ -98,6 +98,20 @@ class CubeMapTexture: public AbstractTexture {
*/
explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {}
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc Texture::setBaseLevel() */
CubeMapTexture& setBaseLevel(Int level) {
AbstractTexture::setBaseLevel(level);
return *this;
}
#endif
/** @copydoc Texture::setMaxLevel() */
CubeMapTexture& setMaxLevel(Int level) {
AbstractTexture::setMaxLevel(level);
return *this;
}
/** @copydoc Texture::setMinificationFilter() */
CubeMapTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);

14
src/Magnum/CubeMapTextureArray.h

@ -89,6 +89,20 @@ class CubeMapTextureArray: public AbstractTexture {
*/
explicit CubeMapTextureArray(): AbstractTexture(GL_TEXTURE_CUBE_MAP_ARRAY) {}
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc Texture::setBaseLevel() */
CubeMapTextureArray& setBaseLevel(Int level) {
AbstractTexture::setBaseLevel(level);
return *this;
}
#endif
/** @copydoc Texture::setMaxLevel() */
CubeMapTextureArray& setMaxLevel(Int level) {
AbstractTexture::setMaxLevel(level);
return *this;
}
/** @copydoc Texture::setMinificationFilter() */
CubeMapTextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);

3
src/Magnum/Extensions.h

@ -212,6 +212,9 @@ namespace GL {
_extension(GL,APPLE,framebuffer_multisample, GLES200, GLES300) // #78
#endif
_extension(GL,APPLE,texture_format_BGRA8888, GLES200, None) // #79
#ifdef MAGNUM_TARGET_GLES2
_extension(GL,APPLE,texture_max_level, GLES200, None) // #80
#endif
} namespace ARM {
#ifdef MAGNUM_TARGET_GLES2
_extension(GL,ARM,rgba8, GLES200, GLES300) // #82

2
src/Magnum/Test/CubeMapTextureArrayGLTest.cpp

@ -97,6 +97,8 @@ void CubeMapTextureArrayGLTest::sampling() {
CubeMapTextureArray texture;
texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
.setMagnificationFilter(Sampler::Filter::Linear)
.setBaseLevel(1)
.setMaxLevel(750)
.setWrapping(Sampler::Wrapping::ClampToBorder)
.setBorderColor(Color3(0.5f))
.setMaxAnisotropy(Sampler::maxMaxAnisotropy());

22
src/Magnum/Test/CubeMapTextureGLTest.cpp

@ -45,6 +45,9 @@ class CubeMapTextureGLTest: public AbstractOpenGLTester {
void construct();
void sampling();
#ifdef MAGNUM_TARGET_GLES2
void samplingMaxLevel();
#endif
#ifndef MAGNUM_TARGET_GLES
void samplingBorderInteger();
#endif
@ -71,6 +74,9 @@ CubeMapTextureGLTest::CubeMapTextureGLTest() {
addTests({&CubeMapTextureGLTest::construct,
&CubeMapTextureGLTest::sampling,
#ifdef MAGNUM_TARGET_GLES2
&CubeMapTextureGLTest::samplingMaxLevel,
#endif
#ifndef MAGNUM_TARGET_GLES
&CubeMapTextureGLTest::samplingBorderInteger,
#endif
@ -108,6 +114,10 @@ void CubeMapTextureGLTest::sampling() {
CubeMapTexture texture;
texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
.setMagnificationFilter(Sampler::Filter::Linear)
#ifndef MAGNUM_TARGET_GLES2
.setBaseLevel(1)
.setMaxLevel(750)
#endif
.setWrapping(Sampler::Wrapping::ClampToBorder)
.setBorderColor(Color3(0.5f))
.setMaxAnisotropy(Sampler::maxMaxAnisotropy());
@ -115,6 +125,18 @@ void CubeMapTextureGLTest::sampling() {
MAGNUM_VERIFY_NO_ERROR();
}
#ifdef MAGNUM_TARGET_GLES2
void CubeMapTextureGLTest::samplingMaxLevel() {
if(!Context::current()->isExtensionSupported<Extensions::GL::APPLE::texture_max_level>())
CORRADE_SKIP(Extensions::GL::APPLE::texture_max_level::string() + std::string(" is not supported."));
CubeMapTexture texture;
texture.setMaxLevel(750);
MAGNUM_VERIFY_NO_ERROR();
}
#endif
#ifndef MAGNUM_TARGET_GLES
void CubeMapTextureGLTest::samplingBorderInteger() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_integer>())

26
src/Magnum/Test/TextureArrayGLTest.cpp

@ -50,6 +50,10 @@ class TextureArrayGLTest: public AbstractOpenGLTester {
#endif
void sampling2D();
#ifdef MAGNUM_TARGET_GLES2
void samplingMaxLevel2D();
#endif
#ifndef MAGNUM_TARGET_GLES
void samplingBorderInteger1D();
void samplingBorderInteger2D();
@ -106,6 +110,10 @@ TextureArrayGLTest::TextureArrayGLTest() {
#endif
&TextureArrayGLTest::sampling2D,
#ifdef MAGNUM_TARGET_GLES2
&TextureArrayGLTest::samplingMaxLevel2D,
#endif
#ifndef MAGNUM_TARGET_GLES
&TextureArrayGLTest::samplingBorderInteger1D,
&TextureArrayGLTest::samplingBorderInteger2D,
@ -189,6 +197,8 @@ void TextureArrayGLTest::sampling1D() {
Texture1DArray texture;
texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
.setMagnificationFilter(Sampler::Filter::Linear)
.setBaseLevel(1)
.setMaxLevel(750)
.setWrapping(Sampler::Wrapping::ClampToBorder)
.setBorderColor(Color3(0.5f))
.setMaxAnisotropy(Sampler::maxMaxAnisotropy());
@ -220,6 +230,10 @@ void TextureArrayGLTest::sampling2D() {
Texture2DArray texture;
texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
.setMagnificationFilter(Sampler::Filter::Linear)
#ifndef MAGNUM_TARGET_GLES2
.setBaseLevel(1)
.setMaxLevel(750)
#endif
#ifndef MAGNUM_TARGET_GLES
.setWrapping(Sampler::Wrapping::ClampToBorder)
.setBorderColor(Color3(0.5f))
@ -231,6 +245,18 @@ void TextureArrayGLTest::sampling2D() {
MAGNUM_VERIFY_NO_ERROR();
}
#ifdef MAGNUM_TARGET_GLES2
void TextureArrayGLTest::samplingMaxLevel2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::APPLE::texture_max_level>())
CORRADE_SKIP(Extensions::GL::APPLE::texture_max_level::string() + std::string(" is not supported."));
Texture2DArray texture;
texture.setMaxLevel(750);
MAGNUM_VERIFY_NO_ERROR();
}
#endif
#ifndef MAGNUM_TARGET_GLES
void TextureArrayGLTest::samplingBorderInteger2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_integer>())

46
src/Magnum/Test/TextureGLTest.cpp

@ -54,6 +54,11 @@ class TextureGLTest: public AbstractOpenGLTester {
void sampling2D();
void sampling3D();
#ifdef MAGNUM_TARGET_GLES2
void samplingMaxLevel2D();
void samplingMaxLevel3D();
#endif
#ifndef MAGNUM_TARGET_GLES
void samplingBorderInteger2D();
void samplingBorderInteger3D();
@ -129,6 +134,11 @@ TextureGLTest::TextureGLTest() {
&TextureGLTest::sampling2D,
&TextureGLTest::sampling3D,
#ifdef MAGNUM_TARGET_GLES2
&TextureGLTest::samplingMaxLevel2D,
&TextureGLTest::samplingMaxLevel3D,
#endif
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::samplingBorderInteger2D,
&TextureGLTest::samplingBorderInteger3D,
@ -234,6 +244,8 @@ void TextureGLTest::sampling1D() {
Texture1D texture;
texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
.setMagnificationFilter(Sampler::Filter::Linear)
.setBaseLevel(1)
.setMaxLevel(750)
.setWrapping(Sampler::Wrapping::ClampToBorder)
.setBorderColor(Color3(0.5f))
.setMaxAnisotropy(Sampler::maxMaxAnisotropy());
@ -246,6 +258,10 @@ void TextureGLTest::sampling2D() {
Texture2D texture;
texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
.setMagnificationFilter(Sampler::Filter::Linear)
#ifndef MAGNUM_TARGET_GLES2
.setBaseLevel(1)
.setMaxLevel(750)
#endif
#ifndef MAGNUM_TARGET_GLES
.setWrapping(Sampler::Wrapping::ClampToBorder)
.setBorderColor(Color3(0.5f))
@ -257,6 +273,18 @@ void TextureGLTest::sampling2D() {
MAGNUM_VERIFY_NO_ERROR();
}
#ifdef MAGNUM_TARGET_GLES2
void TextureGLTest::samplingMaxLevel2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::APPLE::texture_max_level>())
CORRADE_SKIP(Extensions::GL::APPLE::texture_max_level::string() + std::string(" is not supported."));
Texture2D texture;
texture.setMaxLevel(750);
MAGNUM_VERIFY_NO_ERROR();
}
#endif
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::samplingBorderInteger2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_integer>())
@ -293,6 +321,10 @@ void TextureGLTest::sampling3D() {
Texture3D texture;
texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
.setMagnificationFilter(Sampler::Filter::Linear)
#ifndef MAGNUM_TARGET_GLES2
.setBaseLevel(1)
.setMaxLevel(750)
#endif
#ifndef MAGNUM_TARGET_GLES
.setWrapping(Sampler::Wrapping::ClampToBorder)
.setBorderColor(Color3(0.5f))
@ -304,6 +336,20 @@ void TextureGLTest::sampling3D() {
MAGNUM_VERIFY_NO_ERROR();
}
#ifdef MAGNUM_TARGET_GLES2
void TextureGLTest::samplingMaxLevel3D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::OES::texture_3D>())
CORRADE_SKIP(Extensions::GL::OES::texture_3D::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::APPLE::texture_max_level>())
CORRADE_SKIP(Extensions::GL::APPLE::texture_max_level::string() + std::string(" is not supported."));
Texture3D texture;
texture.setMaxLevel(750);
MAGNUM_VERIFY_NO_ERROR();
}
#endif
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::samplingBorderInteger3D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_integer>())

62
src/Magnum/Texture.h

@ -77,10 +77,12 @@ texture.setMagnificationFilter(Sampler::Filter::Linear)
.generateMipmap();
@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().
@attention Note that default configuration is to use mipmaps. Be sure to either
reduce mip level count using @ref setBaseLevel() and @ref setMaxLevel(),
explicitly allocate all mip levels using @ref setStorage(), call
@ref generateMipmap() after uploading the base level to generate the rest
of the mip chain or call @ref setMinificationFilter() with another value to
disable mipmapping.
In shader, the texture is used via `sampler1D`/`sampler2D`/`sampler3D`,
`sampler1DShadow`/`sampler2DShadow`/`sampler3DShadow`,
@ -184,6 +186,47 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
}
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Set base mip level
* @return Reference to self (for method chaining)
*
* Taken into account when generating mipmap using @ref generateMipmap()
* and when considering texture completeness when using mipmap
* filtering. Initial value is `0`.
* @see @ref setMaxLevel(), @ref setMinificationFilter(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_BASE_LEVEL}
* @requires_gles30 Base level is always `0` in OpenGL ES 2.0.
*/
Texture<dimensions>& setBaseLevel(Int level) {
AbstractTexture::setBaseLevel(level);
return *this;
}
#endif
/**
* @brief Set max mip level
* @return Reference to self (for method chaining)
*
* Taken into account when generating mipmap using @ref generateMipmap()
* and when considering texture completeness when using mipmap
* filtering. Initial value is `1000`, which is clamped to count of
* levels specified when using @ref setStorage().
* @see @ref setBaseLevel(), @ref setMinificationFilter(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_MAX_LEVEL}
* @requires_gles30 %Extension @es_extension{APPLE,texture_max_level},
* otherwise the max level is always set to largest possible value
* in OpenGL ES 2.0.
*/
Texture<dimensions>& setMaxLevel(Int level) {
AbstractTexture::setMaxLevel(level);
return *this;
}
/**
* @brief Set minification filter
* @param filter Filter
@ -197,9 +240,10 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* available, the texture is bound to some texture unit 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}
* @see @ref setBaseLevel(), @ref setMaxLevel(), @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<dimensions>& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
@ -330,8 +374,8 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* calls.
* @todo allow the user to specify ColorType explicitly to avoid
* issues in WebGL (see setSubImage())
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexStorage1D}/@fn_gl{TexStorage2D}/@fn_gl{TexStorage3D}
* @see @ref setMaxLevel(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture}
* and @fn_gl{TexStorage1D}/@fn_gl{TexStorage2D}/@fn_gl{TexStorage3D}
* or @fn_gl_extension{TextureStorage1D,EXT,direct_state_access}/
* @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureStorage3D,EXT,direct_state_access},

21
src/Magnum/TextureArray.h

@ -55,6 +55,8 @@ Template class for one- and two-dimensional texture arrays. See also
@section Texture-usage Usage
See @ref Texture documentation for introduction.
Common usage is to fully configure all texture parameters and then set the
data. Example configuration:
@code
@ -77,11 +79,6 @@ for(std::size_t i = 0; i != 16; ++i) {
}
@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().
In shader, the texture is used via `sampler1DArray`/`sampler2DArray`,
`sampler1DArrayShadow`/`sampler1DArrayShadow`, `isampler1DArray`/`isampler2DArray`
or `usampler1DArray`/`usampler2DArray`. See @ref AbstractShaderProgram
@ -107,6 +104,20 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
*/
explicit TextureArray(): AbstractTexture(Implementation::textureArrayTarget<dimensions>()) {}
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc Texture::setBaseLevel() */
TextureArray<dimensions>& setBaseLevel(Int level) {
AbstractTexture::setBaseLevel(level);
return *this;
}
#endif
/** @copydoc Texture::setMaxLevel() */
TextureArray<dimensions>& setMaxLevel(Int level) {
AbstractTexture::setMaxLevel(level);
return *this;
}
/** @copydoc Texture::setMinificationFilter() */
TextureArray<dimensions>& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);

Loading…
Cancel
Save