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); 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) { void AbstractTexture::unbindImplementationDSAEXT(const GLint textureUnit) {
Implementation::TextureState& textureState = *Context::current()->state().texture; Implementation::TextureState& textureState = *Context::current()->state().texture;
@ -274,6 +281,10 @@ void AbstractTexture::bindImplementationMulti(GLint textureUnit) {
glBindTextures(textureUnit, 1, &_id); glBindTextures(textureUnit, 1, &_id);
} }
void AbstractTexture::bindImplementationDSA(const GLint textureUnit) {
glBindTextureUnit(textureUnit, _id);
}
void AbstractTexture::bindImplementationDSAEXT(GLint textureUnit) { void AbstractTexture::bindImplementationDSAEXT(GLint textureUnit) {
_created = true; _created = true;
glBindMultiTextureEXT(GL_TEXTURE0 + textureUnit, _target, _id); glBindMultiTextureEXT(GL_TEXTURE0 + textureUnit, _target, _id);
@ -401,6 +412,10 @@ void AbstractTexture::mipmapImplementationDefault() {
} }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void AbstractTexture::mipmapImplementationDSA() {
glGenerateTextureMipmap(_id);
}
void AbstractTexture::mipmapImplementationDSAEXT() { void AbstractTexture::mipmapImplementationDSAEXT() {
_created = true; _created = true;
glGenerateTextureMipmapEXT(_id, _target); glGenerateTextureMipmapEXT(_id, _target);
@ -810,6 +825,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLint val
} }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLint value) {
glTextureParameteri(_id, parameter, value);
}
void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, GLint value) { void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, GLint value) {
_created = true; _created = true;
glTextureParameteriEXT(_id, _target, parameter, value); glTextureParameteriEXT(_id, _target, parameter, value);
@ -822,6 +841,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLfloat v
} }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLfloat value) {
glTextureParameterf(_id, parameter, value);
}
void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, GLfloat value) { void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, GLfloat value) {
_created = true; _created = true;
glTextureParameterfEXT(_id, _target, parameter, value); glTextureParameterfEXT(_id, _target, parameter, value);
@ -835,6 +858,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLi
} }
#ifndef MAGNUM_TARGET_GLES #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) { void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, const GLint* values) {
_created = true; _created = true;
glTextureParameterivEXT(_id, _target, parameter, values); glTextureParameterivEXT(_id, _target, parameter, values);
@ -848,6 +875,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLf
} }
#ifndef MAGNUM_TARGET_GLES #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) { void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, const GLfloat* values) {
_created = true; _created = true;
glTextureParameterfvEXT(_id, _target, parameter, values); glTextureParameterfvEXT(_id, _target, parameter, values);
@ -860,6 +891,10 @@ void AbstractTexture::parameterIImplementationDefault(GLenum parameter, const GL
glTexParameterIuiv(_target, parameter, values); 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) { void AbstractTexture::parameterIImplementationDSAEXT(GLenum parameter, const GLuint* values) {
_created = true; _created = true;
glTextureParameterIuivEXT(_id, _target, parameter, values); glTextureParameterIuivEXT(_id, _target, parameter, values);
@ -870,6 +905,10 @@ void AbstractTexture::parameterIImplementationDefault(GLenum parameter, const GL
glTexParameterIiv(_target, parameter, values); 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) { void AbstractTexture::parameterIImplementationDSAEXT(GLenum parameter, const GLint* values) {
_created = true; _created = true;
glTextureParameterIivEXT(_id, _target, parameter, values); glTextureParameterIivEXT(_id, _target, parameter, values);
@ -883,59 +922,65 @@ void AbstractTexture::setMaxAnisotropyImplementationExt(GLfloat anisotropy) {
} }
#ifndef MAGNUM_TARGET_GLES2 #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(); bindInternal();
glGetTexLevelParameteriv(target, level, parameter, values); glGetTexLevelParameteriv(_target, level, parameter, values);
} }
#ifndef MAGNUM_TARGET_GLES #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; _created = true;
glGetTextureLevelParameterivEXT(_id, target, level, parameter, values); glGetTextureLevelParameterivEXT(_id, _target, level, parameter, values);
} }
#endif #endif
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageImplementationFallback(const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { void AbstractTexture::storageImplementationFallback(const GLsizei levels, const TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
CORRADE_INTERNAL_ASSERT(target == GL_TEXTURE_1D);
const ColorFormat format = imageFormatForInternalFormat(internalFormat); const ColorFormat format = imageFormatForInternalFormat(internalFormat);
const ColorType type = imageTypeForInternalFormat(internalFormat); const ColorType type = imageTypeForInternalFormat(internalFormat);
for(GLsizei level = 0; level != levels; ++level) 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)}); 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(); 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; _created = true;
glTextureStorage1DEXT(_id, target, levels, GLenum(internalFormat), size[0]); glTextureStorage1DEXT(_id, _target, levels, GLenum(internalFormat), size[0]);
} }
#endif #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 ColorFormat format = imageFormatForInternalFormat(internalFormat);
const ColorType type = imageTypeForInternalFormat(internalFormat); const ColorType type = imageTypeForInternalFormat(internalFormat);
/* Common code for classic types */ /* Common code for classic types */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE) if(_target == GL_TEXTURE_2D || _target == GL_TEXTURE_RECTANGLE)
#else #else
if(target == GL_TEXTURE_2D) if(_target == GL_TEXTURE_2D)
#endif #endif
{ {
for(GLsizei level = 0; level != levels; ++level) 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)}); ImageReference2D{format, type, Math::max(Vector2i(1), size >> level)});
/* Cube map additionally needs to specify all faces */ /* 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(GLsizei level = 0; level != levels; ++level) {
for(GLenum face: {GL_TEXTURE_CUBE_MAP_POSITIVE_X, for(GLenum face: {GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
@ -949,9 +994,9 @@ void AbstractTexture::storageImplementationFallback(const GLenum target, const G
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
/* Array texture is not scaled in "layer" dimension */ /* 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) 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()}}); ImageReference2D{format, type, Vector2i{Math::max(1, size.x() >> level), size.y()}});
#endif #endif
@ -959,14 +1004,13 @@ void AbstractTexture::storageImplementationFallback(const GLenum target, const G
} else CORRADE_ASSERT_UNREACHABLE(); } 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(); bindInternal();
#ifndef MAGNUM_TARGET_GLES2 #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) #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 #else
static_cast<void>(target);
static_cast<void>(levels); static_cast<void>(levels);
static_cast<void>(internalFormat); static_cast<void>(internalFormat);
static_cast<void>(size); static_cast<void>(size);
@ -975,35 +1019,39 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels
} }
#ifndef MAGNUM_TARGET_GLES #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; _created = true;
glTextureStorage2DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y()); glTextureStorage2DEXT(_id, _target, levels, GLenum(internalFormat), size.x(), size.y());
} }
#endif #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 ColorFormat format = imageFormatForInternalFormat(internalFormat);
const ColorType type = imageTypeForInternalFormat(internalFormat); const ColorType type = imageTypeForInternalFormat(internalFormat);
/* Common code for classic type */ /* Common code for classic type */
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
if(target == GL_TEXTURE_3D) if(_target == GL_TEXTURE_3D)
#else #else
if(target == GL_TEXTURE_3D_OES) if(_target == GL_TEXTURE_3D_OES)
#endif #endif
for(GLsizei level = 0; level != levels; ++level) 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)}); ImageReference3D{format, type, Math::max(Vector3i(1), size >> level)});
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
/* Array texture is not scaled in "layer" dimension */ /* Array texture is not scaled in "layer" dimension */
#ifndef MAGNUM_TARGET_GLES #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
else if(target == GL_TEXTURE_2D_ARRAY) else if(_target == GL_TEXTURE_2D_ARRAY)
#endif #endif
for(GLsizei level = 0; level != levels; ++level) 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()}}); ImageReference3D{format, type, Vector3i{Math::max(Vector2i{1}, size.xy() >> level), size.z()}});
#endif #endif
@ -1011,14 +1059,13 @@ void AbstractTexture::storageImplementationFallback(GLenum target, GLsizei level
else CORRADE_ASSERT_UNREACHABLE(); 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(); bindInternal();
#ifndef MAGNUM_TARGET_GLES2 #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) #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 #else
static_cast<void>(target);
static_cast<void>(levels); static_cast<void>(levels);
static_cast<void>(internalFormat); static_cast<void>(internalFormat);
static_cast<void>(size); static_cast<void>(size);
@ -1027,97 +1074,120 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels
} }
#ifndef MAGNUM_TARGET_GLES #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; _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 #endif
#ifndef MAGNUM_TARGET_GLES #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(); bindInternal();
glTexImage2DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); glTexImage2DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
} }
#endif #endif
#ifndef MAGNUM_TARGET_GLES2 #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(); bindInternal();
glTexStorage2DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); glTexStorage2DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
} }
#endif #endif
#ifndef MAGNUM_TARGET_GLES #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; _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(); 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(); 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; _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 #endif
#ifndef MAGNUM_TARGET_GLES #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(); 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; _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(); bindInternal();
glGetnTexImageARB(target, level, GLenum(format), GLenum(type), dataSize, data); glGetnTexImageARB(_target, level, GLenum(format), GLenum(type), dataSize, data);
} }
#endif #endif
#ifndef MAGNUM_TARGET_GLES #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(); 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; _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 #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(); 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 #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; _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 #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(); bindInternal();
#ifndef MAGNUM_TARGET_GLES2 #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) #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 #else
static_cast<void>(target);
static_cast<void>(level); static_cast<void>(level);
static_cast<void>(offset); static_cast<void>(offset);
static_cast<void>(size); static_cast<void>(size);
@ -1129,9 +1199,13 @@ void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level,
} }
#ifndef MAGNUM_TARGET_GLES #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; _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 #endif
@ -1155,111 +1229,111 @@ void AbstractTexture::invalidateSubImageImplementationARB(GLint level, const Vec
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
template<UnsignedInt dimensions> void AbstractTexture::image(GLenum target, GLint level, Image<dimensions>& image) { template<UnsignedInt dimensions> void AbstractTexture::image(GLint level, Image<dimensions>& image) {
const Math::Vector<dimensions, Int> size = DataHelper<dimensions>::imageSize(*this, target, level); const Math::Vector<dimensions, Int> size = DataHelper<dimensions>::imageSize(*this, level);
const std::size_t dataSize = image.dataSize(size); const std::size_t dataSize = image.dataSize(size);
char* data = new char[dataSize]; 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); 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<1>(GLint, Image<1>&);
template void MAGNUM_EXPORT AbstractTexture::image<2>(GLenum, GLint, Image<2>&); template void MAGNUM_EXPORT AbstractTexture::image<2>(GLint, Image<2>&);
template void MAGNUM_EXPORT AbstractTexture::image<3>(GLenum, GLint, Image<3>&); 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) { template<UnsignedInt dimensions> void AbstractTexture::image(GLint level, BufferImage<dimensions>& image, BufferUsage usage) {
const Math::Vector<dimensions, Int> size = DataHelper<dimensions>::imageSize(*this, target, level); const Math::Vector<dimensions, Int> size = DataHelper<dimensions>::imageSize(*this, level);
const std::size_t dataSize = image.dataSize(size); const std::size_t dataSize = image.dataSize(size);
if(image.size() != size) if(image.size() != size)
image.setData(image.format(), image.type(), size, nullptr, usage); image.setData(image.format(), image.type(), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack); 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<1>(GLint, BufferImage<1>&, BufferUsage);
template void MAGNUM_EXPORT AbstractTexture::image<2>(GLenum, GLint, BufferImage<2>&, BufferUsage); template void MAGNUM_EXPORT AbstractTexture::image<2>(GLint, BufferImage<2>&, BufferUsage);
template void MAGNUM_EXPORT AbstractTexture::image<3>(GLenum, GLint, BufferImage<3>&, BufferUsage); template void MAGNUM_EXPORT AbstractTexture::image<3>(GLint, BufferImage<3>&, BufferUsage);
#endif #endif
#endif #endif
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES #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; 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; return value;
} }
#endif #endif
#ifndef MAGNUM_TARGET_GLES2 #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; const Implementation::TextureState& state = *Context::current()->state().texture;
Vector2i value; Vector2i value;
(texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]); (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_WIDTH, &value[0]);
(texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]); (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_HEIGHT, &value[1]);
return value; 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; const Implementation::TextureState& state = *Context::current()->state().texture;
Vector3i value; Vector3i value;
(texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]); (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_WIDTH, &value[0]);
(texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]); (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_HEIGHT, &value[1]);
(texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_DEPTH, &value[2]); (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_DEPTH, &value[2]);
return value; return value;
} }
#endif #endif
#ifndef MAGNUM_TARGET_GLES #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) { 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)(target, levels, internalFormat, size); (texture.*Context::current()->state().texture->storage1DImplementation)(levels, internalFormat, size);
} }
#endif #endif
void AbstractTexture::DataHelper<2>::setStorage(AbstractTexture& texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) { void AbstractTexture::DataHelper<2>::setStorage(AbstractTexture& texture, const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) {
(texture.*Context::current()->state().texture->storage2DImplementation)(target, levels, internalFormat, 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) { void AbstractTexture::DataHelper<3>::setStorage(AbstractTexture& texture, const GLsizei levels, const TextureFormat internalFormat, const Vector3i& size) {
(texture.*Context::current()->state().texture->storage3DImplementation)(target, levels, internalFormat, size); (texture.*Context::current()->state().texture->storage3DImplementation)(levels, internalFormat, size);
} }
#ifndef MAGNUM_TARGET_GLES2 #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) { 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)(target, samples, internalFormat, size, fixedSampleLocations); (texture.*Context::current()->state().texture->storage2DMultisampleImplementation)(samples, internalFormat, size, fixedSampleLocations);
} }
#endif #endif
#ifndef MAGNUM_TARGET_GLES #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) { 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)(target, samples, internalFormat, size, fixedSampleLocations); (texture.*Context::current()->state().texture->storage3DMultisampleImplementation)(samples, internalFormat, size, fixedSampleLocations);
} }
#endif #endif
#ifndef MAGNUM_TARGET_GLES #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); Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
texture.bindInternal(); 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); image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
texture.bindInternal(); 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); 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); 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 #endif
@ -1279,31 +1353,30 @@ void AbstractTexture::DataHelper<2>::setImage(AbstractTexture& texture, const GL
} }
#endif #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 #ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif #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 #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); 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 #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 #ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif #endif
texture.bindInternal(); texture.bindInternal();
#ifndef MAGNUM_TARGET_GLES2 #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) #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 #else
static_cast<void>(target);
static_cast<void>(level); static_cast<void>(level);
static_cast<void>(internalFormat); static_cast<void>(internalFormat);
static_cast<void>(image); static_cast<void>(image);
@ -1312,24 +1385,24 @@ void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GL
} }
#ifndef MAGNUM_TARGET_GLES2 #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); image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
texture.bindInternal(); 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 #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 #ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif #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 #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); 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 #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 implementation-defined values (such as @ref maxColorSamples()) are cached, so
repeated queries don't result in repeated @fn_gl{Get} calls. repeated queries don't result in repeated @fn_gl{Get} calls.
If extension @extension{ARB,multi_bind} is available, @ref bind() uses If on desktop GL and @extension{ARB,direct_state_access} (part of OpenGL 4.5)
@fn_gl{BindTextures} to avoid unnecessary calls to @fn_gl{ActiveTexture}. is available, @ref bind(Int) and @ref unbind(Int) use @fn_gl{BindTextureUnit}.
Otherwise, if extension @extension{EXT,direct_state_access} is available, Otherwise, if @extension{ARB,multi_bind} (part of OpenGL 4.4) is available,
@ref bind() uses @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} @ref bind(Int) and @ref unbind() uses @fn_gl{BindTextures}. Lastly, if
function. @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 extension @extension{EXT,direct_state_access} is available,
also all texture configuration and data updating functions use DSA functions In addition, if either @extension{ARB,direct_state_access} (part of OpenGL 4.5)
to avoid unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. or @extension{EXT,direct_state_access} is available, also all texture
See respective function documentation for more information. configuration and data updating functions use DSA functions to avoid
unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. See
If extension @extension{ARB,robustness} is available, image reading operations respective function documentation for more information.
(such as @ref Texture::image()) are protected from buffer overflow. However, if
both @extension{EXT,direct_state_access} and @extension{ARB,robustness} are If @extension{ARB,multi_bind} (part of OpenGL 4.5) is available,
available, the DSA version is used, because it is better for performance and @ref bind(Int, std::initializer_list<AbstractTexture*>) and @ref unbind(Int, std::size_t)
there isn't any function combining both features. 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 -- To achieve least state changes, fully configure each texture in one run --
method chaining comes in handy -- and try to have often used textures in method chaining comes in handy -- and try to have often used textures in
@ -125,6 +134,7 @@ functions do nothing.
*/ */
class MAGNUM_EXPORT AbstractTexture: public AbstractObject { class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
friend struct Implementation::TextureState; friend struct Implementation::TextureState;
friend class CubeMapTexture;
public: public:
#ifdef MAGNUM_BUILD_DEPRECATED #ifdef MAGNUM_BUILD_DEPRECATED
@ -187,15 +197,17 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
/** /**
* @brief Unbind any texture from given texture unit * @brief Unbind any texture from given texture unit
* *
* If @extension{ARB,multi_bind} (part of OpenGL 4.4) or * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* @extension{EXT,direct_state_access} is not available, the texture * of OpenGL 4.5), @extension{ARB,multi_bind} (part of OpenGL 4.4) nor
* unit is made active before binding the texture. * @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 * @note This function is meant to be used only internally from
* @ref AbstractShaderProgram subclasses. See its documentation * @ref AbstractShaderProgram subclasses. See its documentation
* for more information. * for more information.
* @see @ref bind(), @ref Shader::maxCombinedTextureImageUnits(), * @see @ref bind(), @ref Shader::maxCombinedTextureImageUnits(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture}, @fn_gl{BindTextures} * @fn_gl{BindTextureUnit}, @fn_gl{BindTextures},
* or @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture} and @fn_gl{BindTexture}
*/ */
static void unbind(Int textureUnit); 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 * @note This function is meant to be used only internally from
* @ref AbstractShaderProgram subclasses. See its documentation * @ref AbstractShaderProgram subclasses. See its documentation
* for more information. * for more information.
* @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures}, * @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures}
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or
* @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
*/ */
static void unbind(Int firstTextureUnit, std::size_t count); 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 * @note This function is meant to be used only internally from
* @ref AbstractShaderProgram subclasses. See its documentation * @ref AbstractShaderProgram subclasses. See its documentation
* for more information. * for more information.
* @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures}, * @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures}
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or
* @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
*/ */
static void bind(Int firstTextureUnit, std::initializer_list<AbstractTexture*> textures); 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 * @brief Bind texture to given texture unit
* *
* If @extension{ARB,multi_bind} (part of OpenGL 4.4) or * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* @extension{EXT,direct_state_access} is not available, the texture * of OpenGL 4.5), @extension{ARB,multi_bind} (part of OpenGL 4.4) nor
* unit is made active before binding the texture. * @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 * @note This function is meant to be used only internally from
* @ref AbstractShaderProgram subclasses. See its documentation * @ref AbstractShaderProgram subclasses. See its documentation
* for more information. * for more information.
* @see @ref bind(Int, std::initializer_list<AbstractTexture*>), * @see @ref bind(Int, std::initializer_list<AbstractTexture*>),
* @ref unbind(), @ref Shader::maxCombinedTextureImageUnits(), * @ref unbind(), @ref Shader::maxCombinedTextureImageUnits(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture}, @fn_gl{BindTextures} * @fn_gl{BindTextureUnit}, @fn_gl{BindTextures},
* or @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture} and @fn_gl{BindTexture}
*/ */
void bind(Int textureUnit); void bind(Int textureUnit);
@ -357,8 +367,8 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void generateMipmap(); void generateMipmap();
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
template<UnsignedInt dimensions> void image(GLenum target, GLint level, Image<dimensions>& image); template<UnsignedInt dimensions> void image(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, BufferImage<dimensions>& image, BufferUsage usage);
#endif #endif
GLenum _target; GLenum _target;
@ -367,6 +377,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
static void MAGNUM_LOCAL unbindImplementationDefault(GLint textureUnit); static void MAGNUM_LOCAL unbindImplementationDefault(GLint textureUnit);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL unbindImplementationMulti(GLint textureUnit); static void MAGNUM_LOCAL unbindImplementationMulti(GLint textureUnit);
static void MAGNUM_LOCAL unbindImplementationDSA(GLint textureUnit);
static void MAGNUM_LOCAL unbindImplementationDSAEXT(GLint textureUnit); static void MAGNUM_LOCAL unbindImplementationDSAEXT(GLint textureUnit);
#endif #endif
@ -385,6 +396,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void MAGNUM_LOCAL bindImplementationDefault(GLint textureUnit); void MAGNUM_LOCAL bindImplementationDefault(GLint textureUnit);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL bindImplementationMulti(GLint textureUnit); void MAGNUM_LOCAL bindImplementationMulti(GLint textureUnit);
void MAGNUM_LOCAL bindImplementationDSA(GLint textureUnit);
void MAGNUM_LOCAL bindImplementationDSAEXT(GLint textureUnit); void MAGNUM_LOCAL bindImplementationDSAEXT(GLint textureUnit);
#endif #endif
@ -399,11 +411,17 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void MAGNUM_LOCAL parameterIImplementationDefault(GLenum parameter, const GLint* values); void MAGNUM_LOCAL parameterIImplementationDefault(GLenum parameter, const GLint* values);
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLint value);
void MAGNUM_LOCAL parameterImplementationDSAEXT(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 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 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 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 parameterIImplementationDSAEXT(GLenum parameter, const GLuint* values);
void MAGNUM_LOCAL parameterIImplementationDSA(GLenum parameter, const GLint* values);
void MAGNUM_LOCAL parameterIImplementationDSAEXT(GLenum parameter, const GLint* values); void MAGNUM_LOCAL parameterIImplementationDSAEXT(GLenum parameter, const GLint* values);
#endif #endif
@ -411,70 +429,81 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void MAGNUM_LOCAL setMaxAnisotropyImplementationExt(GLfloat anisotropy); void MAGNUM_LOCAL setMaxAnisotropyImplementationExt(GLfloat anisotropy);
#ifndef MAGNUM_TARGET_GLES2 #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 #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
#endif #endif
void MAGNUM_LOCAL mipmapImplementationDefault(); void MAGNUM_LOCAL mipmapImplementationDefault();
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL mipmapImplementationDSA();
void MAGNUM_LOCAL mipmapImplementationDSAEXT(); void MAGNUM_LOCAL mipmapImplementationDSAEXT();
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageImplementationFallback(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(GLenum target, 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 storageImplementationDSAEXT(GLenum target, 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 #endif
void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size); void MAGNUM_LOCAL storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size); void MAGNUM_LOCAL storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
#ifndef MAGNUM_TARGET_GLES #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 #endif
void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size); void MAGNUM_LOCAL storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size); void MAGNUM_LOCAL storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
#ifndef MAGNUM_TARGET_GLES #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 #endif
#ifndef MAGNUM_TARGET_GLES #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 #endif
#ifndef MAGNUM_TARGET_GLES2 #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 #endif
#ifndef MAGNUM_TARGET_GLES #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 #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageMultisampleImplementationFallback(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(GLenum target, 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 storageMultisampleImplementationDSAEXT(GLenum target, 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 #endif
#ifndef MAGNUM_TARGET_GLES #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 getImageImplementationDefault(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 getImageImplementationDSA(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 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 #endif
#ifndef MAGNUM_TARGET_GLES #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 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 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 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 #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 #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 #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 #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 #endif
void MAGNUM_LOCAL invalidateImageImplementationNoOp(GLint level); void MAGNUM_LOCAL invalidateImageImplementationNoOp(GLint level);
@ -503,17 +532,17 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<1> {
}; };
#endif #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 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, 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, 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, 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, BufferImage1D& image);
static void invalidateSubImage(AbstractTexture& texture, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLint>& size); 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 #endif
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
static Vector2i imageSize(AbstractTexture& texture, GLenum target, GLint level); static Vector2i imageSize(AbstractTexture& texture, GLint level);
#endif #endif
static void setWrapping(AbstractTexture& texture, const Array2D<Sampler::Wrapping>& wrapping); 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 #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 #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); static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference2D& image);
#ifndef MAGNUM_TARGET_GLES2 #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); static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage2D& image);
#endif #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 #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 #endif
static void invalidateSubImage(AbstractTexture& texture, GLint level, const Vector2i& offset, const Vector2i& size); 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 #endif
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
static Vector3i imageSize(AbstractTexture& texture, GLenum target, GLint level); static Vector3i imageSize(AbstractTexture& texture, GLint level);
#endif #endif
static void setWrapping(AbstractTexture& texture, const Array3D<Sampler::Wrapping>& wrapping); 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 #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 #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 #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 #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 #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 #endif
static void invalidateSubImage(AbstractTexture& texture, GLint level, const Vector3i& offset, const Vector3i& size); 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()); 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) { void BufferTexture::setBufferImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer) {
glTextureBufferEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id()); 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); 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) { void BufferTexture::setBufferRangeImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size) {
glTextureBufferRangeEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id(), offset, 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 @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. data source, without any unnecessary interpolation and wrapping methods.
## Usage ## Usage
@ -187,7 +187,8 @@ documentation for more information about usage in shaders.
## Performance optimizations ## 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 functions use DSA to avoid unnecessary calls to @fn_gl{ActiveTexture} and
@fn_gl{BindTexture}. See @fn_gl{BindTexture}. See
@ref AbstractTexture-performance-optimization "relevant section in AbstractTexture documentation" @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 * 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 * filled with data of proper format at any time using @ref Buffer "Buffer"'s
* own data setting functions. * own data setting functions. If neither @extension{ARB,direct_state_access}
* @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* @fn_gl{TexBuffer} or * available, the texture is bound before the operation (if not
* @fn_gl_extension{TextureBuffer,EXT,direct_state_access} * 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); 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 * 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 * be then filled with data of proper format at any time using @ref Buffer "Buffer"'s
* own data setting functions. * own data setting functions. If neither @extension{ARB,direct_state_access}
* @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* @fn_gl{TexBufferRange} or * available, the texture is bound before the operation (if not
* @fn_gl_extension{TextureBufferRange,EXT,direct_state_access} * 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} * @requires_gl43 Extension @extension{ARB,texture_buffer_range}
*/ */
BufferTexture& setBuffer(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); BufferTexture& setBuffer(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size);
@ -280,9 +289,11 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture {
private: private:
void MAGNUM_LOCAL setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer); 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 setBufferImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer);
void MAGNUM_LOCAL setBufferRangeImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); 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); void MAGNUM_LOCAL setBufferRangeImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size);
}; };

122
src/Magnum/CubeMapTexture.cpp

@ -25,12 +25,134 @@
#include "CubeMapTexture.h" #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/maxTextureSize.h"
#include "Implementation/State.h"
#include "Implementation/TextureState.h"
namespace Magnum { 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() { Vector2i CubeMapTexture::maxSize() {
return Vector2i{Implementation::maxCubeMapTextureSideSize()}; 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 @ref MultisampleTexture
*/ */
class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
friend struct Implementation::TextureState;
public: public:
/** @brief Cube map coordinate */ /** @brief Cube map coordinate */
enum class Coordinate: GLenum { enum class Coordinate: GLenum {
@ -112,39 +114,77 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {} explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {}
#ifndef MAGNUM_TARGET_GLES2 #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) { CubeMapTexture& setBaseLevel(Int level) {
AbstractTexture::setBaseLevel(level); AbstractTexture::setBaseLevel(level);
return *this; return *this;
} }
#endif #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) { CubeMapTexture& setMaxLevel(Int level) {
AbstractTexture::setMaxLevel(level); AbstractTexture::setMaxLevel(level);
return *this; 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) { CubeMapTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap); AbstractTexture::setMinificationFilter(filter, mipmap);
return *this; 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) { CubeMapTexture& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter); AbstractTexture::setMagnificationFilter(filter);
return *this; return *this;
} }
#ifndef MAGNUM_TARGET_GLES2 #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) { CubeMapTexture& setMinLod(Float lod) {
AbstractTexture::setMinLod(lod); AbstractTexture::setMinLod(lod);
return *this; 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) { CubeMapTexture& setMaxLod(Float lod) {
AbstractTexture::setMaxLod(lod); AbstractTexture::setMaxLod(lod);
return *this; return *this;
@ -152,53 +192,106 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
#endif #endif
#ifndef MAGNUM_TARGET_GLES #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) { CubeMapTexture& setLodBias(Float bias) {
AbstractTexture::setLodBias(bias); AbstractTexture::setLodBias(bias);
return *this; return *this;
} }
#endif #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) { CubeMapTexture& setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
DataHelper<3>::setWrapping(*this, wrapping); DataHelper<3>::setWrapping(*this, wrapping);
return *this; 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) { CubeMapTexture& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return *this; return *this;
} }
#ifndef MAGNUM_TARGET_GLES #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) { CubeMapTexture& setBorderColor(const Vector4ui& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return *this; 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) { CubeMapTexture& setBorderColor(const Vector4i& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return *this; return *this;
} }
#endif #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) { CubeMapTexture& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy); AbstractTexture::setMaxAnisotropy(anisotropy);
return *this; 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) { CubeMapTexture& setSRGBDecode(bool decode) {
AbstractTexture::setSRGBDecode(decode); AbstractTexture::setSRGBDecode(decode);
return *this; return *this;
} }
#ifndef MAGNUM_TARGET_GLES2 #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() { template<char r, char g, char b, char a> CubeMapTexture& setSwizzle() {
AbstractTexture::setSwizzle<r, g, b, a>(); AbstractTexture::setSwizzle<r, g, b, a>();
return *this; return *this;
@ -232,76 +325,79 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
} }
#ifndef MAGNUM_TARGET_GLES2 #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) { CubeMapTexture& setDepthStencilMode(Sampler::DepthStencilMode mode) {
AbstractTexture::setDepthStencilMode(mode); AbstractTexture::setDepthStencilMode(mode);
return *this; return *this;
} }
#endif #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 #ifndef MAGNUM_TARGET_GLES2
/** /**
* @brief Image size in given mip level * @copybrief Texture::imageSize()
* @param coordinate Coordinate
* @param level Mip level
* *
* 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 * @requires_gles31 Texture image size queries are not available in
* OpenGL ES 3.0 and older. * OpenGL ES 3.0 and older.
*/ */
Vector2i imageSize(Coordinate coordinate, Int level) { Vector2i imageSize(Int level);
return DataHelper<2>::imageSize(*this, GLenum(coordinate), level);
}
#endif
#ifdef MAGNUM_BUILD_DEPRECATED
/** /**
* @brief Set storage * @copybrief imageSize()
* * @deprecated Use @ref Magnum::CubeMapTexture::imageSize(Int) "imageSize(Int)"
* See @ref Texture::setStorage() for more information. * instead.
* @see @ref maxSize()
*/ */
CubeMapTexture& setStorage(Int levels, TextureFormat internalFormat, const Vector2i& size) { CORRADE_DEPRECATED("use imageSize(Int) instead") Vector2i imageSize(Coordinate, Int level) {
DataHelper<2>::setStorage(*this, _target, levels, internalFormat, size); return imageSize(level);
return *this;
} }
#endif
#endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Read given mip level of texture to image * @copybrief Texture::image(Int, Image&)
* @param coordinate Coordinate
* @param level Mip level
* @param image Image where to put the data
* *
* See @ref Texture::image(Int, Image&) for more information. * See @ref Texture::image(Int, Image&) for more information.
* @requires_gl Texture image queries are not available in OpenGL ES. * @requires_gl Texture image queries are not available in OpenGL ES.
*/ */
void image(Coordinate coordinate, Int level, Image2D& image) { void image(Coordinate coordinate, Int level, Image2D& image);
AbstractTexture::image<2>(GLenum(coordinate), level, image);
}
/** /**
* @brief Read given mip level of texture to buffer image * @copybrief Texture::image(Int, BufferImage&, BufferUsage)
* @param coordinate Coordinate
* @param level Mip level
* @param image Buffer image where to put the data
* @param usage Buffer usage
* *
* See @ref Texture::image(Int, BufferImage&, BufferUsage) for more * See @ref Texture::image(Int, BufferImage&, BufferUsage) for more
* information. * information.
* @requires_gl Texture image queries are not available in OpenGL ES. * @requires_gl Texture image queries are not available in OpenGL ES.
*/ */
void image(Coordinate coordinate, Int level, BufferImage2D& image, BufferUsage usage) { void image(Coordinate coordinate, Int level, BufferImage2D& image, BufferUsage usage);
AbstractTexture::image<2>(GLenum(coordinate), level, image, usage);
}
#endif #endif
/** /**
* @brief Set image data * @copybrief Texture::setImage()
* @param coordinate Coordinate
* @param level Mip level
* @param internalFormat Internal format
* @param image @ref Image2D, @ref ImageReference2D or
* @ref Trade::ImageData2D
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* See @ref Texture::setImage() for more information. * See @ref Texture::setImage() for more information.
@ -316,62 +412,75 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
} }
#ifndef MAGNUM_TARGET_GLES2 #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) { CubeMapTexture& setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, BufferImage2D& image) {
DataHelper<2>::setImage(*this, GLenum(coordinate), level, internalFormat, image); DataHelper<2>::setImage(*this, GLenum(coordinate), level, internalFormat, image);
return *this; 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) { CubeMapTexture& setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, BufferImage2D&& image) {
return setImage(coordinate, level, internalFormat, image); return setImage(coordinate, level, internalFormat, image);
} }
#endif #endif
/** /**
* @brief Set image subdata * @copybrief Texture::setSubImage()
* @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
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* See @ref Texture::setSubImage() for more information. * See @ref Texture::setSubImage() for more information.
*/ */
CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const ImageReference2D& image) { CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const ImageReference2D& image);
DataHelper<2>::setSubImage(*this, GLenum(coordinate), level, offset, image);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
/** @overload */ /** @overload
CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D& image) { * @requires_gles30 Pixel buffer objects are not available in OpenGL ES
DataHelper<2>::setSubImage(*this, GLenum(coordinate), level, offset, image); * 2.0.
return *this; */
} 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) { CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D&& image) {
DataHelper<2>::setSubImage(*this, GLenum(coordinate), level, offset, image); return setSubImage(coordinate, level, offset, image);
return *this;
} }
#endif #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() { CubeMapTexture& generateMipmap() {
AbstractTexture::generateMipmap(); AbstractTexture::generateMipmap();
return *this; return *this;
} }
/** @copydoc Texture::invalidateImage() */ /**
* @copybrief Texture::invalidateImage()
*
* See @ref Texture::invalidateImage() for more information.
*/
void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); }
/** /**
* @brief Invalidate texture subimage * @copybrief Texture::invalidateSubImage()
* @param level Mip level
* @param offset Offset into the texture
* @param size Size of invalidated data
* *
* Z coordinate is equivalent to number of texture face, i.e. * 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 * @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; return *this;
} }
#endif #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; 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) { CubeMapTextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap); AbstractTexture::setMinificationFilter(filter, mipmap);
return *this; 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) { CubeMapTextureArray& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter); AbstractTexture::setMagnificationFilter(filter);
return *this; return *this;
@ -173,7 +183,12 @@ class CubeMapTextureArray: public AbstractTexture {
return *this; 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) { CubeMapTextureArray& setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
DataHelper<3>::setWrapping(*this, wrapping); DataHelper<3>::setWrapping(*this, wrapping);
return *this; return *this;
@ -197,31 +212,39 @@ class CubeMapTextureArray: public AbstractTexture {
* *
* See @ref Texture::setBorderColor(const Vector4ui&) for more * See @ref Texture::setBorderColor(const Vector4ui&) for more
* information. * information.
* @requires_gl30 Extension @extension{EXT,texture_integer}
*/ */
CubeMapTextureArray& setBorderColor(const Vector4ui& color) { CubeMapTextureArray& setBorderColor(const Vector4ui& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return *this; return *this;
} }
/** /** @overload
* @copybrief Texture::setBorderColor(const Vector4ui&) * @requires_gl30 Extension @extension{EXT,texture_integer}
* @return Reference to self (for method chaining)
*
* See @ref Texture::setBorderColor(const Vector4i&) for more
* information.
*/ */
CubeMapTextureArray& setBorderColor(const Vector4i& color) { CubeMapTextureArray& setBorderColor(const Vector4i& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return *this; 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) { CubeMapTextureArray& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy); AbstractTexture::setMaxAnisotropy(anisotropy);
return *this; 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) { CubeMapTextureArray& setSRGBDecode(bool decode) {
AbstractTexture::setSRGBDecode(decode); AbstractTexture::setSRGBDecode(decode);
return *this; return *this;
@ -232,6 +255,7 @@ class CubeMapTextureArray: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* See @ref Texture::setSwizzle() for more information. * 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() { template<char r, char g, char b, char a> CubeMapTextureArray& setSwizzle() {
AbstractTexture::setSwizzle<r, g, b, a>(); AbstractTexture::setSwizzle<r, g, b, a>();
@ -265,6 +289,7 @@ class CubeMapTextureArray: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* See @ref Texture::setDepthStencilMode() for more information. * See @ref Texture::setDepthStencilMode() for more information.
* @requires_gl43 Extension @extension{ARB,stencil_texturing}
*/ */
CubeMapTextureArray& setDepthStencilMode(Sampler::DepthStencilMode mode) { CubeMapTextureArray& setDepthStencilMode(Sampler::DepthStencilMode mode) {
AbstractTexture::setDepthStencilMode(mode); AbstractTexture::setDepthStencilMode(mode);
@ -272,57 +297,49 @@ class CubeMapTextureArray: public AbstractTexture {
} }
/** /**
* @brief Image size in given mip level * @copybrief Texture::setStorage()
* @param level Mip level * @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) { CubeMapTextureArray& setStorage(Int levels, TextureFormat internalFormat, const Vector3i& size) {
return DataHelper<3>::imageSize(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level); 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 * See @ref Texture::imageSize() for more information.
* @ref Texture::setStorage() for more information.
* @see @ref maxSize()
*/ */
CubeMapTextureArray& setStorage(Int levels, TextureFormat internalFormat, const Vector3i& size) { Vector3i imageSize(Int level) {
DataHelper<3>::setStorage(*this, _target, levels, internalFormat, size); return DataHelper<3>::imageSize(*this, level);
return *this;
} }
/** /**
* @brief Read given mip level of texture to image * @copybrief Texture::image(Int, Image&)
* @param level Mip level
* @param image Image where to put the data
* *
* See @ref Texture::image(Int, Image&) for more information. * See @ref Texture::image(Int, Image&) for more information.
*/ */
void image(Int level, Image3D& image) { 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 * @copybrief Texture::image(Int, BufferImage&, BufferUsage)
* @param level Mip level
* @param image Buffer image where to put the data
* @param usage Buffer usage
* *
* See @ref Texture::image(Int, BufferImage&, BufferUsage) for more * See @ref Texture::image(Int, BufferImage&, BufferUsage) for more
* information. * information.
*/ */
void image(Int level, BufferImage3D& image, BufferUsage usage) { 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 * @copybrief Texture::setImage()
* @param level Mip level
* @param internalFormat Internal format
* @param image @ref Image3D, @ref ImageReference3D or
* @ref Trade::ImageData3D
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Sets texture image data from three-dimensional image for all cube * Sets texture image data from three-dimensional image for all cube
@ -337,27 +354,31 @@ class CubeMapTextureArray: public AbstractTexture {
* instead. * instead.
*/ */
CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, const ImageReference3D& image) { 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; 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) { 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; 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) { CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage3D&& image) {
return setImage(level, internalFormat, image); return setImage(level, internalFormat, image);
} }
/** /**
* @brief Set texture image 3D subdata * @copybrief Texture::setSubImage()
* @param level Mip level
* @param offset Offset where to put data in the texture
* @param image @ref Image3D, @ref ImageReference3D or
* @ref Trade::ImageData3D
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Z coordinate is equivalent to layer * 6 + number of texture face, * 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. * See @ref Texture::setSubImage() for more information.
*/ */
CubeMapTextureArray& setSubImage(Int level, const Vector3i& offset, const ImageReference3D& image) { 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; return *this;
} }
/** @overload */ /** @overload */
CubeMapTextureArray& setSubImage(Int level, const Vector3i& offset, BufferImage3D& image) { 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; return *this;
} }
@ -381,20 +402,27 @@ class CubeMapTextureArray: public AbstractTexture {
return setSubImage(level, offset, image); 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() { CubeMapTextureArray& generateMipmap() {
AbstractTexture::generateMipmap(); AbstractTexture::generateMipmap();
return *this; return *this;
} }
/** @copydoc Texture::invalidateImage() */ /**
* @copybrief Texture::invalidateImage()
*
* See @ref Texture::invalidateImage() for more information.
*/
void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); }
/** /**
* @brief Invalidate texture subimage * @copybrief Texture::invalidateSubImage()
* @param level Mip level
* @param offset Offset into the texture
* @param size Size of invalidated data
* *
* Z coordinate is equivalent to layer * 6 + number of texture face, * 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). * 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; createImplementation = &AbstractTexture::createImplementationDefault;
} }
/* Bind implementation */ /* Single bind implementation */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::multi_bind>()) { if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
extensions.push_back(Extensions::GL::ARB::multi_bind::string()); /* 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; unbindImplementation = &AbstractTexture::unbindImplementationMulti;
bindMultiImplementation = &AbstractTexture::bindImplementationMulti;
bindImplementation = &AbstractTexture::bindImplementationMulti; bindImplementation = &AbstractTexture::bindImplementationMulti;
} else if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) { } else if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
/* Extension name added below */ /* Extension name added below */
unbindImplementation = &AbstractTexture::unbindImplementationDSAEXT; unbindImplementation = &AbstractTexture::unbindImplementationDSAEXT;
bindMultiImplementation = &AbstractTexture::bindImplementationFallback;
bindImplementation = &AbstractTexture::bindImplementationDSAEXT; bindImplementation = &AbstractTexture::bindImplementationDSAEXT;
} else } else
#endif #endif
{ {
unbindImplementation = &AbstractTexture::unbindImplementationDefault; unbindImplementation = &AbstractTexture::unbindImplementationDefault;
bindMultiImplementation = &AbstractTexture::bindImplementationFallback;
bindImplementation = &AbstractTexture::bindImplementationDefault; 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 */ /* DSA/non-DSA implementation */
#ifndef MAGNUM_TARGET_GLES #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()); extensions.push_back(Extensions::GL::EXT::direct_state_access::string());
parameteriImplementation = &AbstractTexture::parameterImplementationDSAEXT; parameteriImplementation = &AbstractTexture::parameterImplementationDSAEXT;
@ -106,13 +142,16 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
parameterIivImplementation = &AbstractTexture::parameterIImplementationDSAEXT; parameterIivImplementation = &AbstractTexture::parameterIImplementationDSAEXT;
getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSAEXT; getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSAEXT;
mipmapImplementation = &AbstractTexture::mipmapImplementationDSAEXT; mipmapImplementation = &AbstractTexture::mipmapImplementationDSAEXT;
getImageImplementation = &AbstractTexture::getImageImplementationDSAEXT;
subImage1DImplementation = &AbstractTexture::subImageImplementationDSAEXT; subImage1DImplementation = &AbstractTexture::subImageImplementationDSAEXT;
subImage2DImplementation = &AbstractTexture::subImageImplementationDSAEXT; subImage2DImplementation = &AbstractTexture::subImageImplementationDSAEXT;
subImage3DImplementation = &AbstractTexture::subImageImplementationDSAEXT; subImage3DImplementation = &AbstractTexture::subImageImplementationDSAEXT;
setBufferImplementation = &BufferTexture::setBufferImplementationDSAEXT; setBufferImplementation = &BufferTexture::setBufferImplementationDSAEXT;
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSAEXT; setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSAEXT;
getCubeImageSizeImplementation = &CubeMapTexture::getImageSizeImplementationDSAEXT;
cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDSAEXT;
} else } else
#endif #endif
{ {
@ -131,9 +170,6 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
#endif #endif
mipmapImplementation = &AbstractTexture::mipmapImplementationDefault; mipmapImplementation = &AbstractTexture::mipmapImplementationDefault;
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
getImageImplementation = &AbstractTexture::getImageImplementationDefault;
#endif
#ifndef MAGNUM_TARGET_GLES
subImage1DImplementation = &AbstractTexture::subImageImplementationDefault; subImage1DImplementation = &AbstractTexture::subImageImplementationDefault;
#endif #endif
subImage2DImplementation = &AbstractTexture::subImageImplementationDefault; subImage2DImplementation = &AbstractTexture::subImageImplementationDefault;
@ -143,6 +179,11 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
setBufferImplementation = &BufferTexture::setBufferImplementationDefault; setBufferImplementation = &BufferTexture::setBufferImplementationDefault;
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDefault; setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDefault;
#endif #endif
#ifndef MAGNUM_TARGET_GLES2
getCubeImageSizeImplementation = &CubeMapTexture::getImageSizeImplementationDefault;
#endif
cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDefault;
} }
/* Data invalidation implementation */ /* Data invalidation implementation */
@ -159,14 +200,28 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationNoOp; invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationNoOp;
} }
/* Image retrieval implementation */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::robustness>() && /* Image retrieval implementation */
!context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) { 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()); extensions.push_back(Extensions::GL::ARB::robustness::string());
getImageImplementation = &AbstractTexture::getImageImplementationRobustness; 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 #endif
/* Texture storage implementation */ /* Texture storage implementation */
@ -183,7 +238,12 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
#endif #endif
#ifndef MAGNUM_TARGET_GLES #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; storage1DImplementation = &AbstractTexture::storageImplementationDSAEXT;
storage2DImplementation = &AbstractTexture::storageImplementationDSAEXT; storage2DImplementation = &AbstractTexture::storageImplementationDSAEXT;
storage3DImplementation = &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>()) { if(context.isExtensionSupported<Extensions::GL::ARB::texture_storage_multisample>()) {
extensions.push_back(Extensions::GL::ARB::texture_storage_multisample::string()); 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; storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT;
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT; storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT;
} else { } else {

31
src/Magnum/Implementation/TextureState.h

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

65
src/Magnum/MultisampleTexture.h

@ -122,21 +122,6 @@ template<UnsignedInt dimensions> class MultisampleTexture: public AbstractTextur
*/ */
explicit MultisampleTexture(): AbstractTexture(Implementation::multisampleTextureTarget<dimensions>()) {} 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 * @brief Set storage
* @param samples Sample count * @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 * After calling this function the texture is immutable and calling
* @ref setStorage() again is not allowed. * @ref setStorage() again is not allowed.
* *
* If @extension{EXT,direct_state_access} is not available, the texture * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* is bound to some texture unit before the operation. If * 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 * @extension{ARB,texture_storage_multisample} (part of OpenGL 4.3) is
* not available, the feature is emulated using plain * not available, the texture is bound and the feature is emulated
* @extension{ARB,texture_storage} functionality (which unfortunately * using plain @extension{ARB,texture_multisample} functionality.
* doesn't have any DSA alternative, so the texture must be bound
* to some texture unit before).
* @see @ref maxSize(), @ref maxColorSamples(), @ref maxDepthSamples(), * @see @ref maxSize(), @ref maxColorSamples(), @ref maxDepthSamples(),
* @ref maxIntegerSamples(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} * @ref maxIntegerSamples(), @fn_gl2{TextureStorage2DMultisample,TexStorage2DMultisample} /
* and @fn_gl{TexStorage2DMultisample}/@fn_gl{TexStorage3DMultisample} * @fn_gl2{TextureStorage3DMultisample,TexStorage3DMultisample},
* or @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access}/ * @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access} /
* @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access} * @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access},
* eventually @fn_gl{TexImage2DMultisample}/@fn_gl{TexImage3DMultisample} * 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 * @todoc Remove the workaround when it stops breaking Doxygen layout so badly
*/ */
/* The default parameter value was chosen based on discussion in /* The default parameter value was chosen based on discussion in
@ -173,14 +159,35 @@ template<UnsignedInt dimensions> class MultisampleTexture: public AbstractTextur
NotFixed NotFixed
#endif #endif
) { ) {
DataHelper<dimensions>::setStorageMultisample(*this, _target, samples, internalFormat, size, GLboolean(sampleLocations)); DataHelper<dimensions>::setStorageMultisample(*this, samples, internalFormat, size, GLboolean(sampleLocations));
return *this; 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); } 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) { void invalidateSubImage(const VectorTypeFor<dimensions, Int>& offset, const VectorTypeFor<dimensions, Int>& size) {
DataHelper<dimensions>::invalidateSubImage(*this, 0, offset, 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) {} explicit RectangleTexture(): AbstractTexture(GL_TEXTURE_RECTANGLE) {}
/** /**
* @brief Set minification filter * @copybrief Texture::setMinificationFilter()
* @param filter Filter
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Sets filter used when the object pixel size is smaller than the * See @ref Texture::setMinificationFilter() for more information.
* texture size. If @extension{EXT,direct_state_access} is not * Initial value is @ref Sampler::Filter::Linear.
* 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}
*/ */
RectangleTexture& setMinificationFilter(Sampler::Filter filter) { RectangleTexture& setMinificationFilter(Sampler::Filter filter) {
AbstractTexture::setMinificationFilter(filter, Sampler::Mipmap::Base); AbstractTexture::setMinificationFilter(filter, Sampler::Mipmap::Base);
return *this; 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) { RectangleTexture& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter); AbstractTexture::setMagnificationFilter(filter);
return *this; return *this;
} }
/** /**
* @brief Image size * @copybrief Texture::setWrapping()
*
* 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
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Sets wrapping type for coordinates out of @f$ [ 0, size - 1 ] @f$ * Sets wrapping type for coordinates out of @f$ [ 0, size - 1 ] @f$
* range. If @extension{EXT,direct_state_access} is not available, the * range. See @ref Texture::setWrapping() for more information. Initial
* texture is bound to some texture unit before the operation. Initial
* value is @ref Sampler::Wrapping::ClampToEdge. * value is @ref Sampler::Wrapping::ClampToEdge.
* @attention Only @ref Sampler::Wrapping::ClampToEdge and * @attention Only @ref Sampler::Wrapping::ClampToEdge and
* @ref Sampler::Wrapping::ClampToBorder is supported on this * @ref Sampler::Wrapping::ClampToBorder is supported on this
* texture type. * 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) { RectangleTexture& setWrapping(const Array2D<Sampler::Wrapping>& wrapping) {
DataHelper<2>::setWrapping(*this, wrapping); DataHelper<2>::setWrapping(*this, wrapping);
@ -169,40 +148,37 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture {
* *
* See @ref Texture::setBorderColor(const Vector4ui&) for more * See @ref Texture::setBorderColor(const Vector4ui&) for more
* information. * information.
* @requires_gl30 Extension @extension{EXT,texture_integer}
*/ */
RectangleTexture& setBorderColor(const Vector4ui& color) { RectangleTexture& setBorderColor(const Vector4ui& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return *this; return *this;
} }
/** /** @overload
* @copybrief Texture::setBorderColor(const Vector4ui&) * @requires_gl30 Extension @extension{EXT,texture_integer}
* @return Reference to self (for method chaining)
*
* See @ref Texture::setBorderColor(const Vector4i&) for more
* information.
*/ */
RectangleTexture& setBorderColor(const Vector4i& color) { RectangleTexture& setBorderColor(const Vector4i& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return *this; 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) { RectangleTexture& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy); AbstractTexture::setMaxAnisotropy(anisotropy);
return *this; return *this;
} }
/** /**
* @brief Set sRGB decoding * @copybrief Texture::setSRGBDecode()
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Disables or reenables decoding of sRGB values. Initial value is * See @ref Texture::setSRGBDecode() for more information.
* `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}
* @requires_extension Extension @extension{EXT,texture_sRGB_decode} * @requires_extension Extension @extension{EXT,texture_sRGB_decode}
*/ */
RectangleTexture& setSRGBDecode(bool decode) { RectangleTexture& setSRGBDecode(bool decode) {
@ -215,6 +191,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* See @ref Texture::setSwizzle() for more information. * 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() { template<char r, char g, char b, char a> RectangleTexture& setSwizzle() {
AbstractTexture::setSwizzle<r, g, b, a>(); AbstractTexture::setSwizzle<r, g, b, a>();
@ -248,6 +225,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* See @ref Texture::setDepthStencilMode() for more information. * See @ref Texture::setDepthStencilMode() for more information.
* @requires_gl43 Extension @extension{ARB,stencil_texturing}
*/ */
RectangleTexture& setDepthStencilMode(Sampler::DepthStencilMode mode) { RectangleTexture& setDepthStencilMode(Sampler::DepthStencilMode mode) {
AbstractTexture::setDepthStencilMode(mode); AbstractTexture::setDepthStencilMode(mode);
@ -255,124 +233,91 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture {
} }
/** /**
* @brief Set storage * @copybrief Texture::setStorage()
* @param internalFormat Internal format
* @param size Texture size
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Specifies entire structure of a texture at once, removing the need * See @ref Texture::setStorage() for more information.
* for additional consistency checks and memory reallocations when * @see @ref maxSize()
* 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}.
*/ */
RectangleTexture& setStorage(TextureFormat internalFormat, const Vector2i& size) { RectangleTexture& setStorage(TextureFormat internalFormat, const Vector2i& size) {
DataHelper<2>::setStorage(*this, _target, 1, internalFormat, size); DataHelper<2>::setStorage(*this, 1, internalFormat, size);
return *this; return *this;
} }
/** /**
* @brief Read texture to image * @brief Texture image size
* @param image Image where to put the data
* *
* Image parameters like format and type of pixel data are taken from * See @ref Texture::imageSize() for more information.
* given image, image size is taken from the texture using */
* @ref imageSize(). Vector2i imageSize() { return DataHelper<2>::imageSize(*this, 0); }
/**
* @brief Read texture to image
* *
* If @extension{EXT,direct_state_access} is not available, the * See @ref Texture::image(Int, Image&) for more information.
* 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}
*/ */
void image(Image2D& image) { 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 * @brief Read texture to buffer image
* @param image Buffer image where to put the data
* @param usage Buffer usage
* *
* See @ref image(Image2D&) for more information. * See @ref Texture::image(Int, BufferImage&, BufferUsage) for more
* information.
*/ */
void image(BufferImage2D& image, BufferUsage usage) { void image(BufferImage2D& image, BufferUsage usage) {
AbstractTexture::image<2>(_target, 0, image, usage); AbstractTexture::image<2>(0, image, usage);
} }
/** /**
* @brief Set image data * @copybrief Texture::setImage()
* @param internalFormat Internal format
* @param image @ref Image2D, @ref ImageReference2D or
* @ref Trade::ImageData2D
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* On platforms that support it prefer to use @ref setStorage() and * See @ref Texture::setImage() for more information.
* @ref setSubImage() instead, as it avoids unnecessary reallocations * @see @ref maxSize()
* 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}
* @deprecated_gl Prefer to use @ref Magnum::RectangleTexture::setStorage() "setStorage()" * @deprecated_gl Prefer to use @ref Magnum::RectangleTexture::setStorage() "setStorage()"
* and @ref Magnum::RectangleTexture::setSubImage() "setSubImage()" * and @ref Magnum::RectangleTexture::setSubImage() "setSubImage()"
* instead. * instead.
*/ */
RectangleTexture& setImage(TextureFormat internalFormat, const ImageReference2D& image) { RectangleTexture& setImage(TextureFormat internalFormat, const ImageReference2D& image) {
DataHelper<2>::setImage(*this, _target, 0, internalFormat, image); DataHelper<2>::setImage(*this, 0, internalFormat, image);
return *this; 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) { RectangleTexture& setImage(TextureFormat internalFormat, BufferImage2D& image) {
DataHelper<2>::setImage(*this, _target, 0, internalFormat, image); DataHelper<2>::setImage(*this, 0, internalFormat, image);
return *this; 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) { RectangleTexture& setImage(TextureFormat internalFormat, BufferImage2D&& image) {
return setImage(internalFormat, image); return setImage(internalFormat, image);
} }
/** /**
* @brief Set image subdata * @copybrief Texture::setSubImage()
* @param offset Offset where to put data in the texture
* @param image @ref Image2D, @ref ImageReference2D or
* @ref Trade::ImageData2D
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* If @extension{EXT,direct_state_access} is not available, the * See @ref Texture::setSubImage() for more information.
* 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}
*/ */
RectangleTexture& setSubImage(const Vector2i& offset, const ImageReference2D& image) { 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; return *this;
} }
/** @overload */ /** @overload */
RectangleTexture& setSubImage(const Vector2i& offset, BufferImage2D& image) { RectangleTexture& setSubImage(const Vector2i& offset, BufferImage2D& image) {
DataHelper<2>::setSubImage(*this, _target, 0, offset, image); DataHelper<2>::setSubImage(*this, 0, offset, image);
return *this; 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) * See @ref Texture::invalidateImage() for more information.
* is not available, this function does nothing.
* @see @ref invalidateSubImage(), @fn_gl{InvalidateTexImage}
*/ */
void invalidateImage() { AbstractTexture::invalidateImage(0); } void invalidateImage() { AbstractTexture::invalidateImage(0); }
/** /**
* @brief Invalidate texture subimage * @brief Invalidate subtexture
* @param offset Offset into the texture * @param offset Offset into the texture
* @param size Size of invalidated data * @param size Size of invalidated data
* *
* If extension @extension{ARB,invalidate_subdata} (part of OpenGL 4.3) * See @ref Texture::invalidateSubImage() for more information.
* is not available, this function does nothing.
* @see @ref invalidateImage(), @fn_gl{InvalidateTexSubImage}
*/ */
void invalidateSubImage(const Vector2i& offset, const Vector2i& size) { void invalidateSubImage(const Vector2i& offset, const Vector2i& size) {
DataHelper<2>::invalidateSubImage(*this, 0, offset, 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"); CORRADE_SKIP("OpenGL ES 3.1 not supported, skipping image size testing");
#endif #endif
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 0), Vector2i(32)); CORRADE_COMPARE(texture.imageSize(0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 0), Vector2i(32)); CORRADE_COMPARE(texture.imageSize(1), Vector2i(16));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 0), Vector2i(32)); CORRADE_COMPARE(texture.imageSize(2), Vector2i(8));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 0), Vector2i(32)); CORRADE_COMPARE(texture.imageSize(3), Vector2i(4));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 0), Vector2i(32)); CORRADE_COMPARE(texture.imageSize(4), Vector2i(2));
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));
/* Not available */ /* Not available */
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 5), Vector2i(0)); CORRADE_COMPARE(texture.imageSize(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));
MAGNUM_VERIFY_NO_ERROR(); MAGNUM_VERIFY_NO_ERROR();
#endif #endif
@ -445,8 +410,8 @@ void CubeMapTextureGLTest::generateMipmap() {
/** @todo How to test this on ES? */ /** @todo How to test this on ES? */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 0), Vector2i(32)); CORRADE_COMPARE(texture.imageSize(0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 1), Vector2i( 0)); CORRADE_COMPARE(texture.imageSize(1), Vector2i( 0));
#endif #endif
texture.generateMipmap(); texture.generateMipmap();
@ -455,12 +420,12 @@ void CubeMapTextureGLTest::generateMipmap() {
/** @todo How to test this on ES? */ /** @todo How to test this on ES? */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 0), Vector2i(32)); CORRADE_COMPARE(texture.imageSize(0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 1), Vector2i(16)); CORRADE_COMPARE(texture.imageSize(1), Vector2i(16));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 2), Vector2i( 8)); CORRADE_COMPARE(texture.imageSize(2), Vector2i( 8));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 3), Vector2i( 4)); CORRADE_COMPARE(texture.imageSize(3), Vector2i( 4));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 4), Vector2i( 2)); CORRADE_COMPARE(texture.imageSize(4), Vector2i( 2));
CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 5), Vector2i( 1)); CORRADE_COMPARE(texture.imageSize(5), Vector2i( 1));
MAGNUM_VERIFY_NO_ERROR(); MAGNUM_VERIFY_NO_ERROR();
#endif #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); } constexpr CORRADE_DEPRECATED("use dedicated Texture, TextureArray, MultisampleTexture, RectangleTexture classes instead") Target target() const { return static_cast<Target>(_target); }
#endif #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 #ifndef MAGNUM_TARGET_GLES2
/** /**
* @brief Set base mip level * @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() * Taken into account when generating mipmap using @ref generateMipmap()
* and when considering texture completeness when using mipmap * 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(), * @see @ref setMaxLevel(), @ref setMinificationFilter(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} * @fn_gl2{TextureParameter,TexParameter},
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access} * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* with @def_gl{TEXTURE_BASE_LEVEL} * 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. * @requires_gles30 Base level is always `0` in OpenGL ES 2.0.
*/ */
Texture<dimensions>& setBaseLevel(Int level) { 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() * Taken into account when generating mipmap using @ref generateMipmap()
* and when considering texture completeness when using mipmap * 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(). * levels specified when using @ref setStorage().
* @see @ref setBaseLevel(), @ref setMinificationFilter(), * @see @ref setBaseLevel(), @ref setMinificationFilter(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} * @fn_gl2{TextureParameter,TexParameter},
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access} * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* with @def_gl{TEXTURE_MAX_LEVEL} * 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}, * @requires_gles30 Extension @es_extension{APPLE,texture_max_level},
* otherwise the max level is always set to largest possible value * otherwise the max level is always set to largest possible value
* in OpenGL ES 2.0. * in OpenGL ES 2.0.
@ -257,15 +246,16 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Sets filter used when the object pixel size is smaller than the * Sets filter used when the object pixel size is smaller than the
* texture size. If @extension{EXT,direct_state_access} is not * texture size. If on OpenGL ES or neither @extension{ARB,direct_state_access}
* available, the texture is bound to some texture unit before the * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* operation. Initial value is {@ref Sampler::Filter::Nearest, * available, the texture is bound before the operation (if not
* already). Initial value is {@ref Sampler::Filter::Nearest,
* @ref Sampler::Mipmap::Linear}. * @ref Sampler::Mipmap::Linear}.
* @see @ref setMagnificationFilter(), @ref setBaseLevel(), * @see @ref setMagnificationFilter(), @ref setBaseLevel(),
* @ref setMaxLevel(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} * @ref setMaxLevel(), @fn_gl2{TextureParameter,TexParameter},
* and @fn_gl{TexParameter} or * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @def_gl{TEXTURE_MIN_FILTER} * @fn_gl{TexParameter} with @def_gl{TEXTURE_MIN_FILTER}
*/ */
Texture<dimensions>& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { Texture<dimensions>& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap); AbstractTexture::setMinificationFilter(filter, mipmap);
@ -278,13 +268,14 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Sets filter used when the object pixel size is larger than largest * Sets filter used when the object pixel size is larger than largest
* texture size. If @extension{EXT,direct_state_access} is not * texture size. If on OpenGL ES or neither @extension{ARB,direct_state_access}
* available, the texture is bound to some texture unit before the * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* operation. Initial value is @ref Sampler::Filter::Linear. * available, the texture is bound before the operation (if not
* @see @ref setMinificationFilter(), @fn_gl{ActiveTexture}, * already). Initial value is @ref Sampler::Filter::Linear.
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or * @see @ref setMinificationFilter(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* @def_gl{TEXTURE_MAG_FILTER} * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_MAG_FILTER}
*/ */
Texture<dimensions>& setMagnificationFilter(Sampler::Filter filter) { Texture<dimensions>& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter); AbstractTexture::setMagnificationFilter(filter);
@ -296,14 +287,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @brief Set minimum level-of-detail parameter * @brief Set minimum level-of-detail parameter
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Limits selection of highest resolution mipmap. If * Limits selection of highest resolution mipmap. If on OpenGL ES or
* @extension{EXT,direct_state_access} is not available, the texture is * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* bound to some texture unit before the operation. Initial value is * @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already). Initial value is
* `-1000.0f`. * `-1000.0f`.
* @see @ref setMaxLod(), @ref setLodBias(), @fn_gl{ActiveTexture}, * @see @ref setMaxLod(), @ref setLodBias(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @def_gl{TEXTURE_MIN_LOD} * @fn_gl{TexParameter} with @def_gl{TEXTURE_MIN_LOD}
* @requires_gles30 Texture LOD parameters are not available in OpenGL * @requires_gles30 Texture LOD parameters are not available in OpenGL
* ES 2.0. * ES 2.0.
*/ */
@ -316,14 +308,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @brief Set maximum level-of-detail parameter * @brief Set maximum level-of-detail parameter
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Limits selection of lowest resolution mipmap. If * Limits selection of lowest resolution mipmap. If on OpenGL ES or
* @extension{EXT,direct_state_access} is not available, the texture is * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* bound to some texture unit before the operation. Initial value is * @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already). Initial value is
* `1000.0f`. * `1000.0f`.
* @see @ref setMinLod(), @ref setLodBias(), @fn_gl{ActiveTexture}, * @see @ref setMinLod(), @ref setLodBias(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @def_gl{TEXTURE_MAX_LOD} * @fn_gl{TexParameter} with @def_gl{TEXTURE_MAX_LOD}
* @requires_gles30 Texture LOD parameters are not available in OpenGL * @requires_gles30 Texture LOD parameters are not available in OpenGL
* ES 2.0. * ES 2.0.
*/ */
@ -339,13 +332,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Fixed bias value that is added to the level-of-detail parameter. If * Fixed bias value that is added to the level-of-detail parameter. If
* @extension{EXT,direct_state_access} is not available, the texture is * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* bound to some texture unit before the operation. Initial value is * @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already). Initial value is
* `0.0f`. * `0.0f`.
* @see @ref maxLodBias(), @ref setMinLod(), @ref setMaxLod(), * @see @ref maxLodBias(), @ref setMinLod(), @ref setMaxLod(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} * @fn_gl2{TextureParameter,TexParameter},
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access} * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* with @def_gl{TEXTURE_LOD_BIAS} * 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 * @requires_gl Texture LOD bias can be specified only directly in
* fragment shader in OpenGL ES. * fragment shader in OpenGL ES.
*/ */
@ -361,14 +356,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Sets wrapping type for coordinates out of range @f$ [ 0.0, 1.0 ] @f$. * 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 * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* is bound to some texture unit before the operation. Initial value is * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* @ref Sampler::Wrapping::Repeat. * the texture is bound before the operation (if not already). Initial
* @see @ref setBorderColor(), @fn_gl{ActiveTexture}, * value is @ref Sampler::Wrapping::Repeat.
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or * @see @ref setBorderColor(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T}, * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @def_gl{TEXTURE_WRAP_R} * @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) { Texture<dimensions>& setWrapping(const Array<dimensions, Sampler::Wrapping>& wrapping) {
DataHelper<dimensions>::setWrapping(*this, wrapping); DataHelper<dimensions>::setWrapping(*this, wrapping);
@ -380,13 +376,14 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Border color when wrapping is set to @ref Sampler::Wrapping::ClampToBorder. * Border color when wrapping is set to @ref Sampler::Wrapping::ClampToBorder.
* If @extension{EXT,direct_state_access} is not available, the texture * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* is bound to some texture unit before the operation. Initial value is * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* `{0.0f, 0.0f, 0.0f, 0.0f}`. * the texture is bound before the operation (if not already). Initial
* @see @ref setWrapping(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} * value is `{0.0f, 0.0f, 0.0f, 0.0f}`.
* and @fn_gl{TexParameter} or * @see @ref setWrapping(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* @def_gl{TEXTURE_BORDER_COLOR} * 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} * @requires_es_extension Extension @es_extension{NV,texture_border_clamp}
*/ */
Texture<dimensions>& setBorderColor(const Color4& color) { Texture<dimensions>& setBorderColor(const Color4& color) {
@ -400,12 +397,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Border color for integer textures when wrapping is set to * Border color for integer textures when wrapping is set to
* @ref Sampler::Wrapping::ClampToBorder. If @extension{EXT,direct_state_access} * @ref Sampler::Wrapping::ClampToBorder. If neither
* is not available, the texture is bound to some texture unit before * @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* the operation. Initial value is `{0, 0, 0, 0}`. * @extension{EXT,direct_state_access} is available, the texture is
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} * bound before the operation (if not already). Initial value is
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access} * `{0, 0, 0, 0}`.
* with @def_gl{TEXTURE_BORDER_COLOR} * @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_gl30 Extension @extension{EXT,texture_integer}
* @requires_gl Border is available only for float textures in OpenGL * @requires_gl Border is available only for float textures in OpenGL
* ES. * ES.
@ -433,13 +433,14 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* Default value is `1.0f`, which means no anisotropy. Set to value * Default value is `1.0f`, which means no anisotropy. Set to value
* greater than `1.0f` for anisotropic filtering. If extension * greater than `1.0f` for anisotropic filtering. If extension
* @extension{EXT,texture_filter_anisotropic} (desktop or ES) is not * @extension{EXT,texture_filter_anisotropic} (desktop or ES) is not
* available, this function does nothing. If * available, this function does nothing. If on OpenGL ES or neither
* @extension{EXT,direct_state_access} is not available, the texture is * @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* bound to some texture unit before the operation. * @extension{EXT,direct_state_access} is available, the texture is
* @see @ref Sampler::maxMaxAnisotropy(), @fn_gl{ActiveTexture}, * bound before the operation (if not already).
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or * @see @ref Sampler::maxMaxAnisotropy(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* @def_gl{TEXTURE_MAX_ANISOTROPY_EXT} * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexParameter} with @def_gl{TEXTURE_MAX_ANISOTROPY_EXT}
*/ */
Texture<dimensions>& setMaxAnisotropy(Float anisotropy) { Texture<dimensions>& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy); AbstractTexture::setMaxAnisotropy(anisotropy);
@ -450,12 +451,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @brief Set sRGB decoding * @brief Set sRGB decoding
* @return Reference to self (for method chaining) * @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`. * `true`.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and * @see @fn_gl2{TextureParameter,TexParameter},
* @fn_gl{TexParameter} or * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @def_gl{TEXTURE_SRGB_DECODE_EXT} * @fn_gl{TexParameter} with @def_gl{TEXTURE_SRGB_DECODE_EXT}
* @requires_extension Extension @extension{EXT,texture_sRGB_decode} * @requires_extension Extension @extension{EXT,texture_sRGB_decode}
* @requires_es_extension OpenGL ES 3.0 or extension * @requires_es_extension OpenGL ES 3.0 or extension
* @es_extension{EXT,sRGB} and * @es_extension{EXT,sRGB} and
@ -477,15 +481,17 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @code * @code
* texture.setSwizzle<'b', 'g', 'r', '0'>(); * texture.setSwizzle<'b', 'g', 'r', '0'>();
* @endcode * @endcode
* If @extension{EXT,direct_state_access} is not available, * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* the texture is bound to some texture unit before the operation. * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* Initial value is `rgba`. * the texture is bound before the operation (if not already). Initial
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and * value is `rgba`.
* @fn_gl{TexParameter} or * @see @fn_gl2{TextureParameter,TexParameter},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* @def_gl{TEXTURE_SWIZZLE_RGBA} (or @def_gl{TEXTURE_SWIZZLE_R}, * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @def_gl{TEXTURE_SWIZZLE_G}, @def_gl{TEXTURE_SWIZZLE_B} and * @fn_gl{TexParameter} with @def_gl{TEXTURE_SWIZZLE_RGBA} (or
* @def_gl{TEXTURE_SWIZZLE_A} separately in OpenGL ES) * @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_gl33 Extension @extension{ARB,texture_swizzle}
* @requires_gles30 Texture swizzle is not available in OpenGL ES 2.0. * @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 * @brief Set depth texture comparison mode
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* If @extension{EXT,direct_state_access} is not available, * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* the texture is bound to some texture unit before the operation. * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* Initial value is @ref Sampler::CompareMode::None. * 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. * @note Depth textures can be only 1D or 2D.
* @see @ref setCompareFunction(), @fn_gl{ActiveTexture}, * @see @ref setCompareFunction(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @def_gl{TEXTURE_COMPARE_MODE} * @fn_gl{TexParameter} with @def_gl{TEXTURE_COMPARE_MODE}
* @requires_gles30 Extension @es_extension{EXT,shadow_samplers} * @requires_gles30 Extension @es_extension{EXT,shadow_samplers}
*/ */
Texture<dimensions>& setCompareMode(Sampler::CompareMode mode) { Texture<dimensions>& setCompareMode(Sampler::CompareMode mode) {
@ -519,15 +526,16 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Comparison operator used when comparison mode is set to * Comparison operator used when comparison mode is set to
* @ref Sampler::CompareMode::CompareRefToTexture. If * @ref Sampler::CompareMode::CompareRefToTexture. If on OpenGL ES or
* @extension{EXT,direct_state_access} is not available, the texture is * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* bound to some texture unit before the operation. Initial value is * @extension{EXT,direct_state_access} is available, the texture is
* bound before the operation (if not already). Initial value is
* @ref Sampler::CompareFunction::LessOrEqual. * @ref Sampler::CompareFunction::LessOrEqual.
* @note Depth textures can be only 1D or 2D. * @note Depth textures can be only 1D or 2D.
* @see @ref setCompareMode(), @fn_gl{ActiveTexture}, * @see @ref setCompareMode(), @fn_gl2{TextureParameter,TexParameter},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @def_gl{TEXTURE_COMPARE_FUNC} * @fn_gl{TexParameter} with @def_gl{TEXTURE_COMPARE_FUNC}
* @requires_gles30 Extension @es_extension{EXT,shadow_samplers} * @requires_gles30 Extension @es_extension{EXT,shadow_samplers}
*/ */
Texture<dimensions>& setCompareFunction(Sampler::CompareFunction function) { Texture<dimensions>& setCompareFunction(Sampler::CompareFunction function) {
@ -541,13 +549,15 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Selects which component of packed depth/stencil texture is used for * Selects which component of packed depth/stencil texture is used for
* texturing. If @extension{EXT,direct_state_access} is not available, * texturing. If on OpenGL ES or neither @extension{ARB,direct_state_access}
* the texture is bound to some texture unit before the operation. * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* Initial value is @ref Sampler::DepthStencilMode::DepthComponent. * 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. * @note Depth textures can be only 1D or 2D.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} * @see @fn_gl2{TextureParameter,TexParameter},
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access} * @fn_gl_extension{TextureParameter,EXT,direct_state_access},
* with @def_gl{DEPTH_STENCIL_TEXTURE_MODE} * 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_gl43 Extension @extension{ARB,stencil_texturing}
* @requires_gles31 Stencil texturing is not available in OpenGL ES 3.0 * @requires_gles31 Stencil texturing is not available in OpenGL ES 3.0
* and older. * and older.
@ -565,36 +575,52 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @param size Size of largest mip level * @param size Size of largest mip level
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Specifies entire structure of a texture at once, removing the need * After calling this function the texture is immutable and calling
* for additional consistency checks and memory reallocations when * @ref setStorage() or @ref setImage() is not allowed.
* updating the data later. After calling this function the texture *
* is immutable and calling @ref setStorage() or @ref setImage() is not * If on OpenGL ES or neither @extension{ARB,direct_state_access}
* allowed. * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is
* * available, the texture is bound before the operation (if not
* If @extension{EXT,direct_state_access} is not available, the texture * already). If neither @extension{ARB,texture_storage} (part of OpenGL
* is bound to some texture unit before the operation. If * 4.2), OpenGL ES 3.0 nor @es_extension{EXT,texture_storage} in OpenGL
* @extension{ARB,texture_storage} (part of OpenGL 4.2), OpenGL ES 3.0 * ES 2.0 is available, the feature is emulated with sequence of
* or @es_extension{EXT,texture_storage} in OpenGL ES 2.0 is not * @ref setImage() calls.
* available, the feature is emulated with sequence of @ref setImage() * @see @ref maxSize(), @ref setMaxLevel(), @fn_gl2{TextureStorage1D,TexStorage1D} /
* calls. * @fn_gl2{TextureStorage2D,TexStorage2D} / @fn_gl2{TextureStorage3D,TexStorage3D},
* @see @ref maxSize(), @ref setMaxLevel(), @fn_gl{ActiveTexture}, * @fn_gl_extension{TextureStorage1D,EXT,direct_state_access} /
* @fn_gl{BindTexture} and * @fn_gl_extension{TextureStorage2D,EXT,direct_state_access} /
* @fn_gl{TexStorage1D}/@fn_gl{TexStorage2D}/@fn_gl{TexStorage3D}
* or @fn_gl_extension{TextureStorage1D,EXT,direct_state_access}/
* @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureStorage3D,EXT,direct_state_access}, * @fn_gl_extension{TextureStorage3D,EXT,direct_state_access},
* eventually @fn_gl{TexImage1D}/@fn_gl{TexImage2D}/@fn_gl{TexImage3D} * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* or @fn_gl_extension{TextureImage1D,EXT,direct_state_access}/ * @fn_gl{TexStorage1D}/@fn_gl{TexStorage2D}/@fn_gl{TexStorage3D}
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage3D,EXT,direct_state_access}
* @todo allow the user to specify ColorType explicitly to avoid * @todo allow the user to specify ColorType explicitly to avoid
* issues in WebGL (see setSubImage()) * issues in WebGL (see setSubImage())
*/ */
Texture<dimensions>& setStorage(Int levels, TextureFormat internalFormat, const VectorTypeFor<dimensions, Int>& size) { 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; 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 #ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Read given mip level of texture to image * @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 * given image, image size is taken from the texture using
* @ref imageSize(). * @ref imageSize().
* *
* If @extension{EXT,direct_state_access} is not available, the * If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* texture is bound to some texture unit before the operation. If * nor @extension{EXT,direct_state_access} is available, the texture is
* @extension{ARB,robustness} is available, the operation is protected * bound before the operation (if not already). If either
* from buffer overflow. However, if both @extension{EXT,direct_state_access} * @extension{ARB,direct_state_access} or @extension{ARB,robustness}
* and @extension{ARB,robustness} are available, the DSA version is * is available, the operation is protected from buffer overflow.
* used, because it is better for performance and there isn't any * However, if @extension{ARB,direct_state_access} is not available and
* function combining both features. * both @extension{EXT,direct_state_access} and @extension{ARB,robustness}
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and * are available, the robust operation is preferred over DSA.
* @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} * @see @fn_gl2{GetTextureLevelParameter,GetTexLevelParameter},
* with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or @def_gl{TEXTURE_DEPTH}, * @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access},
* then @fn_gl{GetTexImage}, @fn_gl_extension{GetTextureImage,EXT,direct_state_access} * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* or @fn_gl_extension{GetnTexImage,ARB,robustness} * @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. * @requires_gl Texture image queries are not available in OpenGL ES.
*/ */
void image(Int level, Image<dimensions>& image) { 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...) * @extension{ARB,buffer_storage}, avoiding relocations...)
*/ */
void image(Int level, BufferImage<dimensions>& image, BufferUsage usage) { void image(Int level, BufferImage<dimensions>& image, BufferUsage usage) {
AbstractTexture::image<dimensions>(_target, level, image, usage); AbstractTexture::image<dimensions>(level, image, usage);
} }
#endif #endif
@ -653,24 +683,36 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* equivalent in @extension{ARB,direct_state_access}, thus the texture * equivalent in @extension{ARB,direct_state_access}, thus the texture
* needs to be bound to some texture unit before the operation. * needs to be bound to some texture unit before the operation.
* @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and * @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()" * @deprecated_gl Prefer to use @ref Magnum::Texture::setStorage() "setStorage()"
* and @ref Magnum::Texture::setSubImage() "setSubImage()" * and @ref Magnum::Texture::setSubImage() "setSubImage()"
* instead. * instead.
*/ */
Texture<dimensions>& setImage(Int level, TextureFormat internalFormat, const ImageReference<dimensions>& image) { 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; return *this;
} }
#ifndef MAGNUM_TARGET_GLES2 #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) { 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; 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) { Texture<dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions>&& image) {
return setImage(level, internalFormat, 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 * @ref Trade::ImageData of the same dimension count
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* If @extension{EXT,direct_state_access} is not available, the * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* texture is bound to some texture unit before the operation. * 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 * @attention In @ref MAGNUM_TARGET_WEBGL "WebGL" the @ref ColorType of
* data passed in @p image must match the original one specified * data passed in @p image must match the original one specified
* in @ref setImage(). It means that you might not be able to use * in @ref setImage(). It means that you might not be able to use
* @ref setStorage() as it uses implicit @ref ColorType value. * @ref setStorage() as it uses implicit @ref ColorType value.
* *
* @see @ref setStorage(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} * @see @ref setStorage(), @fn_gl2{TextureSubImage1D,TexSubImage1D} /
* and @fn_gl{TexSubImage1D}/@fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D} * @fn_gl2{TextureSubImage2D,TexSubImage2D} / @fn_gl2{TextureSubImage3D,TexSubImage3D},
* or @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}/ * @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access} /
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access} /
* @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access},
* 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) { 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; return *this;
} }
#ifndef MAGNUM_TARGET_GLES2 #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) { 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; 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) { Texture<dimensions>& setSubImage(Int level, const VectorTypeFor<dimensions, Int>& offset, BufferImage<dimensions>&& image) {
return setSubImage(level, offset, image); return setSubImage(level, offset, image);
} }
@ -720,11 +771,13 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @brief Generate mipmap * @brief Generate mipmap
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* If @extension{EXT,direct_state_access} is not available, the texture * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* is bound to some texture unit before the operation. * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* @see @ref setMinificationFilter(), @fn_gl{ActiveTexture}, * the texture is bound before the operation (if not already).
* @fn_gl{BindTexture} and @fn_gl{GenerateMipmap} or * @see @ref setMinificationFilter(), @fn_gl2{GenerateTextureMipmap,GenerateMipmap},
* @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access} * @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} * @requires_gl30 Extension @extension{ARB,framebuffer_object}
*/ */
Texture<dimensions>& generateMipmap() { 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>()) {} 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) { TextureArray<dimensions>& setBaseLevel(Int level) {
AbstractTexture::setBaseLevel(level); AbstractTexture::setBaseLevel(level);
return *this; 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) { TextureArray<dimensions>& setMaxLevel(Int level) {
AbstractTexture::setMaxLevel(level); AbstractTexture::setMaxLevel(level);
return *this; 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) { TextureArray<dimensions>& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap); AbstractTexture::setMinificationFilter(filter, mipmap);
return *this; 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) { TextureArray<dimensions>& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter); AbstractTexture::setMagnificationFilter(filter);
return *this; 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) { TextureArray<dimensions>& setMinLod(Float lod) {
AbstractTexture::setMinLod(lod); AbstractTexture::setMinLod(lod);
return *this; 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) { TextureArray<dimensions>& setMaxLod(Float lod) {
AbstractTexture::setMaxLod(lod); AbstractTexture::setMaxLod(lod);
return *this; return *this;
} }
#endif
#ifndef MAGNUM_TARGET_GLES #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) { TextureArray<dimensions>& setLodBias(Float bias) {
AbstractTexture::setLodBias(bias); AbstractTexture::setLodBias(bias);
return *this; return *this;
} }
#endif #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) { TextureArray<dimensions>& setWrapping(const Array<dimensions+1, Sampler::Wrapping>& wrapping) {
DataHelper<dimensions+1>::setWrapping(*this, wrapping); DataHelper<dimensions+1>::setWrapping(*this, wrapping);
return *this; 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) { TextureArray<dimensions>& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return *this; return *this;
} }
#ifndef MAGNUM_TARGET_GLES #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) { TextureArray<dimensions>& setBorderColor(const Vector4ui& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return *this; 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) { TextureArray<dimensions>& setBorderColor(const Vector4i& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return *this; return *this;
} }
#endif #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) { TextureArray<dimensions>& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy); AbstractTexture::setMaxAnisotropy(anisotropy);
return *this; 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) { TextureArray<dimensions>& setSRGBDecode(bool decode) {
AbstractTexture::setSRGBDecode(decode); AbstractTexture::setSRGBDecode(decode);
return *this; 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() { template<char r, char g, char b, char a> TextureArray<dimensions>& setSwizzle() {
AbstractTexture::setSwizzle<r, g, b, a>(); AbstractTexture::setSwizzle<r, g, b, a>();
return *this; return *this;
} }
#endif
/** /**
* @copybrief Texture::setCompareMode() * @copybrief Texture::setCompareMode()
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* See @ref Texture::setCompareMode() for more information. * 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) { TextureArray<dimensions>& setCompareMode(Sampler::CompareMode mode) {
AbstractTexture::setCompareMode(mode); AbstractTexture::setCompareMode(mode);
@ -230,113 +302,107 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* See @ref Texture::setCompareFunction() for more information. * 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) { TextureArray<dimensions>& setCompareFunction(Sampler::CompareFunction function) {
AbstractTexture::setCompareFunction(function); AbstractTexture::setCompareFunction(function);
return *this; return *this;
} }
#ifndef MAGNUM_TARGET_GLES2
/** /**
* @copybrief Texture::setDepthStencilMode() * @copybrief Texture::setDepthStencilMode()
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* See @ref Texture::setDepthStencilMode() for more information. * 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) { TextureArray<dimensions>& setDepthStencilMode(Sampler::DepthStencilMode mode) {
AbstractTexture::setDepthStencilMode(mode); AbstractTexture::setDepthStencilMode(mode);
return *this; 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 * @copybrief Texture::setStorage()
* @param levels Mip level count
* @param internalFormat Internal format
* @param size Size of largest mip level
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Specifies entire structure of a texture at once, removing the need * See @ref Texture::setStorage() for more information.
* for additional consistency checks and memory reallocations when * @see @ref maxSize()
* 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}.
*/ */
TextureArray<dimensions>& setStorage(Int levels, TextureFormat internalFormat, const VectorTypeFor<dimensions+1, Int>& size) { 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; 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 #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) { 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) { 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 #endif
/** /**
* @brief Set image data * @copybrief Texture::setImage()
* @param level Mip level
* @param internalFormat Internal format
* @param image @ref Image, @ref ImageReference or
* @ref Trade::ImageData of the same dimension count
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* On platforms that support it prefer to use @ref setStorage() and * See @ref Texture::setImage() for more information.
* @ref setSubImage() instead, as it avoids unnecessary reallocations * @see @ref maxSize()
* 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}
* @deprecated_gl Prefer to use @ref Magnum::TextureArray::setStorage() "setStorage()" * @deprecated_gl Prefer to use @ref Magnum::TextureArray::setStorage() "setStorage()"
* and @ref Magnum::TextureArray::setSubImage() "setSubImage()" * and @ref Magnum::TextureArray::setSubImage() "setSubImage()"
* instead. * instead.
*/ */
TextureArray<dimensions>& setImage(Int level, TextureFormat internalFormat, const ImageReference<dimensions+1>& image) { 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; 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) { 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; 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) { TextureArray<dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions+1>&& image) {
return setImage(level, internalFormat, image); return setImage(level, internalFormat, image);
} }
#endif
/** /**
* @brief Set image subdata * @brief Set image subdata
@ -346,22 +412,24 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
* @ref Trade::ImageData of the same dimension count * @ref Trade::ImageData of the same dimension count
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* If @extension{EXT,direct_state_access} is not available, the * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* texture is bound to some texture unit before the operation. * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* @see @ref setStorage(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} * the texture is bound before the operation (if not already).
* and @fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D} or * @see @ref setStorage(), @fn_gl2{TextureSubImage2D,TexSubImage2D}/
* @fn_gl2{TextureSubImage3D,TexSubImage3D},
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access},
* 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) { 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; return *this;
} }
#ifndef MAGNUM_TARGET_GLES2
/** @overload */ /** @overload */
TextureArray<dimensions>& setSubImage(Int level, const VectorTypeFor<dimensions+1, Int>& offset, BufferImage<dimensions+1>& image) { 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; 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) { TextureArray<dimensions>& setSubImage(Int level, const VectorTypeFor<dimensions+1, Int>& offset, BufferImage<dimensions+1>&& image) {
return setSubImage(level, offset, 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() { TextureArray<dimensions>& generateMipmap() {
AbstractTexture::generateMipmap(); AbstractTexture::generateMipmap();
return *this; 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); } 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) { void invalidateSubImage(Int level, const VectorTypeFor<dimensions+1, Int>& offset, const VectorTypeFor<dimensions+1, Int>& size) {
DataHelper<dimensions+1>::invalidateSubImage(*this, level, offset, size); DataHelper<dimensions+1>::invalidateSubImage(*this, level, offset, size);
} }

Loading…
Cancel
Save