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
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, 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;
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, 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]));
}
static void setWrapping(Target target, const Math::Vector<Wrapping, 2>& wrapping);
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());
@ -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, 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]));
}
static void setWrapping(Target target, const Math::Vector<Wrapping, 3>& wrapping);
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());

12
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<size_t textureDimensions> 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, Dimensions>& wrapping) {
bind();

Loading…
Cancel
Save