diff --git a/src/AbstractTexture.cpp b/src/AbstractTexture.cpp index dce557eeb..aa48df3f8 100644 --- a/src/AbstractTexture.cpp +++ b/src/AbstractTexture.cpp @@ -47,8 +47,7 @@ static_assert((filter_or(NearestNeighbor, BaseLevel) == GL_NEAREST) && #endif void AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) { - /* Only base mip level is supported on rectangle textures */ - if(target == GL_TEXTURE_RECTANGLE) mipmap = Mipmap::BaseLevel; + CORRADE_ASSERT(target != GL_TEXTURE_RECTANGLE || mipmap == Mipmap::BaseLevel, "AbstractTexture: rectangle textures cannot have mipmaps", ) bind(); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, @@ -56,7 +55,7 @@ void AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) { } void AbstractTexture::generateMipmap() { - if(target == GL_TEXTURE_RECTANGLE) return; + CORRADE_ASSERT(target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", ) bind(); glGenerateMipmap(target); @@ -100,4 +99,17 @@ AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components comp #undef internalFormatSwitch } +void AbstractTexture::DataHelper<2>::setWrapping(Target target, const Math::Vector& wrapping) { + CORRADE_ASSERT(target != Target::Rectangle || ((wrapping[0] == Wrapping::ClampToEdge || wrapping[0] == Wrapping::ClampToBorder) && (wrapping[0] == Wrapping::ClampToEdge || wrapping[1] == Wrapping::ClampToEdge)), "AbstractTexture: rectangle texture wrapping must either clamp to border or to edge", ) + + glTexParameteri(static_cast(target), GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); + glTexParameteri(static_cast(target), GL_TEXTURE_WRAP_T, static_cast(wrapping[1])); +} + +void AbstractTexture::DataHelper<3>::setWrapping(Target target, const Math::Vector& wrapping) { + glTexParameteri(static_cast(target), GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); + glTexParameteri(static_cast(target), GL_TEXTURE_WRAP_T, static_cast(wrapping[1])); + glTexParameteri(static_cast(target), GL_TEXTURE_WRAP_R, static_cast(wrapping[2])); +} + } diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index 214f8529c..dc7e38d0f 100644 --- a/src/AbstractTexture.h +++ b/src/AbstractTexture.h @@ -35,47 +35,47 @@ class MAGNUM_EXPORT AbstractTexture { AbstractTexture& operator=(AbstractTexture&& other) = delete; public: - /** @brief %Texture filtering */ + /** + * @brief %Texture filtering + * + * @see setMagnificationFilter() and setMinificationFilter() + */ enum class Filter: GLint { - /** - * Nearest neighbor filtering - */ - NearestNeighbor = GL_NEAREST, - - /** - * Linear interpolation filtering - */ - LinearInterpolation = GL_LINEAR + NearestNeighbor = GL_NEAREST, /**< Nearest neighbor filtering */ + LinearInterpolation = GL_LINEAR /**< Linear interpolation filtering */ }; - /** @brief Mip level selection */ + /** + * @brief Mip level selection + * + * @see setMinificationFilter() + */ enum class Mipmap: GLint { - /** - * Select base mip level - */ - BaseLevel = GL_NEAREST & ~GL_NEAREST, + BaseLevel = GL_NEAREST & ~GL_NEAREST, /**< Select base mip level */ /** - * Select nearest mip level. Unavailable on rectangle textures. + * Select nearest mip level. **Unavailable on rectangle textures.** */ NearestLevel = GL_NEAREST_MIPMAP_NEAREST & ~GL_NEAREST, /** - * Linear interpolation of nearest mip levels. Unavailable on - * rectangle textures. + * Linear interpolation of nearest mip levels. **Unavailable on + * rectangle textures.** */ LinearInterpolation = GL_NEAREST_MIPMAP_LINEAR & ~GL_NEAREST }; - /** @brief %Texture wrapping on the edge */ + /** + * @brief %Texture wrapping + * + * @see @ref Texture::setWrapping() "setWrapping()" + */ enum class Wrapping: GLint { - /** - * Repeat texture. Unavailable on rectangle textures. - */ + /** Repeat texture. **Unavailable on rectangle textures.** */ Repeat = GL_REPEAT, /** - * Repeat mirrored texture. Unavailable on rectangle textures. + * Repeat mirrored texture. **Unavailable on rectangle textures.** */ MirroredRepeat = GL_MIRRORED_REPEAT, @@ -247,14 +247,10 @@ class MAGNUM_EXPORT AbstractTexture { */ RGB9Exponent5 = GL_RGB9_E5, - /** - * Compressed red channel, unsigned normalized. - */ + /** Compressed red channel, unsigned normalized. */ CompressedRed = GL_COMPRESSED_RED, - /** - * Compressed red and green channel, unsigned normalized. - */ + /** Compressed red and green channel, unsigned normalized. */ CompressedRedGreen = GL_COMPRESSED_RG, /** Compressed RGB, unsigned normalized. */ @@ -363,12 +359,14 @@ class MAGNUM_EXPORT AbstractTexture { * call generateMipmap(). * * Sets filter used when the object pixel size is smaller than the - * texture size. For rectangle textures only some modes are supported, + * texture size. + * @attention This, @ref Texture::setWrapping() "setWrapping()" and + * setMagnificationFilter() must be called after creating the texture, + * otherwise the texture will be incomplete. + * @attention For rectangle textures only some modes are supported, * see @ref AbstractTexture::Filter "Filter" and * @ref AbstractTexture::Mipmap "Mipmap" documentation for more * information. - * @attention This and setMagnificationFilter() must be called after - * creating the texture, otherwise it will be unusable. */ void setMinificationFilter(Filter filter, Mipmap mipmap = Mipmap::BaseLevel); @@ -378,8 +376,9 @@ class MAGNUM_EXPORT AbstractTexture { * * Sets filter used when the object pixel size is larger than largest * texture size. - * @attention This and setMinificationFilter() must be called after - * creating the texture, otherwise it will be unusable. + * @attention This, @ref Texture::setWrapping() "setWrapping()" and + * setMinificationFilter() must be called after creating the texture, + * otherwise the texture will be incomplete. */ inline void setMagnificationFilter(Filter filter) { bind(); @@ -400,7 +399,7 @@ class MAGNUM_EXPORT AbstractTexture { /** * @brief Generate mipmap * - * Does nothing on rectangle textures. + * Can not be used for rectangle textures. * @see setMinificationFilter() */ void generateMipmap(); @@ -559,10 +558,7 @@ template<> struct AbstractTexture::DataHelper<2> { inline constexpr static Target target() { return Target::Texture2D; } - inline static void setWrapping(Target target, const Math::Vector& wrapping) { - glTexParameteri(static_cast(target), GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); - glTexParameteri(static_cast(target), GL_TEXTURE_WRAP_T, static_cast(wrapping[1])); - } + static void setWrapping(Target target, const Math::Vector& wrapping); template inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) { glTexImage2D(static_cast(target), mipLevel, internalFormat, image->dimensions()[0], image->dimensions()[1], 0, static_cast(image->components()), static_cast(image->type()), image->data()); @@ -580,11 +576,7 @@ template<> struct AbstractTexture::DataHelper<3> { inline constexpr static Target target() { return Target::Texture3D; } - inline static void setWrapping(Target target, const Math::Vector& wrapping) { - glTexParameteri(static_cast(target), GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); - glTexParameteri(static_cast(target), GL_TEXTURE_WRAP_T, static_cast(wrapping[1])); - glTexParameteri(static_cast(target), GL_TEXTURE_WRAP_R, static_cast(wrapping[2])); - } + static void setWrapping(Target target, const Math::Vector& wrapping); template inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) { glTexImage3D(static_cast(target), mipLevel, internalFormat, image->dimensions()[0], image->dimensions()[1], image->dimensions()[2], 0, static_cast(image->components()), static_cast(image->type()), image->data()); diff --git a/src/Texture.h b/src/Texture.h index 40cd11073..b65d7f9fe 100644 --- a/src/Texture.h +++ b/src/Texture.h @@ -28,9 +28,9 @@ namespace Magnum { Template class for one- to three-dimensional textures. -@attention Don't forget to call setMinificationFilter() and -setMagnificationFilter() after creating the texture, otherwise it will be -unusable. +@attention Don't forget to call setWrapping(), setMinificationFilter() and +setMagnificationFilter() after creating the texture, otherwise the texture +will be incomplete. The texture is bound via bind() and setting texture uniform on the shader to the texture (see AbstractShaderProgram::setUniform(GLint, const AbstractTexture*)). @@ -72,6 +72,12 @@ template class Texture: public AbstractTexture { * Sets wrapping type for coordinates out of range (0, 1) for normal * textures and (0, textureSizeInGivenDirection-1) for rectangle * textures. + * @attention This, setMinificationFilter() and + * setMagnificationFilter() must be called after creating the texture, + * otherwise the texture will be incomplete. + * @attention For rectangle textures only some modes are supported, + * see @ref AbstractTexture::Wrapping "Wrapping" documentation for + * more information. */ inline void setWrapping(const Math::Vector& wrapping) { bind();