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 */