diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index 9485d8a47..354fa642b 100644 --- a/src/AbstractTexture.h +++ b/src/AbstractTexture.h @@ -236,6 +236,22 @@ class AbstractTexture { * on dimension count. */ template inline static void set(GLenum target, GLint mipLevel, int internalFormat, const Math::Vector& dimensions, ColorFormat colorFormat, const T* data); + + /** + * @brief Set texture subdata + * @param target Target, such as @c GL_TEXTURE_RECTANGLE + * @param mipLevel Mip level + * @param offset Offset where to put data in the texture + * @param dimensions %Texture dimensions + * @param colorFormat Color format of passed data. Data size + * per color channel is detected from format of passed data + * array. + * @param data %Texture data + * + * Calls @c glTexSubImage1D, @c glTexSubImage2D, @c glTexSubImage3D + * depending on dimension count. + */ + template inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector& offset, const Math::Vector& dimensions, ColorFormat colorFormat, const T* data); #endif }; @@ -251,6 +267,10 @@ template<> struct AbstractTexture::DataHelper<1> { template inline static void set(GLenum target, GLint mipLevel, int internalFormat, const Math::Vector& dimensions, ColorFormat colorFormat, const T* data) { glTexImage1D(target, mipLevel, internalFormat, dimensions.at(0), 0, colorFormat, TypeTraits::glType(), data); } + + template inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector& offset, const Math::Vector& dimensions, ColorFormat colorFormat, const T* data) { + glTexSubImage1D(target, mipLevel, offset.at(0), dimensions.at(0), colorFormat, TypeTraits::glType(), data); + } }; template<> struct AbstractTexture::DataHelper<2> { inline constexpr static GLenum target() { return GL_TEXTURE_2D; } @@ -258,6 +278,10 @@ template<> struct AbstractTexture::DataHelper<2> { template inline static void set(GLenum target, GLint mipLevel, int internalFormat, const Math::Vector& dimensions, ColorFormat colorFormat, const T* data) { glTexImage2D(target, mipLevel, internalFormat, dimensions.at(0), dimensions.at(1), 0, colorFormat, TypeTraits::glType(), data); } + + template inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector& offset, const Math::Vector& dimensions, ColorFormat colorFormat, const T* data) { + glTexSubImage2D(target, mipLevel, offset.at(0), offset.at(1), dimensions.at(0), dimensions.at(1), colorFormat, TypeTraits::glType(), data); + } }; template<> struct AbstractTexture::DataHelper<3> { inline constexpr static GLenum target() { return GL_TEXTURE_3D; } @@ -265,6 +289,10 @@ template<> struct AbstractTexture::DataHelper<3> { template inline static void set(GLenum target, GLint mipLevel, int internalFormat, const Math::Vector& dimensions, ColorFormat colorFormat, const T* data) { glTexImage3D(target, mipLevel, internalFormat, dimensions.at(0), dimensions.at(1), dimensions.at(2), 0, colorFormat, TypeTraits::glType(), data); } + + template inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector& offset, const Math::Vector& dimensions, ColorFormat colorFormat, const T* data) { + glTexSubImage3D(target, mipLevel, offset.at(0), offset.at(1), offset.at(2), dimensions.at(0), dimensions.at(1), dimensions.at(2), colorFormat, TypeTraits::glType(), data); + } }; #endif diff --git a/src/CubeMapTexture.h b/src/CubeMapTexture.h index 4c40ba4bf..e88987aa9 100644 --- a/src/CubeMapTexture.h +++ b/src/CubeMapTexture.h @@ -58,6 +58,9 @@ class CubeMapTexture: public Texture2D { /** @brief Deleted. Use setDataPositiveX() and others instead. */ template inline void setData(GLint mipLevel, int internalFormat, const Math::Vector& _dimensions, ColorFormat colorFormat, const T* data) = delete; + /** @brief Deleted. Use setSubDataPositiveX() and others instead. */ + template inline void setSubData(GLint mipLevel, const Math::Vector& offset, const Math::Vector& _dimensions, ColorFormat colorFormat, const T* data) = delete; + /** * @brief Set texture data for positive X * @@ -67,6 +70,15 @@ class CubeMapTexture: public Texture2D { setData(GL_TEXTURE_CUBE_MAP_POSITIVE_X, mipLevel, internalFormat, _dimensions, colorFormat, data); } + /** + * @brief Set texture subdata for positive X + * + * @copydetails Texture::setSubData() + */ + template inline void setSubDataPositiveX(GLint mipLevel, const Math::Vector& offset, const Math::Vector& _dimensions, ColorFormat colorFormat, const T* data) { + setSubData(GL_TEXTURE_CUBE_MAP_POSITIVE_X, mipLevel, offset, _dimensions, colorFormat, data); + } + /** * @brief Set texture data for negative X * @@ -76,6 +88,15 @@ class CubeMapTexture: public Texture2D { setData(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, mipLevel, internalFormat, _dimensions, colorFormat, data); } + /** + * @brief Set texture subdata for negative X + * + * @copydetails Texture::setSubData() + */ + template inline void setSubDataNegativeX(GLint mipLevel, const Math::Vector& offset, const Math::Vector& _dimensions, ColorFormat colorFormat, const T* data) { + setSubData(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, mipLevel, offset, _dimensions, colorFormat, data); + } + /** * @brief Set texture data for positive Y * @@ -85,6 +106,15 @@ class CubeMapTexture: public Texture2D { setData(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mipLevel, internalFormat, _dimensions, colorFormat, data); } + /** + * @brief Set texture subdata for positive Y + * + * @copydetails Texture::setSubData() + */ + template inline void setSubDataPositiveY(GLint mipLevel, const Math::Vector& offset, const Math::Vector& _dimensions, ColorFormat colorFormat, const T* data) { + setSubData(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mipLevel, offset, _dimensions, colorFormat, data); + } + /** * @brief Set texture data for negative Y * @@ -94,6 +124,15 @@ class CubeMapTexture: public Texture2D { setData(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, mipLevel, internalFormat, _dimensions, colorFormat, data); } + /** + * @brief Set texture subdata for negative Y + * + * @copydetails Texture::setSubData() + */ + template inline void setSubDataNegativeY(GLint mipLevel, const Math::Vector& offset, const Math::Vector& _dimensions, ColorFormat colorFormat, const T* data) { + setSubData(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, mipLevel, offset, _dimensions, colorFormat, data); + } + /** * @brief Set texture data for positive Z * @@ -103,6 +142,15 @@ class CubeMapTexture: public Texture2D { setData(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, mipLevel, internalFormat, _dimensions, colorFormat, data); } + /** + * @brief Set texture subdata for positive Z + * + * @copydetails Texture::setSubData() + */ + template inline void setSubDataPositiveZ(GLint mipLevel, const Math::Vector& offset, const Math::Vector& _dimensions, ColorFormat colorFormat, const T* data) { + setSubData(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, mipLevel, offset, _dimensions, colorFormat, data); + } + /** * @brief Set texture data for negative Z * @@ -112,12 +160,27 @@ class CubeMapTexture: public Texture2D { setData(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, mipLevel, internalFormat, _dimensions, colorFormat, data); } + /** + * @brief Set texture subdata for negative Z + * + * @copydetails Texture::setSubData() + */ + template inline void setSubDataNegativeZ(GLint mipLevel, const Math::Vector& offset, const Math::Vector& _dimensions, ColorFormat colorFormat, const T* data) { + setSubData(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, mipLevel, offset, _dimensions, colorFormat, data); + } + private: template void setData(GLenum target, GLint mipLevel, int internalFormat, const Math::Vector& _dimensions, ColorFormat colorFormat, const T* data) { bind(); DataHelper::template set::TextureType>(target, mipLevel, internalFormat, _dimensions, colorFormat, data); unbind(); } + + template void setSubData(GLenum target, GLint mipLevel, const Math::Vector& offset, const Math::Vector& dimensions, ColorFormat colorFormat, const T* data) { + bind(); + DataHelper::template setSub::TextureType>(target, mipLevel, dimensions, colorFormat, data); + unbind(); + } }; } diff --git a/src/Texture.h b/src/Texture.h index f92559e18..bd51cb285 100644 --- a/src/Texture.h +++ b/src/Texture.h @@ -92,6 +92,21 @@ template class Texture: public AbstractTexture { DataHelper::template set::TextureType>(target, mipLevel, internalFormat, _dimensions, colorFormat, data); unbind(); } + + /** + * @brief Set texture subdata + * @param mipLevel + * @param offset Offset where to put data in the texture + * @param _dimensions %Texture dimensions + * @param colorFormat Color format of passed data. Data size per + * color channel is detected from format of passed data array. + * @param data %Texture data + */ + template inline void setSubData(GLint mipLevel, const Math::Vector& offset, const Math::Vector& _dimensions, ColorFormat colorFormat, const T* data) { + bind(); + DataHelper::template setSub::TextureType>(target, mipLevel, offset, _dimensions, colorFormat, data); + unbind(); + } }; /** @brief One-dimensional texture */