From 63f2e130b1cbb05648879f23690eaa145d14ee19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 7 May 2012 15:33:39 +0200 Subject: [PATCH] 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. --- src/AbstractTexture.cpp | 24 ++++++++++----------- src/AbstractTexture.h | 46 ++++++++++++++++++++--------------------- src/CubeMapTexture.h | 40 +++++++++++++++++++---------------- src/Texture.h | 16 +++++--------- 4 files changed, 62 insertions(+), 64 deletions(-) diff --git a/src/AbstractTexture.cpp b/src/AbstractTexture.cpp index e445d7e3a..0f4dc2b5e 100644 --- a/src/AbstractTexture.cpp +++ b/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(filter)|static_cast(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) { - 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) { + 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(target), GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); - glTexParameteri(static_cast(target), GL_TEXTURE_WRAP_T, static_cast(wrapping[1])); + glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); + glTexParameteri(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])); +void AbstractTexture::DataHelper<3>::setWrapping(GLenum target, const Math::Vector& wrapping) { + glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); + glTexParameteri(target, GL_TEXTURE_WRAP_T, static_cast(wrapping[1])); + glTexParameteri(target, GL_TEXTURE_WRAP_R, static_cast(wrapping[2])); } #endif diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index c3bbbd2db..932b5306d 100644 --- a/src/AbstractTexture.h +++ b/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(filter)); + glTexParameteri(_target, GL_TEXTURE_MAG_FILTER, static_cast(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 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) { - glTexParameteri(static_cast(target), GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); + inline static void setWrapping(GLenum target, const Math::Vector& wrapping) { + glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); } - template inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) { - glTexImage1D(static_cast(target), mipLevel, internalFormat, image->dimensions()[0], 0, static_cast(image->components()), static_cast(image->type()), image->data()); + template inline static void set(GLenum target, GLint mipLevel, InternalFormat internalFormat, T* image) { + glTexImage1D(target, mipLevel, internalFormat, image->dimensions()[0], 0, static_cast(image->components()), static_cast(image->type()), image->data()); } - template inline static void setSub(Target target, GLint mipLevel, const Math::Vector& offset, T* image) { - glTexSubImage1D(static_cast(target), mipLevel, offset[0], image->dimensions()[0], static_cast(image->components()), static_cast(image->type()), image->data()); + template inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector& offset, T* image) { + glTexSubImage1D(target, mipLevel, offset[0], image->dimensions()[0], static_cast(image->components()), static_cast(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); + static void setWrapping(GLenum 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()); + template 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(image->components()), static_cast(image->type()), image->data()); } - template inline static void setSub(Target target, GLint mipLevel, const Math::Vector& offset, T* image) { - glTexSubImage2D(static_cast(target), mipLevel, offset[0], offset[1], image->dimensions()[0], image->dimensions()[1], static_cast(image->components()), static_cast(image->type()), image->data()); + template inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector& offset, T* image) { + glTexSubImage2D(target, mipLevel, offset[0], offset[1], image->dimensions()[0], image->dimensions()[1], static_cast(image->components()), static_cast(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); + static void setWrapping(GLenum 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()); + template 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(image->components()), static_cast(image->type()), image->data()); } - template inline static void setSub(Target target, GLint mipLevel, const Math::Vector& offset, T* image) { - glTexSubImage3D(static_cast(target), mipLevel, offset[0], offset[1], offset[2], image->dimensions()[0], image->dimensions()[1], image->dimensions()[2], static_cast(image->components()), static_cast(image->type()), image->data()); + template inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector& offset, T* image) { + glTexSubImage3D(target, mipLevel, offset[0], offset[1], offset[2], image->dimensions()[0], image->dimensions()[1], image->dimensions()[2], static_cast(image->components()), static_cast(image->type()), image->data()); } }; #endif diff --git a/src/CubeMapTexture.h b/src/CubeMapTexture.h index e2b78ce4d..cf6c70532 100644 --- a/src/CubeMapTexture.h +++ b/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 void setData(GLint mipLevel, InternalFormat internalFormat, T* image) = delete; - template void setSubData(GLint mipLevel, const Math::Vector& offset, T* image) = delete; + /** + * @copydoc Texture::setWrapping() + */ + inline void setWrapping(const Math::Vector& 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 inline void setData(Coordinate coordinate, GLint mipLevel, InternalFormat internalFormat, T* image) { bind(); - DataHelper::set(static_cast(coordinate), mipLevel, internalFormat, image); + DataHelper<2>::set(static_cast(coordinate), mipLevel, internalFormat, image); } /** * @copydoc Texture::setSubData(GLint, const Math::Vector&, T*) - * @param coordinate Coordinate + * @param coordinate Coordinate */ - template inline void setSubData(Coordinate coordinate, GLint mipLevel, const Math::Vector& offset, const T* image) { + template inline void setSubData(Coordinate coordinate, GLint mipLevel, const Math::Vector& offset, const T* image) { bind(); - DataHelper::setSub(static_cast(coordinate), mipLevel, offset, image); + DataHelper<2>::setSub(static_cast(coordinate), mipLevel, offset, image); } }; diff --git a/src/Texture.h b/src/Texture.h index 69fc3fe56..b68adb235 100644 --- a/src/Texture.h +++ b/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 ARB_texture_rectangle (rectangle textures) + +@see CubeMapTexture */ template class Texture: public AbstractTexture { public: @@ -84,12 +86,7 @@ template class Texture: public AbstractTexture { * * @requires_gl31 Extension ARB_texture_rectangle */ - Rectangle = GL_TEXTURE_RECTANGLE, - - /** - * Cube map texture. Use CubeMapTexture class. - */ - CubeMap = GL_TEXTURE_CUBE_MAP + Rectangle = GL_TEXTURE_RECTANGLE }; #else typedef typename DataHelper::Target Target; /**< @brief %Texture target */ @@ -104,10 +101,10 @@ template class Texture: public AbstractTexture { * * Creates one OpenGL texture. */ - inline Texture(GLint layer = 0, Target target = DataHelper::target()): AbstractTexture(layer, static_cast(target)), _target(target) {} + inline Texture(GLint layer = 0, Target target = DataHelper::target()): AbstractTexture(layer, static_cast(target)) {} /** @brief %Texture target */ - inline Target target() const { return _target; } + inline Target target() const { return static_cast(_target); } /** * @brief Set wrapping @@ -157,9 +154,6 @@ template class Texture: public AbstractTexture { bind(); DataHelper::setSub(_target, mipLevel, offset, image); } - - private: - Target _target; }; /** @brief One-dimensional texture */