Browse Source

Fixed CubeMapTexture wrapping, simplified code of texture classes.

Texture now doesn't have it's own redundant copy of target, but uses the
one from AbstractTexture. Subsequently, all DataHelper functions now
accept "untyped" GLenum as target for better flexibility.

CubeMapTexture is not based on Texture2D anymore, all references to cube
map textures were removed from Target enums, so it's now not possible to
create cube map texture other way than using CubeMapTexture class, which
is how it should be done in first place. The wrapping mode fix is thus
now trivial.
pull/279/head
Vladimír Vondruš 14 years ago
parent
commit
63f2e130b1
  1. 24
      src/AbstractTexture.cpp
  2. 46
      src/AbstractTexture.h
  3. 40
      src/CubeMapTexture.h
  4. 16
      src/Texture.h

24
src/AbstractTexture.cpp

@ -47,18 +47,18 @@ static_assert((filter_or(NearestNeighbor, BaseLevel) == GL_NEAREST) &&
#endif
void AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) {
CORRADE_ASSERT(target != GL_TEXTURE_RECTANGLE || mipmap == Mipmap::BaseLevel, "AbstractTexture: rectangle textures cannot have mipmaps", )
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Mipmap::BaseLevel, "AbstractTexture: rectangle textures cannot have mipmaps", )
bind();
glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
glTexParameteri(_target, GL_TEXTURE_MIN_FILTER,
static_cast<GLint>(filter)|static_cast<GLint>(mipmap));
}
void AbstractTexture::generateMipmap() {
CORRADE_ASSERT(target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", )
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", )
bind();
glGenerateMipmap(target);
glGenerateMipmap(_target);
}
AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components components, AbstractTexture::ComponentType type) {
@ -100,17 +100,17 @@ AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components comp
}
#ifndef DOXYGEN_GENERATING_OUTPUT
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", )
void AbstractTexture::DataHelper<2>::setWrapping(GLenum target, const Math::Vector<Wrapping, 2>& wrapping) {
CORRADE_ASSERT(target != GL_TEXTURE_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]));
glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping[0]));
glTexParameteri(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]));
void AbstractTexture::DataHelper<3>::setWrapping(GLenum target, const Math::Vector<Wrapping, 3>& wrapping) {
glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping[0]));
glTexParameteri(target, GL_TEXTURE_WRAP_T, static_cast<GLint>(wrapping[1]));
glTexParameteri(target, GL_TEXTURE_WRAP_R, static_cast<GLint>(wrapping[2]));
}
#endif

46
src/AbstractTexture.h

@ -425,7 +425,7 @@ class MAGNUM_EXPORT AbstractTexture {
*
* Creates one OpenGL texture.
*/
inline AbstractTexture(GLint layer, GLenum target): target(target), _layer(layer) {
inline AbstractTexture(GLint layer, GLenum target): _target(target), _layer(layer) {
glActiveTexture(GL_TEXTURE0 + layer);
glGenTextures(1, &texture);
}
@ -455,7 +455,7 @@ class MAGNUM_EXPORT AbstractTexture {
*/
inline void bind() {
glActiveTexture(GL_TEXTURE0 + _layer);
glBindTexture(target, texture);
glBindTexture(_target, texture);
}
/**
@ -489,7 +489,7 @@ class MAGNUM_EXPORT AbstractTexture {
*/
inline void setMagnificationFilter(Filter filter) {
bind();
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, static_cast<GLint>(filter));
glTexParameteri(_target, GL_TEXTURE_MAG_FILTER, static_cast<GLint>(filter));
}
/**
@ -500,7 +500,7 @@ class MAGNUM_EXPORT AbstractTexture {
*/
inline void setBorderColor(const Vector4& color) {
bind();
glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, color.data());
glTexParameterfv(_target, GL_TEXTURE_BORDER_COLOR, color.data());
}
/**
@ -516,8 +516,9 @@ class MAGNUM_EXPORT AbstractTexture {
template<size_t textureDimensions> struct DataHelper {};
#endif
const GLenum _target; /**< @brief Target */
private:
const GLenum target;
const GLint _layer;
GLuint texture;
};
@ -570,36 +571,35 @@ template<> struct AbstractTexture::DataHelper<1> {
inline constexpr static Target target() { return Target::Texture1D; }
inline static void setWrapping(Target target, const Math::Vector<Wrapping, 1>& wrapping) {
glTexParameteri(static_cast<GLenum>(target), GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping[0]));
inline static void setWrapping(GLenum target, const Math::Vector<Wrapping, 1>& wrapping) {
glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping[0]));
}
template<class T> inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) {
glTexImage1D(static_cast<GLenum>(target), mipLevel, internalFormat, image->dimensions()[0], 0, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
template<class T> inline static void set(GLenum target, GLint mipLevel, InternalFormat internalFormat, T* image) {
glTexImage1D(target, mipLevel, internalFormat, image->dimensions()[0], 0, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
}
template<class T> inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 1>& offset, T* image) {
glTexSubImage1D(static_cast<GLenum>(target), mipLevel, offset[0], image->dimensions()[0], static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
template<class T> inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector<GLint, 1>& offset, T* image) {
glTexSubImage1D(target, mipLevel, offset[0], image->dimensions()[0], static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
}
};
template<> struct AbstractTexture::DataHelper<2> {
enum class Target: GLenum {
Texture2D = GL_TEXTURE_2D,
Array1D = GL_TEXTURE_1D_ARRAY,
Rectangle = GL_TEXTURE_RECTANGLE,
CubeMap = GL_TEXTURE_CUBE_MAP
Rectangle = GL_TEXTURE_RECTANGLE
};
inline constexpr static Target target() { return Target::Texture2D; }
static void setWrapping(Target target, const Math::Vector<Wrapping, 2>& wrapping);
static void setWrapping(GLenum 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());
template<class T> inline static void set(GLenum target, GLint mipLevel, InternalFormat internalFormat, T* image) {
glTexImage2D(target, mipLevel, internalFormat, image->dimensions()[0], image->dimensions()[1], 0, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
}
template<class T> inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 2>& offset, T* image) {
glTexSubImage2D(static_cast<GLenum>(target), mipLevel, offset[0], offset[1], image->dimensions()[0], image->dimensions()[1], static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
template<class T> inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector<GLint, 2>& offset, T* image) {
glTexSubImage2D(target, mipLevel, offset[0], offset[1], image->dimensions()[0], image->dimensions()[1], static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
}
};
template<> struct AbstractTexture::DataHelper<3> {
@ -610,14 +610,14 @@ template<> struct AbstractTexture::DataHelper<3> {
inline constexpr static Target target() { return Target::Texture3D; }
static void setWrapping(Target target, const Math::Vector<Wrapping, 3>& wrapping);
static void setWrapping(GLenum 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());
template<class T> inline static void set(GLenum target, GLint mipLevel, InternalFormat internalFormat, T* image) {
glTexImage3D(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());
}
template<class T> inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 3>& offset, T* image) {
glTexSubImage3D(static_cast<GLenum>(target), mipLevel, offset[0], offset[1], offset[2], image->dimensions()[0], image->dimensions()[1], image->dimensions()[2], static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
template<class T> inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector<GLint, 3>& offset, T* image) {
glTexSubImage3D(target, mipLevel, offset[0], offset[1], offset[2], image->dimensions()[0], image->dimensions()[1], image->dimensions()[2], static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
}
};
#endif

40
src/CubeMapTexture.h

@ -43,19 +43,18 @@ textures, coordinates for cube map textures is signed three-part vector from
the center of the cube, which intersects one of the six sides of the cube map.
See Texture documentation for more information about usage.
@todo The wrap mode is 3D, not 2D! http://www.opengl.org/wiki/Common_Mistakes#Creating_a_Cubemap_Texture
@todo Cube map arrays (OpenGL 4.0, ARB_texture_cube_map_array)
*/
class CubeMapTexture: public Texture2D {
class CubeMapTexture: public AbstractTexture {
public:
/** @brief Cube map coordinate */
enum Coordinate: GLenum {
PositiveX = GL_TEXTURE_CUBE_MAP_POSITIVE_X,
NegativeX = GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
PositiveY = GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
NegativeY = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
PositiveZ = GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
NegativeZ = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
PositiveX = GL_TEXTURE_CUBE_MAP_POSITIVE_X, /**< +X cube side */
NegativeX = GL_TEXTURE_CUBE_MAP_NEGATIVE_X, /**< -X cube side */
PositiveY = GL_TEXTURE_CUBE_MAP_POSITIVE_Y, /**< +Y cube side */
NegativeY = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, /**< -Y cube side */
PositiveZ = GL_TEXTURE_CUBE_MAP_POSITIVE_Z, /**< +Z cube side */
NegativeZ = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z /**< -Z cube side */
};
/**
@ -71,29 +70,34 @@ class CubeMapTexture: public Texture2D {
* @brief Constructor
* @param layer Texture layer (number between 0 and 31)
*
* Creates texture with target Target::CubeMap.
* Creates one cube map OpenGL texture.
*/
inline CubeMapTexture(GLint layer = 0): Texture(layer, Target::CubeMap) {}
inline CubeMapTexture(GLint layer = 0): AbstractTexture(layer, GL_TEXTURE_CUBE_MAP) {}
template<class T> void setData(GLint mipLevel, InternalFormat internalFormat, T* image) = delete;
template<class T> void setSubData(GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, T* image) = delete;
/**
* @copydoc Texture::setWrapping()
*/
inline void setWrapping(const Math::Vector<Wrapping, 3>& wrapping) {
bind();
DataHelper<3>::setWrapping(GL_TEXTURE_CUBE_MAP, wrapping);
}
/**
* @copydetails Texture::setData(GLint, InternalFormat, T*)
* @param coordinate Coordinate
* @copydoc Texture::setData(GLint, InternalFormat, T*)
* @param coordinate Coordinate
*/
template<class T> inline void setData(Coordinate coordinate, GLint mipLevel, InternalFormat internalFormat, T* image) {
bind();
DataHelper<Dimensions>::set(static_cast<Target>(coordinate), mipLevel, internalFormat, image);
DataHelper<2>::set(static_cast<GLenum>(coordinate), mipLevel, internalFormat, image);
}
/**
* @copydoc Texture::setSubData(GLint, const Math::Vector<GLint, Dimensions>&, T*)
* @param coordinate Coordinate
* @param coordinate Coordinate
*/
template<class T> inline void setSubData(Coordinate coordinate, GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, const T* image) {
template<class T> inline void setSubData(Coordinate coordinate, GLint mipLevel, const Math::Vector<GLint, 2>& offset, const T* image) {
bind();
DataHelper<Dimensions>::setSub(static_cast<Target>(coordinate), mipLevel, offset, image);
DataHelper<2>::setSub(static_cast<GLenum>(coordinate), mipLevel, offset, image);
}
};

16
src/Texture.h

@ -49,6 +49,8 @@ don't support mipmapping and repeating wrapping modes, see @ref Texture::Filter
for more information.
@requires_gl31 Extension <tt>ARB_texture_rectangle</tt> (rectangle textures)
@see CubeMapTexture
*/
template<size_t textureDimensions> class Texture: public AbstractTexture {
public:
@ -84,12 +86,7 @@ template<size_t textureDimensions> class Texture: public AbstractTexture {
*
* @requires_gl31 Extension <tt>ARB_texture_rectangle</tt>
*/
Rectangle = GL_TEXTURE_RECTANGLE,
/**
* Cube map texture. Use CubeMapTexture class.
*/
CubeMap = GL_TEXTURE_CUBE_MAP
Rectangle = GL_TEXTURE_RECTANGLE
};
#else
typedef typename DataHelper<Dimensions>::Target Target; /**< @brief %Texture target */
@ -104,10 +101,10 @@ template<size_t textureDimensions> class Texture: public AbstractTexture {
*
* Creates one OpenGL texture.
*/
inline Texture(GLint layer = 0, Target target = DataHelper<Dimensions>::target()): AbstractTexture(layer, static_cast<GLenum>(target)), _target(target) {}
inline Texture(GLint layer = 0, Target target = DataHelper<Dimensions>::target()): AbstractTexture(layer, static_cast<GLenum>(target)) {}
/** @brief %Texture target */
inline Target target() const { return _target; }
inline Target target() const { return static_cast<Target>(_target); }
/**
* @brief Set wrapping
@ -157,9 +154,6 @@ template<size_t textureDimensions> class Texture: public AbstractTexture {
bind();
DataHelper<Dimensions>::setSub(_target, mipLevel, offset, image);
}
private:
Target _target;
};
/** @brief One-dimensional texture */

Loading…
Cancel
Save