Browse Source

Implemented ARB_texture_storage.

Equivalent functionality is in ES3 and also EXT_texture_storage ES2
extension.
pull/7/head
Vladimír Vondruš 14 years ago
parent
commit
f83c2b601b
  1. 69
      src/AbstractTexture.cpp
  2. 48
      src/AbstractTexture.h
  3. 15
      src/CubeMapTexture.h
  4. 24
      src/CubeMapTextureArray.h
  5. 58
      src/Texture.h

69
src/AbstractTexture.cpp

@ -33,6 +33,14 @@ AbstractTexture::ParameterfvImplementation AbstractTexture::parameterfvImplement
AbstractTexture::MipmapImplementation AbstractTexture::mipmapImplementation = AbstractTexture::MipmapImplementation AbstractTexture::mipmapImplementation =
&AbstractTexture::mipmapImplementationDefault; &AbstractTexture::mipmapImplementationDefault;
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
AbstractTexture::Storage1DImplementation AbstractTexture::storage1DImplementation =
&AbstractTexture::storageImplementationDefault;
#endif
AbstractTexture::Storage2DImplementation AbstractTexture::storage2DImplementation =
&AbstractTexture::storageImplementationDefault;
AbstractTexture::Storage3DImplementation AbstractTexture::storage3DImplementation =
&AbstractTexture::storageImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
AbstractTexture::Image1DImplementation AbstractTexture::image1DImplementation = AbstractTexture::Image1DImplementation AbstractTexture::image1DImplementation =
&AbstractTexture::imageImplementationDefault; &AbstractTexture::imageImplementationDefault;
#endif #endif
@ -209,6 +217,9 @@ void AbstractTexture::initializeContextBasedFunctionality(Context* context) {
parameterfImplementation = &AbstractTexture::parameterImplementationDSA; parameterfImplementation = &AbstractTexture::parameterImplementationDSA;
parameterfvImplementation = &AbstractTexture::parameterImplementationDSA; parameterfvImplementation = &AbstractTexture::parameterImplementationDSA;
mipmapImplementation = &AbstractTexture::mipmapImplementationDSA; mipmapImplementation = &AbstractTexture::mipmapImplementationDSA;
storage1DImplementation = &AbstractTexture::storageImplementationDSA;
storage2DImplementation = &AbstractTexture::storageImplementationDSA;
storage3DImplementation = &AbstractTexture::storageImplementationDSA;
image1DImplementation = &AbstractTexture::imageImplementationDSA; image1DImplementation = &AbstractTexture::imageImplementationDSA;
image2DImplementation = &AbstractTexture::imageImplementationDSA; image2DImplementation = &AbstractTexture::imageImplementationDSA;
image3DImplementation = &AbstractTexture::imageImplementationDSA; image3DImplementation = &AbstractTexture::imageImplementationDSA;
@ -258,6 +269,64 @@ void AbstractTexture::parameterImplementationDSA(GLenum parameter, const GLfloat
glTextureParameterfvEXT(_id, _target, parameter, values); glTextureParameterfvEXT(_id, _target, parameter, values);
} }
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Math::Vector< 1, GLsizei >& size) {
bindInternal();
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
glTexStorage1D(target, levels, GLenum(internalFormat), size[0]);
#else
//glTexStorage2DEXT(target, levels, GLenum(internalFormat), size.x(), size.y());
static_cast<void>(target);
static_cast<void>(levels);
static_cast<void>(internalFormat);
static_cast<void>(size);
#endif
}
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Math::Vector< 1, GLsizei >& size) {
glTextureStorage1DEXT(_id, target, levels, GLenum(internalFormat), size[0]);
}
#endif
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Vector2i& size) {
bindInternal();
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
glTexStorage2D(target, levels, GLenum(internalFormat), size.x(), size.y());
#else
//glTexStorage2DEXT(target, levels, GLenum(internalFormat), size.x(), size.y());
static_cast<void>(target);
static_cast<void>(levels);
static_cast<void>(internalFormat);
static_cast<void>(size);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Vector2i& size) {
glTextureStorage2DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y());
}
#endif
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Vector3i& size) {
bindInternal();
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
glTexStorage3D(target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
#else
//glTexStorage3DEXT(target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
static_cast<void>(target);
static_cast<void>(levels);
static_cast<void>(internalFormat);
static_cast<void>(size);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Vector3i& size) {
glTextureStorage3DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
}
void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) { void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
bindInternal(); bindInternal();
glTexImage1D(target, level, static_cast<GLint>(internalFormat), size[0], 0, static_cast<GLenum>(format), static_cast<GLenum>(type), data); glTexImage1D(target, level, static_cast<GLint>(internalFormat), size[0], 0, static_cast<GLenum>(format), static_cast<GLenum>(type), data);

48
src/AbstractTexture.h

@ -42,16 +42,17 @@ repeated @fn_gl{Get} calls.
If extension @extension{EXT,direct_state_access} is available, bind() uses DSA If extension @extension{EXT,direct_state_access} is available, bind() uses DSA
function to avoid unnecessary calls to @fn_gl{ActiveTexture}. Also all texture function to avoid unnecessary calls to @fn_gl{ActiveTexture}. Also all texture
configuration functions use DSA functions to avoid unnecessary calls to configuration and data updating functions use DSA functions to avoid
@fn_gl{ActiveTexture} and @fn_gl{BindTexture}. See respective function unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. See
documentation for more information. respective function documentation for more information.
To achieve least state changes, fully configure each texture in one run -- To achieve least state changes, fully configure each texture in one run --
method chaining comes in handy -- and try to have often used textures in method chaining comes in handy -- and try to have often used textures in
dedicated layers, not occupied by other textures. dedicated layers, not occupied by other textures. First configure the texture
and *then* set the data, so OpenGL can optimize them to match the settings. To
Always fully configure the texture before setting the texture data, so OpenGL avoid redundant consistency checks and memory reallocations when updating
can optimize the data to match your settings. texture data, set texture storage at once using @ref Texture::setStorage() "setStorage()"
and then set data using @ref Texture::setSubImage() "setSubImage()".
You can use functions invalidateImage() and @ref Texture::invalidateSubImage() "invalidateSubImage()" You can use functions invalidateImage() and @ref Texture::invalidateSubImage() "invalidateSubImage()"
if you don't need texture data anymore to avoid unnecessary memory operations if you don't need texture data anymore to avoid unnecessary memory operations
@ -1187,6 +1188,27 @@ class MAGNUM_EXPORT AbstractTexture {
#endif #endif
static MAGNUM_LOCAL MipmapImplementation mipmapImplementation; static MAGNUM_LOCAL MipmapImplementation mipmapImplementation;
#ifndef MAGNUM_TARGET_GLES
typedef void(AbstractTexture::*Storage1DImplementation)(GLenum, GLsizei, InternalFormat, const Math::Vector<1, GLsizei>&);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size);
void MAGNUM_LOCAL storageImplementationDSA(GLenum target, GLsizei levels, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size);
static Storage1DImplementation storage1DImplementation;
#endif
typedef void(AbstractTexture::*Storage2DImplementation)(GLenum, GLsizei, InternalFormat, const Vector2i&);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, InternalFormat internalFormat, const Vector2i& size);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageImplementationDSA(GLenum target, GLsizei levels, InternalFormat internalFormat, const Vector2i& size);
#endif
static Storage2DImplementation storage2DImplementation;
typedef void(AbstractTexture::*Storage3DImplementation)(GLenum, GLsizei, InternalFormat, const Vector3i&);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, InternalFormat internalFormat, const Vector3i& size);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageImplementationDSA(GLenum target, GLsizei levels, InternalFormat internalFormat, const Vector3i& size);
#endif
static Storage3DImplementation storage3DImplementation;
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
typedef void(AbstractTexture::*Image1DImplementation)(GLenum, GLint, InternalFormat, const Math::Vector<1, GLsizei>&, AbstractImage::Format, AbstractImage::Type, const GLvoid*); typedef void(AbstractTexture::*Image1DImplementation)(GLenum, GLint, InternalFormat, const Math::Vector<1, GLsizei>&, AbstractImage::Format, AbstractImage::Type, const GLvoid*);
void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint level, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data); void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint level, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data);
@ -1262,6 +1284,10 @@ template<> struct AbstractTexture::DataHelper<1> {
(texture->*parameteriImplementation)(GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping.x())); (texture->*parameteriImplementation)(GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping.x()));
} }
inline static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
(texture->*storage1DImplementation)(target, levels, internalFormat, size);
}
template<class Image> inline static typename std::enable_if<Image::Dimensions == 1, void>::type set(AbstractTexture* texture, GLenum target, GLint level, InternalFormat internalFormat, Image* image) { template<class Image> inline static typename std::enable_if<Image::Dimensions == 1, void>::type set(AbstractTexture* texture, GLenum target, GLint level, InternalFormat internalFormat, Image* image) {
(texture->*image1DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), image->data()); (texture->*image1DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), image->data());
} }
@ -1289,6 +1315,10 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
static void setWrapping(AbstractTexture* texture, const Array2D<Wrapping>& wrapping); static void setWrapping(AbstractTexture* texture, const Array2D<Wrapping>& wrapping);
inline static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, InternalFormat internalFormat, const Vector2i& size) {
(texture->*storage2DImplementation)(target, levels, internalFormat, size);
}
template<class Image> inline static typename std::enable_if<Image::Dimensions == 2, void>::type set(AbstractTexture* texture, GLenum target, GLint level, InternalFormat internalFormat, Image* image) { template<class Image> inline static typename std::enable_if<Image::Dimensions == 2, void>::type set(AbstractTexture* texture, GLenum target, GLint level, InternalFormat internalFormat, Image* image) {
(texture->*image2DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), image->data()); (texture->*image2DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), image->data());
} }
@ -1319,6 +1349,10 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
static void setWrapping(AbstractTexture* texture, const Array3D<Wrapping>& wrapping); static void setWrapping(AbstractTexture* texture, const Array3D<Wrapping>& wrapping);
inline static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, InternalFormat internalFormat, const Vector3i& size) {
(texture->*storage3DImplementation)(target, levels, internalFormat, size);
}
template<class Image> inline static typename std::enable_if<Image::Dimensions == 3, void>::type set(AbstractTexture* texture, GLenum target, GLint level, InternalFormat internalFormat, Image* image) { template<class Image> inline static typename std::enable_if<Image::Dimensions == 3, void>::type set(AbstractTexture* texture, GLenum target, GLint level, InternalFormat internalFormat, Image* image) {
(texture->*image3DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), image->data()); (texture->*image3DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), image->data());
} }

15
src/CubeMapTexture.h

@ -51,8 +51,9 @@ Image2D positiveX({256, 256}, Image2D::Components::RGBA, Image2D::ComponentType:
CubeMapTexture texture; CubeMapTexture texture;
texture.setMagnificationFilter(Texture2D::Filter::Linear) texture.setMagnificationFilter(Texture2D::Filter::Linear)
// ... // ...
->setImage(CubeMapTexture::Coordinate::PositiveX, 0, Texture2D::Format::RGBA8, &positiveX) ->setStorage(Math::log2(256)+1, Texture2D::Format::RGBA8, {256, 256})
->setImage(CubeMapTexture::Coordinate::NegativeX, 0, Texture2D::Format::RGBA8, &negativeX) ->setSubImage(CubeMapTexture::Coordinate::PositiveX, 0, {}, &positiveX)
->setSubImage(CubeMapTexture::Coordinate::NegativeX, 0, {}, &negativeX)
// ... // ...
@endcode @endcode
@ -109,6 +110,16 @@ class CubeMapTexture: public AbstractTexture {
return this; return this;
} }
/**
* @brief Set storage
*
* See Texture::setStorage() for more information.
*/
inline CubeMapTexture* setStorage(GLsizei levels, InternalFormat internalFormat, const Vector2i& size) {
DataHelper<2>::setStorage(this, _target, levels, internalFormat, size);
return this;
}
/** /**
* @brief Set image data * @brief Set image data
* @param coordinate Coordinate * @param coordinate Coordinate

24
src/CubeMapTextureArray.h

@ -34,24 +34,24 @@ See CubeMapTexture documentation for introduction.
@section CubeMapTextureArray-usage Usage @section CubeMapTextureArray-usage Usage
Common usage is to specify each layer and face separately using setSubImage(). Common usage is to specify each layer and face separately using setSubImage().
You have to allocate the memory for all layers and faces first, possibly by You have to allocate the memory for all layers and faces first either by
passing properly sized empty Image to setImage(). Example: array with 16 calling setStorage() or by passing properly sized empty Image to setImage().
layers of cube map faces, each face consisting of six 64x64 images: Example: array with 16 layers of cube map faces, each face consisting of six
64x64 images:
@code @code
Image3D dummy({64, 64, 16*6}, Image3D::Components::RGBA, Image3D::ComponentType::UnsignedByte, nullptr); Image3D dummy({64, 64, 16*6}, Image3D::Components::RGBA, Image3D::ComponentType::UnsignedByte, nullptr);
CubeMapTextureArray texture; CubeMapTextureArray texture;
texture.setMagnificationFilter(CubeMapTextureArray::Filter::Linear) texture.setMagnificationFilter(CubeMapTextureArray::Filter::Linear)
// ... // ...
->setImage(0, CubeMapTextureArray::Format::RGBA8, &dummy); ->setStorage(Math::log2(64)+1, CubeMapTextureArray::Format::RGBA8, {64, 64, 16});
for(std::size_t i = 0; i != 16; ++i) { for(std::size_t i = 0; i != 16; ++i) {
void* dataPositiveX = ...; void* dataPositiveX = ...;
Image2D imagePositiveX({64, 64}, Image3D::Components::RGBA, Image3D::ComponentType::UnsignedByte, imagePositiveX); Image2D imagePositiveX({64, 64}, Image3D::Components::RGBA, Image3D::ComponentType::UnsignedByte, imagePositiveX);
// ... // ...
texture->setSubImage(i, CubeMapTextureArray::Coordinate::PositiveX, 0, {}, imagePositiveX);
texture->setSubImage(i, CubeMapTextureArray::Coordinate::PositiveX, 0, imagePositiveX); texture->setSubImage(i, CubeMapTextureArray::Coordinate::NegativeX, 0, {}, imageNegativeX);
texture->setSubImage(i, CubeMapTextureArray::Coordinate::NegativeX, 0, imageNegativeX);
// ... // ...
} }
@ -99,6 +99,16 @@ class CubeMapTextureArray: public AbstractTexture {
return this; return this;
} }
/**
* @brief Set storage
*
* See Texture::setStorage() for more information.
*/
inline CubeMapTextureArray* setStorage(GLsizei levels, InternalFormat internalFormat, const Vector3i& size) {
DataHelper<3>::setStorage(this, _target, levels, internalFormat, size);
return this;
}
/** /**
* @brief Set image data * @brief Set image data
* @param level Mip level * @param level Mip level

58
src/Texture.h

@ -44,17 +44,18 @@ texture.setMagnificationFilter(Texture2D::Filter::Linear)
->setMinificationFilter(Texture2D::Filter::Linear, Texture2D::Mipmap::Linear) ->setMinificationFilter(Texture2D::Filter::Linear, Texture2D::Mipmap::Linear)
->setWrapping(Texture2D::Wrapping::ClampToEdge) ->setWrapping(Texture2D::Wrapping::ClampToEdge)
->setMaxAnisotropy(Texture2D::maxSupportedAnisotropy) ->setMaxAnisotropy(Texture2D::maxSupportedAnisotropy)
->setImage(0, Texture2D::Format::RGBA8, &image) ->setStorage(Math::log2(4096)+1, Texture2D::Format::RGBA8, {4096, 4096})
->setSubImage(0, {}, &image)
->generateMipmap(); ->generateMipmap();
@endcode @endcode
@attention Don't forget to fully configure the texture before use. Note that @attention Don't forget to fully configure the texture before use. Note that
default configuration (if setMinificationFilter() is not called with default configuration (if setMinificationFilter() is not called with
another value) is to use mipmaps, so be sure to either call setMinificationFilter(), another value) is to use mipmaps, so be sure to either call setMinificationFilter(),
explicitly set all mip levels or call generateMipmap(). If using rectangle explicitly specify all mip levels with setStorage() and setImage() or call
texture, you must also call setWrapping(), because the initial value is generateMipmap(). If using rectangle texture, you must also call
not supported on rectangle textures. See also setMagnificationFilter() and setWrapping(), because the initial value is not supported on rectangle
setBorderColor(). textures. See also setMagnificationFilter() and setBorderColor().
The texture is bound to layer specified by shader via bind(). In shader, the The texture is bound to layer specified by shader via bind(). In shader, the
texture is used via `sampler1D`, `sampler2D` or `sampler3D` depending on texture is used via `sampler1D`, `sampler2D` or `sampler3D` depending on
@ -67,16 +68,14 @@ You can create texture arrays by passing @ref Texture::Target "Texture2D::Target
or @ref Texture::Target "Texture3D::Target::Texture2DArray" to constructor. or @ref Texture::Target "Texture3D::Target::Texture2DArray" to constructor.
It is possible to specify each layer separately using setSubImage(), but you It is possible to specify each layer separately using setSubImage(), but you
have to allocate the memory for all layers first, possibly by passing properly have to allocate the memory for all layers first either by calling setStorage()
sized empty Image to setImage(). Example: 2D texture array with 16 layers of or by passing properly sized empty Image to setImage(). Example: 2D texture
64x64 images: array with 16 layers of 64x64 images:
@code @code
Image3D dummy({64, 64, 16}, Image3D::Components::RGBA, Image3D::ComponentType::UnsignedByte, nullptr);
Texture3D texture(Texture3D::Target::Texture2DArray); Texture3D texture(Texture3D::Target::Texture2DArray);
texture.setMagnificationFilter(Texture2D::Filter::Linear) texture.setMagnificationFilter(Texture2D::Filter::Linear)
// ... // ...
->setImage(0, Texture2D::Format::RGBA8, &dummy); ->setStorage(levels, Texture2D::Format::RGBA8, {64, 64,16});
for(std::size_t i = 0; i != 16; ++i) { for(std::size_t i = 0; i != 16; ++i) {
void* data = ...; void* data = ...;
@ -198,6 +197,33 @@ template<std::uint8_t dimensions> class Texture: public AbstractTexture {
return this; return this;
} }
/**
* @brief Set storage
* @param levels Mip level count
* @param internalFormat Internal format
* @param size Size of largest mip level
* @return Pointer to self (for method chaining)
*
* Specifies entire structure of a texture at once, removing the need
* for additional consistency checks and memory reallocations when
* updating the data later. After calling this function the texture
* is immutable and calling setStorage() or setImage() is not allowed.
*
* If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some layer before the operation.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexStorage1D}/@fn_gl{TexStorage2D}/@fn_gl{TexStorage3D}
* or @fn_gl_extension{TextureStorage1D,EXT,direct_state_access}/
* @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureStorage3D,EXT,direct_state_access}
* @requires_gl42 %Extension @extension{ARB,texture_storage}
* @requires_gles30 %Extension @es_extension{EXT,texture_storage}
*/
inline Texture<Dimensions>* setStorage(GLsizei levels, InternalFormat internalFormat, const typename DimensionTraits<Dimensions, GLint>::VectorType& size) {
DataHelper<Dimensions>::setStorage(this, _target, levels, internalFormat, size);
return this;
}
/** /**
* @brief Set image data * @brief Set image data
* @param level Mip level * @param level Mip level
@ -208,9 +234,13 @@ template<std::uint8_t dimensions> class Texture: public AbstractTexture {
* *
* The image is not deleted afterwards. * The image is not deleted afterwards.
* *
* For better performance when generating mipmaps using
* generateMipmap() or calling setImage() more than once use
* setStorage() and setSubImage() instead.
*
* If @extension{EXT,direct_state_access} is not available, the * If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some layer before the operation. * texture is bound to some layer before the operation.
* @see setSubImage(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexImage1D}/@fn_gl{TexImage2D}/@fn_gl{TexImage3D} or * @fn_gl{TexImage1D}/@fn_gl{TexImage2D}/@fn_gl{TexImage3D} or
* @fn_gl_extension{TextureImage1D,EXT,direct_state_access}/ * @fn_gl_extension{TextureImage1D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/
@ -240,8 +270,8 @@ template<std::uint8_t dimensions> class Texture: public AbstractTexture {
* *
* If @extension{EXT,direct_state_access} is not available, the * If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some layer before the operation. * texture is bound to some layer before the operation.
* @see setImage(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and * @see setStorage(), setImage(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture}
* @fn_gl{TexSubImage1D}/@fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D} * and @fn_gl{TexSubImage1D}/@fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D}
* or @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}/ * or @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}/
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access}

Loading…
Cancel
Save