Browse Source

Full ARB_direct_state_access support in textures.

ARB_DSA is now preferred in single-bind cases, as it is easier to use
than passing pointers to ARB_multi_bind. ARB_multi_bind was preferred
for single-bind previously simply because EXT_DSA was not in core.

Because there is a lot to say about feature selection for each function,
I took this as a opportunity to remove redundant documentation blocks,
just refer to Texture documentation from everywhere and add extension
requirements and deprecation where needed, so it's clear for each class
what needs what.

ARB_DSA also took the opportunity to finally remove all target enum
values from function calls and because of that the CubeMapTexture has to
handle a bunch of special cases. In order:

-   CubeMapTexture::imageSize() now doesn't take face parameter and
    returns one value for all faces. I'm thus now also assuming that the
    user is sane and called either setStorage() or setImage() with the
    same size for all faces. In non-ARB_DSA path I'm thus querying only
    size of +X face and returning it as size for all faces. The old
    imageSize(Coordinate, Int) overload is still present, but ignores
    the first parameter and calls imageSize(Int). It is marked as
    deprecated and will be removed in some future release.
-   CubeMapTexture::image() now needs to call glTextureSubImage() in
    ARB_DSA path to make it possible to extract single face. Other code
    paths (EXT_DSA, Robustness and "default") remain the same.
-   CubeMapTexture::setSubImage() calls glTextureSubImage3D() in
    ARB_DSA, because it is not possible to specify face index in
    glTextureSubImage2D(). Other code paths (EXT_DSA and "default")
    remain the same.

Implementation of these special cases is extracted into CubeMapTexture
class to avoid pollution of AbstractTexture with incompatible nonsense.
pull/77/head
Vladimír Vondruš 12 years ago
parent
commit
a5381993a5
  1. 319
      src/Magnum/AbstractTexture.cpp
  2. 191
      src/Magnum/AbstractTexture.h
  3. 8
      src/Magnum/BufferTexture.cpp
  4. 31
      src/Magnum/BufferTexture.h
  5. 122
      src/Magnum/CubeMapTexture.cpp
  6. 283
      src/Magnum/CubeMapTexture.h
  7. 136
      src/Magnum/CubeMapTextureArray.h
  8. 97
      src/Magnum/Implementation/TextureState.cpp
  9. 31
      src/Magnum/Implementation/TextureState.h
  10. 65
      src/Magnum/MultisampleTexture.h
  11. 187
      src/Magnum/RectangleTexture.h
  12. 63
      src/Magnum/Test/CubeMapTextureGLTest.cpp
  13. 411
      src/Magnum/Texture.h
  14. 263
      src/Magnum/TextureArray.h

319
src/Magnum/AbstractTexture.cpp

@ -143,6 +143,13 @@ void AbstractTexture::unbindImplementationMulti(const GLint textureUnit) {
glBindTextures(textureUnit, 1, &zero);
}
void AbstractTexture::unbindImplementationDSA(const GLint textureUnit) {
Implementation::TextureState& textureState = *Context::current()->state().texture;
CORRADE_INTERNAL_ASSERT(textureState.bindings[textureUnit].first != 0);
glBindTextureUnit(textureUnit, 0);
}
void AbstractTexture::unbindImplementationDSAEXT(const GLint textureUnit) {
Implementation::TextureState& textureState = *Context::current()->state().texture;
@ -274,6 +281,10 @@ void AbstractTexture::bindImplementationMulti(GLint textureUnit) {
glBindTextures(textureUnit, 1, &_id);
}
void AbstractTexture::bindImplementationDSA(const GLint textureUnit) {
glBindTextureUnit(textureUnit, _id);
}
void AbstractTexture::bindImplementationDSAEXT(GLint textureUnit) {
_created = true;
glBindMultiTextureEXT(GL_TEXTURE0 + textureUnit, _target, _id);
@ -401,6 +412,10 @@ void AbstractTexture::mipmapImplementationDefault() {
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::mipmapImplementationDSA() {
glGenerateTextureMipmap(_id);
}
void AbstractTexture::mipmapImplementationDSAEXT() {
_created = true;
glGenerateTextureMipmapEXT(_id, _target);
@ -810,6 +825,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLint val
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLint value) {
glTextureParameteri(_id, parameter, value);
}
void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, GLint value) {
_created = true;
glTextureParameteriEXT(_id, _target, parameter, value);
@ -822,6 +841,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLfloat v
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLfloat value) {
glTextureParameterf(_id, parameter, value);
}
void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, GLfloat value) {
_created = true;
glTextureParameterfEXT(_id, _target, parameter, value);
@ -835,6 +858,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLi
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLint* const values) {
glTextureParameteriv(_id, parameter, values);
}
void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, const GLint* values) {
_created = true;
glTextureParameterivEXT(_id, _target, parameter, values);
@ -848,6 +875,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLf
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLfloat* const values) {
glTextureParameterfv(_id, parameter, values);
}
void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, const GLfloat* values) {
_created = true;
glTextureParameterfvEXT(_id, _target, parameter, values);
@ -860,6 +891,10 @@ void AbstractTexture::parameterIImplementationDefault(GLenum parameter, const GL
glTexParameterIuiv(_target, parameter, values);
}
void AbstractTexture::parameterIImplementationDSA(const GLenum parameter, const GLuint* const values) {
glTextureParameterIuiv(_id, parameter, values);
}
void AbstractTexture::parameterIImplementationDSAEXT(GLenum parameter, const GLuint* values) {
_created = true;
glTextureParameterIuivEXT(_id, _target, parameter, values);
@ -870,6 +905,10 @@ void AbstractTexture::parameterIImplementationDefault(GLenum parameter, const GL
glTexParameterIiv(_target, parameter, values);
}
void AbstractTexture::parameterIImplementationDSA(const GLenum parameter, const GLint* const values) {
glTextureParameterIiv(_id, parameter, values);
}
void AbstractTexture::parameterIImplementationDSAEXT(GLenum parameter, const GLint* values) {
_created = true;
glTextureParameterIivEXT(_id, _target, parameter, values);
@ -883,59 +922,65 @@ void AbstractTexture::setMaxAnisotropyImplementationExt(GLfloat anisotropy) {
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::getLevelParameterImplementationDefault(GLenum target, GLint level, GLenum parameter, GLint* values) {
void AbstractTexture::getLevelParameterImplementationDefault(GLint level, GLenum parameter, GLint* values) {
bindInternal();
glGetTexLevelParameteriv(target, level, parameter, values);
glGetTexLevelParameteriv(_target, level, parameter, values);
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::getLevelParameterImplementationDSAEXT(GLenum target, GLint level, GLenum parameter, GLint* values) {
void AbstractTexture::getLevelParameterImplementationDSA(const GLint level, const GLenum parameter, GLint* const values) {
glGetTextureLevelParameteriv(_id, level, parameter, values);
}
void AbstractTexture::getLevelParameterImplementationDSAEXT(GLint level, GLenum parameter, GLint* values) {
_created = true;
glGetTextureLevelParameterivEXT(_id, target, level, parameter, values);
glGetTextureLevelParameterivEXT(_id, _target, level, parameter, values);
}
#endif
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageImplementationFallback(const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
CORRADE_INTERNAL_ASSERT(target == GL_TEXTURE_1D);
void AbstractTexture::storageImplementationFallback(const GLsizei levels, const TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
const ColorFormat format = imageFormatForInternalFormat(internalFormat);
const ColorType type = imageTypeForInternalFormat(internalFormat);
for(GLsizei level = 0; level != levels; ++level)
DataHelper<1>::setImage(*this, target, level, internalFormat,
DataHelper<1>::setImage(*this, level, internalFormat,
ImageReference1D{format, type, Math::max(Math::Vector<1, GLsizei>(1), size >> level)});
}
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
void AbstractTexture::storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
bindInternal();
glTexStorage1D(target, levels, GLenum(internalFormat), size[0]);
glTexStorage1D(_target, levels, GLenum(internalFormat), size[0]);
}
void AbstractTexture::storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
void AbstractTexture::storageImplementationDSA(const GLsizei levels, const TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
glTextureStorage1D(_id, levels, GLenum(internalFormat), size[0]);
}
void AbstractTexture::storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
_created = true;
glTextureStorage1DEXT(_id, target, levels, GLenum(internalFormat), size[0]);
glTextureStorage1DEXT(_id, _target, levels, GLenum(internalFormat), size[0]);
}
#endif
void AbstractTexture::storageImplementationFallback(const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) {
void AbstractTexture::storageImplementationFallback(const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) {
const ColorFormat format = imageFormatForInternalFormat(internalFormat);
const ColorType type = imageTypeForInternalFormat(internalFormat);
/* Common code for classic types */
#ifndef MAGNUM_TARGET_GLES
if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE)
if(_target == GL_TEXTURE_2D || _target == GL_TEXTURE_RECTANGLE)
#else
if(target == GL_TEXTURE_2D)
if(_target == GL_TEXTURE_2D)
#endif
{
for(GLsizei level = 0; level != levels; ++level)
DataHelper<2>::setImage(*this, target, level, internalFormat,
DataHelper<2>::setImage(*this, level, internalFormat,
ImageReference2D{format, type, Math::max(Vector2i(1), size >> level)});
/* Cube map additionally needs to specify all faces */
} else if(target == GL_TEXTURE_CUBE_MAP) {
} else if(_target == GL_TEXTURE_CUBE_MAP) {
for(GLsizei level = 0; level != levels; ++level) {
for(GLenum face: {GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
@ -949,9 +994,9 @@ void AbstractTexture::storageImplementationFallback(const GLenum target, const G
#ifndef MAGNUM_TARGET_GLES
/* Array texture is not scaled in "layer" dimension */
} else if(target == GL_TEXTURE_1D_ARRAY) {
} else if(_target == GL_TEXTURE_1D_ARRAY) {
for(GLsizei level = 0; level != levels; ++level)
DataHelper<2>::setImage(*this, target, level, internalFormat,
DataHelper<2>::setImage(*this, level, internalFormat,
ImageReference2D{format, type, Vector2i{Math::max(1, size.x() >> level), size.y()}});
#endif
@ -959,14 +1004,13 @@ void AbstractTexture::storageImplementationFallback(const GLenum target, const G
} else CORRADE_ASSERT_UNREACHABLE();
}
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) {
void AbstractTexture::storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector2i& size) {
bindInternal();
#ifndef MAGNUM_TARGET_GLES2
glTexStorage2D(target, levels, GLenum(internalFormat), size.x(), size.y());
glTexStorage2D(_target, levels, GLenum(internalFormat), size.x(), size.y());
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glTexStorage2DEXT(target, levels, GLenum(internalFormat), size.x(), size.y());
glTexStorage2DEXT(_target, levels, GLenum(internalFormat), size.x(), size.y());
#else
static_cast<void>(target);
static_cast<void>(levels);
static_cast<void>(internalFormat);
static_cast<void>(size);
@ -975,35 +1019,39 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) {
void AbstractTexture::storageImplementationDSA(const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) {
glTextureStorage2D(_id, levels, GLenum(internalFormat), size.x(), size.y());
}
void AbstractTexture::storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Vector2i& size) {
_created = true;
glTextureStorage2DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y());
glTextureStorage2DEXT(_id, _target, levels, GLenum(internalFormat), size.x(), size.y());
}
#endif
void AbstractTexture::storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) {
void AbstractTexture::storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Vector3i& size) {
const ColorFormat format = imageFormatForInternalFormat(internalFormat);
const ColorType type = imageTypeForInternalFormat(internalFormat);
/* Common code for classic type */
#ifndef MAGNUM_TARGET_GLES2
if(target == GL_TEXTURE_3D)
if(_target == GL_TEXTURE_3D)
#else
if(target == GL_TEXTURE_3D_OES)
if(_target == GL_TEXTURE_3D_OES)
#endif
for(GLsizei level = 0; level != levels; ++level)
DataHelper<3>::setImage(*this, target, level, internalFormat,
DataHelper<3>::setImage(*this, level, internalFormat,
ImageReference3D{format, type, Math::max(Vector3i(1), size >> level)});
#ifndef MAGNUM_TARGET_GLES2
/* Array texture is not scaled in "layer" dimension */
#ifndef MAGNUM_TARGET_GLES
else if(target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY)
else if(_target == GL_TEXTURE_2D_ARRAY || _target == GL_TEXTURE_CUBE_MAP_ARRAY)
#else
else if(target == GL_TEXTURE_2D_ARRAY)
else if(_target == GL_TEXTURE_2D_ARRAY)
#endif
for(GLsizei level = 0; level != levels; ++level)
DataHelper<3>::setImage(*this, target, level, internalFormat,
DataHelper<3>::setImage(*this, level, internalFormat,
ImageReference3D{format, type, Vector3i{Math::max(Vector2i{1}, size.xy() >> level), size.z()}});
#endif
@ -1011,14 +1059,13 @@ void AbstractTexture::storageImplementationFallback(GLenum target, GLsizei level
else CORRADE_ASSERT_UNREACHABLE();
}
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) {
void AbstractTexture::storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector3i& size) {
bindInternal();
#ifndef MAGNUM_TARGET_GLES2
glTexStorage3D(target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
glTexStorage3D(_target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glTexStorage3DEXT(target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
glTexStorage3DEXT(_target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
#else
static_cast<void>(target);
static_cast<void>(levels);
static_cast<void>(internalFormat);
static_cast<void>(size);
@ -1027,97 +1074,120 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) {
void AbstractTexture::storageImplementationDSA(const GLsizei levels, const TextureFormat internalFormat, const Vector3i& size) {
glTextureStorage3D(_id, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
}
void AbstractTexture::storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Vector3i& size) {
_created = true;
glTextureStorage3DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
glTextureStorage3DEXT(_id, _target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageMultisampleImplementationFallback(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
void AbstractTexture::storageMultisampleImplementationFallback(const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
bindInternal();
glTexImage2DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
glTexImage2DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
}
#endif
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::storageMultisampleImplementationDefault(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
void AbstractTexture::storageMultisampleImplementationDefault(const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
bindInternal();
glTexStorage2DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
glTexStorage2DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
void AbstractTexture::storageMultisampleImplementationDSA(const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
glTextureStorage2DMultisample(_id, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
}
void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
_created = true;
glTextureStorage2DMultisampleEXT(_id, target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
glTextureStorage2DMultisampleEXT(_id, _target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
}
void AbstractTexture::storageMultisampleImplementationFallback(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
void AbstractTexture::storageMultisampleImplementationFallback(const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
bindInternal();
glTexImage3DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations);
glTexImage3DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations);
}
void AbstractTexture::storageMultisampleImplementationDefault(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
void AbstractTexture::storageMultisampleImplementationDefault(const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
bindInternal();
glTexStorage3DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations);
glTexStorage3DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations);
}
void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
void AbstractTexture::storageMultisampleImplementationDSA(const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
glTextureStorage3DMultisample(_id, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations);
}
void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
_created = true;
glTextureStorage3DMultisampleEXT(_id, target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations);
glTextureStorage3DMultisampleEXT(_id, _target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::getImageImplementationDefault(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) {
void AbstractTexture::getImageImplementationDefault(const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) {
bindInternal();
glGetTexImage(target, level, GLenum(format), GLenum(type), data);
glGetTexImage(_target, level, GLenum(format), GLenum(type), data);
}
void AbstractTexture::getImageImplementationDSAEXT(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) {
void AbstractTexture::getImageImplementationDSA(const GLint level, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) {
glGetTextureImage(_id, level, GLenum(format), GLenum(type), dataSize, data);
}
void AbstractTexture::getImageImplementationDSAEXT(const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) {
_created = true;
glGetTextureImageEXT(_id, target, level, GLenum(format), GLenum(type), data);
glGetTextureImageEXT(_id, _target, level, GLenum(format), GLenum(type), data);
}
void AbstractTexture::getImageImplementationRobustness(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) {
void AbstractTexture::getImageImplementationRobustness(const GLint level, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) {
bindInternal();
glGetnTexImageARB(target, level, GLenum(format), GLenum(type), dataSize, data);
glGetnTexImageARB(_target, level, GLenum(format), GLenum(type), dataSize, data);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDefault(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) {
bindInternal();
glTexSubImage1D(target, level, offset[0], size[0], GLenum(format), GLenum(type), data);
glTexSubImage1D(_target, level, offset[0], size[0], GLenum(format), GLenum(type), data);
}
void AbstractTexture::subImageImplementationDSA(const GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, const ColorFormat format, const ColorType type, const GLvoid* const data) {
glTextureSubImage1D(_id, level, offset[0], size[0], GLenum(format), GLenum(type), data);
}
void AbstractTexture::subImageImplementationDSAEXT(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDSAEXT(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) {
_created = true;
glTextureSubImage1DEXT(_id, target, level, offset[0], size[0], GLenum(format), GLenum(type), data);
glTextureSubImage1DEXT(_id, _target, level, offset[0], size[0], GLenum(format), GLenum(type), data);
}
#endif
void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDefault(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) {
bindInternal();
glTexSubImage2D(target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data);
glTexSubImage2D(_target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data);
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::subImageImplementationDSAEXT(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDSA(const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) {
glTextureSubImage2D(_id, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data);
}
void AbstractTexture::subImageImplementationDSAEXT(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) {
_created = true;
glTextureSubImage2DEXT(_id, target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data);
glTextureSubImage2DEXT(_id, _target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data);
}
#endif
void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDefault(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) {
bindInternal();
#ifndef MAGNUM_TARGET_GLES2
glTexSubImage3D(target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data);
glTexSubImage3D(_target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data);
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glTexSubImage3DOES(target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data);
glTexSubImage3DOES(_target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data);
#else
static_cast<void>(target);
static_cast<void>(level);
static_cast<void>(offset);
static_cast<void>(size);
@ -1129,9 +1199,13 @@ void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level,
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::subImageImplementationDSAEXT(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDSA(const GLint level, const Vector3i& offset, const Vector3i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) {
glTextureSubImage3D(_id, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data);
}
void AbstractTexture::subImageImplementationDSAEXT(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) {
_created = true;
glTextureSubImage3DEXT(_id, target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data);
glTextureSubImage3DEXT(_id, _target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data);
}
#endif
@ -1155,111 +1229,111 @@ void AbstractTexture::invalidateSubImageImplementationARB(GLint level, const Vec
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES
template<UnsignedInt dimensions> void AbstractTexture::image(GLenum target, GLint level, Image<dimensions>& image) {
const Math::Vector<dimensions, Int> size = DataHelper<dimensions>::imageSize(*this, target, level);
template<UnsignedInt dimensions> void AbstractTexture::image(GLint level, Image<dimensions>& image) {
const Math::Vector<dimensions, Int> size = DataHelper<dimensions>::imageSize(*this, level);
const std::size_t dataSize = image.dataSize(size);
char* data = new char[dataSize];
(this->*Context::current()->state().texture->getImageImplementation)(target, level, image.format(), image.type(), dataSize, data);
(this->*Context::current()->state().texture->getImageImplementation)(level, image.format(), image.type(), dataSize, data);
image.setData(image.format(), image.type(), size, data);
}
template void MAGNUM_EXPORT AbstractTexture::image<1>(GLenum, GLint, Image<1>&);
template void MAGNUM_EXPORT AbstractTexture::image<2>(GLenum, GLint, Image<2>&);
template void MAGNUM_EXPORT AbstractTexture::image<3>(GLenum, GLint, Image<3>&);
template void MAGNUM_EXPORT AbstractTexture::image<1>(GLint, Image<1>&);
template void MAGNUM_EXPORT AbstractTexture::image<2>(GLint, Image<2>&);
template void MAGNUM_EXPORT AbstractTexture::image<3>(GLint, Image<3>&);
template<UnsignedInt dimensions> void AbstractTexture::image(GLenum target, GLint level, BufferImage<dimensions>& image, BufferUsage usage) {
const Math::Vector<dimensions, Int> size = DataHelper<dimensions>::imageSize(*this, target, level);
template<UnsignedInt dimensions> void AbstractTexture::image(GLint level, BufferImage<dimensions>& image, BufferUsage usage) {
const Math::Vector<dimensions, Int> size = DataHelper<dimensions>::imageSize(*this, level);
const std::size_t dataSize = image.dataSize(size);
if(image.size() != size)
image.setData(image.format(), image.type(), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
(this->*Context::current()->state().texture->getImageImplementation)(target, level, image.format(), image.type(), dataSize, nullptr);
(this->*Context::current()->state().texture->getImageImplementation)(level, image.format(), image.type(), dataSize, nullptr);
}
template void MAGNUM_EXPORT AbstractTexture::image<1>(GLenum, GLint, BufferImage<1>&, BufferUsage);
template void MAGNUM_EXPORT AbstractTexture::image<2>(GLenum, GLint, BufferImage<2>&, BufferUsage);
template void MAGNUM_EXPORT AbstractTexture::image<3>(GLenum, GLint, BufferImage<3>&, BufferUsage);
template void MAGNUM_EXPORT AbstractTexture::image<1>(GLint, BufferImage<1>&, BufferUsage);
template void MAGNUM_EXPORT AbstractTexture::image<2>(GLint, BufferImage<2>&, BufferUsage);
template void MAGNUM_EXPORT AbstractTexture::image<3>(GLint, BufferImage<3>&, BufferUsage);
#endif
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES
Math::Vector<1, GLint> AbstractTexture::DataHelper<1>::imageSize(AbstractTexture& texture, const GLenum target, const GLint level) {
Math::Vector<1, GLint> AbstractTexture::DataHelper<1>::imageSize(AbstractTexture& texture, const GLint level) {
Math::Vector<1, GLint> value;
(texture.*Context::current()->state().texture->getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]);
(texture.*Context::current()->state().texture->getLevelParameterivImplementation)(level, GL_TEXTURE_WIDTH, &value[0]);
return value;
}
#endif
#ifndef MAGNUM_TARGET_GLES2
Vector2i AbstractTexture::DataHelper<2>::imageSize(AbstractTexture& texture, const GLenum target, const GLint level) {
Vector2i AbstractTexture::DataHelper<2>::imageSize(AbstractTexture& texture, const GLint level) {
const Implementation::TextureState& state = *Context::current()->state().texture;
Vector2i value;
(texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]);
(texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]);
(texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_WIDTH, &value[0]);
(texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_HEIGHT, &value[1]);
return value;
}
Vector3i AbstractTexture::DataHelper<3>::imageSize(AbstractTexture& texture, const GLenum target, const GLint level) {
Vector3i AbstractTexture::DataHelper<3>::imageSize(AbstractTexture& texture, const GLint level) {
const Implementation::TextureState& state = *Context::current()->state().texture;
Vector3i value;
(texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]);
(texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]);
(texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_DEPTH, &value[2]);
(texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_WIDTH, &value[0]);
(texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_HEIGHT, &value[1]);
(texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_DEPTH, &value[2]);
return value;
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::DataHelper<1>::setStorage(AbstractTexture& texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Math::Vector< 1, GLsizei >& size) {
(texture.*Context::current()->state().texture->storage1DImplementation)(target, levels, internalFormat, size);
void AbstractTexture::DataHelper<1>::setStorage(AbstractTexture& texture, const GLsizei levels, const TextureFormat internalFormat, const Math::Vector< 1, GLsizei >& size) {
(texture.*Context::current()->state().texture->storage1DImplementation)(levels, internalFormat, size);
}
#endif
void AbstractTexture::DataHelper<2>::setStorage(AbstractTexture& texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) {
(texture.*Context::current()->state().texture->storage2DImplementation)(target, levels, internalFormat, size);
void AbstractTexture::DataHelper<2>::setStorage(AbstractTexture& texture, const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) {
(texture.*Context::current()->state().texture->storage2DImplementation)(levels, internalFormat, size);
}
void AbstractTexture::DataHelper<3>::setStorage(AbstractTexture& texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Vector3i& size) {
(texture.*Context::current()->state().texture->storage3DImplementation)(target, levels, internalFormat, size);
void AbstractTexture::DataHelper<3>::setStorage(AbstractTexture& texture, const GLsizei levels, const TextureFormat internalFormat, const Vector3i& size) {
(texture.*Context::current()->state().texture->storage3DImplementation)(levels, internalFormat, size);
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::DataHelper<2>::setStorageMultisample(AbstractTexture& texture, const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
(texture.*Context::current()->state().texture->storage2DMultisampleImplementation)(target, samples, internalFormat, size, fixedSampleLocations);
void AbstractTexture::DataHelper<2>::setStorageMultisample(AbstractTexture& texture, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
(texture.*Context::current()->state().texture->storage2DMultisampleImplementation)(samples, internalFormat, size, fixedSampleLocations);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::DataHelper<3>::setStorageMultisample(AbstractTexture& texture, const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
(texture.*Context::current()->state().texture->storage3DMultisampleImplementation)(target, samples, internalFormat, size, fixedSampleLocations);
void AbstractTexture::DataHelper<3>::setStorageMultisample(AbstractTexture& texture, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
(texture.*Context::current()->state().texture->storage3DMultisampleImplementation)(samples, internalFormat, size, fixedSampleLocations);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference1D& image) {
void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, const ImageReference1D& image) {
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
texture.bindInternal();
glTexImage1D(target, level, GLint(internalFormat), image.size()[0], 0, GLenum(image.format()), GLenum(image.type()), image.data());
glTexImage1D(texture._target, level, GLint(internalFormat), image.size()[0], 0, GLenum(image.format()), GLenum(image.type()), image.data());
}
void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage1D& image) {
void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, BufferImage1D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
texture.bindInternal();
glTexImage1D(target, level, GLint(internalFormat), image.size()[0], 0, GLenum(image.format()), GLenum(image.type()), nullptr);
glTexImage1D(texture._target, level, GLint(internalFormat), image.size()[0], 0, GLenum(image.format()), GLenum(image.type()), nullptr);
}
void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image) {
void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image) {
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
(texture.*Context::current()->state().texture->subImage1DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data());
(texture.*Context::current()->state().texture->subImage1DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data());
}
void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image) {
void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
(texture.*Context::current()->state().texture->subImage1DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr);
(texture.*Context::current()->state().texture->subImage1DImplementation)(level, offset, image.size(), image.format(), image.type(), nullptr);
}
#endif
@ -1279,31 +1353,30 @@ void AbstractTexture::DataHelper<2>::setImage(AbstractTexture& texture, const GL
}
#endif
void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector2i& offset, const ImageReference2D& image) {
void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLint level, const Vector2i& offset, const ImageReference2D& image) {
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
(texture.*Context::current()->state().texture->subImage2DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data());
(texture.*Context::current()->state().texture->subImage2DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data());
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector2i& offset, BufferImage2D& image) {
void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLint level, const Vector2i& offset, BufferImage2D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
(texture.*Context::current()->state().texture->subImage2DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr);
(texture.*Context::current()->state().texture->subImage2DImplementation)(level, offset, image.size(), image.format(), image.type(), nullptr);
}
#endif
void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference3D& image) {
void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, const ImageReference3D& image) {
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
texture.bindInternal();
#ifndef MAGNUM_TARGET_GLES2
glTexImage3D(target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), image.data());
glTexImage3D(texture._target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), image.data());
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glTexImage3DOES(target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), image.data());
glTexImage3DOES(texture._target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), image.data());
#else
static_cast<void>(target);
static_cast<void>(level);
static_cast<void>(internalFormat);
static_cast<void>(image);
@ -1312,24 +1385,24 @@ void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GL
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage3D& image) {
void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, BufferImage3D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
texture.bindInternal();
glTexImage3D(target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), nullptr);
glTexImage3D(texture._target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), nullptr);
}
#endif
void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector3i& offset, const ImageReference3D& image) {
void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLint level, const Vector3i& offset, const ImageReference3D& image) {
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
(texture.*Context::current()->state().texture->subImage3DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data());
(texture.*Context::current()->state().texture->subImage3DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data());
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector3i& offset, BufferImage3D& image) {
void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLint level, const Vector3i& offset, BufferImage3D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
(texture.*Context::current()->state().texture->subImage3DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr);
(texture.*Context::current()->state().texture->subImage3DImplementation)(level, offset, image.size(), image.format(), image.type(), nullptr);
}
#endif

191
src/Magnum/AbstractTexture.h

@ -74,22 +74,31 @@ to not affect active bindings in user units. Texture limits and
implementation-defined values (such as @ref maxColorSamples()) are cached, so
repeated queries don't result in repeated @fn_gl{Get} calls.
If extension @extension{ARB,multi_bind} is available, @ref bind() uses
@fn_gl{BindTextures} to avoid unnecessary calls to @fn_gl{ActiveTexture}.
Otherwise, if extension @extension{EXT,direct_state_access} is available,
@ref bind() uses @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
function.
In addition, if extension @extension{EXT,direct_state_access} is available,
also all texture configuration and data updating functions use DSA functions
to avoid unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}.
See respective function documentation for more information.
If extension @extension{ARB,robustness} is available, image reading operations
(such as @ref Texture::image()) are protected from buffer overflow. However, if
both @extension{EXT,direct_state_access} and @extension{ARB,robustness} are
available, the DSA version is used, because it is better for performance and
there isn't any function combining both features.
If on desktop GL and @extension{ARB,direct_state_access} (part of OpenGL 4.5)
is available, @ref bind(Int) and @ref unbind(Int) use @fn_gl{BindTextureUnit}.
Otherwise, if @extension{ARB,multi_bind} (part of OpenGL 4.4) is available,
@ref bind(Int) and @ref unbind() uses @fn_gl{BindTextures}. Lastly, if
@extension{EXT,direct_state_access} is available, @fn_gl_extension{BindNamedTexture,EXT,direct_state_access}
function is used to avoid unnecessary calls to @fn_gl{ActiveTexture}.
In addition, if either @extension{ARB,direct_state_access} (part of OpenGL 4.5)
or @extension{EXT,direct_state_access} is available, also all texture
configuration and data updating functions use DSA functions to avoid
unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. See
respective function documentation for more information.
If @extension{ARB,multi_bind} (part of OpenGL 4.5) is available,
@ref bind(Int, std::initializer_list<AbstractTexture*>) and @ref unbind(Int, std::size_t)
use @fn_gl{BindTextures} to avoid unnecessary calls to @fn_gl{ActiveTexture}.
Otherwise the feature is emulated with sequence of @ref bind(Int)/@ref unbind(Int)
calls.
If either @extension{ARB,direct_state_access} or @extension{ARB,robustness} is
available, image reading operations (such as @ref Texture::image()) are
protected from buffer overflow. However, if @extension{ARB,direct_state_access}
is not available and both @extension{EXT,direct_state_access} and
@extension{ARB,robustness} are available, the robust version is preferred over
DSA.
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
@ -125,6 +134,7 @@ functions do nothing.
*/
class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
friend struct Implementation::TextureState;
friend class CubeMapTexture;
public:
#ifdef MAGNUM_BUILD_DEPRECATED
@ -187,15 +197,17 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
/**
* @brief Unbind any texture from given texture unit
*
* If @extension{ARB,multi_bind} (part of OpenGL 4.4) or
* @extension{EXT,direct_state_access} is not available, the texture
* unit is made active before binding the texture.
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5), @extension{ARB,multi_bind} (part of OpenGL 4.4) nor
* @extension{EXT,direct_state_access} is available, the texture unit
* is made active before unbinding the texture.
* @note This function is meant to be used only internally from
* @ref AbstractShaderProgram subclasses. See its documentation
* for more information.
* @see @ref bind(), @ref Shader::maxCombinedTextureImageUnits(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture}, @fn_gl{BindTextures}
* or @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
* @fn_gl{BindTextureUnit}, @fn_gl{BindTextures},
* @fn_gl_extension{BindMultiTexture,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture} and @fn_gl{BindTexture}
*/
static void unbind(Int textureUnit);
@ -208,9 +220,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
* @note This function is meant to be used only internally from
* @ref AbstractShaderProgram subclasses. See its documentation
* for more information.
* @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or
* @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
* @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures}
*/
static void unbind(Int firstTextureUnit, std::size_t count);
@ -225,9 +235,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
* @note This function is meant to be used only internally from
* @ref AbstractShaderProgram subclasses. See its documentation
* for more information.
* @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or
* @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
* @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures}
*/
static void bind(Int firstTextureUnit, std::initializer_list<AbstractTexture*> textures);
@ -290,16 +298,18 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
/**
* @brief Bind texture to given texture unit
*
* If @extension{ARB,multi_bind} (part of OpenGL 4.4) or
* @extension{EXT,direct_state_access} is not available, the texture
* unit is made active before binding the texture.
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5), @extension{ARB,multi_bind} (part of OpenGL 4.4) nor
* @extension{EXT,direct_state_access} is available, the texture unit
* is made active before binding the texture.
* @note This function is meant to be used only internally from
* @ref AbstractShaderProgram subclasses. See its documentation
* for more information.
* @see @ref bind(Int, std::initializer_list<AbstractTexture*>),
* @ref unbind(), @ref Shader::maxCombinedTextureImageUnits(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture}, @fn_gl{BindTextures}
* or @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
* @fn_gl{BindTextureUnit}, @fn_gl{BindTextures},
* @fn_gl_extension{BindMultiTexture,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture} and @fn_gl{BindTexture}
*/
void bind(Int textureUnit);
@ -357,8 +367,8 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void generateMipmap();
#ifndef MAGNUM_TARGET_GLES
template<UnsignedInt dimensions> void image(GLenum target, GLint level, Image<dimensions>& image);
template<UnsignedInt dimensions> void image(GLenum target, GLint level, BufferImage<dimensions>& image, BufferUsage usage);
template<UnsignedInt dimensions> void image(GLint level, Image<dimensions>& image);
template<UnsignedInt dimensions> void image(GLint level, BufferImage<dimensions>& image, BufferUsage usage);
#endif
GLenum _target;
@ -367,6 +377,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
static void MAGNUM_LOCAL unbindImplementationDefault(GLint textureUnit);
#ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL unbindImplementationMulti(GLint textureUnit);
static void MAGNUM_LOCAL unbindImplementationDSA(GLint textureUnit);
static void MAGNUM_LOCAL unbindImplementationDSAEXT(GLint textureUnit);
#endif
@ -385,6 +396,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void MAGNUM_LOCAL bindImplementationDefault(GLint textureUnit);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL bindImplementationMulti(GLint textureUnit);
void MAGNUM_LOCAL bindImplementationDSA(GLint textureUnit);
void MAGNUM_LOCAL bindImplementationDSAEXT(GLint textureUnit);
#endif
@ -399,11 +411,17 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void MAGNUM_LOCAL parameterIImplementationDefault(GLenum parameter, const GLint* values);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLint value);
void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, GLint value);
void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLfloat value);
void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, GLfloat value);
void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, const GLint* values);
void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, const GLint* values);
void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, const GLfloat* values);
void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, const GLfloat* values);
void MAGNUM_LOCAL parameterIImplementationDSA(GLenum parameter, const GLuint* values);
void MAGNUM_LOCAL parameterIImplementationDSAEXT(GLenum parameter, const GLuint* values);
void MAGNUM_LOCAL parameterIImplementationDSA(GLenum parameter, const GLint* values);
void MAGNUM_LOCAL parameterIImplementationDSAEXT(GLenum parameter, const GLint* values);
#endif
@ -411,70 +429,81 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void MAGNUM_LOCAL setMaxAnisotropyImplementationExt(GLfloat anisotropy);
#ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL getLevelParameterImplementationDefault(GLenum target, GLint level, GLenum parameter, GLint* values);
void MAGNUM_LOCAL getLevelParameterImplementationDefault(GLint level, GLenum parameter, GLint* values);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL getLevelParameterImplementationDSAEXT(GLenum target, GLint level, GLenum parameter, GLint* values);
void MAGNUM_LOCAL getLevelParameterImplementationDSA(GLint level, GLenum parameter, GLint* values);
void MAGNUM_LOCAL getLevelParameterImplementationDSAEXT(GLint level, GLenum parameter, GLint* values);
#endif
#endif
void MAGNUM_LOCAL mipmapImplementationDefault();
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL mipmapImplementationDSA();
void MAGNUM_LOCAL mipmapImplementationDSAEXT();
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
void MAGNUM_LOCAL storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
void MAGNUM_LOCAL storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
void MAGNUM_LOCAL storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
void MAGNUM_LOCAL storageImplementationDSA(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
void MAGNUM_LOCAL storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
#endif
void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageImplementationDSA(GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
#endif
void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
void MAGNUM_LOCAL storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
void MAGNUM_LOCAL storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
void MAGNUM_LOCAL storageImplementationDSA(GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
void MAGNUM_LOCAL storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
#endif
#ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL getImageImplementationDefault(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationDSAEXT(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationRobustness(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationDefault(GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationDSA(GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationDSAEXT(GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationRobustness(GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL subImageImplementationDSAEXT(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL subImageImplementationDefault(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL subImageImplementationDSA(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL subImageImplementationDSAEXT(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL subImageImplementationDefault(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL subImageImplementationDSAEXT(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL subImageImplementationDSA(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL subImageImplementationDSAEXT(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL subImageImplementationDefault(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL subImageImplementationDSAEXT(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL subImageImplementationDSA(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL subImageImplementationDSAEXT(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
void MAGNUM_LOCAL invalidateImageImplementationNoOp(GLint level);
@ -503,17 +532,17 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<1> {
};
#endif
static Math::Vector<1, GLint> imageSize(AbstractTexture& texture, GLenum target, GLint level);
static Math::Vector<1, GLint> imageSize(AbstractTexture& texture, GLint level);
static void setWrapping(AbstractTexture& texture, const Array1D<Sampler::Wrapping>& wrapping);
static void setStorage(AbstractTexture& texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
static void setStorage(AbstractTexture& texture, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference1D& image);
static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage1D& image);
static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, const ImageReference1D& image);
static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, BufferImage1D& image);
static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image);
static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image);
static void setSubImage(AbstractTexture& texture, GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image);
static void setSubImage(AbstractTexture& texture, GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image);
static void invalidateSubImage(AbstractTexture& texture, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLint>& size);
};
@ -531,25 +560,31 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
#endif
#ifndef MAGNUM_TARGET_GLES2
static Vector2i imageSize(AbstractTexture& texture, GLenum target, GLint level);
static Vector2i imageSize(AbstractTexture& texture, GLint level);
#endif
static void setWrapping(AbstractTexture& texture, const Array2D<Sampler::Wrapping>& wrapping);
static void setStorage(AbstractTexture& texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
static void setStorage(AbstractTexture& texture, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
#ifndef MAGNUM_TARGET_GLES2
static void setStorageMultisample(AbstractTexture& texture, GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedSampleLocations);
static void setStorageMultisample(AbstractTexture& texture, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedSampleLocations);
#endif
static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, const ImageReference2D& image) {
setImage(texture, texture._target, level, internalFormat, image);
}
static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference2D& image);
#ifndef MAGNUM_TARGET_GLES2
static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, BufferImage2D& image) {
setImage(texture, texture._target, level, internalFormat, image);
}
static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage2D& image);
#endif
static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Vector2i& offset, const ImageReference2D& image);
static void setSubImage(AbstractTexture& texture, GLint level, const Vector2i& offset, const ImageReference2D& image);
#ifndef MAGNUM_TARGET_GLES2
static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Vector2i& offset, BufferImage2D& image);
static void setSubImage(AbstractTexture& texture, GLint level, const Vector2i& offset, BufferImage2D& image);
#endif
static void invalidateSubImage(AbstractTexture& texture, GLint level, const Vector2i& offset, const Vector2i& size);
@ -570,25 +605,25 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
#endif
#ifndef MAGNUM_TARGET_GLES2
static Vector3i imageSize(AbstractTexture& texture, GLenum target, GLint level);
static Vector3i imageSize(AbstractTexture& texture, GLint level);
#endif
static void setWrapping(AbstractTexture& texture, const Array3D<Sampler::Wrapping>& wrapping);
static void setStorage(AbstractTexture& texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
static void setStorage(AbstractTexture& texture, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
#ifndef MAGNUM_TARGET_GLES
static void setStorageMultisample(AbstractTexture& texture, GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedSampleLocations);
static void setStorageMultisample(AbstractTexture& texture, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedSampleLocations);
#endif
static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference3D& image);
static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, const ImageReference3D& image);
#ifndef MAGNUM_TARGET_GLES2
static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage3D& image);
static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, BufferImage3D& image);
#endif
static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Vector3i& offset, const ImageReference3D& image);
static void setSubImage(AbstractTexture& texture, GLint level, const Vector3i& offset, const ImageReference3D& image);
#ifndef MAGNUM_TARGET_GLES2
static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Vector3i& offset, BufferImage3D& image);
static void setSubImage(AbstractTexture& texture, GLint level, const Vector3i& offset, BufferImage3D& image);
#endif
static void invalidateSubImage(AbstractTexture& texture, GLint level, const Vector3i& offset, const Vector3i& size);

8
src/Magnum/BufferTexture.cpp

@ -75,6 +75,10 @@ void BufferTexture::setBufferImplementationDefault(BufferTextureFormat internalF
glTexBuffer(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id());
}
void BufferTexture::setBufferImplementationDSA(const BufferTextureFormat internalFormat, Buffer& buffer) {
glTextureBuffer(id(), GLenum(internalFormat), buffer.id());
}
void BufferTexture::setBufferImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer) {
glTextureBufferEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id());
}
@ -84,6 +88,10 @@ void BufferTexture::setBufferRangeImplementationDefault(BufferTextureFormat inte
glTexBufferRange(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id(), offset, size);
}
void BufferTexture::setBufferRangeImplementationDSA(const BufferTextureFormat internalFormat, Buffer& buffer, const GLintptr offset, const GLsizeiptr size) {
glTextureBufferRange(id(), GLenum(internalFormat), buffer.id(), offset, size);
}
void BufferTexture::setBufferRangeImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size) {
glTextureBufferRangeEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id(), offset, size);
}

31
src/Magnum/BufferTexture.h

@ -154,7 +154,7 @@ enum class BufferTextureFormat: GLenum {
/**
@brief Buffer texture
This texture is, unlike classic textures such as @ref Texture used as simple
This texture is, unlike classic textures such as @ref Texture, used as simple
data source, without any unnecessary interpolation and wrapping methods.
## Usage
@ -187,7 +187,8 @@ documentation for more information about usage in shaders.
## Performance optimizations
If extension @extension{EXT,direct_state_access} is available, @ref setBuffer()
If on desktop GL and either @extension{ARB,direct_state_access} (part of OpenGL
4.5) or @extension{EXT,direct_state_access} is available, @ref setBuffer()
functions use DSA to avoid unnecessary calls to @fn_gl{ActiveTexture} and
@fn_gl{BindTexture}. See
@ref AbstractTexture-performance-optimization "relevant section in AbstractTexture documentation"
@ -241,10 +242,14 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture {
*
* Binds given buffer to this texture. The buffer itself can be then
* filled with data of proper format at any time using @ref Buffer "Buffer"'s
* own data setting functions.
* @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexBuffer} or
* @fn_gl_extension{TextureBuffer,EXT,direct_state_access}
* own data setting functions. If neither @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* available, the texture is bound before the operation (if not
* already).
* @see @ref maxSize(), @fn_gl2{TextureBuffer,TexBuffer},
* @fn_gl_extension{TextureBuffer,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexBuffer}
*/
BufferTexture& setBuffer(BufferTextureFormat internalFormat, Buffer& buffer);
@ -258,10 +263,14 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture {
*
* Binds range of given buffer to this texture. The buffer itself can
* be then filled with data of proper format at any time using @ref Buffer "Buffer"'s
* own data setting functions.
* @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexBufferRange} or
* @fn_gl_extension{TextureBufferRange,EXT,direct_state_access}
* own data setting functions. If neither @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* available, the texture is bound before the operation (if not
* already).
* @see @ref maxSize(), @fn_gl2{TextureBufferRange,TexBufferRange},
* @fn_gl_extension{TextureBufferRange,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexBufferRange}
* @requires_gl43 Extension @extension{ARB,texture_buffer_range}
*/
BufferTexture& setBuffer(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size);
@ -280,9 +289,11 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture {
private:
void MAGNUM_LOCAL setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer);
void MAGNUM_LOCAL setBufferImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer);
void MAGNUM_LOCAL setBufferImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer);
void MAGNUM_LOCAL setBufferRangeImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size);
void MAGNUM_LOCAL setBufferRangeImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size);
void MAGNUM_LOCAL setBufferRangeImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size);
};

122
src/Magnum/CubeMapTexture.cpp

@ -25,12 +25,134 @@
#include "CubeMapTexture.h"
#ifndef MAGNUM_TARGET_GLES2
#include "Magnum/BufferImage.h"
#endif
#include "Magnum/Context.h"
#include "Magnum/Image.h"
#include "Implementation/maxTextureSize.h"
#include "Implementation/State.h"
#include "Implementation/TextureState.h"
namespace Magnum {
static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 0 &&
GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1 &&
GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2 &&
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3 &&
GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4 &&
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5,
"Unexpected GL enum values for cube faces");
Vector2i CubeMapTexture::maxSize() {
return Vector2i{Implementation::maxCubeMapTextureSideSize()};
}
#ifndef MAGNUM_TARGET_GLES2
Vector2i CubeMapTexture::imageSize(const Int level) {
return (this->*Context::current()->state().texture->getCubeImageSizeImplementation)(level);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void CubeMapTexture::image(const Coordinate coordinate, const Int level, Image2D& image) {
const Vector2i size = imageSize(level);
const std::size_t dataSize = image.dataSize(size);
char* data = new char[dataSize];
(this->*Context::current()->state().texture->getCubeImageImplementation)(coordinate, level, size, image.format(), image.type(), dataSize, data);
image.setData(image.format(), image.type(), size, data);
}
void CubeMapTexture::image(const Coordinate coordinate, const Int level, BufferImage2D& image, const BufferUsage usage) {
const Vector2i size = imageSize(level);
const std::size_t dataSize = image.dataSize(size);
if(image.size() != size)
image.setData(image.format(), image.type(), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
(this->*Context::current()->state().texture->getCubeImageImplementation)(coordinate, level, size, image.format(), image.type(), dataSize, nullptr);
}
#endif
CubeMapTexture& CubeMapTexture::setSubImage(const Coordinate coordinate, const Int level, const Vector2i& offset, const ImageReference2D& image) {
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
(this->*Context::current()->state().texture->cubeSubImageImplementation)(coordinate, level, offset, image.size(), image.format(), image.type(), image.data());
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
CubeMapTexture& CubeMapTexture::setSubImage(const Coordinate coordinate, const Int level, const Vector2i& offset, BufferImage2D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
(this->*Context::current()->state().texture->cubeSubImageImplementation)(coordinate, level, offset, image.size(), image.format(), image.type(), nullptr);
return *this;
}
#endif
#ifndef MAGNUM_TARGET_GLES2
Vector2i CubeMapTexture::getImageSizeImplementationDefault(const Int level) {
Vector2i size;
bindInternal();
glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_WIDTH, &size.x());
glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_HEIGHT, &size.y());
return size;
}
#ifndef MAGNUM_TARGET_GLES
Vector2i CubeMapTexture::getImageSizeImplementationDSA(const Int level) {
Vector2i size;
glGetTextureLevelParameteriv(_id, level, GL_TEXTURE_WIDTH, &size.x());
glGetTextureLevelParameteriv(_id, level, GL_TEXTURE_HEIGHT, &size.y());
return size;
}
Vector2i CubeMapTexture::getImageSizeImplementationDSAEXT(const Int level) {
_created = true;
Vector2i size;
glGetTextureLevelParameterivEXT(_id, GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_WIDTH, &size.x());
glGetTextureLevelParameterivEXT(_id, GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_HEIGHT, &size.y());
return size;
}
#endif
#endif
#ifndef MAGNUM_TARGET_GLES
void CubeMapTexture::getImageImplementationDefault(const Coordinate coordinate, const GLint level, const Vector2i&, const ColorFormat format, const ColorType type, std::size_t, GLvoid* const data) {
bindInternal();
glGetTexImage(GLenum(coordinate), level, GLenum(format), GLenum(type), data);
}
void CubeMapTexture::getImageImplementationDSA(const Coordinate coordinate, const GLint level, const Vector2i& size, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) {
glGetTextureSubImage(_id, level, 0, 0, GLenum(coordinate) - GL_TEXTURE_CUBE_MAP_POSITIVE_X, size.x(), size.y(), 1, GLenum(format), GLenum(type), dataSize, data);
}
void CubeMapTexture::getImageImplementationDSAEXT(const Coordinate coordinate, const GLint level, const Vector2i&, const ColorFormat format, const ColorType type, std::size_t, GLvoid* const data) {
_created = true;
glGetTextureImageEXT(_id, GLenum(coordinate), level, GLenum(format), GLenum(type), data);
}
void CubeMapTexture::getImageImplementationRobustness(const Coordinate coordinate, const GLint level, const Vector2i&, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) {
bindInternal();
glGetnTexImageARB(GLenum(coordinate), level, GLenum(format), GLenum(type), dataSize, data);
}
#endif
void CubeMapTexture::subImageImplementationDefault(const Coordinate coordinate, const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) {
bindInternal();
glTexSubImage2D(GLenum(coordinate), level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data);
}
#ifndef MAGNUM_TARGET_GLES
void CubeMapTexture::subImageImplementationDSA(const Coordinate coordinate, const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) {
glTextureSubImage3D(_id, level, offset.x(), offset.y(), GLenum(coordinate) - GL_TEXTURE_CUBE_MAP_POSITIVE_X, size.x(), size.y(), 1, GLenum(format), GLenum(type), data);
}
void CubeMapTexture::subImageImplementationDSAEXT(const Coordinate coordinate, const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) {
_created = true;
glTextureSubImage2DEXT(_id, GLenum(coordinate), level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data);
}
#endif
}

283
src/Magnum/CubeMapTexture.h

@ -80,6 +80,8 @@ which intersects one of the six sides of the cube map. See
@ref MultisampleTexture
*/
class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
friend struct Implementation::TextureState;
public:
/** @brief Cube map coordinate */
enum class Coordinate: GLenum {
@ -112,39 +114,77 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {}
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc Texture::setBaseLevel() */
/**
* @copybrief Texture::setBaseLevel()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setBaseLevel() for more information.
* @requires_gles30 Base level is always `0` in OpenGL ES 2.0.
*/
CubeMapTexture& setBaseLevel(Int level) {
AbstractTexture::setBaseLevel(level);
return *this;
}
#endif
/** @copydoc Texture::setMaxLevel() */
/**
* @copybrief Texture::setMaxLevel()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMaxLevel() for more information.
* @requires_gles30 Extension @es_extension{APPLE,texture_max_level},
* otherwise the max level is always set to largest possible value
* in OpenGL ES 2.0.
*/
CubeMapTexture& setMaxLevel(Int level) {
AbstractTexture::setMaxLevel(level);
return *this;
}
/** @copydoc Texture::setMinificationFilter() */
/**
* @copybrief Texture::setMinificationFilter()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMinificationFilter() for more information.
*/
CubeMapTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;
}
/** @copydoc Texture::setMagnificationFilter() */
/**
* @copybrief Texture::setMagnificationFilter()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMagnificationFilter() for more information.
*/
CubeMapTexture& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc Texture::setMinLod() */
/**
* @copybrief Texture::setMinLod()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMinLod() for more information.
* @requires_gles30 Texture LOD parameters are not available in OpenGL
* ES 2.0.
*/
CubeMapTexture& setMinLod(Float lod) {
AbstractTexture::setMinLod(lod);
return *this;
}
/** @copydoc Texture::setMaxLod() */
/**
* @copybrief Texture::setMaxLod()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMaxLod() for more information.
* @requires_gles30 Texture LOD parameters are not available in OpenGL
* ES 2.0.
*/
CubeMapTexture& setMaxLod(Float lod) {
AbstractTexture::setMaxLod(lod);
return *this;
@ -152,53 +192,106 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
#endif
#ifndef MAGNUM_TARGET_GLES
/** @copydoc Texture::setLodBias() */
/**
* @copybrief Texture::setLodBias()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setLodBias() for more information.
* @requires_gl Texture LOD bias can be specified only directly in
* fragment shader in OpenGL ES.
*/
CubeMapTexture& setLodBias(Float bias) {
AbstractTexture::setLodBias(bias);
return *this;
}
#endif
/** @copydoc Texture::setWrapping() */
/**
* @copybrief Texture::setWrapping()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setWrapping() for more information.
*/
CubeMapTexture& setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
DataHelper<3>::setWrapping(*this, wrapping);
return *this;
}
/** @copydoc Texture::setBorderColor(const Color4&) */
/**
* @copybrief Texture::setBorderColor(const Color4&)
* @return Reference to self (for method chaining)
*
* See @ref Texture::setBorderColor(const Color4&) for more
* information.
* @requires_es_extension Extension @es_extension{NV,texture_border_clamp}
*/
CubeMapTexture& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
#ifndef MAGNUM_TARGET_GLES
/** @copydoc Texture::setBorderColor(const Vector4ui&) */
/**
* @copybrief Texture::setBorderColor(const Vector4ui&)
* @return Reference to self (for method chaining)
*
* See @ref Texture::setBorderColor(const Vector4ui&) for more
* information.
* @requires_gl30 Extension @extension{EXT,texture_integer}
* @requires_gl Border is available only for float textures in OpenGL
* ES.
*/
CubeMapTexture& setBorderColor(const Vector4ui& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
/** @copydoc Texture::setBorderColor(const Vector4i&) */
/** @overload
* @requires_gl30 Extension @extension{EXT,texture_integer}
* @requires_gl Border is available only for float textures in OpenGL
* ES.
*/
CubeMapTexture& setBorderColor(const Vector4i& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
#endif
/** @copydoc Texture::setMaxAnisotropy() */
/**
* @copybrief Texture::setMaxAnisotropy()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMaxAnisotropy() for more information.
*/
CubeMapTexture& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return *this;
}
/** @copydoc Texture::setSRGBDecode() */
/**
* @copybrief Texture::setSRGBDecode()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setSRGBDecode() for more information.
* @requires_extension Extension @extension{EXT,texture_sRGB_decode}
* @requires_es_extension OpenGL ES 3.0 or extension
* @es_extension{EXT,sRGB} and
* @es_extension2{EXT,texture_sRGB_decode,texture_sRGB_decode}
*/
CubeMapTexture& setSRGBDecode(bool decode) {
AbstractTexture::setSRGBDecode(decode);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc Texture::setSwizzle() */
/**
* @copybrief Texture::setSwizzle()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setSwizzle() for more information.
* @requires_gl33 Extension @extension{ARB,texture_swizzle}
* @requires_gles30 Texture swizzle is not available in OpenGL ES 2.0.
*/
template<char r, char g, char b, char a> CubeMapTexture& setSwizzle() {
AbstractTexture::setSwizzle<r, g, b, a>();
return *this;
@ -232,76 +325,79 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
}
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc Texture::setDepthStencilMode() */
/**
* @copybrief Texture::setDepthStencilMode()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setDepthStencilMode() for more information.
* @requires_gl43 Extension @extension{ARB,stencil_texturing}
* @requires_gles31 Stencil texturing is not available in OpenGL ES 3.0
* and older.
*/
CubeMapTexture& setDepthStencilMode(Sampler::DepthStencilMode mode) {
AbstractTexture::setDepthStencilMode(mode);
return *this;
}
#endif
/**
* @copybrief Texture::setStorage()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setStorage() for more information.
* @see @ref maxSize()
*/
CubeMapTexture& setStorage(Int levels, TextureFormat internalFormat, const Vector2i& size) {
DataHelper<2>::setStorage(*this, levels, internalFormat, size);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Image size in given mip level
* @param coordinate Coordinate
* @param level Mip level
* @copybrief Texture::imageSize()
*
* See @ref Texture::imageSize() for more information.
* If on OpenGL ES or @extension{ARB,direct_state_access} (part of
* OpenGL 4.5) is not available, it is assumed that faces have the same
* size and just the size of @ref Coordinate::PositiveX face is
* queried. See @ref Texture::imageSize() for more information.
* @requires_gles31 Texture image size queries are not available in
* OpenGL ES 3.0 and older.
*/
Vector2i imageSize(Coordinate coordinate, Int level) {
return DataHelper<2>::imageSize(*this, GLenum(coordinate), level);
}
#endif
Vector2i imageSize(Int level);
#ifdef MAGNUM_BUILD_DEPRECATED
/**
* @brief Set storage
*
* See @ref Texture::setStorage() for more information.
* @see @ref maxSize()
* @copybrief imageSize()
* @deprecated Use @ref Magnum::CubeMapTexture::imageSize(Int) "imageSize(Int)"
* instead.
*/
CubeMapTexture& setStorage(Int levels, TextureFormat internalFormat, const Vector2i& size) {
DataHelper<2>::setStorage(*this, _target, levels, internalFormat, size);
return *this;
CORRADE_DEPRECATED("use imageSize(Int) instead") Vector2i imageSize(Coordinate, Int level) {
return imageSize(level);
}
#endif
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Read given mip level of texture to image
* @param coordinate Coordinate
* @param level Mip level
* @param image Image where to put the data
* @copybrief Texture::image(Int, Image&)
*
* See @ref Texture::image(Int, Image&) for more information.
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void image(Coordinate coordinate, Int level, Image2D& image) {
AbstractTexture::image<2>(GLenum(coordinate), level, image);
}
void image(Coordinate coordinate, Int level, Image2D& image);
/**
* @brief Read given mip level of texture to buffer image
* @param coordinate Coordinate
* @param level Mip level
* @param image Buffer image where to put the data
* @param usage Buffer usage
* @copybrief Texture::image(Int, BufferImage&, BufferUsage)
*
* See @ref Texture::image(Int, BufferImage&, BufferUsage) for more
* information.
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void image(Coordinate coordinate, Int level, BufferImage2D& image, BufferUsage usage) {
AbstractTexture::image<2>(GLenum(coordinate), level, image, usage);
}
void image(Coordinate coordinate, Int level, BufferImage2D& image, BufferUsage usage);
#endif
/**
* @brief Set image data
* @param coordinate Coordinate
* @param level Mip level
* @param internalFormat Internal format
* @param image @ref Image2D, @ref ImageReference2D or
* @ref Trade::ImageData2D
* @copybrief Texture::setImage()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setImage() for more information.
@ -316,62 +412,75 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
/** @overload
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @deprecated_gl Prefer to use @ref Magnum::CubeMapTexture::setStorage() "setStorage()"
* and @ref Magnum::CubeMapTexture::setSubImage() "setSubImage()"
* instead.
*/
CubeMapTexture& setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, BufferImage2D& image) {
DataHelper<2>::setImage(*this, GLenum(coordinate), level, internalFormat, image);
return *this;
}
/** @overload */
/** @overload
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @deprecated_gl Prefer to use @ref Magnum::CubeMapTexture::setStorage() "setStorage()"
* and @ref Magnum::CubeMapTexture::setSubImage() "setSubImage()"
* instead.
*/
CubeMapTexture& setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, BufferImage2D&& image) {
return setImage(coordinate, level, internalFormat, image);
}
#endif
/**
* @brief Set image subdata
* @param coordinate Coordinate
* @param level Mip level
* @param offset Offset where to put data in the texture
* @param image @ref Image2D, @ref ImageReference2D or
* @ref Trade::ImageData2D
* @copybrief Texture::setSubImage()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setSubImage() for more information.
*/
CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const ImageReference2D& image) {
DataHelper<2>::setSubImage(*this, GLenum(coordinate), level, offset, image);
return *this;
}
CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const ImageReference2D& image);
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D& image) {
DataHelper<2>::setSubImage(*this, GLenum(coordinate), level, offset, image);
return *this;
}
/** @overload
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
*/
CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D& image);
/** @overload */
/** @overload
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
*/
CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D&& image) {
DataHelper<2>::setSubImage(*this, GLenum(coordinate), level, offset, image);
return *this;
return setSubImage(coordinate, level, offset, image);
}
#endif
/** @copydoc Texture::generateMipmap() */
/**
* @copybrief Texture::generateMipmap()
* @return Reference to self (for method chaining)
*
* See @ref Texture::generateMipmap() for more information.
* @requires_gl30 Extension @extension{ARB,framebuffer_object}
*/
CubeMapTexture& generateMipmap() {
AbstractTexture::generateMipmap();
return *this;
}
/** @copydoc Texture::invalidateImage() */
/**
* @copybrief Texture::invalidateImage()
*
* See @ref Texture::invalidateImage() for more information.
*/
void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); }
/**
* @brief Invalidate texture subimage
* @param level Mip level
* @param offset Offset into the texture
* @param size Size of invalidated data
* @copybrief Texture::invalidateSubImage()
*
* Z coordinate is equivalent to number of texture face, i.e.
* @ref Coordinate::PositiveX is `0` and so on, in the same order as in
@ -394,6 +503,26 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
return *this;
}
#endif
private:
Vector2i MAGNUM_LOCAL getImageSizeImplementationDefault(Int level);
#ifndef MAGNUM_TARGET_GLES
Vector2i MAGNUM_LOCAL getImageSizeImplementationDSA(Int level);
Vector2i MAGNUM_LOCAL getImageSizeImplementationDSAEXT(Int level);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL getImageImplementationDefault(Coordinate coordinate, GLint level, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationDSA(Coordinate coordinate, GLint level, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationDSAEXT(Coordinate coordinate, GLint level, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationRobustness(Coordinate coordinate, GLint level, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
#endif
void MAGNUM_LOCAL subImageImplementationDefault(Coordinate coordinate, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL subImageImplementationDSA(Coordinate coordinate, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL subImageImplementationDSAEXT(Coordinate coordinate, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
};
}

136
src/Magnum/CubeMapTextureArray.h

@ -128,13 +128,23 @@ class CubeMapTextureArray: public AbstractTexture {
return *this;
}
/** @copydoc Texture::setMinificationFilter() */
/**
* @copybrief Texture::setMinificationFilter()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMinificationFilter() for more information.
*/
CubeMapTextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;
}
/** @copydoc Texture::setMagnificationFilter() */
/**
* @copybrief Texture::setMagnificationFilter()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMagnificationFilter() for more information.
*/
CubeMapTextureArray& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return *this;
@ -173,7 +183,12 @@ class CubeMapTextureArray: public AbstractTexture {
return *this;
}
/** @copydoc Texture::setWrapping() */
/**
* @copybrief Texture::setWrapping()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setWrapping() for more information.
*/
CubeMapTextureArray& setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
DataHelper<3>::setWrapping(*this, wrapping);
return *this;
@ -197,31 +212,39 @@ class CubeMapTextureArray: public AbstractTexture {
*
* See @ref Texture::setBorderColor(const Vector4ui&) for more
* information.
* @requires_gl30 Extension @extension{EXT,texture_integer}
*/
CubeMapTextureArray& setBorderColor(const Vector4ui& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
/**
* @copybrief Texture::setBorderColor(const Vector4ui&)
* @return Reference to self (for method chaining)
*
* See @ref Texture::setBorderColor(const Vector4i&) for more
* information.
/** @overload
* @requires_gl30 Extension @extension{EXT,texture_integer}
*/
CubeMapTextureArray& setBorderColor(const Vector4i& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
/** @copydoc Texture::setMaxAnisotropy() */
/**
* @copybrief Texture::setMaxAnisotropy()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMaxAnisotropy() for more information.
*/
CubeMapTextureArray& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return *this;
}
/** @copydoc RectangleTexture::setSRGBDecode() */
/**
* @copybrief Texture::setSRGBDecode()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setSRGBDecode() for more information.
* @requires_extension Extension @extension{EXT,texture_sRGB_decode}
*/
CubeMapTextureArray& setSRGBDecode(bool decode) {
AbstractTexture::setSRGBDecode(decode);
return *this;
@ -232,6 +255,7 @@ class CubeMapTextureArray: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* See @ref Texture::setSwizzle() for more information.
* @requires_gl33 Extension @extension{ARB,texture_swizzle}
*/
template<char r, char g, char b, char a> CubeMapTextureArray& setSwizzle() {
AbstractTexture::setSwizzle<r, g, b, a>();
@ -265,6 +289,7 @@ class CubeMapTextureArray: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* See @ref Texture::setDepthStencilMode() for more information.
* @requires_gl43 Extension @extension{ARB,stencil_texturing}
*/
CubeMapTextureArray& setDepthStencilMode(Sampler::DepthStencilMode mode) {
AbstractTexture::setDepthStencilMode(mode);
@ -272,57 +297,49 @@ class CubeMapTextureArray: public AbstractTexture {
}
/**
* @brief Image size in given mip level
* @param level Mip level
* @copybrief Texture::setStorage()
* @return Reference to self (for method chaining)
*
* See @ref Texture::imageSize() for more information.
* Z coordinate of @p size must be multiple of 6.
*
* See @ref Texture::setStorage() for more information.
* @see @ref maxSize()
*/
Vector3i imageSize(Int level) {
return DataHelper<3>::imageSize(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level);
CubeMapTextureArray& setStorage(Int levels, TextureFormat internalFormat, const Vector3i& size) {
DataHelper<3>::setStorage(*this, levels, internalFormat, size);
return *this;
}
/**
* @brief Set storage
* @copybrief Texture::imageSize()
*
* Z coordinate of @p size must be multiple of 6. See
* @ref Texture::setStorage() for more information.
* @see @ref maxSize()
* See @ref Texture::imageSize() for more information.
*/
CubeMapTextureArray& setStorage(Int levels, TextureFormat internalFormat, const Vector3i& size) {
DataHelper<3>::setStorage(*this, _target, levels, internalFormat, size);
return *this;
Vector3i imageSize(Int level) {
return DataHelper<3>::imageSize(*this, level);
}
/**
* @brief Read given mip level of texture to image
* @param level Mip level
* @param image Image where to put the data
* @copybrief Texture::image(Int, Image&)
*
* See @ref Texture::image(Int, Image&) for more information.
*/
void image(Int level, Image3D& image) {
AbstractTexture::image<3>(GL_TEXTURE_CUBE_MAP_ARRAY, level, image);
AbstractTexture::image<3>(level, image);
}
/**
* @brief Read given mip level of texture to buffer image
* @param level Mip level
* @param image Buffer image where to put the data
* @param usage Buffer usage
* @copybrief Texture::image(Int, BufferImage&, BufferUsage)
*
* See @ref Texture::image(Int, BufferImage&, BufferUsage) for more
* information.
*/
void image(Int level, BufferImage3D& image, BufferUsage usage) {
AbstractTexture::image<3>(GL_TEXTURE_CUBE_MAP_ARRAY, level, image, usage);
AbstractTexture::image<3>(level, image, usage);
}
/**
* @brief Set image data
* @param level Mip level
* @param internalFormat Internal format
* @param image @ref Image3D, @ref ImageReference3D or
* @ref Trade::ImageData3D
* @copybrief Texture::setImage()
* @return Reference to self (for method chaining)
*
* Sets texture image data from three-dimensional image for all cube
@ -337,27 +354,31 @@ class CubeMapTextureArray: public AbstractTexture {
* instead.
*/
CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, const ImageReference3D& image) {
DataHelper<3>::setImage(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image);
DataHelper<3>::setImage(*this, level, internalFormat, image);
return *this;
}
/** @overload */
/** @overload
* @deprecated_gl Prefer to use @ref Magnum::CubeMapTextureArray::setStorage() "setStorage()"
* and @ref Magnum::CubeMapTextureArray::setSubImage() "setSubImage()"
* instead.
*/
CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage3D& image) {
DataHelper<3>::setImage(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image);
DataHelper<3>::setImage(*this, level, internalFormat, image);
return *this;
}
/** @overload */
/** @overload
* @deprecated_gl Prefer to use @ref Magnum::CubeMapTextureArray::setStorage() "setStorage()"
* and @ref Magnum::CubeMapTextureArray::setSubImage() "setSubImage()"
* instead.
*/
CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage3D&& image) {
return setImage(level, internalFormat, image);
}
/**
* @brief Set texture image 3D subdata
* @param level Mip level
* @param offset Offset where to put data in the texture
* @param image @ref Image3D, @ref ImageReference3D or
* @ref Trade::ImageData3D
* @copybrief Texture::setSubImage()
* @return Reference to self (for method chaining)
*
* Z coordinate is equivalent to layer * 6 + number of texture face,
@ -366,13 +387,13 @@ class CubeMapTextureArray: public AbstractTexture {
* See @ref Texture::setSubImage() for more information.
*/
CubeMapTextureArray& setSubImage(Int level, const Vector3i& offset, const ImageReference3D& image) {
DataHelper<3>::setSubImage(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image);
DataHelper<3>::setSubImage(*this, level, offset, image);
return *this;
}
/** @overload */
CubeMapTextureArray& setSubImage(Int level, const Vector3i& offset, BufferImage3D& image) {
DataHelper<3>::setSubImage(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image);
DataHelper<3>::setSubImage(*this, level, offset, image);
return *this;
}
@ -381,20 +402,27 @@ class CubeMapTextureArray: public AbstractTexture {
return setSubImage(level, offset, image);
}
/** @copydoc Texture::generateMipmap() */
/**
* @copybrief Texture::generateMipmap()
* @return Reference to self (for method chaining)
*
* See @ref Texture::generateMipmap() for more information.
* @requires_gl30 Extension @extension{ARB,framebuffer_object}
*/
CubeMapTextureArray& generateMipmap() {
AbstractTexture::generateMipmap();
return *this;
}
/** @copydoc Texture::invalidateImage() */
/**
* @copybrief Texture::invalidateImage()
*
* See @ref Texture::invalidateImage() for more information.
*/
void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); }
/**
* @brief Invalidate texture subimage
* @param level Mip level
* @param offset Offset into the texture
* @param size Size of invalidated data
* @copybrief Texture::invalidateSubImage()
*
* Z coordinate is equivalent to layer * 6 + number of texture face,
* i.e. +X is `0` and so on, in order of (+X, -X, +Y, -Y, +Z, -Z).

97
src/Magnum/Implementation/TextureState.cpp

@ -69,33 +69,69 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
createImplementation = &AbstractTexture::createImplementationDefault;
}
/* Bind implementation */
/* Single bind implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
extensions.push_back(Extensions::GL::ARB::multi_bind::string());
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
/* Extension name added below */
unbindImplementation = &AbstractTexture::unbindImplementationDSA;
bindImplementation = &AbstractTexture::bindImplementationDSA;
} else if(context.isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
/* Extension name added below */
unbindImplementation = &AbstractTexture::unbindImplementationMulti;
bindMultiImplementation = &AbstractTexture::bindImplementationMulti;
bindImplementation = &AbstractTexture::bindImplementationMulti;
} else if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
/* Extension name added below */
unbindImplementation = &AbstractTexture::unbindImplementationDSAEXT;
bindMultiImplementation = &AbstractTexture::bindImplementationFallback;
bindImplementation = &AbstractTexture::bindImplementationDSAEXT;
} else
#endif
{
unbindImplementation = &AbstractTexture::unbindImplementationDefault;
bindMultiImplementation = &AbstractTexture::bindImplementationFallback;
bindImplementation = &AbstractTexture::bindImplementationDefault;
}
/* Multi bind implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
extensions.push_back(Extensions::GL::ARB::multi_bind::string());
bindMultiImplementation = &AbstractTexture::bindImplementationMulti;
} else
#endif
{
bindMultiImplementation = &AbstractTexture::bindImplementationFallback;
}
/* DSA/non-DSA implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
extensions.push_back(Extensions::GL::ARB::direct_state_access::string());
parameteriImplementation = &AbstractTexture::parameterImplementationDSA;
parameterfImplementation = &AbstractTexture::parameterImplementationDSA;
parameterivImplementation = &AbstractTexture::parameterImplementationDSA;
parameterfvImplementation = &AbstractTexture::parameterImplementationDSA;
parameterIuivImplementation = &AbstractTexture::parameterIImplementationDSA;
parameterIivImplementation = &AbstractTexture::parameterIImplementationDSA;
getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSA;
mipmapImplementation = &AbstractTexture::mipmapImplementationDSA;
subImage1DImplementation = &AbstractTexture::subImageImplementationDSA;
subImage2DImplementation = &AbstractTexture::subImageImplementationDSA;
subImage3DImplementation = &AbstractTexture::subImageImplementationDSA;
setBufferImplementation = &BufferTexture::setBufferImplementationDSA;
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSA;
getCubeImageSizeImplementation = &CubeMapTexture::getImageSizeImplementationDSA;
cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDSA;
} else if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
extensions.push_back(Extensions::GL::EXT::direct_state_access::string());
parameteriImplementation = &AbstractTexture::parameterImplementationDSAEXT;
@ -106,13 +142,16 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
parameterIivImplementation = &AbstractTexture::parameterIImplementationDSAEXT;
getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSAEXT;
mipmapImplementation = &AbstractTexture::mipmapImplementationDSAEXT;
getImageImplementation = &AbstractTexture::getImageImplementationDSAEXT;
subImage1DImplementation = &AbstractTexture::subImageImplementationDSAEXT;
subImage2DImplementation = &AbstractTexture::subImageImplementationDSAEXT;
subImage3DImplementation = &AbstractTexture::subImageImplementationDSAEXT;
setBufferImplementation = &BufferTexture::setBufferImplementationDSAEXT;
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSAEXT;
getCubeImageSizeImplementation = &CubeMapTexture::getImageSizeImplementationDSAEXT;
cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDSAEXT;
} else
#endif
{
@ -131,9 +170,6 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
#endif
mipmapImplementation = &AbstractTexture::mipmapImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
getImageImplementation = &AbstractTexture::getImageImplementationDefault;
#endif
#ifndef MAGNUM_TARGET_GLES
subImage1DImplementation = &AbstractTexture::subImageImplementationDefault;
#endif
subImage2DImplementation = &AbstractTexture::subImageImplementationDefault;
@ -143,6 +179,11 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
setBufferImplementation = &BufferTexture::setBufferImplementationDefault;
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDefault;
#endif
#ifndef MAGNUM_TARGET_GLES2
getCubeImageSizeImplementation = &CubeMapTexture::getImageSizeImplementationDefault;
#endif
cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDefault;
}
/* Data invalidation implementation */
@ -159,14 +200,28 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationNoOp;
}
/* Image retrieval implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::robustness>() &&
!context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
/* Image retrieval implementation */
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
/* Extension name added above */
getImageImplementation = &AbstractTexture::getImageImplementationDSA;
getCubeImageImplementation = &CubeMapTexture::getImageImplementationDSA;
} else if(context.isExtensionSupported<Extensions::GL::ARB::robustness>()) {
extensions.push_back(Extensions::GL::ARB::robustness::string());
getImageImplementation = &AbstractTexture::getImageImplementationRobustness;
} else getImageImplementation = &AbstractTexture::getImageImplementationDefault;
getCubeImageImplementation = &CubeMapTexture::getImageImplementationRobustness;
} else if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
/* Extension name added above */
getImageImplementation = &AbstractTexture::getImageImplementationDSAEXT;
getCubeImageImplementation = &CubeMapTexture::getImageImplementationDSAEXT;
} else {
getImageImplementation = &AbstractTexture::getImageImplementationDefault;
getCubeImageImplementation = &CubeMapTexture::getImageImplementationDefault;
}
#endif
/* Texture storage implementation */
@ -183,7 +238,12 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
#endif
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
storage1DImplementation = &AbstractTexture::storageImplementationDSA;
storage2DImplementation = &AbstractTexture::storageImplementationDSA;
storage3DImplementation = &AbstractTexture::storageImplementationDSA;
} else if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
storage1DImplementation = &AbstractTexture::storageImplementationDSAEXT;
storage2DImplementation = &AbstractTexture::storageImplementationDSAEXT;
storage3DImplementation = &AbstractTexture::storageImplementationDSAEXT;
@ -213,7 +273,10 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
if(context.isExtensionSupported<Extensions::GL::ARB::texture_storage_multisample>()) {
extensions.push_back(Extensions::GL::ARB::texture_storage_multisample::string());
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA;
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA;
} else if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT;
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT;
} else {

31
src/Magnum/Implementation/TextureState.h

@ -28,8 +28,7 @@
#include <string>
#include <vector>
#include "Magnum/Magnum.h"
#include "Magnum/OpenGL.h"
#include "Magnum/CubeMapTexture.h"
namespace Magnum { namespace Implementation {
@ -55,26 +54,26 @@ struct TextureState {
#endif
void(AbstractTexture::*setMaxAnisotropyImplementation)(GLfloat);
#ifndef MAGNUM_TARGET_GLES2
void(AbstractTexture::*getLevelParameterivImplementation)(GLenum, GLint, GLenum, GLint*);
void(AbstractTexture::*getLevelParameterivImplementation)(GLint, GLenum, GLint*);
#endif
void(AbstractTexture::*mipmapImplementation)();
#ifndef MAGNUM_TARGET_GLES
void(AbstractTexture::*storage1DImplementation)(GLenum, GLsizei, TextureFormat, const Math::Vector<1, GLsizei>&);
void(AbstractTexture::*storage1DImplementation)(GLsizei, TextureFormat, const Math::Vector<1, GLsizei>&);
#endif
void(AbstractTexture::*storage2DImplementation)(GLenum, GLsizei, TextureFormat, const Vector2i&);
void(AbstractTexture::*storage3DImplementation)(GLenum, GLsizei, TextureFormat, const Vector3i&);
void(AbstractTexture::*storage2DImplementation)(GLsizei, TextureFormat, const Vector2i&);
void(AbstractTexture::*storage3DImplementation)(GLsizei, TextureFormat, const Vector3i&);
#ifndef MAGNUM_TARGET_GLES2
void(AbstractTexture::*storage2DMultisampleImplementation)(GLenum, GLsizei, TextureFormat, const Vector2i&, GLboolean);
void(AbstractTexture::*storage2DMultisampleImplementation)(GLsizei, TextureFormat, const Vector2i&, GLboolean);
#endif
#ifndef MAGNUM_TARGET_GLES
void(AbstractTexture::*storage3DMultisampleImplementation)(GLenum, GLsizei, TextureFormat, const Vector3i&, GLboolean);
void(AbstractTexture::*getImageImplementation)(GLenum, GLint, ColorFormat, ColorType, std::size_t, GLvoid*);
void(AbstractTexture::*storage3DMultisampleImplementation)(GLsizei, TextureFormat, const Vector3i&, GLboolean);
void(AbstractTexture::*getImageImplementation)(GLint, ColorFormat, ColorType, std::size_t, GLvoid*);
#endif
#ifndef MAGNUM_TARGET_GLES
void(AbstractTexture::*subImage1DImplementation)(GLenum, GLint, const Math::Vector<1, GLint>&, const Math::Vector<1, GLsizei>&, ColorFormat, ColorType, const GLvoid*);
void(AbstractTexture::*subImage1DImplementation)(GLint, const Math::Vector<1, GLint>&, const Math::Vector<1, GLsizei>&, ColorFormat, ColorType, const GLvoid*);
#endif
void(AbstractTexture::*subImage2DImplementation)(GLenum, GLint, const Vector2i&, const Vector2i&, ColorFormat, ColorType, const GLvoid*);
void(AbstractTexture::*subImage3DImplementation)(GLenum, GLint, const Vector3i&, const Vector3i&, ColorFormat, ColorType, const GLvoid*);
void(AbstractTexture::*subImage2DImplementation)(GLint, const Vector2i&, const Vector2i&, ColorFormat, ColorType, const GLvoid*);
void(AbstractTexture::*subImage3DImplementation)(GLint, const Vector3i&, const Vector3i&, ColorFormat, ColorType, const GLvoid*);
void(AbstractTexture::*invalidateImageImplementation)(GLint);
void(AbstractTexture::*invalidateSubImageImplementation)(GLint, const Vector3i&, const Vector3i&);
@ -83,6 +82,14 @@ struct TextureState {
void(BufferTexture::*setBufferRangeImplementation)(BufferTextureFormat, Buffer&, GLintptr, GLsizeiptr);
#endif
#ifndef MAGNUM_TARGET_GLES2
Vector2i(CubeMapTexture::*getCubeImageSizeImplementation)(Int);
#endif
#ifndef MAGNUM_TARGET_GLES
void(CubeMapTexture::*getCubeImageImplementation)(CubeMapTexture::Coordinate, GLint, const Vector2i&, ColorFormat, ColorType, std::size_t, GLvoid*);
#endif
void(CubeMapTexture::*cubeSubImageImplementation)(CubeMapTexture::Coordinate, GLint, const Vector2i&, const Vector2i&, ColorFormat, ColorType, const GLvoid*);
GLint maxSize,
max3DSize,
maxCubeMapSize;

65
src/Magnum/MultisampleTexture.h

@ -122,21 +122,6 @@ template<UnsignedInt dimensions> class MultisampleTexture: public AbstractTextur
*/
explicit MultisampleTexture(): AbstractTexture(Implementation::multisampleTextureTarget<dimensions>()) {}
/**
* @brief Image size
*
* The result is not cached in any way. If
* @extension{EXT,direct_state_access} is not available, the texture
* is bound to some texture unit before the operation.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or
* @def_gl{TEXTURE_DEPTH}
*/
VectorTypeFor<dimensions, Int> imageSize() {
return DataHelper<dimensions>::imageSize(*this, _target, 0);
}
/**
* @brief Set storage
* @param samples Sample count
@ -148,19 +133,20 @@ template<UnsignedInt dimensions> class MultisampleTexture: public AbstractTextur
* After calling this function the texture is immutable and calling
* @ref setStorage() again is not allowed.
*
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some texture unit before the operation. If
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the texture is bound before the operation (if not already). If
* @extension{ARB,texture_storage_multisample} (part of OpenGL 4.3) is
* not available, the feature is emulated using plain
* @extension{ARB,texture_storage} functionality (which unfortunately
* doesn't have any DSA alternative, so the texture must be bound
* to some texture unit before).
* not available, the texture is bound and the feature is emulated
* using plain @extension{ARB,texture_multisample} functionality.
* @see @ref maxSize(), @ref maxColorSamples(), @ref maxDepthSamples(),
* @ref maxIntegerSamples(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture}
* and @fn_gl{TexStorage2DMultisample}/@fn_gl{TexStorage3DMultisample}
* or @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access}/
* @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access}
* eventually @fn_gl{TexImage2DMultisample}/@fn_gl{TexImage3DMultisample}
* @ref maxIntegerSamples(), @fn_gl2{TextureStorage2DMultisample,TexStorage2DMultisample} /
* @fn_gl2{TextureStorage3DMultisample,TexStorage3DMultisample},
* @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access} /
* @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture}
* and @fn_gl{TexStorage2DMultisample} / @fn_gl{TexStorage3DMultisample}
* or @fn_gl{TexImage2DMultisample} / @fn_gl{TexImage3DMultisample}
* @todoc Remove the workaround when it stops breaking Doxygen layout so badly
*/
/* The default parameter value was chosen based on discussion in
@ -173,14 +159,35 @@ template<UnsignedInt dimensions> class MultisampleTexture: public AbstractTextur
NotFixed
#endif
) {
DataHelper<dimensions>::setStorageMultisample(*this, _target, samples, internalFormat, size, GLboolean(sampleLocations));
DataHelper<dimensions>::setStorageMultisample(*this, samples, internalFormat, size, GLboolean(sampleLocations));
return *this;
}
/** @copydoc RectangleTexture::invalidateImage() */
/**
* @brief Texture image size
*
* See @ref Texture::imageSize() for more information.
* @requires_gles31 Texture image size queries are not available in
* OpenGL ES 3.0 and older.
*/
VectorTypeFor<dimensions, Int> imageSize() {
return DataHelper<dimensions>::imageSize(*this, 0);
}
/**
* @copybrief Texture::invalidateImage()
* @return Reference to self (for method chaining)
*
* See @ref Texture::invalidateImage() for more information.
*/
void invalidateImage() { AbstractTexture::invalidateImage(0); }
/** @copydoc RectangleTexture::invalidateSubImage() */
/**
* @copybrief Texture::invalidateSubImage()
* @return Reference to self (for method chaining)
*
* See @ref Texture::invalidateSubImage() for more information.
*/
void invalidateSubImage(const VectorTypeFor<dimensions, Int>& offset, const VectorTypeFor<dimensions, Int>& size) {
DataHelper<dimensions>::invalidateSubImage(*this, 0, offset, size);
}

187
src/Magnum/RectangleTexture.h

@ -92,59 +92,38 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture {
explicit RectangleTexture(): AbstractTexture(GL_TEXTURE_RECTANGLE) {}
/**
* @brief Set minification filter
* @param filter Filter
* @copybrief Texture::setMinificationFilter()
* @return Reference to self (for method chaining)
*
* Sets filter used when the object pixel size is smaller than the
* texture size. If @extension{EXT,direct_state_access} is not
* available, the texture is bound to some texture unit before the
* operation. Initial value is @ref Sampler::Filter::Linear.
* @see @ref setMagnificationFilter(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_MIN_FILTER}
* See @ref Texture::setMinificationFilter() for more information.
* Initial value is @ref Sampler::Filter::Linear.
*/
RectangleTexture& setMinificationFilter(Sampler::Filter filter) {
AbstractTexture::setMinificationFilter(filter, Sampler::Mipmap::Base);
return *this;
}
/** @copydoc Texture::setMagnificationFilter() */
/**
* @copybrief Texture::setMagnificationFilter()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMagnificationFilter() for more information.
*/
RectangleTexture& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return *this;
}
/**
* @brief Image size
*
* The result is not cached in any way. If
* @extension{EXT,direct_state_access} is not available, the texture
* is bound to some texture unit before the operation.
* @see @ref image(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_WIDTH} and @def_gl{TEXTURE_HEIGHT}
*/
Vector2i imageSize() { return DataHelper<2>::imageSize(*this, _target, 0); }
/**
* @brief Set wrapping
* @param wrapping Wrapping type for all texture dimensions
* @copybrief Texture::setWrapping()
* @return Reference to self (for method chaining)
*
* Sets wrapping type for coordinates out of @f$ [ 0, size - 1 ] @f$
* range. If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some texture unit before the operation. Initial
* range. See @ref Texture::setWrapping() for more information. Initial
* value is @ref Sampler::Wrapping::ClampToEdge.
* @attention Only @ref Sampler::Wrapping::ClampToEdge and
* @ref Sampler::Wrapping::ClampToBorder is supported on this
* texture type.
* @see @ref setBorderColor(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T},
* @def_gl{TEXTURE_WRAP_R}
*/
RectangleTexture& setWrapping(const Array2D<Sampler::Wrapping>& wrapping) {
DataHelper<2>::setWrapping(*this, wrapping);
@ -169,40 +148,37 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture {
*
* See @ref Texture::setBorderColor(const Vector4ui&) for more
* information.
* @requires_gl30 Extension @extension{EXT,texture_integer}
*/
RectangleTexture& setBorderColor(const Vector4ui& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
/**
* @copybrief Texture::setBorderColor(const Vector4ui&)
* @return Reference to self (for method chaining)
*
* See @ref Texture::setBorderColor(const Vector4i&) for more
* information.
/** @overload
* @requires_gl30 Extension @extension{EXT,texture_integer}
*/
RectangleTexture& setBorderColor(const Vector4i& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
/** @copydoc Texture::setMaxAnisotropy() */
/**
* @copybrief Texture::setMaxAnisotropy()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMaxAnisotropy() for more information.
*/
RectangleTexture& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return *this;
}
/**
* @brief Set sRGB decoding
* @copybrief Texture::setSRGBDecode()
* @return Reference to self (for method chaining)
*
* Disables or reenables decoding of sRGB values. Initial value is
* `true`.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_SRGB_DECODE_EXT}
* See @ref Texture::setSRGBDecode() for more information.
* @requires_extension Extension @extension{EXT,texture_sRGB_decode}
*/
RectangleTexture& setSRGBDecode(bool decode) {
@ -215,6 +191,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* See @ref Texture::setSwizzle() for more information.
* @requires_gl33 Extension @extension{ARB,texture_swizzle}
*/
template<char r, char g, char b, char a> RectangleTexture& setSwizzle() {
AbstractTexture::setSwizzle<r, g, b, a>();
@ -248,6 +225,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* See @ref Texture::setDepthStencilMode() for more information.
* @requires_gl43 Extension @extension{ARB,stencil_texturing}
*/
RectangleTexture& setDepthStencilMode(Sampler::DepthStencilMode mode) {
AbstractTexture::setDepthStencilMode(mode);
@ -255,124 +233,91 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture {
}
/**
* @brief Set storage
* @param internalFormat Internal format
* @param size Texture size
* @copybrief Texture::setStorage()
* @return Reference 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 @ref setStorage() or @ref setImage() is not
* allowed.
*
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some texture unit before the operation. If
* @extension{ARB,texture_storage} (part of OpenGL 4.2), OpenGL ES 3.0
* or @es_extension{EXT,texture_storage} in OpenGL ES 2.0 is not
* available, the feature is emulated with @ref setImage() call.
* @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexStorage2D} or
* @fn_gl_extension{TextureStorage2D,EXT,direct_state_access},
* eventually @fn_gl{TexImage2D} or
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}.
* See @ref Texture::setStorage() for more information.
* @see @ref maxSize()
*/
RectangleTexture& setStorage(TextureFormat internalFormat, const Vector2i& size) {
DataHelper<2>::setStorage(*this, _target, 1, internalFormat, size);
DataHelper<2>::setStorage(*this, 1, internalFormat, size);
return *this;
}
/**
* @brief Read texture to image
* @param image Image where to put the data
* @brief Texture image size
*
* Image parameters like format and type of pixel data are taken from
* given image, image size is taken from the texture using
* @ref imageSize().
* See @ref Texture::imageSize() for more information.
*/
Vector2i imageSize() { return DataHelper<2>::imageSize(*this, 0); }
/**
* @brief Read texture to image
*
* If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some texture unit before the operation. If
* @extension{ARB,robustness} is available, the operation is protected
* from buffer overflow. However, if both @extension{EXT,direct_state_access}
* and @extension{ARB,robustness} are available, the DSA version is
* used, because it is better for performance and there isn't any
* function combining both features.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_WIDTH} and @def_gl{TEXTURE_HEIGHT}, then
* @fn_gl{GetTexImage}, @fn_gl_extension{GetTextureImage,EXT,direct_state_access}
* or @fn_gl_extension{GetnTexImage,ARB,robustness}
* See @ref Texture::image(Int, Image&) for more information.
*/
void image(Image2D& image) {
AbstractTexture::image<2>(_target, 0, image);
AbstractTexture::image<2>(0, image);
}
/**
* @brief Read given mip level of texture to buffer image
* @param image Buffer image where to put the data
* @param usage Buffer usage
* @brief Read texture to buffer image
*
* See @ref image(Image2D&) for more information.
* See @ref Texture::image(Int, BufferImage&, BufferUsage) for more
* information.
*/
void image(BufferImage2D& image, BufferUsage usage) {
AbstractTexture::image<2>(_target, 0, image, usage);
AbstractTexture::image<2>(0, image, usage);
}
/**
* @brief Set image data
* @param internalFormat Internal format
* @param image @ref Image2D, @ref ImageReference2D or
* @ref Trade::ImageData2D
* @copybrief Texture::setImage()
* @return Reference to self (for method chaining)
*
* On platforms that support it prefer to use @ref setStorage() and
* @ref setSubImage() instead, as it avoids unnecessary reallocations
* and has better performance characteristics. This call also has no
* equivalent in @extension{ARB,direct_state_access}, thus the texture
* needs to be bound to some texture unit before the operation.
* @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexImage2D}
* See @ref Texture::setImage() for more information.
* @see @ref maxSize()
* @deprecated_gl Prefer to use @ref Magnum::RectangleTexture::setStorage() "setStorage()"
* and @ref Magnum::RectangleTexture::setSubImage() "setSubImage()"
* instead.
*/
RectangleTexture& setImage(TextureFormat internalFormat, const ImageReference2D& image) {
DataHelper<2>::setImage(*this, _target, 0, internalFormat, image);
DataHelper<2>::setImage(*this, 0, internalFormat, image);
return *this;
}
/** @overload */
/** @overload
* @deprecated_gl Prefer to use @ref Magnum::RectangleTexture::setStorage() "setStorage()"
* and @ref Magnum::RectangleTexture::setSubImage() "setSubImage()"
* instead.
*/
RectangleTexture& setImage(TextureFormat internalFormat, BufferImage2D& image) {
DataHelper<2>::setImage(*this, _target, 0, internalFormat, image);
DataHelper<2>::setImage(*this, 0, internalFormat, image);
return *this;
}
/** @overload */
/** @overload
* @deprecated_gl Prefer to use @ref Magnum::RectangleTexture::setStorage() "setStorage()"
* and @ref Magnum::RectangleTexture::setSubImage() "setSubImage()"
* instead.
*/
RectangleTexture& setImage(TextureFormat internalFormat, BufferImage2D&& image) {
return setImage(internalFormat, image);
}
/**
* @brief Set image subdata
* @param offset Offset where to put data in the texture
* @param image @ref Image2D, @ref ImageReference2D or
* @ref Trade::ImageData2D
* @copybrief Texture::setSubImage()
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some texture unit before the operation.
* @see @ref setStorage(), @ref setImage(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexSubImage2D} or
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}
* See @ref Texture::setSubImage() for more information.
*/
RectangleTexture& setSubImage(const Vector2i& offset, const ImageReference2D& image) {
DataHelper<2>::setSubImage(*this, _target, 0, offset, image);
DataHelper<2>::setSubImage(*this, 0, offset, image);
return *this;
}
/** @overload */
RectangleTexture& setSubImage(const Vector2i& offset, BufferImage2D& image) {
DataHelper<2>::setSubImage(*this, _target, 0, offset, image);
DataHelper<2>::setSubImage(*this, 0, offset, image);
return *this;
}
@ -382,22 +327,18 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture {
}
/**
* @brief Invalidate texture image
* @brief Invalidate texture
*
* If extension @extension{ARB,invalidate_subdata} (part of OpenGL 4.3)
* is not available, this function does nothing.
* @see @ref invalidateSubImage(), @fn_gl{InvalidateTexImage}
* See @ref Texture::invalidateImage() for more information.
*/
void invalidateImage() { AbstractTexture::invalidateImage(0); }
/**
* @brief Invalidate texture subimage
* @brief Invalidate subtexture
* @param offset Offset into the texture
* @param size Size of invalidated data
*
* If extension @extension{ARB,invalidate_subdata} (part of OpenGL 4.3)
* is not available, this function does nothing.
* @see @ref invalidateImage(), @fn_gl{InvalidateTexSubImage}
* See @ref Texture::invalidateSubImage() for more information.
*/
void invalidateSubImage(const Vector2i& offset, const Vector2i& size) {
DataHelper<2>::invalidateSubImage(*this, 0, offset, size);

63
src/Magnum/Test/CubeMapTextureGLTest.cpp

@ -265,48 +265,13 @@ void CubeMapTextureGLTest::storage() {
CORRADE_SKIP("OpenGL ES 3.1 not supported, skipping image size testing");
#endif
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 1), Vector2i(16));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 1), Vector2i(16));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 1), Vector2i(16));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 1), Vector2i(16));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 1), Vector2i(16));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 1), Vector2i(16));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 2), Vector2i(8));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 2), Vector2i(8));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 2), Vector2i(8));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 2), Vector2i(8));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 2), Vector2i(8));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 2), Vector2i(8));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 3), Vector2i(4));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 3), Vector2i(4));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 3), Vector2i(4));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 3), Vector2i(4));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 3), Vector2i(4));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 3), Vector2i(4));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 4), Vector2i(2));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 4), Vector2i(2));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 4), Vector2i(2));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 4), Vector2i(2));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 4), Vector2i(2));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 4), Vector2i(2));
CORRADE_COMPARE(texture.imageSize(0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(1), Vector2i(16));
CORRADE_COMPARE(texture.imageSize(2), Vector2i(8));
CORRADE_COMPARE(texture.imageSize(3), Vector2i(4));
CORRADE_COMPARE(texture.imageSize(4), Vector2i(2));
/* Not available */
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 5), Vector2i(0));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 5), Vector2i(0));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 5), Vector2i(0));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 5), Vector2i(0));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 5), Vector2i(0));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 5), Vector2i(0));
CORRADE_COMPARE(texture.imageSize(5), Vector2i(0));
MAGNUM_VERIFY_NO_ERROR();
#endif
@ -445,8 +410,8 @@ void CubeMapTextureGLTest::generateMipmap() {
/** @todo How to test this on ES? */
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 1), Vector2i( 0));
CORRADE_COMPARE(texture.imageSize(0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(1), Vector2i( 0));
#endif
texture.generateMipmap();
@ -455,12 +420,12 @@ void CubeMapTextureGLTest::generateMipmap() {
/** @todo How to test this on ES? */
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 1), Vector2i(16));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 2), Vector2i( 8));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 3), Vector2i( 4));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 4), Vector2i( 2));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 5), Vector2i( 1));
CORRADE_COMPARE(texture.imageSize(0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(1), Vector2i(16));
CORRADE_COMPARE(texture.imageSize(2), Vector2i( 8));
CORRADE_COMPARE(texture.imageSize(3), Vector2i( 4));
CORRADE_COMPARE(texture.imageSize(4), Vector2i( 2));
CORRADE_COMPARE(texture.imageSize(5), Vector2i( 1));
MAGNUM_VERIFY_NO_ERROR();
#endif

411
src/Magnum/Texture.h

@ -188,25 +188,6 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
constexpr CORRADE_DEPRECATED("use dedicated Texture, TextureArray, MultisampleTexture, RectangleTexture classes instead") Target target() const { return static_cast<Target>(_target); }
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Image size in given mip level
*
* The result is not cached in any way. If
* @extension{EXT,direct_state_access} is not available, the texture
* is bound to some texture unit before the operation.
* @see @ref image(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or
* @def_gl{TEXTURE_DEPTH}
* @requires_gles31 Texture image size queries are not available in
* OpenGL ES 3.0 and older.
*/
VectorTypeFor<dimensions, Int> imageSize(Int level) {
return DataHelper<dimensions>::imageSize(*this, _target, level);
}
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Set base mip level
@ -214,11 +195,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
*
* Taken into account when generating mipmap using @ref generateMipmap()
* and when considering texture completeness when using mipmap
* filtering. Initial value is `0`.
* filtering. If on OpenGL ES or neither @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* available, the texture is bound before the operation (if not
* already). Initial value is `0`.
* @see @ref setMaxLevel(), @ref setMinificationFilter(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_BASE_LEVEL}
* @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_BASE_LEVEL}
* @requires_gles30 Base level is always `0` in OpenGL ES 2.0.
*/
Texture<dimensions>& setBaseLevel(Int level) {
@ -233,12 +218,16 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
*
* Taken into account when generating mipmap using @ref generateMipmap()
* and when considering texture completeness when using mipmap
* filtering. Initial value is `1000`, which is clamped to count of
* filtering. If on OpenGL ES or neither @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* available, the texture is bound before the operation (if not
* already). Initial value is `1000`, which is clamped to count of
* levels specified when using @ref setStorage().
* @see @ref setBaseLevel(), @ref setMinificationFilter(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_MAX_LEVEL}
* @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_MAX_LEVEL}
* @requires_gles30 Extension @es_extension{APPLE,texture_max_level},
* otherwise the max level is always set to largest possible value
* in OpenGL ES 2.0.
@ -257,15 +246,16 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* Sets filter used when the object pixel size is smaller than the
* texture size. If @extension{EXT,direct_state_access} is not
* available, the texture is bound to some texture unit before the
* operation. Initial value is {@ref Sampler::Filter::Nearest,
* texture size. If on OpenGL ES or neither @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* available, the texture is bound before the operation (if not
* already). Initial value is {@ref Sampler::Filter::Nearest,
* @ref Sampler::Mipmap::Linear}.
* @see @ref setMagnificationFilter(), @ref setBaseLevel(),
* @ref setMaxLevel(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture}
* and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_MIN_FILTER}
* @ref setMaxLevel(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_MIN_FILTER}
*/
Texture<dimensions>& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
@ -278,13 +268,14 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* Sets filter used when the object pixel size is larger than largest
* texture size. If @extension{EXT,direct_state_access} is not
* available, the texture is bound to some texture unit before the
* operation. Initial value is @ref Sampler::Filter::Linear.
* @see @ref setMinificationFilter(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_MAG_FILTER}
* texture size. If on OpenGL ES or neither @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* available, the texture is bound before the operation (if not
* already). Initial value is @ref Sampler::Filter::Linear.
* @see @ref setMinificationFilter(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_MAG_FILTER}
*/
Texture<dimensions>& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
@ -296,14 +287,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @brief Set minimum level-of-detail parameter
* @return Reference to self (for method chaining)
*
* Limits selection of highest resolution mipmap. If
* @extension{EXT,direct_state_access} is not available, the texture is
* bound to some texture unit before the operation. Initial value is
* Limits selection of highest resolution mipmap. If on OpenGL ES or
* neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already). Initial value is
* `-1000.0f`.
* @see @ref setMaxLod(), @ref setLodBias(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_MIN_LOD}
* @see @ref setMaxLod(), @ref setLodBias(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_MIN_LOD}
* @requires_gles30 Texture LOD parameters are not available in OpenGL
* ES 2.0.
*/
@ -316,14 +308,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @brief Set maximum level-of-detail parameter
* @return Reference to self (for method chaining)
*
* Limits selection of lowest resolution mipmap. If
* @extension{EXT,direct_state_access} is not available, the texture is
* bound to some texture unit before the operation. Initial value is
* Limits selection of lowest resolution mipmap. If on OpenGL ES or
* neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already). Initial value is
* `1000.0f`.
* @see @ref setMinLod(), @ref setLodBias(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_MAX_LOD}
* @see @ref setMinLod(), @ref setLodBias(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_MAX_LOD}
* @requires_gles30 Texture LOD parameters are not available in OpenGL
* ES 2.0.
*/
@ -339,13 +332,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* Fixed bias value that is added to the level-of-detail parameter. If
* @extension{EXT,direct_state_access} is not available, the texture is
* bound to some texture unit before the operation. Initial value is
* neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already). Initial value is
* `0.0f`.
* @see @ref maxLodBias(), @ref setMinLod(), @ref setMaxLod(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_LOD_BIAS}
* @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_LOD_BIAS}
* @requires_gl Texture LOD bias can be specified only directly in
* fragment shader in OpenGL ES.
*/
@ -361,14 +356,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* Sets wrapping type for coordinates out of range @f$ [ 0.0, 1.0 ] @f$.
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some texture unit before the operation. Initial value is
* @ref Sampler::Wrapping::Repeat.
* @see @ref setBorderColor(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T},
* @def_gl{TEXTURE_WRAP_R}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the texture is bound before the operation (if not already). Initial
* value is @ref Sampler::Wrapping::Repeat.
* @see @ref setBorderColor(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_WRAP_S},
* @def_gl{TEXTURE_WRAP_T}, @def_gl{TEXTURE_WRAP_R}
*/
Texture<dimensions>& setWrapping(const Array<dimensions, Sampler::Wrapping>& wrapping) {
DataHelper<dimensions>::setWrapping(*this, wrapping);
@ -380,13 +376,14 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* Border color when wrapping is set to @ref Sampler::Wrapping::ClampToBorder.
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some texture unit before the operation. Initial value is
* `{0.0f, 0.0f, 0.0f, 0.0f}`.
* @see @ref setWrapping(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture}
* and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_BORDER_COLOR}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the texture is bound before the operation (if not already). Initial
* value is `{0.0f, 0.0f, 0.0f, 0.0f}`.
* @see @ref setWrapping(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_BORDER_COLOR}
* @requires_es_extension Extension @es_extension{NV,texture_border_clamp}
*/
Texture<dimensions>& setBorderColor(const Color4& color) {
@ -400,12 +397,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* Border color for integer textures when wrapping is set to
* @ref Sampler::Wrapping::ClampToBorder. If @extension{EXT,direct_state_access}
* is not available, the texture is bound to some texture unit before
* the operation. Initial value is `{0, 0, 0, 0}`.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_BORDER_COLOR}
* @ref Sampler::Wrapping::ClampToBorder. If neither
* @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already). Initial value is
* `{0, 0, 0, 0}`.
* @see @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_BORDER_COLOR}
* @requires_gl30 Extension @extension{EXT,texture_integer}
* @requires_gl Border is available only for float textures in OpenGL
* ES.
@ -433,13 +433,14 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* Default value is `1.0f`, which means no anisotropy. Set to value
* greater than `1.0f` for anisotropic filtering. If extension
* @extension{EXT,texture_filter_anisotropic} (desktop or ES) is not
* available, this function does nothing. If
* @extension{EXT,direct_state_access} is not available, the texture is
* bound to some texture unit before the operation.
* @see @ref Sampler::maxMaxAnisotropy(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_MAX_ANISOTROPY_EXT}
* available, this function does nothing. If on OpenGL ES or neither
* @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already).
* @see @ref Sampler::maxMaxAnisotropy(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_MAX_ANISOTROPY_EXT}
*/
Texture<dimensions>& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
@ -450,12 +451,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @brief Set sRGB decoding
* @return Reference to self (for method chaining)
*
* Disables or reenables decoding of sRGB values. Initial value is
* Disables or reenables decoding of sRGB values. If on OpenGL ES or
* neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already). Initial value is
* `true`.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_SRGB_DECODE_EXT}
* @see @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_SRGB_DECODE_EXT}
* @requires_extension Extension @extension{EXT,texture_sRGB_decode}
* @requires_es_extension OpenGL ES 3.0 or extension
* @es_extension{EXT,sRGB} and
@ -477,15 +481,17 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @code
* texture.setSwizzle<'b', 'g', 'r', '0'>();
* @endcode
* If @extension{EXT,direct_state_access} is not available,
* the texture is bound to some texture unit before the operation.
* Initial value is `rgba`.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_SWIZZLE_RGBA} (or @def_gl{TEXTURE_SWIZZLE_R},
* @def_gl{TEXTURE_SWIZZLE_G}, @def_gl{TEXTURE_SWIZZLE_B} and
* @def_gl{TEXTURE_SWIZZLE_A} separately in OpenGL ES)
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the texture is bound before the operation (if not already). Initial
* value is `rgba`.
* @see @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_SWIZZLE_RGBA} (or
* @def_gl{TEXTURE_SWIZZLE_R}, @def_gl{TEXTURE_SWIZZLE_G},
* @def_gl{TEXTURE_SWIZZLE_B} and @def_gl{TEXTURE_SWIZZLE_A}
* separately in OpenGL ES)
* @requires_gl33 Extension @extension{ARB,texture_swizzle}
* @requires_gles30 Texture swizzle is not available in OpenGL ES 2.0.
*/
@ -499,14 +505,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @brief Set depth texture comparison mode
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available,
* the texture is bound to some texture unit before the operation.
* Initial value is @ref Sampler::CompareMode::None.
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the texture is bound before the operation (if not already). Initial
* value is @ref Sampler::CompareMode::None.
* @note Depth textures can be only 1D or 2D.
* @see @ref setCompareFunction(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_COMPARE_MODE}
* @see @ref setCompareFunction(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_COMPARE_MODE}
* @requires_gles30 Extension @es_extension{EXT,shadow_samplers}
*/
Texture<dimensions>& setCompareMode(Sampler::CompareMode mode) {
@ -519,15 +526,16 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* Comparison operator used when comparison mode is set to
* @ref Sampler::CompareMode::CompareRefToTexture. If
* @extension{EXT,direct_state_access} is not available, the texture is
* bound to some texture unit before the operation. Initial value is
* @ref Sampler::CompareMode::CompareRefToTexture. If on OpenGL ES or
* neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already). Initial value is
* @ref Sampler::CompareFunction::LessOrEqual.
* @note Depth textures can be only 1D or 2D.
* @see @ref setCompareMode(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_COMPARE_FUNC}
* @see @ref setCompareMode(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_COMPARE_FUNC}
* @requires_gles30 Extension @es_extension{EXT,shadow_samplers}
*/
Texture<dimensions>& setCompareFunction(Sampler::CompareFunction function) {
@ -541,13 +549,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* Selects which component of packed depth/stencil texture is used for
* texturing. If @extension{EXT,direct_state_access} is not available,
* the texture is bound to some texture unit before the operation.
* Initial value is @ref Sampler::DepthStencilMode::DepthComponent.
* texturing. If on OpenGL ES or neither @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* available, the texture is bound before the operation (if not
* already). Initial value is @ref Sampler::DepthStencilMode::DepthComponent.
* @note Depth textures can be only 1D or 2D.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{DEPTH_STENCIL_TEXTURE_MODE}
* @see @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{DEPTH_STENCIL_TEXTURE_MODE}
* @requires_gl43 Extension @extension{ARB,stencil_texturing}
* @requires_gles31 Stencil texturing is not available in OpenGL ES 3.0
* and older.
@ -565,36 +575,52 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @param size Size of largest mip level
* @return Reference 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 @ref setStorage() or @ref setImage() is not
* allowed.
*
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some texture unit before the operation. If
* @extension{ARB,texture_storage} (part of OpenGL 4.2), OpenGL ES 3.0
* or @es_extension{EXT,texture_storage} in OpenGL ES 2.0 is not
* available, the feature is emulated with sequence of @ref setImage()
* calls.
* @see @ref maxSize(), @ref setMaxLevel(), @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}/
* After calling this function the texture is immutable and calling
* @ref setStorage() or @ref setImage() is not allowed.
*
* If on OpenGL ES or neither @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* available, the texture is bound before the operation (if not
* already). If neither @extension{ARB,texture_storage} (part of OpenGL
* 4.2), OpenGL ES 3.0 nor @es_extension{EXT,texture_storage} in OpenGL
* ES 2.0 is available, the feature is emulated with sequence of
* @ref setImage() calls.
* @see @ref maxSize(), @ref setMaxLevel(), @fn_gl2{TextureStorage1D,TexStorage1D} /
* @fn_gl2{TextureStorage2D,TexStorage2D} / @fn_gl2{TextureStorage3D,TexStorage3D},
* @fn_gl_extension{TextureStorage1D,EXT,direct_state_access} /
* @fn_gl_extension{TextureStorage2D,EXT,direct_state_access} /
* @fn_gl_extension{TextureStorage3D,EXT,direct_state_access},
* eventually @fn_gl{TexImage1D}/@fn_gl{TexImage2D}/@fn_gl{TexImage3D}
* or @fn_gl_extension{TextureImage1D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage3D,EXT,direct_state_access}
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexStorage1D}/@fn_gl{TexStorage2D}/@fn_gl{TexStorage3D}
* @todo allow the user to specify ColorType explicitly to avoid
* issues in WebGL (see setSubImage())
*/
Texture<dimensions>& setStorage(Int levels, TextureFormat internalFormat, const VectorTypeFor<dimensions, Int>& size) {
DataHelper<dimensions>::setStorage(*this, _target, levels, internalFormat, size);
DataHelper<dimensions>::setStorage(*this, levels, internalFormat, size);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Image size in given mip level
*
* The result is not cached in any way. If on OpenGL ES or neither
* @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already).
* @see @ref image(), @fn_gl2{GetTextureLevelParameter,GetTexLevelParameter},
* @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{GetTexLevelParameter} with @def_gl{TEXTURE_WIDTH},
* @def_gl{TEXTURE_HEIGHT}, @def_gl{TEXTURE_DEPTH}
* @requires_gles31 Texture image size queries are not available in
* OpenGL ES 3.0 and older.
*/
VectorTypeFor<dimensions, Int> imageSize(Int level) {
return DataHelper<dimensions>::imageSize(*this, level);
}
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Read given mip level of texture to image
@ -605,22 +631,26 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* given image, image size is taken from the texture using
* @ref imageSize().
*
* If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some texture unit before the operation. If
* @extension{ARB,robustness} is available, the operation is protected
* from buffer overflow. However, if both @extension{EXT,direct_state_access}
* and @extension{ARB,robustness} are available, the DSA version is
* used, because it is better for performance and there isn't any
* function combining both features.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or @def_gl{TEXTURE_DEPTH},
* then @fn_gl{GetTexImage}, @fn_gl_extension{GetTextureImage,EXT,direct_state_access}
* or @fn_gl_extension{GetnTexImage,ARB,robustness}
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already). If either
* @extension{ARB,direct_state_access} or @extension{ARB,robustness}
* is available, the operation is protected from buffer overflow.
* However, if @extension{ARB,direct_state_access} is not available and
* both @extension{EXT,direct_state_access} and @extension{ARB,robustness}
* are available, the robust operation is preferred over DSA.
* @see @fn_gl2{GetTextureLevelParameter,GetTexLevelParameter},
* @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{GetTexLevelParameter} with @def_gl{TEXTURE_WIDTH},
* @def_gl{TEXTURE_HEIGHT}, @def_gl{TEXTURE_DEPTH}, then
* @fn_gl2{GetTextureImage,GetTexImage},
* @fn_gl_extension{GetnTexImage,ARB,robustness} or
* @fn_gl_extension{GetTextureImage,EXT,direct_state_access},
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void image(Int level, Image<dimensions>& image) {
AbstractTexture::image<dimensions>(_target, level, image);
AbstractTexture::image<dimensions>(level, image);
}
/**
@ -635,7 +665,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @extension{ARB,buffer_storage}, avoiding relocations...)
*/
void image(Int level, BufferImage<dimensions>& image, BufferUsage usage) {
AbstractTexture::image<dimensions>(_target, level, image, usage);
AbstractTexture::image<dimensions>(level, image, usage);
}
#endif
@ -653,24 +683,36 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* equivalent in @extension{ARB,direct_state_access}, thus the texture
* needs to be bound to some texture unit before the operation.
* @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexImage1D}/@fn_gl{TexImage2D}/@fn_gl{TexImage3D}
* @fn_gl{TexImage1D} / @fn_gl{TexImage2D} / @fn_gl{TexImage3D}
* @deprecated_gl Prefer to use @ref Magnum::Texture::setStorage() "setStorage()"
* and @ref Magnum::Texture::setSubImage() "setSubImage()"
* instead.
*/
Texture<dimensions>& setImage(Int level, TextureFormat internalFormat, const ImageReference<dimensions>& image) {
DataHelper<dimensions>::setImage(*this, _target, level, internalFormat, image);
DataHelper<dimensions>::setImage(*this, level, internalFormat, image);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
/** @overload
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @deprecated_gl Prefer to use @ref Magnum::Texture::setStorage() "setStorage()"
* and @ref Magnum::Texture::setSubImage() "setSubImage()"
* instead.
*/
Texture<dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions>& image) {
DataHelper<dimensions>::setImage(*this, _target, level, internalFormat, image);
DataHelper<dimensions>::setImage(*this, level, internalFormat, image);
return *this;
}
/** @overload */
/** @overload
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @deprecated_gl Prefer to use @ref Magnum::Texture::setStorage() "setStorage()"
* and @ref Magnum::Texture::setSubImage() "setSubImage()"
* instead.
*/
Texture<dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions>&& image) {
return setImage(level, internalFormat, image);
}
@ -684,33 +726,42 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @ref Trade::ImageData of the same dimension count
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some texture unit before the operation.
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the texture is bound before the operation (if not already).
*
* @attention In @ref MAGNUM_TARGET_WEBGL "WebGL" the @ref ColorType of
* data passed in @p image must match the original one specified
* in @ref setImage(). It means that you might not be able to use
* @ref setStorage() as it uses implicit @ref ColorType value.
*
* @see @ref setStorage(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture}
* and @fn_gl{TexSubImage1D}/@fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D}
* or @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}/
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access}
* @see @ref setStorage(), @fn_gl2{TextureSubImage1D,TexSubImage1D} /
* @fn_gl2{TextureSubImage2D,TexSubImage2D} / @fn_gl2{TextureSubImage3D,TexSubImage3D},
* @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access} /
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access} /
* @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexSubImage1D} / @fn_gl{TexSubImage2D} / @fn_gl{TexSubImage3D}
*/
Texture<dimensions>& setSubImage(Int level, const VectorTypeFor<dimensions, Int>& offset, const ImageReference<dimensions>& image) {
DataHelper<Dimensions>::setSubImage(*this, _target, level, offset, image);
DataHelper<Dimensions>::setSubImage(*this, level, offset, image);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
/** @overload
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
*/
Texture<dimensions>& setSubImage(Int level, const VectorTypeFor<dimensions, Int>& offset, BufferImage<dimensions>& image) {
DataHelper<Dimensions>::setSubImage(*this, _target, level, offset, image);
DataHelper<Dimensions>::setSubImage(*this, level, offset, image);
return *this;
}
/** @overload */
/** @overload
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
*/
Texture<dimensions>& setSubImage(Int level, const VectorTypeFor<dimensions, Int>& offset, BufferImage<dimensions>&& image) {
return setSubImage(level, offset, image);
}
@ -720,11 +771,13 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @brief Generate mipmap
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some texture unit before the operation.
* @see @ref setMinificationFilter(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{GenerateMipmap} or
* @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the texture is bound before the operation (if not already).
* @see @ref setMinificationFilter(), @fn_gl2{GenerateTextureMipmap,GenerateMipmap},
* @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{GenerateMipmap}
* @requires_gl30 Extension @extension{ARB,framebuffer_object}
*/
Texture<dimensions>& generateMipmap() {

263
src/Magnum/TextureArray.h

@ -118,107 +118,179 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
*/
explicit TextureArray(): AbstractTexture(Implementation::textureArrayTarget<dimensions>()) {}
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc Texture::setBaseLevel() */
/**
* @copybrief Texture::setBaseLevel()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setBaseLevel() for more information.
*/
TextureArray<dimensions>& setBaseLevel(Int level) {
AbstractTexture::setBaseLevel(level);
return *this;
}
#endif
/** @copydoc Texture::setMaxLevel() */
/**
* @copybrief Texture::setMaxLevel()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMaxLevel() for more information.
*/
TextureArray<dimensions>& setMaxLevel(Int level) {
AbstractTexture::setMaxLevel(level);
return *this;
}
/** @copydoc Texture::setMinificationFilter() */
/**
* @copybrief Texture::setMinificationFilter()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMinificationFilter() for more information.
*/
TextureArray<dimensions>& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;
}
/** @copydoc Texture::setMagnificationFilter() */
/**
* @copybrief Texture::setMagnificationFilter()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMagnificationFilter() for more information.
*/
TextureArray<dimensions>& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc Texture::setMinLod() */
/**
* @copybrief Texture::setMinLod()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMinLod() for more information.
*/
TextureArray<dimensions>& setMinLod(Float lod) {
AbstractTexture::setMinLod(lod);
return *this;
}
/** @copydoc Texture::setMaxLod() */
/**
* @copybrief Texture::setMaxLod()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMaxLod() for more information.
*/
TextureArray<dimensions>& setMaxLod(Float lod) {
AbstractTexture::setMaxLod(lod);
return *this;
}
#endif
#ifndef MAGNUM_TARGET_GLES
/** @copydoc Texture::setLodBias() */
/**
* @copybrief Texture::setLodBias()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setLodBias() for more information.
* @requires_gl Texture LOD bias can be specified only directly in
* fragment shader in OpenGL ES.
*/
TextureArray<dimensions>& setLodBias(Float bias) {
AbstractTexture::setLodBias(bias);
return *this;
}
#endif
/** @copydoc Texture::setWrapping() */
/**
* @copybrief Texture::setWrapping()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setWrapping() for more information.
*/
TextureArray<dimensions>& setWrapping(const Array<dimensions+1, Sampler::Wrapping>& wrapping) {
DataHelper<dimensions+1>::setWrapping(*this, wrapping);
return *this;
}
/** @copydoc Texture::setBorderColor(const Color4&) */
/**
* @copybrief Texture::setBorderColor(const Color4&)
* @return Reference to self (for method chaining)
*
* See @ref Texture::setBorderColor(const Color4&) for more
* information.
* @requires_es_extension Extension @es_extension{NV,texture_border_clamp}
*/
TextureArray<dimensions>& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
#ifndef MAGNUM_TARGET_GLES
/** @copydoc Texture::setBorderColor(const Vector4ui&) */
/**
* @copybrief Texture::setBorderColor(const Vector4ui&)
* @return Reference to self (for method chaining)
*
* See @ref Texture::setBorderColor(const Vector4ui&) for more
* information.
* @requires_gl30 Extension @extension{EXT,texture_integer}
* @requires_gl Border is available only for float textures in OpenGL
* ES.
*/
TextureArray<dimensions>& setBorderColor(const Vector4ui& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
/** @copydoc Texture::setBorderColor(const Vector4i&) */
/** @overload
* @requires_gl30 Extension @extension{EXT,texture_integer}
* @requires_gl Border is available only for float textures in OpenGL
* ES.
*/
TextureArray<dimensions>& setBorderColor(const Vector4i& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
#endif
/** @copydoc Texture::setMaxAnisotropy() */
/**
* @copybrief Texture::setMaxAnisotropy()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setMaxAnisotropy() for more information.
*/
TextureArray<dimensions>& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return *this;
}
/** @copydoc Texture::setSRGBDecode() */
/**
* @copybrief Texture::setSRGBDecode()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setSRGBDecode() for more information.
* @requires_extension Extension @extension{EXT,texture_sRGB_decode}
* @requires_es_extension Extension @es_extension2{EXT,texture_sRGB_decode,texture_sRGB_decode}
*/
TextureArray<dimensions>& setSRGBDecode(bool decode) {
AbstractTexture::setSRGBDecode(decode);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc Texture::setSwizzle() */
/**
* @copybrief Texture::setSwizzle()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setSwizzle() for more information.
* @requires_gl33 Extension @extension{ARB,texture_swizzle}
*/
template<char r, char g, char b, char a> TextureArray<dimensions>& setSwizzle() {
AbstractTexture::setSwizzle<r, g, b, a>();
return *this;
}
#endif
/**
* @copybrief Texture::setCompareMode()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setCompareMode() for more information.
* @requires_gles30 Extension @es_extension{EXT,shadow_samplers} and
* @es_extension{NV,shadow_samplers_array}
*/
TextureArray<dimensions>& setCompareMode(Sampler::CompareMode mode) {
AbstractTexture::setCompareMode(mode);
@ -230,113 +302,107 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* See @ref Texture::setCompareFunction() for more information.
* @requires_gles30 Extension @es_extension{EXT,shadow_samplers} and
* @es_extension{NV,shadow_samplers_array}
*/
TextureArray<dimensions>& setCompareFunction(Sampler::CompareFunction function) {
AbstractTexture::setCompareFunction(function);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/**
* @copybrief Texture::setDepthStencilMode()
* @return Reference to self (for method chaining)
*
* See @ref Texture::setDepthStencilMode() for more information.
* @requires_gl43 Extension @extension{ARB,stencil_texturing}
* @requires_gles31 Stencil texturing is not available in OpenGL ES 3.0
* and older.
*/
TextureArray<dimensions>& setDepthStencilMode(Sampler::DepthStencilMode mode) {
AbstractTexture::setDepthStencilMode(mode);
return *this;
}
#endif
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc Texture::imageSize() */
VectorTypeFor<dimensions+1, Int> imageSize(Int level) {
return DataHelper<dimensions+1>::imageSize(*this, _target, level);
}
#endif
/**
* @brief Set storage
* @param levels Mip level count
* @param internalFormat Internal format
* @param size Size of largest mip level
* @copybrief Texture::setStorage()
* @return Reference 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 @ref setStorage() or @ref setImage() is not
* allowed.
*
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some texture unit before the operation. If
* @extension{ARB,texture_storage} (part of OpenGL 4.2) or OpenGL ES
* 3.0 is not available, the feature is emulated with sequence of
* @ref setImage() calls.
* @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexStorage2D}/@fn_gl{TexStorage3D} or
* @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureStorage3D,EXT,direct_state_access},
* eventually @fn_gl{TexImage2D}/@fn_gl{TexImage3D} or
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage3D,EXT,direct_state_access}.
* See @ref Texture::setStorage() for more information.
* @see @ref maxSize()
*/
TextureArray<dimensions>& setStorage(Int levels, TextureFormat internalFormat, const VectorTypeFor<dimensions+1, Int>& size) {
DataHelper<dimensions+1>::setStorage(*this, _target, levels, internalFormat, size);
DataHelper<dimensions+1>::setStorage(*this, levels, internalFormat, size);
return *this;
}
/**
* @copybrief Texture::imageSize()
*
* See @ref Texture::imageSize() for more information.
* @requires_gles31 Texture image size queries are not available in
* OpenGL ES 3.0 and older.
*/
VectorTypeFor<dimensions+1, Int> imageSize(Int level) {
return DataHelper<dimensions+1>::imageSize(*this, level);
}
#ifndef MAGNUM_TARGET_GLES
/** @copydoc Texture::image(Int, Image<dimensions>&) */
/**
* @copybrief Texture::image(Int, Image&)
* @return Reference to self (for method chaining)
*
* See @ref Texture::image(Int, Image&) for more information.
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void image(Int level, Image<dimensions+1>& image) {
AbstractTexture::image<dimensions+1>(_target, level, image);
AbstractTexture::image<dimensions+1>(level, image);
}
/** @copydoc Texture::imate(Int, BufferImage<dimensions>&, BufferUsage) */
/**
* @copybrief Texture::image(Int, BufferImage&, BufferUsage)
* @return Reference to self (for method chaining)
*
* See @ref Texture::image(Int, BufferImage&, BufferUsage) for more
* information.
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void image(Int level, BufferImage<dimensions+1>& image, BufferUsage usage) {
AbstractTexture::image<dimensions+1>(_target, level, image, usage);
AbstractTexture::image<dimensions+1>(level, image, usage);
}
#endif
/**
* @brief Set image data
* @param level Mip level
* @param internalFormat Internal format
* @param image @ref Image, @ref ImageReference or
* @ref Trade::ImageData of the same dimension count
* @copybrief Texture::setImage()
* @return Reference to self (for method chaining)
*
* On platforms that support it prefer to use @ref setStorage() and
* @ref setSubImage() instead, as it avoids unnecessary reallocations
* and has better performance characteristics. This call also has no
* equivalent in @extension{ARB,direct_state_access}, thus the texture
* needs to be bound to some texture unit before the operation.
* @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexImage2D}/@fn_gl{TexImage3D}
* See @ref Texture::setImage() for more information.
* @see @ref maxSize()
* @deprecated_gl Prefer to use @ref Magnum::TextureArray::setStorage() "setStorage()"
* and @ref Magnum::TextureArray::setSubImage() "setSubImage()"
* instead.
*/
TextureArray<dimensions>& setImage(Int level, TextureFormat internalFormat, const ImageReference<dimensions+1>& image) {
DataHelper<dimensions+1>::setImage(*this, _target, level, internalFormat, image);
DataHelper<dimensions+1>::setImage(*this, level, internalFormat, image);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
/** @overload
* @deprecated_gl Prefer to use @ref Magnum::TextureArray::setStorage() "setStorage()"
* and @ref Magnum::TextureArray::setSubImage() "setSubImage()"
* instead.
*/
TextureArray<dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions+1>& image) {
DataHelper<dimensions+1>::setImage(*this, _target, level, internalFormat, image);
DataHelper<dimensions+1>::setImage(*this, level, internalFormat, image);
return *this;
}
/** @overload */
/** @overload
* @deprecated_gl Prefer to use @ref Magnum::TextureArray::setStorage() "setStorage()"
* and @ref Magnum::TextureArray::setSubImage() "setSubImage()"
* instead.
*/
TextureArray<dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions+1>&& image) {
return setImage(level, internalFormat, image);
}
#endif
/**
* @brief Set image subdata
@ -346,22 +412,24 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
* @ref Trade::ImageData of the same dimension count
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some texture unit before the operation.
* @see @ref setStorage(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture}
* and @fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D} or
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the texture is bound before the operation (if not already).
* @see @ref setStorage(), @fn_gl2{TextureSubImage2D,TexSubImage2D}/
* @fn_gl2{TextureSubImage3D,TexSubImage3D},
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access}
* @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D}
*/
TextureArray<dimensions>& setSubImage(Int level, const VectorTypeFor<dimensions+1, Int>& offset, const ImageReference<dimensions+1>& image) {
DataHelper<dimensions+1>::setSubImage(*this, _target, level, offset, image);
DataHelper<dimensions+1>::setSubImage(*this, level, offset, image);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
TextureArray<dimensions>& setSubImage(Int level, const VectorTypeFor<dimensions+1, Int>& offset, BufferImage<dimensions+1>& image) {
DataHelper<dimensions+1>::setSubImage(*this, _target, level, offset, image);
DataHelper<dimensions+1>::setSubImage(*this, level, offset, image);
return *this;
}
@ -369,18 +437,33 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
TextureArray<dimensions>& setSubImage(Int level, const VectorTypeFor<dimensions+1, Int>& offset, BufferImage<dimensions+1>&& image) {
return setSubImage(level, offset, image);
}
#endif
/** @copydoc Texture::generateMipmap() */
/**
* @copybrief Texture::generateMipmap()
* @return Reference to self (for method chaining)
*
* See @ref Texture::generateMipmap() for more information.
* @requires_gl30 Extension @extension{ARB,framebuffer_object}
*/
TextureArray<dimensions>& generateMipmap() {
AbstractTexture::generateMipmap();
return *this;
}
/** @copydoc Texture::invalidateImage() */
/**
* @copybrief Texture::invalidateImage()
* @return Reference to self (for method chaining)
*
* See @ref Texture::invalidateImage() for more information.
*/
void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); }
/** @copydoc Texture::invalidateSubImage() */
/**
* @copybrief Texture::invalidateSubImage()
* @return Reference to self (for method chaining)
*
* See @ref Texture::invalidateSubImage() for more information.
*/
void invalidateSubImage(Int level, const VectorTypeFor<dimensions+1, Int>& offset, const VectorTypeFor<dimensions+1, Int>& size) {
DataHelper<dimensions+1>::invalidateSubImage(*this, level, offset, size);
}

Loading…
Cancel
Save