Browse Source

Rectangle texture safety guards, doc++

* Added asserts for unsupported mipmap and wrapping modes instead of
   previous blind behavior, moved more-than-one-liner functions into
   *.cpp
 * Updated documentation to reflect the rectangle texture inabilities to
   user, changed "unusable" to "incomplete" to be consistent with OpenGL
   terminology.
 * Removed some unneeded rows in documentation.
vectorfields
Vladimír Vondruš 14 years ago
parent
commit
d8deeb836a
  1. 18
      src/AbstractTexture.cpp
  2. 80
      src/AbstractTexture.h
  3. 12
      src/Texture.h

18
src/AbstractTexture.cpp

@ -47,8 +47,7 @@ static_assert((filter_or(NearestNeighbor, BaseLevel) == GL_NEAREST) &&
#endif #endif
void AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) { void AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) {
/* Only base mip level is supported on rectangle textures */ CORRADE_ASSERT(target != GL_TEXTURE_RECTANGLE || mipmap == Mipmap::BaseLevel, "AbstractTexture: rectangle textures cannot have mipmaps", )
if(target == GL_TEXTURE_RECTANGLE) mipmap = Mipmap::BaseLevel;
bind(); bind();
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
@ -56,7 +55,7 @@ void AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) {
} }
void AbstractTexture::generateMipmap() { void AbstractTexture::generateMipmap() {
if(target == GL_TEXTURE_RECTANGLE) return; CORRADE_ASSERT(target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", )
bind(); bind();
glGenerateMipmap(target); glGenerateMipmap(target);
@ -100,4 +99,17 @@ AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components comp
#undef internalFormatSwitch #undef internalFormatSwitch
} }
void AbstractTexture::DataHelper<2>::setWrapping(Target target, const Math::Vector<Wrapping, 2>& 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<GLenum>(target), GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping[0]));
glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_WRAP_T, static_cast<GLint>(wrapping[1]));
}
void AbstractTexture::DataHelper<3>::setWrapping(Target target, const Math::Vector<Wrapping, 3>& wrapping) {
glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping[0]));
glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_WRAP_T, static_cast<GLint>(wrapping[1]));
glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_WRAP_R, static_cast<GLint>(wrapping[2]));
}
} }

80
src/AbstractTexture.h

@ -35,47 +35,47 @@ class MAGNUM_EXPORT AbstractTexture {
AbstractTexture& operator=(AbstractTexture&& other) = delete; AbstractTexture& operator=(AbstractTexture&& other) = delete;
public: public:
/** @brief %Texture filtering */ /**
* @brief %Texture filtering
*
* @see setMagnificationFilter() and setMinificationFilter()
*/
enum class Filter: GLint { enum class Filter: GLint {
/** NearestNeighbor = GL_NEAREST, /**< Nearest neighbor filtering */
* Nearest neighbor filtering LinearInterpolation = GL_LINEAR /**< Linear interpolation filtering */
*/
NearestNeighbor = GL_NEAREST,
/**
* Linear interpolation filtering
*/
LinearInterpolation = GL_LINEAR
}; };
/** @brief Mip level selection */ /**
* @brief Mip level selection
*
* @see setMinificationFilter()
*/
enum class Mipmap: GLint { enum class Mipmap: GLint {
/** BaseLevel = GL_NEAREST & ~GL_NEAREST, /**< Select base mip level */
* Select base mip level
*/
BaseLevel = GL_NEAREST & ~GL_NEAREST,
/** /**
* Select nearest mip level. Unavailable on rectangle textures. * Select nearest mip level. **Unavailable on rectangle textures.**
*/ */
NearestLevel = GL_NEAREST_MIPMAP_NEAREST & ~GL_NEAREST, NearestLevel = GL_NEAREST_MIPMAP_NEAREST & ~GL_NEAREST,
/** /**
* Linear interpolation of nearest mip levels. Unavailable on * Linear interpolation of nearest mip levels. **Unavailable on
* rectangle textures. * rectangle textures.**
*/ */
LinearInterpolation = GL_NEAREST_MIPMAP_LINEAR & ~GL_NEAREST 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 { enum class Wrapping: GLint {
/** /** Repeat texture. **Unavailable on rectangle textures.** */
* Repeat texture. Unavailable on rectangle textures.
*/
Repeat = GL_REPEAT, Repeat = GL_REPEAT,
/** /**
* Repeat mirrored texture. Unavailable on rectangle textures. * Repeat mirrored texture. **Unavailable on rectangle textures.**
*/ */
MirroredRepeat = GL_MIRRORED_REPEAT, MirroredRepeat = GL_MIRRORED_REPEAT,
@ -247,14 +247,10 @@ class MAGNUM_EXPORT AbstractTexture {
*/ */
RGB9Exponent5 = GL_RGB9_E5, RGB9Exponent5 = GL_RGB9_E5,
/** /** Compressed red channel, unsigned normalized. */
* Compressed red channel, unsigned normalized.
*/
CompressedRed = GL_COMPRESSED_RED, CompressedRed = GL_COMPRESSED_RED,
/** /** Compressed red and green channel, unsigned normalized. */
* Compressed red and green channel, unsigned normalized.
*/
CompressedRedGreen = GL_COMPRESSED_RG, CompressedRedGreen = GL_COMPRESSED_RG,
/** Compressed RGB, unsigned normalized. */ /** Compressed RGB, unsigned normalized. */
@ -363,12 +359,14 @@ class MAGNUM_EXPORT AbstractTexture {
* call generateMipmap(). * call generateMipmap().
* *
* Sets filter used when the object pixel size is smaller than the * 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 * see @ref AbstractTexture::Filter "Filter" and
* @ref AbstractTexture::Mipmap "Mipmap" documentation for more * @ref AbstractTexture::Mipmap "Mipmap" documentation for more
* information. * 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); 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 * Sets filter used when the object pixel size is larger than largest
* texture size. * texture size.
* @attention This and setMinificationFilter() must be called after * @attention This, @ref Texture::setWrapping() "setWrapping()" and
* creating the texture, otherwise it will be unusable. * setMinificationFilter() must be called after creating the texture,
* otherwise the texture will be incomplete.
*/ */
inline void setMagnificationFilter(Filter filter) { inline void setMagnificationFilter(Filter filter) {
bind(); bind();
@ -400,7 +399,7 @@ class MAGNUM_EXPORT AbstractTexture {
/** /**
* @brief Generate mipmap * @brief Generate mipmap
* *
* Does nothing on rectangle textures. * Can not be used for rectangle textures.
* @see setMinificationFilter() * @see setMinificationFilter()
*/ */
void generateMipmap(); void generateMipmap();
@ -559,10 +558,7 @@ template<> struct AbstractTexture::DataHelper<2> {
inline constexpr static Target target() { return Target::Texture2D; } inline constexpr static Target target() { return Target::Texture2D; }
inline static void setWrapping(Target target, const Math::Vector<Wrapping, 2>& wrapping) { static void setWrapping(Target target, const Math::Vector<Wrapping, 2>& wrapping);
glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping[0]));
glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_WRAP_T, static_cast<GLint>(wrapping[1]));
}
template<class T> inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) { template<class T> inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) {
glTexImage2D(static_cast<GLenum>(target), mipLevel, internalFormat, image->dimensions()[0], image->dimensions()[1], 0, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data()); glTexImage2D(static_cast<GLenum>(target), mipLevel, internalFormat, image->dimensions()[0], image->dimensions()[1], 0, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
@ -580,11 +576,7 @@ template<> struct AbstractTexture::DataHelper<3> {
inline constexpr static Target target() { return Target::Texture3D; } inline constexpr static Target target() { return Target::Texture3D; }
inline static void setWrapping(Target target, const Math::Vector<Wrapping, 3>& wrapping) { static void setWrapping(Target target, const Math::Vector<Wrapping, 3>& wrapping);
glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping[0]));
glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_WRAP_T, static_cast<GLint>(wrapping[1]));
glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_WRAP_R, static_cast<GLint>(wrapping[2]));
}
template<class T> inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) { template<class T> inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) {
glTexImage3D(static_cast<GLenum>(target), mipLevel, internalFormat, image->dimensions()[0], image->dimensions()[1], image->dimensions()[2], 0, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data()); glTexImage3D(static_cast<GLenum>(target), mipLevel, internalFormat, image->dimensions()[0], image->dimensions()[1], image->dimensions()[2], 0, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());

12
src/Texture.h

@ -28,9 +28,9 @@ namespace Magnum {
Template class for one- to three-dimensional textures. Template class for one- to three-dimensional textures.
@attention Don't forget to call setMinificationFilter() and @attention Don't forget to call setWrapping(), setMinificationFilter() and
setMagnificationFilter() after creating the texture, otherwise it will be setMagnificationFilter() after creating the texture, otherwise the texture
unusable. will be incomplete.
The texture is bound via bind() and setting texture uniform on the shader to the The texture is bound via bind() and setting texture uniform on the shader to the
texture (see AbstractShaderProgram::setUniform(GLint, const AbstractTexture*)). texture (see AbstractShaderProgram::setUniform(GLint, const AbstractTexture*)).
@ -72,6 +72,12 @@ template<size_t textureDimensions> class Texture: public AbstractTexture {
* Sets wrapping type for coordinates out of range (0, 1) for normal * Sets wrapping type for coordinates out of range (0, 1) for normal
* textures and (0, textureSizeInGivenDirection-1) for rectangle * textures and (0, textureSizeInGivenDirection-1) for rectangle
* textures. * 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, Dimensions>& wrapping) { inline void setWrapping(const Math::Vector<Wrapping, Dimensions>& wrapping) {
bind(); bind();

Loading…
Cancel
Save