From a5381993a52c905ca2099605b51039a6c63e8793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 18 Nov 2014 20:28:52 +0100 Subject: [PATCH] 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. --- src/Magnum/AbstractTexture.cpp | 319 ++++++++++------ src/Magnum/AbstractTexture.h | 191 ++++++---- src/Magnum/BufferTexture.cpp | 8 + src/Magnum/BufferTexture.h | 31 +- src/Magnum/CubeMapTexture.cpp | 122 ++++++ src/Magnum/CubeMapTexture.h | 283 ++++++++++---- src/Magnum/CubeMapTextureArray.h | 136 ++++--- src/Magnum/Implementation/TextureState.cpp | 97 ++++- src/Magnum/Implementation/TextureState.h | 31 +- src/Magnum/MultisampleTexture.h | 65 ++-- src/Magnum/RectangleTexture.h | 187 ++++------ src/Magnum/Test/CubeMapTextureGLTest.cpp | 63 +--- src/Magnum/Texture.h | 411 ++++++++++++--------- src/Magnum/TextureArray.h | 263 ++++++++----- 14 files changed, 1366 insertions(+), 841 deletions(-) diff --git a/src/Magnum/AbstractTexture.cpp b/src/Magnum/AbstractTexture.cpp index 55b8fcd01..7db1951d5 100644 --- a/src/Magnum/AbstractTexture.cpp +++ b/src/Magnum/AbstractTexture.cpp @@ -143,6 +143,13 @@ void AbstractTexture::unbindImplementationMulti(const GLint textureUnit) { glBindTextures(textureUnit, 1, &zero); } +void AbstractTexture::unbindImplementationDSA(const GLint textureUnit) { + Implementation::TextureState& textureState = *Context::current()->state().texture; + + CORRADE_INTERNAL_ASSERT(textureState.bindings[textureUnit].first != 0); + glBindTextureUnit(textureUnit, 0); +} + void AbstractTexture::unbindImplementationDSAEXT(const GLint textureUnit) { Implementation::TextureState& textureState = *Context::current()->state().texture; @@ -274,6 +281,10 @@ void AbstractTexture::bindImplementationMulti(GLint textureUnit) { glBindTextures(textureUnit, 1, &_id); } +void AbstractTexture::bindImplementationDSA(const GLint textureUnit) { + glBindTextureUnit(textureUnit, _id); +} + void AbstractTexture::bindImplementationDSAEXT(GLint textureUnit) { _created = true; glBindMultiTextureEXT(GL_TEXTURE0 + textureUnit, _target, _id); @@ -401,6 +412,10 @@ void AbstractTexture::mipmapImplementationDefault() { } #ifndef MAGNUM_TARGET_GLES +void AbstractTexture::mipmapImplementationDSA() { + glGenerateTextureMipmap(_id); +} + void AbstractTexture::mipmapImplementationDSAEXT() { _created = true; glGenerateTextureMipmapEXT(_id, _target); @@ -810,6 +825,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLint val } #ifndef MAGNUM_TARGET_GLES +void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLint value) { + glTextureParameteri(_id, parameter, value); +} + void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, GLint value) { _created = true; glTextureParameteriEXT(_id, _target, parameter, value); @@ -822,6 +841,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLfloat v } #ifndef MAGNUM_TARGET_GLES +void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLfloat value) { + glTextureParameterf(_id, parameter, value); +} + void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, GLfloat value) { _created = true; glTextureParameterfEXT(_id, _target, parameter, value); @@ -835,6 +858,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLi } #ifndef MAGNUM_TARGET_GLES +void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLint* const values) { + glTextureParameteriv(_id, parameter, values); +} + void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, const GLint* values) { _created = true; glTextureParameterivEXT(_id, _target, parameter, values); @@ -848,6 +875,10 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLf } #ifndef MAGNUM_TARGET_GLES +void AbstractTexture::parameterImplementationDSA(const GLenum parameter, const GLfloat* const values) { + glTextureParameterfv(_id, parameter, values); +} + void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, const GLfloat* values) { _created = true; glTextureParameterfvEXT(_id, _target, parameter, values); @@ -860,6 +891,10 @@ void AbstractTexture::parameterIImplementationDefault(GLenum parameter, const GL glTexParameterIuiv(_target, parameter, values); } +void AbstractTexture::parameterIImplementationDSA(const GLenum parameter, const GLuint* const values) { + glTextureParameterIuiv(_id, parameter, values); +} + void AbstractTexture::parameterIImplementationDSAEXT(GLenum parameter, const GLuint* values) { _created = true; glTextureParameterIuivEXT(_id, _target, parameter, values); @@ -870,6 +905,10 @@ void AbstractTexture::parameterIImplementationDefault(GLenum parameter, const GL glTexParameterIiv(_target, parameter, values); } +void AbstractTexture::parameterIImplementationDSA(const GLenum parameter, const GLint* const values) { + glTextureParameterIiv(_id, parameter, values); +} + void AbstractTexture::parameterIImplementationDSAEXT(GLenum parameter, const GLint* values) { _created = true; glTextureParameterIivEXT(_id, _target, parameter, values); @@ -883,59 +922,65 @@ void AbstractTexture::setMaxAnisotropyImplementationExt(GLfloat anisotropy) { } #ifndef MAGNUM_TARGET_GLES2 -void AbstractTexture::getLevelParameterImplementationDefault(GLenum target, GLint level, GLenum parameter, GLint* values) { +void AbstractTexture::getLevelParameterImplementationDefault(GLint level, GLenum parameter, GLint* values) { bindInternal(); - glGetTexLevelParameteriv(target, level, parameter, values); + glGetTexLevelParameteriv(_target, level, parameter, values); } #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::getLevelParameterImplementationDSAEXT(GLenum target, GLint level, GLenum parameter, GLint* values) { +void AbstractTexture::getLevelParameterImplementationDSA(const GLint level, const GLenum parameter, GLint* const values) { + glGetTextureLevelParameteriv(_id, level, parameter, values); +} + +void AbstractTexture::getLevelParameterImplementationDSAEXT(GLint level, GLenum parameter, GLint* values) { _created = true; - glGetTextureLevelParameterivEXT(_id, target, level, parameter, values); + glGetTextureLevelParameterivEXT(_id, _target, level, parameter, values); } #endif #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::storageImplementationFallback(const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { - CORRADE_INTERNAL_ASSERT(target == GL_TEXTURE_1D); - +void AbstractTexture::storageImplementationFallback(const GLsizei levels, const TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { const ColorFormat format = imageFormatForInternalFormat(internalFormat); const ColorType type = imageTypeForInternalFormat(internalFormat); for(GLsizei level = 0; level != levels; ++level) - DataHelper<1>::setImage(*this, target, level, internalFormat, + DataHelper<1>::setImage(*this, level, internalFormat, ImageReference1D{format, type, Math::max(Math::Vector<1, GLsizei>(1), size >> level)}); } -void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { +void AbstractTexture::storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { bindInternal(); - glTexStorage1D(target, levels, GLenum(internalFormat), size[0]); + glTexStorage1D(_target, levels, GLenum(internalFormat), size[0]); } -void AbstractTexture::storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { +void AbstractTexture::storageImplementationDSA(const GLsizei levels, const TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { + glTextureStorage1D(_id, levels, GLenum(internalFormat), size[0]); +} + +void AbstractTexture::storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { _created = true; - glTextureStorage1DEXT(_id, target, levels, GLenum(internalFormat), size[0]); + glTextureStorage1DEXT(_id, _target, levels, GLenum(internalFormat), size[0]); } #endif -void AbstractTexture::storageImplementationFallback(const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) { +void AbstractTexture::storageImplementationFallback(const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) { const ColorFormat format = imageFormatForInternalFormat(internalFormat); const ColorType type = imageTypeForInternalFormat(internalFormat); /* Common code for classic types */ #ifndef MAGNUM_TARGET_GLES - if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE) + if(_target == GL_TEXTURE_2D || _target == GL_TEXTURE_RECTANGLE) #else - if(target == GL_TEXTURE_2D) + if(_target == GL_TEXTURE_2D) #endif { for(GLsizei level = 0; level != levels; ++level) - DataHelper<2>::setImage(*this, target, level, internalFormat, + DataHelper<2>::setImage(*this, level, internalFormat, ImageReference2D{format, type, Math::max(Vector2i(1), size >> level)}); /* Cube map additionally needs to specify all faces */ - } else if(target == GL_TEXTURE_CUBE_MAP) { + } else if(_target == GL_TEXTURE_CUBE_MAP) { for(GLsizei level = 0; level != levels; ++level) { for(GLenum face: {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, @@ -949,9 +994,9 @@ void AbstractTexture::storageImplementationFallback(const GLenum target, const G #ifndef MAGNUM_TARGET_GLES /* Array texture is not scaled in "layer" dimension */ - } else if(target == GL_TEXTURE_1D_ARRAY) { + } else if(_target == GL_TEXTURE_1D_ARRAY) { for(GLsizei level = 0; level != levels; ++level) - DataHelper<2>::setImage(*this, target, level, internalFormat, + DataHelper<2>::setImage(*this, level, internalFormat, ImageReference2D{format, type, Vector2i{Math::max(1, size.x() >> level), size.y()}}); #endif @@ -959,14 +1004,13 @@ void AbstractTexture::storageImplementationFallback(const GLenum target, const G } else CORRADE_ASSERT_UNREACHABLE(); } -void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) { +void AbstractTexture::storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector2i& size) { bindInternal(); #ifndef MAGNUM_TARGET_GLES2 - glTexStorage2D(target, levels, GLenum(internalFormat), size.x(), size.y()); + glTexStorage2D(_target, levels, GLenum(internalFormat), size.x(), size.y()); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glTexStorage2DEXT(target, levels, GLenum(internalFormat), size.x(), size.y()); + glTexStorage2DEXT(_target, levels, GLenum(internalFormat), size.x(), size.y()); #else - static_cast(target); static_cast(levels); static_cast(internalFormat); static_cast(size); @@ -975,35 +1019,39 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels } #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) { +void AbstractTexture::storageImplementationDSA(const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) { + glTextureStorage2D(_id, levels, GLenum(internalFormat), size.x(), size.y()); +} + +void AbstractTexture::storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Vector2i& size) { _created = true; - glTextureStorage2DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y()); + glTextureStorage2DEXT(_id, _target, levels, GLenum(internalFormat), size.x(), size.y()); } #endif -void AbstractTexture::storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { +void AbstractTexture::storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { const ColorFormat format = imageFormatForInternalFormat(internalFormat); const ColorType type = imageTypeForInternalFormat(internalFormat); /* Common code for classic type */ #ifndef MAGNUM_TARGET_GLES2 - if(target == GL_TEXTURE_3D) + if(_target == GL_TEXTURE_3D) #else - if(target == GL_TEXTURE_3D_OES) + if(_target == GL_TEXTURE_3D_OES) #endif for(GLsizei level = 0; level != levels; ++level) - DataHelper<3>::setImage(*this, target, level, internalFormat, + DataHelper<3>::setImage(*this, level, internalFormat, ImageReference3D{format, type, Math::max(Vector3i(1), size >> level)}); #ifndef MAGNUM_TARGET_GLES2 /* Array texture is not scaled in "layer" dimension */ #ifndef MAGNUM_TARGET_GLES - else if(target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY) + else if(_target == GL_TEXTURE_2D_ARRAY || _target == GL_TEXTURE_CUBE_MAP_ARRAY) #else - else if(target == GL_TEXTURE_2D_ARRAY) + else if(_target == GL_TEXTURE_2D_ARRAY) #endif for(GLsizei level = 0; level != levels; ++level) - DataHelper<3>::setImage(*this, target, level, internalFormat, + DataHelper<3>::setImage(*this, level, internalFormat, ImageReference3D{format, type, Vector3i{Math::max(Vector2i{1}, size.xy() >> level), size.z()}}); #endif @@ -1011,14 +1059,13 @@ void AbstractTexture::storageImplementationFallback(GLenum target, GLsizei level else CORRADE_ASSERT_UNREACHABLE(); } -void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { +void AbstractTexture::storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { bindInternal(); #ifndef MAGNUM_TARGET_GLES2 - glTexStorage3D(target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); + glTexStorage3D(_target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glTexStorage3DEXT(target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); + glTexStorage3DEXT(_target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); #else - static_cast(target); static_cast(levels); static_cast(internalFormat); static_cast(size); @@ -1027,97 +1074,120 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels } #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { +void AbstractTexture::storageImplementationDSA(const GLsizei levels, const TextureFormat internalFormat, const Vector3i& size) { + glTextureStorage3D(_id, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); +} + +void AbstractTexture::storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { _created = true; - glTextureStorage3DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); + glTextureStorage3DEXT(_id, _target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::storageMultisampleImplementationFallback(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { +void AbstractTexture::storageMultisampleImplementationFallback(const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { bindInternal(); - glTexImage2DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); + glTexImage2DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); } #endif #ifndef MAGNUM_TARGET_GLES2 -void AbstractTexture::storageMultisampleImplementationDefault(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { +void AbstractTexture::storageMultisampleImplementationDefault(const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { bindInternal(); - glTexStorage2DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); + glTexStorage2DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { +void AbstractTexture::storageMultisampleImplementationDSA(const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { + glTextureStorage2DMultisample(_id, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); +} + +void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { _created = true; - glTextureStorage2DMultisampleEXT(_id, target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); + glTextureStorage2DMultisampleEXT(_id, _target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); } -void AbstractTexture::storageMultisampleImplementationFallback(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { +void AbstractTexture::storageMultisampleImplementationFallback(const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { bindInternal(); - glTexImage3DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); + glTexImage3DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); } -void AbstractTexture::storageMultisampleImplementationDefault(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { +void AbstractTexture::storageMultisampleImplementationDefault(const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { bindInternal(); - glTexStorage3DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); + glTexStorage3DMultisample(_target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); } -void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { +void AbstractTexture::storageMultisampleImplementationDSA(const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { + glTextureStorage3DMultisample(_id, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); +} + +void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { _created = true; - glTextureStorage3DMultisampleEXT(_id, target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); + glTextureStorage3DMultisampleEXT(_id, _target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::getImageImplementationDefault(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) { +void AbstractTexture::getImageImplementationDefault(const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) { bindInternal(); - glGetTexImage(target, level, GLenum(format), GLenum(type), data); + glGetTexImage(_target, level, GLenum(format), GLenum(type), data); } -void AbstractTexture::getImageImplementationDSAEXT(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) { +void AbstractTexture::getImageImplementationDSA(const GLint level, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { + glGetTextureImage(_id, level, GLenum(format), GLenum(type), dataSize, data); +} + +void AbstractTexture::getImageImplementationDSAEXT(const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) { _created = true; - glGetTextureImageEXT(_id, target, level, GLenum(format), GLenum(type), data); + glGetTextureImageEXT(_id, _target, level, GLenum(format), GLenum(type), data); } -void AbstractTexture::getImageImplementationRobustness(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { +void AbstractTexture::getImageImplementationRobustness(const GLint level, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { bindInternal(); - glGetnTexImageARB(target, level, GLenum(format), GLenum(type), dataSize, data); + glGetnTexImageARB(_target, level, GLenum(format), GLenum(type), dataSize, data); } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::subImageImplementationDefault(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) { bindInternal(); - glTexSubImage1D(target, level, offset[0], size[0], GLenum(format), GLenum(type), data); + glTexSubImage1D(_target, level, offset[0], size[0], GLenum(format), GLenum(type), data); +} + +void AbstractTexture::subImageImplementationDSA(const GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { + glTextureSubImage1D(_id, level, offset[0], size[0], GLenum(format), GLenum(type), data); } -void AbstractTexture::subImageImplementationDSAEXT(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::subImageImplementationDSAEXT(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) { _created = true; - glTextureSubImage1DEXT(_id, target, level, offset[0], size[0], GLenum(format), GLenum(type), data); + glTextureSubImage1DEXT(_id, _target, level, offset[0], size[0], GLenum(format), GLenum(type), data); } #endif -void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::subImageImplementationDefault(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) { bindInternal(); - glTexSubImage2D(target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); + glTexSubImage2D(_target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); } #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::subImageImplementationDSAEXT(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::subImageImplementationDSA(const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { + glTextureSubImage2D(_id, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); +} + +void AbstractTexture::subImageImplementationDSAEXT(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) { _created = true; - glTextureSubImage2DEXT(_id, target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); + glTextureSubImage2DEXT(_id, _target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); } #endif -void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::subImageImplementationDefault(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) { bindInternal(); #ifndef MAGNUM_TARGET_GLES2 - glTexSubImage3D(target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); + glTexSubImage3D(_target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glTexSubImage3DOES(target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); + glTexSubImage3DOES(_target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); #else - static_cast(target); static_cast(level); static_cast(offset); static_cast(size); @@ -1129,9 +1199,13 @@ void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, } #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::subImageImplementationDSAEXT(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) { +void AbstractTexture::subImageImplementationDSA(const GLint level, const Vector3i& offset, const Vector3i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { + glTextureSubImage3D(_id, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); +} + +void AbstractTexture::subImageImplementationDSAEXT(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) { _created = true; - glTextureSubImage3DEXT(_id, target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); + glTextureSubImage3DEXT(_id, _target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); } #endif @@ -1155,111 +1229,111 @@ void AbstractTexture::invalidateSubImageImplementationARB(GLint level, const Vec #ifndef DOXYGEN_GENERATING_OUTPUT #ifndef MAGNUM_TARGET_GLES -template void AbstractTexture::image(GLenum target, GLint level, Image& image) { - const Math::Vector size = DataHelper::imageSize(*this, target, level); +template void AbstractTexture::image(GLint level, Image& image) { + const Math::Vector size = DataHelper::imageSize(*this, level); const std::size_t dataSize = image.dataSize(size); char* data = new char[dataSize]; - (this->*Context::current()->state().texture->getImageImplementation)(target, level, image.format(), image.type(), dataSize, data); + (this->*Context::current()->state().texture->getImageImplementation)(level, image.format(), image.type(), dataSize, data); image.setData(image.format(), image.type(), size, data); } -template void MAGNUM_EXPORT AbstractTexture::image<1>(GLenum, GLint, Image<1>&); -template void MAGNUM_EXPORT AbstractTexture::image<2>(GLenum, GLint, Image<2>&); -template void MAGNUM_EXPORT AbstractTexture::image<3>(GLenum, GLint, Image<3>&); +template void MAGNUM_EXPORT AbstractTexture::image<1>(GLint, Image<1>&); +template void MAGNUM_EXPORT AbstractTexture::image<2>(GLint, Image<2>&); +template void MAGNUM_EXPORT AbstractTexture::image<3>(GLint, Image<3>&); -template void AbstractTexture::image(GLenum target, GLint level, BufferImage& image, BufferUsage usage) { - const Math::Vector size = DataHelper::imageSize(*this, target, level); +template void AbstractTexture::image(GLint level, BufferImage& image, BufferUsage usage) { + const Math::Vector size = DataHelper::imageSize(*this, level); const std::size_t dataSize = image.dataSize(size); if(image.size() != size) image.setData(image.format(), image.type(), size, nullptr, usage); image.buffer().bindInternal(Buffer::TargetHint::PixelPack); - (this->*Context::current()->state().texture->getImageImplementation)(target, level, image.format(), image.type(), dataSize, nullptr); + (this->*Context::current()->state().texture->getImageImplementation)(level, image.format(), image.type(), dataSize, nullptr); } -template void MAGNUM_EXPORT AbstractTexture::image<1>(GLenum, GLint, BufferImage<1>&, BufferUsage); -template void MAGNUM_EXPORT AbstractTexture::image<2>(GLenum, GLint, BufferImage<2>&, BufferUsage); -template void MAGNUM_EXPORT AbstractTexture::image<3>(GLenum, GLint, BufferImage<3>&, BufferUsage); +template void MAGNUM_EXPORT AbstractTexture::image<1>(GLint, BufferImage<1>&, BufferUsage); +template void MAGNUM_EXPORT AbstractTexture::image<2>(GLint, BufferImage<2>&, BufferUsage); +template void MAGNUM_EXPORT AbstractTexture::image<3>(GLint, BufferImage<3>&, BufferUsage); #endif #endif #ifndef DOXYGEN_GENERATING_OUTPUT #ifndef MAGNUM_TARGET_GLES -Math::Vector<1, GLint> AbstractTexture::DataHelper<1>::imageSize(AbstractTexture& texture, const GLenum target, const GLint level) { +Math::Vector<1, GLint> AbstractTexture::DataHelper<1>::imageSize(AbstractTexture& texture, const GLint level) { Math::Vector<1, GLint> value; - (texture.*Context::current()->state().texture->getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]); + (texture.*Context::current()->state().texture->getLevelParameterivImplementation)(level, GL_TEXTURE_WIDTH, &value[0]); return value; } #endif #ifndef MAGNUM_TARGET_GLES2 -Vector2i AbstractTexture::DataHelper<2>::imageSize(AbstractTexture& texture, const GLenum target, const GLint level) { +Vector2i AbstractTexture::DataHelper<2>::imageSize(AbstractTexture& texture, const GLint level) { const Implementation::TextureState& state = *Context::current()->state().texture; Vector2i value; - (texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]); - (texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]); + (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_WIDTH, &value[0]); + (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_HEIGHT, &value[1]); return value; } -Vector3i AbstractTexture::DataHelper<3>::imageSize(AbstractTexture& texture, const GLenum target, const GLint level) { +Vector3i AbstractTexture::DataHelper<3>::imageSize(AbstractTexture& texture, const GLint level) { const Implementation::TextureState& state = *Context::current()->state().texture; Vector3i value; - (texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]); - (texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]); - (texture.*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_DEPTH, &value[2]); + (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_WIDTH, &value[0]); + (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_HEIGHT, &value[1]); + (texture.*state.getLevelParameterivImplementation)(level, GL_TEXTURE_DEPTH, &value[2]); return value; } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::DataHelper<1>::setStorage(AbstractTexture& texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Math::Vector< 1, GLsizei >& size) { - (texture.*Context::current()->state().texture->storage1DImplementation)(target, levels, internalFormat, size); +void AbstractTexture::DataHelper<1>::setStorage(AbstractTexture& texture, const GLsizei levels, const TextureFormat internalFormat, const Math::Vector< 1, GLsizei >& size) { + (texture.*Context::current()->state().texture->storage1DImplementation)(levels, internalFormat, size); } #endif -void AbstractTexture::DataHelper<2>::setStorage(AbstractTexture& texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) { - (texture.*Context::current()->state().texture->storage2DImplementation)(target, levels, internalFormat, size); +void AbstractTexture::DataHelper<2>::setStorage(AbstractTexture& texture, const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) { + (texture.*Context::current()->state().texture->storage2DImplementation)(levels, internalFormat, size); } -void AbstractTexture::DataHelper<3>::setStorage(AbstractTexture& texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Vector3i& size) { - (texture.*Context::current()->state().texture->storage3DImplementation)(target, levels, internalFormat, size); +void AbstractTexture::DataHelper<3>::setStorage(AbstractTexture& texture, const GLsizei levels, const TextureFormat internalFormat, const Vector3i& size) { + (texture.*Context::current()->state().texture->storage3DImplementation)(levels, internalFormat, size); } #ifndef MAGNUM_TARGET_GLES2 -void AbstractTexture::DataHelper<2>::setStorageMultisample(AbstractTexture& texture, const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { - (texture.*Context::current()->state().texture->storage2DMultisampleImplementation)(target, samples, internalFormat, size, fixedSampleLocations); +void AbstractTexture::DataHelper<2>::setStorageMultisample(AbstractTexture& texture, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { + (texture.*Context::current()->state().texture->storage2DMultisampleImplementation)(samples, internalFormat, size, fixedSampleLocations); } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::DataHelper<3>::setStorageMultisample(AbstractTexture& texture, const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { - (texture.*Context::current()->state().texture->storage3DMultisampleImplementation)(target, samples, internalFormat, size, fixedSampleLocations); +void AbstractTexture::DataHelper<3>::setStorageMultisample(AbstractTexture& texture, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { + (texture.*Context::current()->state().texture->storage3DMultisampleImplementation)(samples, internalFormat, size, fixedSampleLocations); } #endif #ifndef MAGNUM_TARGET_GLES -void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference1D& image) { +void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, const ImageReference1D& image) { Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); texture.bindInternal(); - glTexImage1D(target, level, GLint(internalFormat), image.size()[0], 0, GLenum(image.format()), GLenum(image.type()), image.data()); + glTexImage1D(texture._target, level, GLint(internalFormat), image.size()[0], 0, GLenum(image.format()), GLenum(image.type()), image.data()); } -void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage1D& image) { +void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, BufferImage1D& image) { image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); texture.bindInternal(); - glTexImage1D(target, level, GLint(internalFormat), image.size()[0], 0, GLenum(image.format()), GLenum(image.type()), nullptr); + glTexImage1D(texture._target, level, GLint(internalFormat), image.size()[0], 0, GLenum(image.format()), GLenum(image.type()), nullptr); } -void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image) { +void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image) { Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); - (texture.*Context::current()->state().texture->subImage1DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data()); + (texture.*Context::current()->state().texture->subImage1DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data()); } -void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image) { +void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image) { image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); - (texture.*Context::current()->state().texture->subImage1DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr); + (texture.*Context::current()->state().texture->subImage1DImplementation)(level, offset, image.size(), image.format(), image.type(), nullptr); } #endif @@ -1279,31 +1353,30 @@ void AbstractTexture::DataHelper<2>::setImage(AbstractTexture& texture, const GL } #endif -void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector2i& offset, const ImageReference2D& image) { +void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLint level, const Vector2i& offset, const ImageReference2D& image) { #ifndef MAGNUM_TARGET_GLES2 Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); #endif - (texture.*Context::current()->state().texture->subImage2DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data()); + (texture.*Context::current()->state().texture->subImage2DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data()); } #ifndef MAGNUM_TARGET_GLES2 -void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector2i& offset, BufferImage2D& image) { +void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLint level, const Vector2i& offset, BufferImage2D& image) { image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); - (texture.*Context::current()->state().texture->subImage2DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr); + (texture.*Context::current()->state().texture->subImage2DImplementation)(level, offset, image.size(), image.format(), image.type(), nullptr); } #endif -void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference3D& image) { +void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, const ImageReference3D& image) { #ifndef MAGNUM_TARGET_GLES2 Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); #endif texture.bindInternal(); #ifndef MAGNUM_TARGET_GLES2 - glTexImage3D(target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), image.data()); + glTexImage3D(texture._target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), image.data()); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) - glTexImage3DOES(target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), image.data()); + glTexImage3DOES(texture._target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), image.data()); #else - static_cast(target); static_cast(level); static_cast(internalFormat); static_cast(image); @@ -1312,24 +1385,24 @@ void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GL } #ifndef MAGNUM_TARGET_GLES2 -void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage3D& image) { +void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, BufferImage3D& image) { image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); texture.bindInternal(); - glTexImage3D(target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), nullptr); + glTexImage3D(texture._target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), nullptr); } #endif -void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector3i& offset, const ImageReference3D& image) { +void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLint level, const Vector3i& offset, const ImageReference3D& image) { #ifndef MAGNUM_TARGET_GLES2 Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); #endif - (texture.*Context::current()->state().texture->subImage3DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data()); + (texture.*Context::current()->state().texture->subImage3DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data()); } #ifndef MAGNUM_TARGET_GLES2 -void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector3i& offset, BufferImage3D& image) { +void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLint level, const Vector3i& offset, BufferImage3D& image) { image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); - (texture.*Context::current()->state().texture->subImage3DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr); + (texture.*Context::current()->state().texture->subImage3DImplementation)(level, offset, image.size(), image.format(), image.type(), nullptr); } #endif diff --git a/src/Magnum/AbstractTexture.h b/src/Magnum/AbstractTexture.h index 99f55eeb3..e40536423 100644 --- a/src/Magnum/AbstractTexture.h +++ b/src/Magnum/AbstractTexture.h @@ -74,22 +74,31 @@ to not affect active bindings in user units. Texture limits and implementation-defined values (such as @ref maxColorSamples()) are cached, so repeated queries don't result in repeated @fn_gl{Get} calls. -If extension @extension{ARB,multi_bind} is available, @ref bind() uses -@fn_gl{BindTextures} to avoid unnecessary calls to @fn_gl{ActiveTexture}. -Otherwise, if extension @extension{EXT,direct_state_access} is available, -@ref bind() uses @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} -function. - -In addition, if extension @extension{EXT,direct_state_access} is available, -also all texture configuration and data updating functions use DSA functions -to avoid unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. -See respective function documentation for more information. - -If extension @extension{ARB,robustness} is available, image reading operations -(such as @ref Texture::image()) are protected from buffer overflow. However, if -both @extension{EXT,direct_state_access} and @extension{ARB,robustness} are -available, the DSA version is used, because it is better for performance and -there isn't any function combining both features. +If on desktop GL and @extension{ARB,direct_state_access} (part of OpenGL 4.5) +is available, @ref bind(Int) and @ref unbind(Int) use @fn_gl{BindTextureUnit}. +Otherwise, if @extension{ARB,multi_bind} (part of OpenGL 4.4) is available, +@ref bind(Int) and @ref unbind() uses @fn_gl{BindTextures}. Lastly, if +@extension{EXT,direct_state_access} is available, @fn_gl_extension{BindNamedTexture,EXT,direct_state_access} +function is used to avoid unnecessary calls to @fn_gl{ActiveTexture}. + +In addition, if either @extension{ARB,direct_state_access} (part of OpenGL 4.5) +or @extension{EXT,direct_state_access} is available, also all texture +configuration and data updating functions use DSA functions to avoid +unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. See +respective function documentation for more information. + +If @extension{ARB,multi_bind} (part of OpenGL 4.5) is available, +@ref bind(Int, std::initializer_list) and @ref unbind(Int, std::size_t) +use @fn_gl{BindTextures} to avoid unnecessary calls to @fn_gl{ActiveTexture}. +Otherwise the feature is emulated with sequence of @ref bind(Int)/@ref unbind(Int) +calls. + +If either @extension{ARB,direct_state_access} or @extension{ARB,robustness} is +available, image reading operations (such as @ref Texture::image()) are +protected from buffer overflow. However, if @extension{ARB,direct_state_access} +is not available and both @extension{EXT,direct_state_access} and +@extension{ARB,robustness} are available, the robust version is preferred over +DSA. To achieve least state changes, fully configure each texture in one run -- method chaining comes in handy -- and try to have often used textures in @@ -125,6 +134,7 @@ functions do nothing. */ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { friend struct Implementation::TextureState; + friend class CubeMapTexture; public: #ifdef MAGNUM_BUILD_DEPRECATED @@ -187,15 +197,17 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { /** * @brief Unbind any texture from given texture unit * - * If @extension{ARB,multi_bind} (part of OpenGL 4.4) or - * @extension{EXT,direct_state_access} is not available, the texture - * unit is made active before binding the texture. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5), @extension{ARB,multi_bind} (part of OpenGL 4.4) nor + * @extension{EXT,direct_state_access} is available, the texture unit + * is made active before unbinding the texture. * @note This function is meant to be used only internally from * @ref AbstractShaderProgram subclasses. See its documentation * for more information. * @see @ref bind(), @ref Shader::maxCombinedTextureImageUnits(), - * @fn_gl{ActiveTexture}, @fn_gl{BindTexture}, @fn_gl{BindTextures} - * or @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} + * @fn_gl{BindTextureUnit}, @fn_gl{BindTextures}, + * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture} and @fn_gl{BindTexture} */ static void unbind(Int textureUnit); @@ -208,9 +220,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { * @note This function is meant to be used only internally from * @ref AbstractShaderProgram subclasses. See its documentation * for more information. - * @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures}, - * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or - * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} + * @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures} */ static void unbind(Int firstTextureUnit, std::size_t count); @@ -225,9 +235,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { * @note This function is meant to be used only internally from * @ref AbstractShaderProgram subclasses. See its documentation * for more information. - * @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures}, - * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or - * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} + * @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures} */ static void bind(Int firstTextureUnit, std::initializer_list textures); @@ -290,16 +298,18 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { /** * @brief Bind texture to given texture unit * - * If @extension{ARB,multi_bind} (part of OpenGL 4.4) or - * @extension{EXT,direct_state_access} is not available, the texture - * unit is made active before binding the texture. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5), @extension{ARB,multi_bind} (part of OpenGL 4.4) nor + * @extension{EXT,direct_state_access} is available, the texture unit + * is made active before binding the texture. * @note This function is meant to be used only internally from * @ref AbstractShaderProgram subclasses. See its documentation * for more information. * @see @ref bind(Int, std::initializer_list), * @ref unbind(), @ref Shader::maxCombinedTextureImageUnits(), - * @fn_gl{ActiveTexture}, @fn_gl{BindTexture}, @fn_gl{BindTextures} - * or @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} + * @fn_gl{BindTextureUnit}, @fn_gl{BindTextures}, + * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture} and @fn_gl{BindTexture} */ void bind(Int textureUnit); @@ -357,8 +367,8 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { void generateMipmap(); #ifndef MAGNUM_TARGET_GLES - template void image(GLenum target, GLint level, Image& image); - template void image(GLenum target, GLint level, BufferImage& image, BufferUsage usage); + template void image(GLint level, Image& image); + template void image(GLint level, BufferImage& image, BufferUsage usage); #endif GLenum _target; @@ -367,6 +377,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { static void MAGNUM_LOCAL unbindImplementationDefault(GLint textureUnit); #ifndef MAGNUM_TARGET_GLES static void MAGNUM_LOCAL unbindImplementationMulti(GLint textureUnit); + static void MAGNUM_LOCAL unbindImplementationDSA(GLint textureUnit); static void MAGNUM_LOCAL unbindImplementationDSAEXT(GLint textureUnit); #endif @@ -385,6 +396,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { void MAGNUM_LOCAL bindImplementationDefault(GLint textureUnit); #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL bindImplementationMulti(GLint textureUnit); + void MAGNUM_LOCAL bindImplementationDSA(GLint textureUnit); void MAGNUM_LOCAL bindImplementationDSAEXT(GLint textureUnit); #endif @@ -399,11 +411,17 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { void MAGNUM_LOCAL parameterIImplementationDefault(GLenum parameter, const GLint* values); #endif #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLint value); void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, GLint value); + void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLfloat value); void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, GLfloat value); + void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, const GLint* values); void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, const GLint* values); + void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, const GLfloat* values); void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, const GLfloat* values); + void MAGNUM_LOCAL parameterIImplementationDSA(GLenum parameter, const GLuint* values); void MAGNUM_LOCAL parameterIImplementationDSAEXT(GLenum parameter, const GLuint* values); + void MAGNUM_LOCAL parameterIImplementationDSA(GLenum parameter, const GLint* values); void MAGNUM_LOCAL parameterIImplementationDSAEXT(GLenum parameter, const GLint* values); #endif @@ -411,70 +429,81 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { void MAGNUM_LOCAL setMaxAnisotropyImplementationExt(GLfloat anisotropy); #ifndef MAGNUM_TARGET_GLES2 - void MAGNUM_LOCAL getLevelParameterImplementationDefault(GLenum target, GLint level, GLenum parameter, GLint* values); + void MAGNUM_LOCAL getLevelParameterImplementationDefault(GLint level, GLenum parameter, GLint* values); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL getLevelParameterImplementationDSAEXT(GLenum target, GLint level, GLenum parameter, GLint* values); + void MAGNUM_LOCAL getLevelParameterImplementationDSA(GLint level, GLenum parameter, GLint* values); + void MAGNUM_LOCAL getLevelParameterImplementationDSAEXT(GLint level, GLenum parameter, GLint* values); #endif #endif void MAGNUM_LOCAL mipmapImplementationDefault(); #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL mipmapImplementationDSA(); void MAGNUM_LOCAL mipmapImplementationDSAEXT(); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); - void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); - void MAGNUM_LOCAL storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); + void MAGNUM_LOCAL storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); + void MAGNUM_LOCAL storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); + void MAGNUM_LOCAL storageImplementationDSA(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); + void MAGNUM_LOCAL storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); #endif - void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size); - void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size); + void MAGNUM_LOCAL storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Vector2i& size); + void MAGNUM_LOCAL storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector2i& size); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size); + void MAGNUM_LOCAL storageImplementationDSA(GLsizei levels, TextureFormat internalFormat, const Vector2i& size); + void MAGNUM_LOCAL storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Vector2i& size); #endif - void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size); - void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size); + void MAGNUM_LOCAL storageImplementationFallback(GLsizei levels, TextureFormat internalFormat, const Vector3i& size); + void MAGNUM_LOCAL storageImplementationDefault(GLsizei levels, TextureFormat internalFormat, const Vector3i& size); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size); + void MAGNUM_LOCAL storageImplementationDSA(GLsizei levels, TextureFormat internalFormat, const Vector3i& size); + void MAGNUM_LOCAL storageImplementationDSAEXT(GLsizei levels, TextureFormat internalFormat, const Vector3i& size); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); #endif #ifndef MAGNUM_TARGET_GLES2 - void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); - void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); - void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); + void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL getImageImplementationDefault(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); - void MAGNUM_LOCAL getImageImplementationDSAEXT(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); - void MAGNUM_LOCAL getImageImplementationRobustness(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationDefault(GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationDSA(GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationDSAEXT(GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationRobustness(GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); #endif #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data); - void MAGNUM_LOCAL subImageImplementationDSAEXT(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDefault(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSA(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSAEXT(GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data); #endif - void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDefault(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL subImageImplementationDSAEXT(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSA(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSAEXT(GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); #endif - void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDefault(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL subImageImplementationDSAEXT(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSA(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSAEXT(GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data); #endif void MAGNUM_LOCAL invalidateImageImplementationNoOp(GLint level); @@ -503,17 +532,17 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<1> { }; #endif - static Math::Vector<1, GLint> imageSize(AbstractTexture& texture, GLenum target, GLint level); + static Math::Vector<1, GLint> imageSize(AbstractTexture& texture, GLint level); static void setWrapping(AbstractTexture& texture, const Array1D& wrapping); - static void setStorage(AbstractTexture& texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); + static void setStorage(AbstractTexture& texture, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size); - static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference1D& image); - static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage1D& image); + static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, const ImageReference1D& image); + static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, BufferImage1D& image); - static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image); - static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image); + static void setSubImage(AbstractTexture& texture, GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image); + static void setSubImage(AbstractTexture& texture, GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image); static void invalidateSubImage(AbstractTexture& texture, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLint>& size); }; @@ -531,25 +560,31 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> { #endif #ifndef MAGNUM_TARGET_GLES2 - static Vector2i imageSize(AbstractTexture& texture, GLenum target, GLint level); + static Vector2i imageSize(AbstractTexture& texture, GLint level); #endif static void setWrapping(AbstractTexture& texture, const Array2D& wrapping); - static void setStorage(AbstractTexture& texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size); + static void setStorage(AbstractTexture& texture, GLsizei levels, TextureFormat internalFormat, const Vector2i& size); #ifndef MAGNUM_TARGET_GLES2 - static void setStorageMultisample(AbstractTexture& texture, GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedSampleLocations); + static void setStorageMultisample(AbstractTexture& texture, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedSampleLocations); #endif + static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, const ImageReference2D& image) { + setImage(texture, texture._target, level, internalFormat, image); + } static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference2D& image); #ifndef MAGNUM_TARGET_GLES2 + static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, BufferImage2D& image) { + setImage(texture, texture._target, level, internalFormat, image); + } static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage2D& image); #endif - static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Vector2i& offset, const ImageReference2D& image); + static void setSubImage(AbstractTexture& texture, GLint level, const Vector2i& offset, const ImageReference2D& image); #ifndef MAGNUM_TARGET_GLES2 - static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Vector2i& offset, BufferImage2D& image); + static void setSubImage(AbstractTexture& texture, GLint level, const Vector2i& offset, BufferImage2D& image); #endif static void invalidateSubImage(AbstractTexture& texture, GLint level, const Vector2i& offset, const Vector2i& size); @@ -570,25 +605,25 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> { #endif #ifndef MAGNUM_TARGET_GLES2 - static Vector3i imageSize(AbstractTexture& texture, GLenum target, GLint level); + static Vector3i imageSize(AbstractTexture& texture, GLint level); #endif static void setWrapping(AbstractTexture& texture, const Array3D& wrapping); - static void setStorage(AbstractTexture& texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size); + static void setStorage(AbstractTexture& texture, GLsizei levels, TextureFormat internalFormat, const Vector3i& size); #ifndef MAGNUM_TARGET_GLES - static void setStorageMultisample(AbstractTexture& texture, GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedSampleLocations); + static void setStorageMultisample(AbstractTexture& texture, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedSampleLocations); #endif - static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference3D& image); + static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, const ImageReference3D& image); #ifndef MAGNUM_TARGET_GLES2 - static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage3D& image); + static void setImage(AbstractTexture& texture, GLint level, TextureFormat internalFormat, BufferImage3D& image); #endif - static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Vector3i& offset, const ImageReference3D& image); + static void setSubImage(AbstractTexture& texture, GLint level, const Vector3i& offset, const ImageReference3D& image); #ifndef MAGNUM_TARGET_GLES2 - static void setSubImage(AbstractTexture& texture, GLenum target, GLint level, const Vector3i& offset, BufferImage3D& image); + static void setSubImage(AbstractTexture& texture, GLint level, const Vector3i& offset, BufferImage3D& image); #endif static void invalidateSubImage(AbstractTexture& texture, GLint level, const Vector3i& offset, const Vector3i& size); diff --git a/src/Magnum/BufferTexture.cpp b/src/Magnum/BufferTexture.cpp index 0c45eb264..369190bbe 100644 --- a/src/Magnum/BufferTexture.cpp +++ b/src/Magnum/BufferTexture.cpp @@ -75,6 +75,10 @@ void BufferTexture::setBufferImplementationDefault(BufferTextureFormat internalF glTexBuffer(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id()); } +void BufferTexture::setBufferImplementationDSA(const BufferTextureFormat internalFormat, Buffer& buffer) { + glTextureBuffer(id(), GLenum(internalFormat), buffer.id()); +} + void BufferTexture::setBufferImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer) { glTextureBufferEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id()); } @@ -84,6 +88,10 @@ void BufferTexture::setBufferRangeImplementationDefault(BufferTextureFormat inte glTexBufferRange(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id(), offset, size); } +void BufferTexture::setBufferRangeImplementationDSA(const BufferTextureFormat internalFormat, Buffer& buffer, const GLintptr offset, const GLsizeiptr size) { + glTextureBufferRange(id(), GLenum(internalFormat), buffer.id(), offset, size); +} + void BufferTexture::setBufferRangeImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size) { glTextureBufferRangeEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id(), offset, size); } diff --git a/src/Magnum/BufferTexture.h b/src/Magnum/BufferTexture.h index 50fc4eee8..152a0bb59 100644 --- a/src/Magnum/BufferTexture.h +++ b/src/Magnum/BufferTexture.h @@ -154,7 +154,7 @@ enum class BufferTextureFormat: GLenum { /** @brief Buffer texture -This texture is, unlike classic textures such as @ref Texture used as simple +This texture is, unlike classic textures such as @ref Texture, used as simple data source, without any unnecessary interpolation and wrapping methods. ## Usage @@ -187,7 +187,8 @@ documentation for more information about usage in shaders. ## Performance optimizations -If extension @extension{EXT,direct_state_access} is available, @ref setBuffer() +If on desktop GL and either @extension{ARB,direct_state_access} (part of OpenGL +4.5) or @extension{EXT,direct_state_access} is available, @ref setBuffer() functions use DSA to avoid unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. See @ref AbstractTexture-performance-optimization "relevant section in AbstractTexture documentation" @@ -241,10 +242,14 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture { * * Binds given buffer to this texture. The buffer itself can be then * filled with data of proper format at any time using @ref Buffer "Buffer"'s - * own data setting functions. - * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexBuffer} or - * @fn_gl_extension{TextureBuffer,EXT,direct_state_access} + * own data setting functions. If neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). + * @see @ref maxSize(), @fn_gl2{TextureBuffer,TexBuffer}, + * @fn_gl_extension{TextureBuffer,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexBuffer} */ BufferTexture& setBuffer(BufferTextureFormat internalFormat, Buffer& buffer); @@ -258,10 +263,14 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture { * * Binds range of given buffer to this texture. The buffer itself can * be then filled with data of proper format at any time using @ref Buffer "Buffer"'s - * own data setting functions. - * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexBufferRange} or - * @fn_gl_extension{TextureBufferRange,EXT,direct_state_access} + * own data setting functions. If neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). + * @see @ref maxSize(), @fn_gl2{TextureBufferRange,TexBufferRange}, + * @fn_gl_extension{TextureBufferRange,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexBufferRange} * @requires_gl43 Extension @extension{ARB,texture_buffer_range} */ BufferTexture& setBuffer(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); @@ -280,9 +289,11 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture { private: void MAGNUM_LOCAL setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer); + void MAGNUM_LOCAL setBufferImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer); void MAGNUM_LOCAL setBufferImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer); void MAGNUM_LOCAL setBufferRangeImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); + void MAGNUM_LOCAL setBufferRangeImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); void MAGNUM_LOCAL setBufferRangeImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size); }; diff --git a/src/Magnum/CubeMapTexture.cpp b/src/Magnum/CubeMapTexture.cpp index f53d297d4..cdd139767 100644 --- a/src/Magnum/CubeMapTexture.cpp +++ b/src/Magnum/CubeMapTexture.cpp @@ -25,12 +25,134 @@ #include "CubeMapTexture.h" +#ifndef MAGNUM_TARGET_GLES2 +#include "Magnum/BufferImage.h" +#endif +#include "Magnum/Context.h" +#include "Magnum/Image.h" + #include "Implementation/maxTextureSize.h" +#include "Implementation/State.h" +#include "Implementation/TextureState.h" namespace Magnum { +static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 0 && + GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1 && + GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2 && + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3 && + GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4 && + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5, + "Unexpected GL enum values for cube faces"); + Vector2i CubeMapTexture::maxSize() { return Vector2i{Implementation::maxCubeMapTextureSideSize()}; } +#ifndef MAGNUM_TARGET_GLES2 +Vector2i CubeMapTexture::imageSize(const Int level) { + return (this->*Context::current()->state().texture->getCubeImageSizeImplementation)(level); +} +#endif + +#ifndef MAGNUM_TARGET_GLES +void CubeMapTexture::image(const Coordinate coordinate, const Int level, Image2D& image) { + const Vector2i size = imageSize(level); + const std::size_t dataSize = image.dataSize(size); + char* data = new char[dataSize]; + (this->*Context::current()->state().texture->getCubeImageImplementation)(coordinate, level, size, image.format(), image.type(), dataSize, data); + image.setData(image.format(), image.type(), size, data); +} + +void CubeMapTexture::image(const Coordinate coordinate, const Int level, BufferImage2D& image, const BufferUsage usage) { + const Vector2i size = imageSize(level); + const std::size_t dataSize = image.dataSize(size); + if(image.size() != size) + image.setData(image.format(), image.type(), size, nullptr, usage); + + image.buffer().bindInternal(Buffer::TargetHint::PixelPack); + (this->*Context::current()->state().texture->getCubeImageImplementation)(coordinate, level, size, image.format(), image.type(), dataSize, nullptr); +} +#endif + +CubeMapTexture& CubeMapTexture::setSubImage(const Coordinate coordinate, const Int level, const Vector2i& offset, const ImageReference2D& image) { + #ifndef MAGNUM_TARGET_GLES2 + Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); + #endif + (this->*Context::current()->state().texture->cubeSubImageImplementation)(coordinate, level, offset, image.size(), image.format(), image.type(), image.data()); + return *this; +} + +#ifndef MAGNUM_TARGET_GLES2 +CubeMapTexture& CubeMapTexture::setSubImage(const Coordinate coordinate, const Int level, const Vector2i& offset, BufferImage2D& image) { + image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack); + (this->*Context::current()->state().texture->cubeSubImageImplementation)(coordinate, level, offset, image.size(), image.format(), image.type(), nullptr); + return *this; +} +#endif + +#ifndef MAGNUM_TARGET_GLES2 +Vector2i CubeMapTexture::getImageSizeImplementationDefault(const Int level) { + Vector2i size; + bindInternal(); + glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_WIDTH, &size.x()); + glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_HEIGHT, &size.y()); + return size; +} + +#ifndef MAGNUM_TARGET_GLES +Vector2i CubeMapTexture::getImageSizeImplementationDSA(const Int level) { + Vector2i size; + glGetTextureLevelParameteriv(_id, level, GL_TEXTURE_WIDTH, &size.x()); + glGetTextureLevelParameteriv(_id, level, GL_TEXTURE_HEIGHT, &size.y()); + return size; +} + +Vector2i CubeMapTexture::getImageSizeImplementationDSAEXT(const Int level) { + _created = true; + Vector2i size; + glGetTextureLevelParameterivEXT(_id, GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_WIDTH, &size.x()); + glGetTextureLevelParameterivEXT(_id, GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_HEIGHT, &size.y()); + return size; +} +#endif +#endif + +#ifndef MAGNUM_TARGET_GLES +void CubeMapTexture::getImageImplementationDefault(const Coordinate coordinate, const GLint level, const Vector2i&, const ColorFormat format, const ColorType type, std::size_t, GLvoid* const data) { + bindInternal(); + glGetTexImage(GLenum(coordinate), level, GLenum(format), GLenum(type), data); +} + +void CubeMapTexture::getImageImplementationDSA(const Coordinate coordinate, const GLint level, const Vector2i& size, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { + glGetTextureSubImage(_id, level, 0, 0, GLenum(coordinate) - GL_TEXTURE_CUBE_MAP_POSITIVE_X, size.x(), size.y(), 1, GLenum(format), GLenum(type), dataSize, data); +} + +void CubeMapTexture::getImageImplementationDSAEXT(const Coordinate coordinate, const GLint level, const Vector2i&, const ColorFormat format, const ColorType type, std::size_t, GLvoid* const data) { + _created = true; + glGetTextureImageEXT(_id, GLenum(coordinate), level, GLenum(format), GLenum(type), data); +} + +void CubeMapTexture::getImageImplementationRobustness(const Coordinate coordinate, const GLint level, const Vector2i&, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { + bindInternal(); + glGetnTexImageARB(GLenum(coordinate), level, GLenum(format), GLenum(type), dataSize, data); +} +#endif + +void CubeMapTexture::subImageImplementationDefault(const Coordinate coordinate, const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { + bindInternal(); + glTexSubImage2D(GLenum(coordinate), level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); +} + +#ifndef MAGNUM_TARGET_GLES +void CubeMapTexture::subImageImplementationDSA(const Coordinate coordinate, const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { + glTextureSubImage3D(_id, level, offset.x(), offset.y(), GLenum(coordinate) - GL_TEXTURE_CUBE_MAP_POSITIVE_X, size.x(), size.y(), 1, GLenum(format), GLenum(type), data); +} + +void CubeMapTexture::subImageImplementationDSAEXT(const Coordinate coordinate, const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { + _created = true; + glTextureSubImage2DEXT(_id, GLenum(coordinate), level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); +} +#endif + } diff --git a/src/Magnum/CubeMapTexture.h b/src/Magnum/CubeMapTexture.h index 3a88c01fd..8ee20bf94 100644 --- a/src/Magnum/CubeMapTexture.h +++ b/src/Magnum/CubeMapTexture.h @@ -80,6 +80,8 @@ which intersects one of the six sides of the cube map. See @ref MultisampleTexture */ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { + friend struct Implementation::TextureState; + public: /** @brief Cube map coordinate */ enum class Coordinate: GLenum { @@ -112,39 +114,77 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {} #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setBaseLevel() */ + /** + * @copybrief Texture::setBaseLevel() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setBaseLevel() for more information. + * @requires_gles30 Base level is always `0` in OpenGL ES 2.0. + */ CubeMapTexture& setBaseLevel(Int level) { AbstractTexture::setBaseLevel(level); return *this; } #endif - /** @copydoc Texture::setMaxLevel() */ + /** + * @copybrief Texture::setMaxLevel() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxLevel() for more information. + * @requires_gles30 Extension @es_extension{APPLE,texture_max_level}, + * otherwise the max level is always set to largest possible value + * in OpenGL ES 2.0. + */ CubeMapTexture& setMaxLevel(Int level) { AbstractTexture::setMaxLevel(level); return *this; } - /** @copydoc Texture::setMinificationFilter() */ + /** + * @copybrief Texture::setMinificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMinificationFilter() for more information. + */ CubeMapTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { AbstractTexture::setMinificationFilter(filter, mipmap); return *this; } - /** @copydoc Texture::setMagnificationFilter() */ + /** + * @copybrief Texture::setMagnificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMagnificationFilter() for more information. + */ CubeMapTexture& setMagnificationFilter(Sampler::Filter filter) { AbstractTexture::setMagnificationFilter(filter); return *this; } #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setMinLod() */ + /** + * @copybrief Texture::setMinLod() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMinLod() for more information. + * @requires_gles30 Texture LOD parameters are not available in OpenGL + * ES 2.0. + */ CubeMapTexture& setMinLod(Float lod) { AbstractTexture::setMinLod(lod); return *this; } - /** @copydoc Texture::setMaxLod() */ + /** + * @copybrief Texture::setMaxLod() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxLod() for more information. + * @requires_gles30 Texture LOD parameters are not available in OpenGL + * ES 2.0. + */ CubeMapTexture& setMaxLod(Float lod) { AbstractTexture::setMaxLod(lod); return *this; @@ -152,53 +192,106 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { #endif #ifndef MAGNUM_TARGET_GLES - /** @copydoc Texture::setLodBias() */ + /** + * @copybrief Texture::setLodBias() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setLodBias() for more information. + * @requires_gl Texture LOD bias can be specified only directly in + * fragment shader in OpenGL ES. + */ CubeMapTexture& setLodBias(Float bias) { AbstractTexture::setLodBias(bias); return *this; } #endif - /** @copydoc Texture::setWrapping() */ + /** + * @copybrief Texture::setWrapping() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setWrapping() for more information. + */ CubeMapTexture& setWrapping(const Array3D& wrapping) { DataHelper<3>::setWrapping(*this, wrapping); return *this; } - /** @copydoc Texture::setBorderColor(const Color4&) */ + /** + * @copybrief Texture::setBorderColor(const Color4&) + * @return Reference to self (for method chaining) + * + * See @ref Texture::setBorderColor(const Color4&) for more + * information. + * @requires_es_extension Extension @es_extension{NV,texture_border_clamp} + */ CubeMapTexture& setBorderColor(const Color4& color) { AbstractTexture::setBorderColor(color); return *this; } #ifndef MAGNUM_TARGET_GLES - /** @copydoc Texture::setBorderColor(const Vector4ui&) */ + /** + * @copybrief Texture::setBorderColor(const Vector4ui&) + * @return Reference to self (for method chaining) + * + * See @ref Texture::setBorderColor(const Vector4ui&) for more + * information. + * @requires_gl30 Extension @extension{EXT,texture_integer} + * @requires_gl Border is available only for float textures in OpenGL + * ES. + */ CubeMapTexture& setBorderColor(const Vector4ui& color) { AbstractTexture::setBorderColor(color); return *this; } - /** @copydoc Texture::setBorderColor(const Vector4i&) */ + /** @overload + * @requires_gl30 Extension @extension{EXT,texture_integer} + * @requires_gl Border is available only for float textures in OpenGL + * ES. + */ CubeMapTexture& setBorderColor(const Vector4i& color) { AbstractTexture::setBorderColor(color); return *this; } #endif - /** @copydoc Texture::setMaxAnisotropy() */ + /** + * @copybrief Texture::setMaxAnisotropy() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxAnisotropy() for more information. + */ CubeMapTexture& setMaxAnisotropy(Float anisotropy) { AbstractTexture::setMaxAnisotropy(anisotropy); return *this; } - /** @copydoc Texture::setSRGBDecode() */ + /** + * @copybrief Texture::setSRGBDecode() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSRGBDecode() for more information. + * @requires_extension Extension @extension{EXT,texture_sRGB_decode} + * @requires_es_extension OpenGL ES 3.0 or extension + * @es_extension{EXT,sRGB} and + * @es_extension2{EXT,texture_sRGB_decode,texture_sRGB_decode} + */ CubeMapTexture& setSRGBDecode(bool decode) { AbstractTexture::setSRGBDecode(decode); return *this; } #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setSwizzle() */ + /** + * @copybrief Texture::setSwizzle() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSwizzle() for more information. + * @requires_gl33 Extension @extension{ARB,texture_swizzle} + * @requires_gles30 Texture swizzle is not available in OpenGL ES 2.0. + */ template CubeMapTexture& setSwizzle() { AbstractTexture::setSwizzle(); return *this; @@ -232,76 +325,79 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { } #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setDepthStencilMode() */ + /** + * @copybrief Texture::setDepthStencilMode() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setDepthStencilMode() for more information. + * @requires_gl43 Extension @extension{ARB,stencil_texturing} + * @requires_gles31 Stencil texturing is not available in OpenGL ES 3.0 + * and older. + */ CubeMapTexture& setDepthStencilMode(Sampler::DepthStencilMode mode) { AbstractTexture::setDepthStencilMode(mode); return *this; } #endif + /** + * @copybrief Texture::setStorage() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setStorage() for more information. + * @see @ref maxSize() + */ + CubeMapTexture& setStorage(Int levels, TextureFormat internalFormat, const Vector2i& size) { + DataHelper<2>::setStorage(*this, levels, internalFormat, size); + return *this; + } + #ifndef MAGNUM_TARGET_GLES2 /** - * @brief Image size in given mip level - * @param coordinate Coordinate - * @param level Mip level + * @copybrief Texture::imageSize() * - * See @ref Texture::imageSize() for more information. + * If on OpenGL ES or @extension{ARB,direct_state_access} (part of + * OpenGL 4.5) is not available, it is assumed that faces have the same + * size and just the size of @ref Coordinate::PositiveX face is + * queried. See @ref Texture::imageSize() for more information. * @requires_gles31 Texture image size queries are not available in * OpenGL ES 3.0 and older. */ - Vector2i imageSize(Coordinate coordinate, Int level) { - return DataHelper<2>::imageSize(*this, GLenum(coordinate), level); - } - #endif + Vector2i imageSize(Int level); + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @brief Set storage - * - * See @ref Texture::setStorage() for more information. - * @see @ref maxSize() + * @copybrief imageSize() + * @deprecated Use @ref Magnum::CubeMapTexture::imageSize(Int) "imageSize(Int)" + * instead. */ - CubeMapTexture& setStorage(Int levels, TextureFormat internalFormat, const Vector2i& size) { - DataHelper<2>::setStorage(*this, _target, levels, internalFormat, size); - return *this; + CORRADE_DEPRECATED("use imageSize(Int) instead") Vector2i imageSize(Coordinate, Int level) { + return imageSize(level); } + #endif + #endif #ifndef MAGNUM_TARGET_GLES /** - * @brief Read given mip level of texture to image - * @param coordinate Coordinate - * @param level Mip level - * @param image Image where to put the data + * @copybrief Texture::image(Int, Image&) * * See @ref Texture::image(Int, Image&) for more information. * @requires_gl Texture image queries are not available in OpenGL ES. */ - void image(Coordinate coordinate, Int level, Image2D& image) { - AbstractTexture::image<2>(GLenum(coordinate), level, image); - } + void image(Coordinate coordinate, Int level, Image2D& image); /** - * @brief Read given mip level of texture to buffer image - * @param coordinate Coordinate - * @param level Mip level - * @param image Buffer image where to put the data - * @param usage Buffer usage + * @copybrief Texture::image(Int, BufferImage&, BufferUsage) * * See @ref Texture::image(Int, BufferImage&, BufferUsage) for more * information. * @requires_gl Texture image queries are not available in OpenGL ES. */ - void image(Coordinate coordinate, Int level, BufferImage2D& image, BufferUsage usage) { - AbstractTexture::image<2>(GLenum(coordinate), level, image, usage); - } + void image(Coordinate coordinate, Int level, BufferImage2D& image, BufferUsage usage); #endif /** - * @brief Set image data - * @param coordinate Coordinate - * @param level Mip level - * @param internalFormat Internal format - * @param image @ref Image2D, @ref ImageReference2D or - * @ref Trade::ImageData2D + * @copybrief Texture::setImage() * @return Reference to self (for method chaining) * * See @ref Texture::setImage() for more information. @@ -316,62 +412,75 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { } #ifndef MAGNUM_TARGET_GLES2 - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + * @deprecated_gl Prefer to use @ref Magnum::CubeMapTexture::setStorage() "setStorage()" + * and @ref Magnum::CubeMapTexture::setSubImage() "setSubImage()" + * instead. + */ CubeMapTexture& setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, BufferImage2D& image) { DataHelper<2>::setImage(*this, GLenum(coordinate), level, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + * @deprecated_gl Prefer to use @ref Magnum::CubeMapTexture::setStorage() "setStorage()" + * and @ref Magnum::CubeMapTexture::setSubImage() "setSubImage()" + * instead. + */ CubeMapTexture& setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, BufferImage2D&& image) { return setImage(coordinate, level, internalFormat, image); } #endif /** - * @brief Set image subdata - * @param coordinate Coordinate - * @param level Mip level - * @param offset Offset where to put data in the texture - * @param image @ref Image2D, @ref ImageReference2D or - * @ref Trade::ImageData2D + * @copybrief Texture::setSubImage() * @return Reference to self (for method chaining) * * See @ref Texture::setSubImage() for more information. */ - CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const ImageReference2D& image) { - DataHelper<2>::setSubImage(*this, GLenum(coordinate), level, offset, image); - return *this; - } + CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const ImageReference2D& image); #ifndef MAGNUM_TARGET_GLES2 - /** @overload */ - CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D& image) { - DataHelper<2>::setSubImage(*this, GLenum(coordinate), level, offset, image); - return *this; - } + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + */ + CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D& image); - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + */ CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D&& image) { - DataHelper<2>::setSubImage(*this, GLenum(coordinate), level, offset, image); - return *this; + return setSubImage(coordinate, level, offset, image); } #endif - /** @copydoc Texture::generateMipmap() */ + /** + * @copybrief Texture::generateMipmap() + * @return Reference to self (for method chaining) + * + * See @ref Texture::generateMipmap() for more information. + * @requires_gl30 Extension @extension{ARB,framebuffer_object} + */ CubeMapTexture& generateMipmap() { AbstractTexture::generateMipmap(); return *this; } - /** @copydoc Texture::invalidateImage() */ + /** + * @copybrief Texture::invalidateImage() + * + * See @ref Texture::invalidateImage() for more information. + */ void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } /** - * @brief Invalidate texture subimage - * @param level Mip level - * @param offset Offset into the texture - * @param size Size of invalidated data + * @copybrief Texture::invalidateSubImage() * * Z coordinate is equivalent to number of texture face, i.e. * @ref Coordinate::PositiveX is `0` and so on, in the same order as in @@ -394,6 +503,26 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { return *this; } #endif + + private: + Vector2i MAGNUM_LOCAL getImageSizeImplementationDefault(Int level); + #ifndef MAGNUM_TARGET_GLES + Vector2i MAGNUM_LOCAL getImageSizeImplementationDSA(Int level); + Vector2i MAGNUM_LOCAL getImageSizeImplementationDSAEXT(Int level); + #endif + + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL getImageImplementationDefault(Coordinate coordinate, GLint level, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationDSA(Coordinate coordinate, GLint level, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationDSAEXT(Coordinate coordinate, GLint level, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + void MAGNUM_LOCAL getImageImplementationRobustness(Coordinate coordinate, GLint level, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data); + #endif + + void MAGNUM_LOCAL subImageImplementationDefault(Coordinate coordinate, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL subImageImplementationDSA(Coordinate coordinate, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSAEXT(Coordinate coordinate, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data); + #endif }; } diff --git a/src/Magnum/CubeMapTextureArray.h b/src/Magnum/CubeMapTextureArray.h index 8868b4105..b8dbc9178 100644 --- a/src/Magnum/CubeMapTextureArray.h +++ b/src/Magnum/CubeMapTextureArray.h @@ -128,13 +128,23 @@ class CubeMapTextureArray: public AbstractTexture { return *this; } - /** @copydoc Texture::setMinificationFilter() */ + /** + * @copybrief Texture::setMinificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMinificationFilter() for more information. + */ CubeMapTextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { AbstractTexture::setMinificationFilter(filter, mipmap); return *this; } - /** @copydoc Texture::setMagnificationFilter() */ + /** + * @copybrief Texture::setMagnificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMagnificationFilter() for more information. + */ CubeMapTextureArray& setMagnificationFilter(Sampler::Filter filter) { AbstractTexture::setMagnificationFilter(filter); return *this; @@ -173,7 +183,12 @@ class CubeMapTextureArray: public AbstractTexture { return *this; } - /** @copydoc Texture::setWrapping() */ + /** + * @copybrief Texture::setWrapping() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setWrapping() for more information. + */ CubeMapTextureArray& setWrapping(const Array3D& wrapping) { DataHelper<3>::setWrapping(*this, wrapping); return *this; @@ -197,31 +212,39 @@ class CubeMapTextureArray: public AbstractTexture { * * See @ref Texture::setBorderColor(const Vector4ui&) for more * information. + * @requires_gl30 Extension @extension{EXT,texture_integer} */ CubeMapTextureArray& setBorderColor(const Vector4ui& color) { AbstractTexture::setBorderColor(color); return *this; } - /** - * @copybrief Texture::setBorderColor(const Vector4ui&) - * @return Reference to self (for method chaining) - * - * See @ref Texture::setBorderColor(const Vector4i&) for more - * information. + /** @overload + * @requires_gl30 Extension @extension{EXT,texture_integer} */ CubeMapTextureArray& setBorderColor(const Vector4i& color) { AbstractTexture::setBorderColor(color); return *this; } - /** @copydoc Texture::setMaxAnisotropy() */ + /** + * @copybrief Texture::setMaxAnisotropy() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxAnisotropy() for more information. + */ CubeMapTextureArray& setMaxAnisotropy(Float anisotropy) { AbstractTexture::setMaxAnisotropy(anisotropy); return *this; } - /** @copydoc RectangleTexture::setSRGBDecode() */ + /** + * @copybrief Texture::setSRGBDecode() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSRGBDecode() for more information. + * @requires_extension Extension @extension{EXT,texture_sRGB_decode} + */ CubeMapTextureArray& setSRGBDecode(bool decode) { AbstractTexture::setSRGBDecode(decode); return *this; @@ -232,6 +255,7 @@ class CubeMapTextureArray: public AbstractTexture { * @return Reference to self (for method chaining) * * See @ref Texture::setSwizzle() for more information. + * @requires_gl33 Extension @extension{ARB,texture_swizzle} */ template CubeMapTextureArray& setSwizzle() { AbstractTexture::setSwizzle(); @@ -265,6 +289,7 @@ class CubeMapTextureArray: public AbstractTexture { * @return Reference to self (for method chaining) * * See @ref Texture::setDepthStencilMode() for more information. + * @requires_gl43 Extension @extension{ARB,stencil_texturing} */ CubeMapTextureArray& setDepthStencilMode(Sampler::DepthStencilMode mode) { AbstractTexture::setDepthStencilMode(mode); @@ -272,57 +297,49 @@ class CubeMapTextureArray: public AbstractTexture { } /** - * @brief Image size in given mip level - * @param level Mip level + * @copybrief Texture::setStorage() + * @return Reference to self (for method chaining) * - * See @ref Texture::imageSize() for more information. + * Z coordinate of @p size must be multiple of 6. + * + * See @ref Texture::setStorage() for more information. + * @see @ref maxSize() */ - Vector3i imageSize(Int level) { - return DataHelper<3>::imageSize(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level); + CubeMapTextureArray& setStorage(Int levels, TextureFormat internalFormat, const Vector3i& size) { + DataHelper<3>::setStorage(*this, levels, internalFormat, size); + return *this; } /** - * @brief Set storage + * @copybrief Texture::imageSize() * - * Z coordinate of @p size must be multiple of 6. See - * @ref Texture::setStorage() for more information. - * @see @ref maxSize() + * See @ref Texture::imageSize() for more information. */ - CubeMapTextureArray& setStorage(Int levels, TextureFormat internalFormat, const Vector3i& size) { - DataHelper<3>::setStorage(*this, _target, levels, internalFormat, size); - return *this; + Vector3i imageSize(Int level) { + return DataHelper<3>::imageSize(*this, level); } /** - * @brief Read given mip level of texture to image - * @param level Mip level - * @param image Image where to put the data + * @copybrief Texture::image(Int, Image&) * * See @ref Texture::image(Int, Image&) for more information. */ void image(Int level, Image3D& image) { - AbstractTexture::image<3>(GL_TEXTURE_CUBE_MAP_ARRAY, level, image); + AbstractTexture::image<3>(level, image); } /** - * @brief Read given mip level of texture to buffer image - * @param level Mip level - * @param image Buffer image where to put the data - * @param usage Buffer usage + * @copybrief Texture::image(Int, BufferImage&, BufferUsage) * * See @ref Texture::image(Int, BufferImage&, BufferUsage) for more * information. */ void image(Int level, BufferImage3D& image, BufferUsage usage) { - AbstractTexture::image<3>(GL_TEXTURE_CUBE_MAP_ARRAY, level, image, usage); + AbstractTexture::image<3>(level, image, usage); } /** - * @brief Set image data - * @param level Mip level - * @param internalFormat Internal format - * @param image @ref Image3D, @ref ImageReference3D or - * @ref Trade::ImageData3D + * @copybrief Texture::setImage() * @return Reference to self (for method chaining) * * Sets texture image data from three-dimensional image for all cube @@ -337,27 +354,31 @@ class CubeMapTextureArray: public AbstractTexture { * instead. */ CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, const ImageReference3D& image) { - DataHelper<3>::setImage(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image); + DataHelper<3>::setImage(*this, level, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @deprecated_gl Prefer to use @ref Magnum::CubeMapTextureArray::setStorage() "setStorage()" + * and @ref Magnum::CubeMapTextureArray::setSubImage() "setSubImage()" + * instead. + */ CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage3D& image) { - DataHelper<3>::setImage(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image); + DataHelper<3>::setImage(*this, level, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @deprecated_gl Prefer to use @ref Magnum::CubeMapTextureArray::setStorage() "setStorage()" + * and @ref Magnum::CubeMapTextureArray::setSubImage() "setSubImage()" + * instead. + */ CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage3D&& image) { return setImage(level, internalFormat, image); } /** - * @brief Set texture image 3D subdata - * @param level Mip level - * @param offset Offset where to put data in the texture - * @param image @ref Image3D, @ref ImageReference3D or - * @ref Trade::ImageData3D + * @copybrief Texture::setSubImage() * @return Reference to self (for method chaining) * * Z coordinate is equivalent to layer * 6 + number of texture face, @@ -366,13 +387,13 @@ class CubeMapTextureArray: public AbstractTexture { * See @ref Texture::setSubImage() for more information. */ CubeMapTextureArray& setSubImage(Int level, const Vector3i& offset, const ImageReference3D& image) { - DataHelper<3>::setSubImage(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image); + DataHelper<3>::setSubImage(*this, level, offset, image); return *this; } /** @overload */ CubeMapTextureArray& setSubImage(Int level, const Vector3i& offset, BufferImage3D& image) { - DataHelper<3>::setSubImage(*this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image); + DataHelper<3>::setSubImage(*this, level, offset, image); return *this; } @@ -381,20 +402,27 @@ class CubeMapTextureArray: public AbstractTexture { return setSubImage(level, offset, image); } - /** @copydoc Texture::generateMipmap() */ + /** + * @copybrief Texture::generateMipmap() + * @return Reference to self (for method chaining) + * + * See @ref Texture::generateMipmap() for more information. + * @requires_gl30 Extension @extension{ARB,framebuffer_object} + */ CubeMapTextureArray& generateMipmap() { AbstractTexture::generateMipmap(); return *this; } - /** @copydoc Texture::invalidateImage() */ + /** + * @copybrief Texture::invalidateImage() + * + * See @ref Texture::invalidateImage() for more information. + */ void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } /** - * @brief Invalidate texture subimage - * @param level Mip level - * @param offset Offset into the texture - * @param size Size of invalidated data + * @copybrief Texture::invalidateSubImage() * * Z coordinate is equivalent to layer * 6 + number of texture face, * i.e. +X is `0` and so on, in order of (+X, -X, +Y, -Y, +Z, -Z). diff --git a/src/Magnum/Implementation/TextureState.cpp b/src/Magnum/Implementation/TextureState.cpp index b2e3b2db5..83a7b00de 100644 --- a/src/Magnum/Implementation/TextureState.cpp +++ b/src/Magnum/Implementation/TextureState.cpp @@ -69,33 +69,69 @@ TextureState::TextureState(Context& context, std::vector& extension createImplementation = &AbstractTexture::createImplementationDefault; } - /* Bind implementation */ + /* Single bind implementation */ #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) { - extensions.push_back(Extensions::GL::ARB::multi_bind::string()); + if(context.isExtensionSupported()) { + /* Extension name added below */ + + unbindImplementation = &AbstractTexture::unbindImplementationDSA; + bindImplementation = &AbstractTexture::bindImplementationDSA; + } else if(context.isExtensionSupported()) { + /* Extension name added below */ unbindImplementation = &AbstractTexture::unbindImplementationMulti; - bindMultiImplementation = &AbstractTexture::bindImplementationMulti; bindImplementation = &AbstractTexture::bindImplementationMulti; } else if(context.isExtensionSupported()) { /* Extension name added below */ unbindImplementation = &AbstractTexture::unbindImplementationDSAEXT; - bindMultiImplementation = &AbstractTexture::bindImplementationFallback; bindImplementation = &AbstractTexture::bindImplementationDSAEXT; } else #endif { unbindImplementation = &AbstractTexture::unbindImplementationDefault; - bindMultiImplementation = &AbstractTexture::bindImplementationFallback; bindImplementation = &AbstractTexture::bindImplementationDefault; } + /* Multi bind implementation */ + #ifndef MAGNUM_TARGET_GLES + if(context.isExtensionSupported()) { + extensions.push_back(Extensions::GL::ARB::multi_bind::string()); + + bindMultiImplementation = &AbstractTexture::bindImplementationMulti; + + } else + #endif + { + bindMultiImplementation = &AbstractTexture::bindImplementationFallback; + } + /* DSA/non-DSA implementation */ #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) { + if(context.isExtensionSupported()) { + 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.push_back(Extensions::GL::EXT::direct_state_access::string()); parameteriImplementation = &AbstractTexture::parameterImplementationDSAEXT; @@ -106,13 +142,16 @@ TextureState::TextureState(Context& context, std::vector& extension parameterIivImplementation = &AbstractTexture::parameterIImplementationDSAEXT; getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSAEXT; mipmapImplementation = &AbstractTexture::mipmapImplementationDSAEXT; - getImageImplementation = &AbstractTexture::getImageImplementationDSAEXT; subImage1DImplementation = &AbstractTexture::subImageImplementationDSAEXT; subImage2DImplementation = &AbstractTexture::subImageImplementationDSAEXT; subImage3DImplementation = &AbstractTexture::subImageImplementationDSAEXT; setBufferImplementation = &BufferTexture::setBufferImplementationDSAEXT; setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSAEXT; + + getCubeImageSizeImplementation = &CubeMapTexture::getImageSizeImplementationDSAEXT; + cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDSAEXT; + } else #endif { @@ -131,9 +170,6 @@ TextureState::TextureState(Context& context, std::vector& extension #endif mipmapImplementation = &AbstractTexture::mipmapImplementationDefault; #ifndef MAGNUM_TARGET_GLES - getImageImplementation = &AbstractTexture::getImageImplementationDefault; - #endif - #ifndef MAGNUM_TARGET_GLES subImage1DImplementation = &AbstractTexture::subImageImplementationDefault; #endif subImage2DImplementation = &AbstractTexture::subImageImplementationDefault; @@ -143,6 +179,11 @@ TextureState::TextureState(Context& context, std::vector& extension setBufferImplementation = &BufferTexture::setBufferImplementationDefault; setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDefault; #endif + + #ifndef MAGNUM_TARGET_GLES2 + getCubeImageSizeImplementation = &CubeMapTexture::getImageSizeImplementationDefault; + #endif + cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDefault; } /* Data invalidation implementation */ @@ -159,14 +200,28 @@ TextureState::TextureState(Context& context, std::vector& extension invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationNoOp; } - /* Image retrieval implementation */ #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported() && - !context.isExtensionSupported()) { + /* Image retrieval implementation */ + if(context.isExtensionSupported()) { + /* Extension name added above */ + getImageImplementation = &AbstractTexture::getImageImplementationDSA; + getCubeImageImplementation = &CubeMapTexture::getImageImplementationDSA; + + } else if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::ARB::robustness::string()); getImageImplementation = &AbstractTexture::getImageImplementationRobustness; - } else getImageImplementation = &AbstractTexture::getImageImplementationDefault; + getCubeImageImplementation = &CubeMapTexture::getImageImplementationRobustness; + + } else if(context.isExtensionSupported()) { + /* Extension name added above */ + getImageImplementation = &AbstractTexture::getImageImplementationDSAEXT; + getCubeImageImplementation = &CubeMapTexture::getImageImplementationDSAEXT; + + } else { + getImageImplementation = &AbstractTexture::getImageImplementationDefault; + getCubeImageImplementation = &CubeMapTexture::getImageImplementationDefault; + } #endif /* Texture storage implementation */ @@ -183,7 +238,12 @@ TextureState::TextureState(Context& context, std::vector& extension #endif #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) { + if(context.isExtensionSupported()) { + storage1DImplementation = &AbstractTexture::storageImplementationDSA; + storage2DImplementation = &AbstractTexture::storageImplementationDSA; + storage3DImplementation = &AbstractTexture::storageImplementationDSA; + + } else if(context.isExtensionSupported()) { storage1DImplementation = &AbstractTexture::storageImplementationDSAEXT; storage2DImplementation = &AbstractTexture::storageImplementationDSAEXT; storage3DImplementation = &AbstractTexture::storageImplementationDSAEXT; @@ -213,7 +273,10 @@ TextureState::TextureState(Context& context, std::vector& extension if(context.isExtensionSupported()) { extensions.push_back(Extensions::GL::ARB::texture_storage_multisample::string()); - if(context.isExtensionSupported()) { + if(context.isExtensionSupported()) { + storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA; + storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA; + } else if(context.isExtensionSupported()) { storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT; storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT; } else { diff --git a/src/Magnum/Implementation/TextureState.h b/src/Magnum/Implementation/TextureState.h index 5c0180776..e46a8079a 100644 --- a/src/Magnum/Implementation/TextureState.h +++ b/src/Magnum/Implementation/TextureState.h @@ -28,8 +28,7 @@ #include #include -#include "Magnum/Magnum.h" -#include "Magnum/OpenGL.h" +#include "Magnum/CubeMapTexture.h" namespace Magnum { namespace Implementation { @@ -55,26 +54,26 @@ struct TextureState { #endif void(AbstractTexture::*setMaxAnisotropyImplementation)(GLfloat); #ifndef MAGNUM_TARGET_GLES2 - void(AbstractTexture::*getLevelParameterivImplementation)(GLenum, GLint, GLenum, GLint*); + void(AbstractTexture::*getLevelParameterivImplementation)(GLint, GLenum, GLint*); #endif void(AbstractTexture::*mipmapImplementation)(); #ifndef MAGNUM_TARGET_GLES - void(AbstractTexture::*storage1DImplementation)(GLenum, GLsizei, TextureFormat, const Math::Vector<1, GLsizei>&); + void(AbstractTexture::*storage1DImplementation)(GLsizei, TextureFormat, const Math::Vector<1, GLsizei>&); #endif - void(AbstractTexture::*storage2DImplementation)(GLenum, GLsizei, TextureFormat, const Vector2i&); - void(AbstractTexture::*storage3DImplementation)(GLenum, GLsizei, TextureFormat, const Vector3i&); + void(AbstractTexture::*storage2DImplementation)(GLsizei, TextureFormat, const Vector2i&); + void(AbstractTexture::*storage3DImplementation)(GLsizei, TextureFormat, const Vector3i&); #ifndef MAGNUM_TARGET_GLES2 - void(AbstractTexture::*storage2DMultisampleImplementation)(GLenum, GLsizei, TextureFormat, const Vector2i&, GLboolean); + void(AbstractTexture::*storage2DMultisampleImplementation)(GLsizei, TextureFormat, const Vector2i&, GLboolean); #endif #ifndef MAGNUM_TARGET_GLES - void(AbstractTexture::*storage3DMultisampleImplementation)(GLenum, GLsizei, TextureFormat, const Vector3i&, GLboolean); - void(AbstractTexture::*getImageImplementation)(GLenum, GLint, ColorFormat, ColorType, std::size_t, GLvoid*); + void(AbstractTexture::*storage3DMultisampleImplementation)(GLsizei, TextureFormat, const Vector3i&, GLboolean); + void(AbstractTexture::*getImageImplementation)(GLint, ColorFormat, ColorType, std::size_t, GLvoid*); #endif #ifndef MAGNUM_TARGET_GLES - void(AbstractTexture::*subImage1DImplementation)(GLenum, GLint, const Math::Vector<1, GLint>&, const Math::Vector<1, GLsizei>&, ColorFormat, ColorType, const GLvoid*); + void(AbstractTexture::*subImage1DImplementation)(GLint, const Math::Vector<1, GLint>&, const Math::Vector<1, GLsizei>&, ColorFormat, ColorType, const GLvoid*); #endif - void(AbstractTexture::*subImage2DImplementation)(GLenum, GLint, const Vector2i&, const Vector2i&, ColorFormat, ColorType, const GLvoid*); - void(AbstractTexture::*subImage3DImplementation)(GLenum, GLint, const Vector3i&, const Vector3i&, ColorFormat, ColorType, const GLvoid*); + void(AbstractTexture::*subImage2DImplementation)(GLint, const Vector2i&, const Vector2i&, ColorFormat, ColorType, const GLvoid*); + void(AbstractTexture::*subImage3DImplementation)(GLint, const Vector3i&, const Vector3i&, ColorFormat, ColorType, const GLvoid*); void(AbstractTexture::*invalidateImageImplementation)(GLint); void(AbstractTexture::*invalidateSubImageImplementation)(GLint, const Vector3i&, const Vector3i&); @@ -83,6 +82,14 @@ struct TextureState { void(BufferTexture::*setBufferRangeImplementation)(BufferTextureFormat, Buffer&, GLintptr, GLsizeiptr); #endif + #ifndef MAGNUM_TARGET_GLES2 + Vector2i(CubeMapTexture::*getCubeImageSizeImplementation)(Int); + #endif + #ifndef MAGNUM_TARGET_GLES + void(CubeMapTexture::*getCubeImageImplementation)(CubeMapTexture::Coordinate, GLint, const Vector2i&, ColorFormat, ColorType, std::size_t, GLvoid*); + #endif + void(CubeMapTexture::*cubeSubImageImplementation)(CubeMapTexture::Coordinate, GLint, const Vector2i&, const Vector2i&, ColorFormat, ColorType, const GLvoid*); + GLint maxSize, max3DSize, maxCubeMapSize; diff --git a/src/Magnum/MultisampleTexture.h b/src/Magnum/MultisampleTexture.h index bc53318a3..734ab908c 100644 --- a/src/Magnum/MultisampleTexture.h +++ b/src/Magnum/MultisampleTexture.h @@ -122,21 +122,6 @@ template class MultisampleTexture: public AbstractTextur */ explicit MultisampleTexture(): AbstractTexture(Implementation::multisampleTextureTarget()) {} - /** - * @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 imageSize() { - return DataHelper::imageSize(*this, _target, 0); - } - /** * @brief Set storage * @param samples Sample count @@ -148,19 +133,20 @@ template class MultisampleTexture: public AbstractTextur * After calling this function the texture is immutable and calling * @ref setStorage() again is not allowed. * - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. If + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). If * @extension{ARB,texture_storage_multisample} (part of OpenGL 4.3) is - * not available, the feature is emulated using plain - * @extension{ARB,texture_storage} functionality (which unfortunately - * doesn't have any DSA alternative, so the texture must be bound - * to some texture unit before). + * not available, the texture is bound and the feature is emulated + * using plain @extension{ARB,texture_multisample} functionality. * @see @ref maxSize(), @ref maxColorSamples(), @ref maxDepthSamples(), - * @ref maxIntegerSamples(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} - * and @fn_gl{TexStorage2DMultisample}/@fn_gl{TexStorage3DMultisample} - * or @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access}/ - * @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access} - * eventually @fn_gl{TexImage2DMultisample}/@fn_gl{TexImage3DMultisample} + * @ref maxIntegerSamples(), @fn_gl2{TextureStorage2DMultisample,TexStorage2DMultisample} / + * @fn_gl2{TextureStorage3DMultisample,TexStorage3DMultisample}, + * @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access} / + * @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} + * and @fn_gl{TexStorage2DMultisample} / @fn_gl{TexStorage3DMultisample} + * or @fn_gl{TexImage2DMultisample} / @fn_gl{TexImage3DMultisample} * @todoc Remove the workaround when it stops breaking Doxygen layout so badly */ /* The default parameter value was chosen based on discussion in @@ -173,14 +159,35 @@ template class MultisampleTexture: public AbstractTextur NotFixed #endif ) { - DataHelper::setStorageMultisample(*this, _target, samples, internalFormat, size, GLboolean(sampleLocations)); + DataHelper::setStorageMultisample(*this, samples, internalFormat, size, GLboolean(sampleLocations)); return *this; } - /** @copydoc RectangleTexture::invalidateImage() */ + /** + * @brief Texture image size + * + * See @ref Texture::imageSize() for more information. + * @requires_gles31 Texture image size queries are not available in + * OpenGL ES 3.0 and older. + */ + VectorTypeFor imageSize() { + return DataHelper::imageSize(*this, 0); + } + + /** + * @copybrief Texture::invalidateImage() + * @return Reference to self (for method chaining) + * + * See @ref Texture::invalidateImage() for more information. + */ void invalidateImage() { AbstractTexture::invalidateImage(0); } - /** @copydoc RectangleTexture::invalidateSubImage() */ + /** + * @copybrief Texture::invalidateSubImage() + * @return Reference to self (for method chaining) + * + * See @ref Texture::invalidateSubImage() for more information. + */ void invalidateSubImage(const VectorTypeFor& offset, const VectorTypeFor& size) { DataHelper::invalidateSubImage(*this, 0, offset, size); } diff --git a/src/Magnum/RectangleTexture.h b/src/Magnum/RectangleTexture.h index b7e112b63..a16356d02 100644 --- a/src/Magnum/RectangleTexture.h +++ b/src/Magnum/RectangleTexture.h @@ -92,59 +92,38 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { explicit RectangleTexture(): AbstractTexture(GL_TEXTURE_RECTANGLE) {} /** - * @brief Set minification filter - * @param filter Filter + * @copybrief Texture::setMinificationFilter() * @return Reference to self (for method chaining) * - * Sets filter used when the object pixel size is smaller than the - * texture size. If @extension{EXT,direct_state_access} is not - * available, the texture is bound to some texture unit before the - * operation. Initial value is @ref Sampler::Filter::Linear. - * @see @ref setMagnificationFilter(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_MIN_FILTER} + * See @ref Texture::setMinificationFilter() for more information. + * Initial value is @ref Sampler::Filter::Linear. */ RectangleTexture& setMinificationFilter(Sampler::Filter filter) { AbstractTexture::setMinificationFilter(filter, Sampler::Mipmap::Base); return *this; } - /** @copydoc Texture::setMagnificationFilter() */ + /** + * @copybrief Texture::setMagnificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMagnificationFilter() for more information. + */ RectangleTexture& setMagnificationFilter(Sampler::Filter filter) { AbstractTexture::setMagnificationFilter(filter); return *this; } /** - * @brief Image size - * - * The result is not cached in any way. If - * @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. - * @see @ref image(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_WIDTH} and @def_gl{TEXTURE_HEIGHT} - */ - Vector2i imageSize() { return DataHelper<2>::imageSize(*this, _target, 0); } - - /** - * @brief Set wrapping - * @param wrapping Wrapping type for all texture dimensions + * @copybrief Texture::setWrapping() * @return Reference to self (for method chaining) * * Sets wrapping type for coordinates out of @f$ [ 0, size - 1 ] @f$ - * range. If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. Initial + * range. See @ref Texture::setWrapping() for more information. Initial * value is @ref Sampler::Wrapping::ClampToEdge. * @attention Only @ref Sampler::Wrapping::ClampToEdge and * @ref Sampler::Wrapping::ClampToBorder is supported on this * texture type. - * @see @ref setBorderColor(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T}, - * @def_gl{TEXTURE_WRAP_R} */ RectangleTexture& setWrapping(const Array2D& wrapping) { DataHelper<2>::setWrapping(*this, wrapping); @@ -169,40 +148,37 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * * See @ref Texture::setBorderColor(const Vector4ui&) for more * information. + * @requires_gl30 Extension @extension{EXT,texture_integer} */ RectangleTexture& setBorderColor(const Vector4ui& color) { AbstractTexture::setBorderColor(color); return *this; } - /** - * @copybrief Texture::setBorderColor(const Vector4ui&) - * @return Reference to self (for method chaining) - * - * See @ref Texture::setBorderColor(const Vector4i&) for more - * information. + /** @overload + * @requires_gl30 Extension @extension{EXT,texture_integer} */ RectangleTexture& setBorderColor(const Vector4i& color) { AbstractTexture::setBorderColor(color); return *this; } - /** @copydoc Texture::setMaxAnisotropy() */ + /** + * @copybrief Texture::setMaxAnisotropy() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxAnisotropy() for more information. + */ RectangleTexture& setMaxAnisotropy(Float anisotropy) { AbstractTexture::setMaxAnisotropy(anisotropy); return *this; } /** - * @brief Set sRGB decoding + * @copybrief Texture::setSRGBDecode() * @return Reference to self (for method chaining) * - * Disables or reenables decoding of sRGB values. Initial value is - * `true`. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_SRGB_DECODE_EXT} + * See @ref Texture::setSRGBDecode() for more information. * @requires_extension Extension @extension{EXT,texture_sRGB_decode} */ RectangleTexture& setSRGBDecode(bool decode) { @@ -215,6 +191,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * @return Reference to self (for method chaining) * * See @ref Texture::setSwizzle() for more information. + * @requires_gl33 Extension @extension{ARB,texture_swizzle} */ template RectangleTexture& setSwizzle() { AbstractTexture::setSwizzle(); @@ -248,6 +225,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * @return Reference to self (for method chaining) * * See @ref Texture::setDepthStencilMode() for more information. + * @requires_gl43 Extension @extension{ARB,stencil_texturing} */ RectangleTexture& setDepthStencilMode(Sampler::DepthStencilMode mode) { AbstractTexture::setDepthStencilMode(mode); @@ -255,124 +233,91 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { } /** - * @brief Set storage - * @param internalFormat Internal format - * @param size Texture size + * @copybrief Texture::setStorage() * @return Reference to self (for method chaining) * - * Specifies entire structure of a texture at once, removing the need - * for additional consistency checks and memory reallocations when - * updating the data later. After calling this function the texture - * is immutable and calling @ref setStorage() or @ref setImage() is not - * allowed. - * - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. If - * @extension{ARB,texture_storage} (part of OpenGL 4.2), OpenGL ES 3.0 - * or @es_extension{EXT,texture_storage} in OpenGL ES 2.0 is not - * available, the feature is emulated with @ref setImage() call. - * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexStorage2D} or - * @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}, - * eventually @fn_gl{TexImage2D} or - * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}. + * See @ref Texture::setStorage() for more information. + * @see @ref maxSize() */ RectangleTexture& setStorage(TextureFormat internalFormat, const Vector2i& size) { - DataHelper<2>::setStorage(*this, _target, 1, internalFormat, size); + DataHelper<2>::setStorage(*this, 1, internalFormat, size); return *this; } /** - * @brief Read texture to image - * @param image Image where to put the data + * @brief Texture image size * - * Image parameters like format and type of pixel data are taken from - * given image, image size is taken from the texture using - * @ref imageSize(). + * See @ref Texture::imageSize() for more information. + */ + Vector2i imageSize() { return DataHelper<2>::imageSize(*this, 0); } + + /** + * @brief Read texture to image * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. If - * @extension{ARB,robustness} is available, the operation is protected - * from buffer overflow. However, if both @extension{EXT,direct_state_access} - * and @extension{ARB,robustness} are available, the DSA version is - * used, because it is better for performance and there isn't any - * function combining both features. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_WIDTH} and @def_gl{TEXTURE_HEIGHT}, then - * @fn_gl{GetTexImage}, @fn_gl_extension{GetTextureImage,EXT,direct_state_access} - * or @fn_gl_extension{GetnTexImage,ARB,robustness} + * See @ref Texture::image(Int, Image&) for more information. */ void image(Image2D& image) { - AbstractTexture::image<2>(_target, 0, image); + AbstractTexture::image<2>(0, image); } /** - * @brief Read given mip level of texture to buffer image - * @param image Buffer image where to put the data - * @param usage Buffer usage + * @brief Read texture to buffer image * - * See @ref image(Image2D&) for more information. + * See @ref Texture::image(Int, BufferImage&, BufferUsage) for more + * information. */ void image(BufferImage2D& image, BufferUsage usage) { - AbstractTexture::image<2>(_target, 0, image, usage); + AbstractTexture::image<2>(0, image, usage); } /** - * @brief Set image data - * @param internalFormat Internal format - * @param image @ref Image2D, @ref ImageReference2D or - * @ref Trade::ImageData2D + * @copybrief Texture::setImage() * @return Reference to self (for method chaining) * - * On platforms that support it prefer to use @ref setStorage() and - * @ref setSubImage() instead, as it avoids unnecessary reallocations - * and has better performance characteristics. This call also has no - * equivalent in @extension{ARB,direct_state_access}, thus the texture - * needs to be bound to some texture unit before the operation. - * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexImage2D} + * See @ref Texture::setImage() for more information. + * @see @ref maxSize() * @deprecated_gl Prefer to use @ref Magnum::RectangleTexture::setStorage() "setStorage()" * and @ref Magnum::RectangleTexture::setSubImage() "setSubImage()" * instead. */ RectangleTexture& setImage(TextureFormat internalFormat, const ImageReference2D& image) { - DataHelper<2>::setImage(*this, _target, 0, internalFormat, image); + DataHelper<2>::setImage(*this, 0, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @deprecated_gl Prefer to use @ref Magnum::RectangleTexture::setStorage() "setStorage()" + * and @ref Magnum::RectangleTexture::setSubImage() "setSubImage()" + * instead. + */ RectangleTexture& setImage(TextureFormat internalFormat, BufferImage2D& image) { - DataHelper<2>::setImage(*this, _target, 0, internalFormat, image); + DataHelper<2>::setImage(*this, 0, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @deprecated_gl Prefer to use @ref Magnum::RectangleTexture::setStorage() "setStorage()" + * and @ref Magnum::RectangleTexture::setSubImage() "setSubImage()" + * instead. + */ RectangleTexture& setImage(TextureFormat internalFormat, BufferImage2D&& image) { return setImage(internalFormat, image); } /** - * @brief Set image subdata - * @param offset Offset where to put data in the texture - * @param image @ref Image2D, @ref ImageReference2D or - * @ref Trade::ImageData2D + * @copybrief Texture::setSubImage() * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. - * @see @ref setStorage(), @ref setImage(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexSubImage2D} or - * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access} + * See @ref Texture::setSubImage() for more information. */ RectangleTexture& setSubImage(const Vector2i& offset, const ImageReference2D& image) { - DataHelper<2>::setSubImage(*this, _target, 0, offset, image); + DataHelper<2>::setSubImage(*this, 0, offset, image); return *this; } /** @overload */ RectangleTexture& setSubImage(const Vector2i& offset, BufferImage2D& image) { - DataHelper<2>::setSubImage(*this, _target, 0, offset, image); + DataHelper<2>::setSubImage(*this, 0, offset, image); return *this; } @@ -382,22 +327,18 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { } /** - * @brief Invalidate texture image + * @brief Invalidate texture * - * If extension @extension{ARB,invalidate_subdata} (part of OpenGL 4.3) - * is not available, this function does nothing. - * @see @ref invalidateSubImage(), @fn_gl{InvalidateTexImage} + * See @ref Texture::invalidateImage() for more information. */ void invalidateImage() { AbstractTexture::invalidateImage(0); } /** - * @brief Invalidate texture subimage + * @brief Invalidate subtexture * @param offset Offset into the texture * @param size Size of invalidated data * - * If extension @extension{ARB,invalidate_subdata} (part of OpenGL 4.3) - * is not available, this function does nothing. - * @see @ref invalidateImage(), @fn_gl{InvalidateTexSubImage} + * See @ref Texture::invalidateSubImage() for more information. */ void invalidateSubImage(const Vector2i& offset, const Vector2i& size) { DataHelper<2>::invalidateSubImage(*this, 0, offset, size); diff --git a/src/Magnum/Test/CubeMapTextureGLTest.cpp b/src/Magnum/Test/CubeMapTextureGLTest.cpp index e71d10b2c..803c2e6d9 100644 --- a/src/Magnum/Test/CubeMapTextureGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureGLTest.cpp @@ -265,48 +265,13 @@ void CubeMapTextureGLTest::storage() { CORRADE_SKIP("OpenGL ES 3.1 not supported, skipping image size testing"); #endif - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 0), Vector2i(32)); - - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 1), Vector2i(16)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 1), Vector2i(16)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 1), Vector2i(16)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 1), Vector2i(16)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 1), Vector2i(16)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 1), Vector2i(16)); - - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 2), Vector2i(8)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 2), Vector2i(8)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 2), Vector2i(8)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 2), Vector2i(8)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 2), Vector2i(8)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 2), Vector2i(8)); - - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 3), Vector2i(4)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 3), Vector2i(4)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 3), Vector2i(4)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 3), Vector2i(4)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 3), Vector2i(4)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 3), Vector2i(4)); - - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 4), Vector2i(2)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 4), Vector2i(2)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 4), Vector2i(2)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 4), Vector2i(2)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 4), Vector2i(2)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 4), Vector2i(2)); - + CORRADE_COMPARE(texture.imageSize(0), Vector2i(32)); + CORRADE_COMPARE(texture.imageSize(1), Vector2i(16)); + CORRADE_COMPARE(texture.imageSize(2), Vector2i(8)); + CORRADE_COMPARE(texture.imageSize(3), Vector2i(4)); + CORRADE_COMPARE(texture.imageSize(4), Vector2i(2)); /* Not available */ - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 5), Vector2i(0)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeX, 5), Vector2i(0)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveY, 5), Vector2i(0)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeY, 5), Vector2i(0)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveZ, 5), Vector2i(0)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::NegativeZ, 5), Vector2i(0)); + CORRADE_COMPARE(texture.imageSize(5), Vector2i(0)); MAGNUM_VERIFY_NO_ERROR(); #endif @@ -445,8 +410,8 @@ void CubeMapTextureGLTest::generateMipmap() { /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 1), Vector2i( 0)); + CORRADE_COMPARE(texture.imageSize(0), Vector2i(32)); + CORRADE_COMPARE(texture.imageSize(1), Vector2i( 0)); #endif texture.generateMipmap(); @@ -455,12 +420,12 @@ void CubeMapTextureGLTest::generateMipmap() { /** @todo How to test this on ES? */ #ifndef MAGNUM_TARGET_GLES - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 0), Vector2i(32)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 1), Vector2i(16)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 2), Vector2i( 8)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 3), Vector2i( 4)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 4), Vector2i( 2)); - CORRADE_COMPARE(texture.imageSize(CubeMapTexture::Coordinate::PositiveX, 5), Vector2i( 1)); + CORRADE_COMPARE(texture.imageSize(0), Vector2i(32)); + CORRADE_COMPARE(texture.imageSize(1), Vector2i(16)); + CORRADE_COMPARE(texture.imageSize(2), Vector2i( 8)); + CORRADE_COMPARE(texture.imageSize(3), Vector2i( 4)); + CORRADE_COMPARE(texture.imageSize(4), Vector2i( 2)); + CORRADE_COMPARE(texture.imageSize(5), Vector2i( 1)); MAGNUM_VERIFY_NO_ERROR(); #endif diff --git a/src/Magnum/Texture.h b/src/Magnum/Texture.h index 4ba823ea1..fbaa36cae 100644 --- a/src/Magnum/Texture.h +++ b/src/Magnum/Texture.h @@ -188,25 +188,6 @@ template class Texture: public AbstractTexture { constexpr CORRADE_DEPRECATED("use dedicated Texture, TextureArray, MultisampleTexture, RectangleTexture classes instead") Target target() const { return static_cast(_target); } #endif - #ifndef MAGNUM_TARGET_GLES2 - /** - * @brief Image size in given mip level - * - * The result is not cached in any way. If - * @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. - * @see @ref image(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or - * @def_gl{TEXTURE_DEPTH} - * @requires_gles31 Texture image size queries are not available in - * OpenGL ES 3.0 and older. - */ - VectorTypeFor imageSize(Int level) { - return DataHelper::imageSize(*this, _target, level); - } - #endif - #ifndef MAGNUM_TARGET_GLES2 /** * @brief Set base mip level @@ -214,11 +195,15 @@ template class Texture: public AbstractTexture { * * Taken into account when generating mipmap using @ref generateMipmap() * and when considering texture completeness when using mipmap - * filtering. Initial value is `0`. + * filtering. If on OpenGL ES or neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). Initial value is `0`. * @see @ref setMaxLevel(), @ref setMinificationFilter(), - * @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_BASE_LEVEL} + * @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_BASE_LEVEL} * @requires_gles30 Base level is always `0` in OpenGL ES 2.0. */ Texture& setBaseLevel(Int level) { @@ -233,12 +218,16 @@ template class Texture: public AbstractTexture { * * Taken into account when generating mipmap using @ref generateMipmap() * and when considering texture completeness when using mipmap - * filtering. Initial value is `1000`, which is clamped to count of + * filtering. If on OpenGL ES or neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). Initial value is `1000`, which is clamped to count of * levels specified when using @ref setStorage(). * @see @ref setBaseLevel(), @ref setMinificationFilter(), - * @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_MAX_LEVEL} + * @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_MAX_LEVEL} * @requires_gles30 Extension @es_extension{APPLE,texture_max_level}, * otherwise the max level is always set to largest possible value * in OpenGL ES 2.0. @@ -257,15 +246,16 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Sets filter used when the object pixel size is smaller than the - * texture size. If @extension{EXT,direct_state_access} is not - * available, the texture is bound to some texture unit before the - * operation. Initial value is {@ref Sampler::Filter::Nearest, + * texture size. If on OpenGL ES or neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). Initial value is {@ref Sampler::Filter::Nearest, * @ref Sampler::Mipmap::Linear}. * @see @ref setMagnificationFilter(), @ref setBaseLevel(), - * @ref setMaxLevel(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} - * and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_MIN_FILTER} + * @ref setMaxLevel(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_MIN_FILTER} */ Texture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { AbstractTexture::setMinificationFilter(filter, mipmap); @@ -278,13 +268,14 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Sets filter used when the object pixel size is larger than largest - * texture size. If @extension{EXT,direct_state_access} is not - * available, the texture is bound to some texture unit before the - * operation. Initial value is @ref Sampler::Filter::Linear. - * @see @ref setMinificationFilter(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_MAG_FILTER} + * texture size. If on OpenGL ES or neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). Initial value is @ref Sampler::Filter::Linear. + * @see @ref setMinificationFilter(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_MAG_FILTER} */ Texture& setMagnificationFilter(Sampler::Filter filter) { AbstractTexture::setMagnificationFilter(filter); @@ -296,14 +287,15 @@ template class Texture: public AbstractTexture { * @brief Set minimum level-of-detail parameter * @return Reference to self (for method chaining) * - * Limits selection of highest resolution mipmap. If - * @extension{EXT,direct_state_access} is not available, the texture is - * bound to some texture unit before the operation. Initial value is + * Limits selection of highest resolution mipmap. If on OpenGL ES or + * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). Initial value is * `-1000.0f`. - * @see @ref setMaxLod(), @ref setLodBias(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_MIN_LOD} + * @see @ref setMaxLod(), @ref setLodBias(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_MIN_LOD} * @requires_gles30 Texture LOD parameters are not available in OpenGL * ES 2.0. */ @@ -316,14 +308,15 @@ template class Texture: public AbstractTexture { * @brief Set maximum level-of-detail parameter * @return Reference to self (for method chaining) * - * Limits selection of lowest resolution mipmap. If - * @extension{EXT,direct_state_access} is not available, the texture is - * bound to some texture unit before the operation. Initial value is + * Limits selection of lowest resolution mipmap. If on OpenGL ES or + * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). Initial value is * `1000.0f`. - * @see @ref setMinLod(), @ref setLodBias(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_MAX_LOD} + * @see @ref setMinLod(), @ref setLodBias(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_MAX_LOD} * @requires_gles30 Texture LOD parameters are not available in OpenGL * ES 2.0. */ @@ -339,13 +332,15 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Fixed bias value that is added to the level-of-detail parameter. If - * @extension{EXT,direct_state_access} is not available, the texture is - * bound to some texture unit before the operation. Initial value is + * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). Initial value is * `0.0f`. * @see @ref maxLodBias(), @ref setMinLod(), @ref setMaxLod(), - * @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_LOD_BIAS} + * @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_LOD_BIAS} * @requires_gl Texture LOD bias can be specified only directly in * fragment shader in OpenGL ES. */ @@ -361,14 +356,15 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Sets wrapping type for coordinates out of range @f$ [ 0.0, 1.0 ] @f$. - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. Initial value is - * @ref Sampler::Wrapping::Repeat. - * @see @ref setBorderColor(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T}, - * @def_gl{TEXTURE_WRAP_R} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). Initial + * value is @ref Sampler::Wrapping::Repeat. + * @see @ref setBorderColor(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_WRAP_S}, + * @def_gl{TEXTURE_WRAP_T}, @def_gl{TEXTURE_WRAP_R} */ Texture& setWrapping(const Array& wrapping) { DataHelper::setWrapping(*this, wrapping); @@ -380,13 +376,14 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Border color when wrapping is set to @ref Sampler::Wrapping::ClampToBorder. - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. Initial value is - * `{0.0f, 0.0f, 0.0f, 0.0f}`. - * @see @ref setWrapping(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} - * and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_BORDER_COLOR} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). Initial + * value is `{0.0f, 0.0f, 0.0f, 0.0f}`. + * @see @ref setWrapping(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_BORDER_COLOR} * @requires_es_extension Extension @es_extension{NV,texture_border_clamp} */ Texture& setBorderColor(const Color4& color) { @@ -400,12 +397,15 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Border color for integer textures when wrapping is set to - * @ref Sampler::Wrapping::ClampToBorder. If @extension{EXT,direct_state_access} - * is not available, the texture is bound to some texture unit before - * the operation. Initial value is `{0, 0, 0, 0}`. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_BORDER_COLOR} + * @ref Sampler::Wrapping::ClampToBorder. If neither + * @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). Initial value is + * `{0, 0, 0, 0}`. + * @see @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_BORDER_COLOR} * @requires_gl30 Extension @extension{EXT,texture_integer} * @requires_gl Border is available only for float textures in OpenGL * ES. @@ -433,13 +433,14 @@ template class Texture: public AbstractTexture { * Default value is `1.0f`, which means no anisotropy. Set to value * greater than `1.0f` for anisotropic filtering. If extension * @extension{EXT,texture_filter_anisotropic} (desktop or ES) is not - * available, this function does nothing. If - * @extension{EXT,direct_state_access} is not available, the texture is - * bound to some texture unit before the operation. - * @see @ref Sampler::maxMaxAnisotropy(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_MAX_ANISOTROPY_EXT} + * available, this function does nothing. If on OpenGL ES or neither + * @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). + * @see @ref Sampler::maxMaxAnisotropy(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_MAX_ANISOTROPY_EXT} */ Texture& setMaxAnisotropy(Float anisotropy) { AbstractTexture::setMaxAnisotropy(anisotropy); @@ -450,12 +451,15 @@ template class Texture: public AbstractTexture { * @brief Set sRGB decoding * @return Reference to self (for method chaining) * - * Disables or reenables decoding of sRGB values. Initial value is + * Disables or reenables decoding of sRGB values. If on OpenGL ES or + * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). Initial value is * `true`. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_SRGB_DECODE_EXT} + * @see @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_SRGB_DECODE_EXT} * @requires_extension Extension @extension{EXT,texture_sRGB_decode} * @requires_es_extension OpenGL ES 3.0 or extension * @es_extension{EXT,sRGB} and @@ -477,15 +481,17 @@ template class Texture: public AbstractTexture { * @code * texture.setSwizzle<'b', 'g', 'r', '0'>(); * @endcode - * If @extension{EXT,direct_state_access} is not available, - * the texture is bound to some texture unit before the operation. - * Initial value is `rgba`. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_SWIZZLE_RGBA} (or @def_gl{TEXTURE_SWIZZLE_R}, - * @def_gl{TEXTURE_SWIZZLE_G}, @def_gl{TEXTURE_SWIZZLE_B} and - * @def_gl{TEXTURE_SWIZZLE_A} separately in OpenGL ES) + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). Initial + * value is `rgba`. + * @see @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_SWIZZLE_RGBA} (or + * @def_gl{TEXTURE_SWIZZLE_R}, @def_gl{TEXTURE_SWIZZLE_G}, + * @def_gl{TEXTURE_SWIZZLE_B} and @def_gl{TEXTURE_SWIZZLE_A} + * separately in OpenGL ES) * @requires_gl33 Extension @extension{ARB,texture_swizzle} * @requires_gles30 Texture swizzle is not available in OpenGL ES 2.0. */ @@ -499,14 +505,15 @@ template class Texture: public AbstractTexture { * @brief Set depth texture comparison mode * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available, - * the texture is bound to some texture unit before the operation. - * Initial value is @ref Sampler::CompareMode::None. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). Initial + * value is @ref Sampler::CompareMode::None. * @note Depth textures can be only 1D or 2D. - * @see @ref setCompareFunction(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_COMPARE_MODE} + * @see @ref setCompareFunction(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_COMPARE_MODE} * @requires_gles30 Extension @es_extension{EXT,shadow_samplers} */ Texture& setCompareMode(Sampler::CompareMode mode) { @@ -519,15 +526,16 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Comparison operator used when comparison mode is set to - * @ref Sampler::CompareMode::CompareRefToTexture. If - * @extension{EXT,direct_state_access} is not available, the texture is - * bound to some texture unit before the operation. Initial value is + * @ref Sampler::CompareMode::CompareRefToTexture. If on OpenGL ES or + * neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). Initial value is * @ref Sampler::CompareFunction::LessOrEqual. * @note Depth textures can be only 1D or 2D. - * @see @ref setCompareMode(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{TexParameter} or - * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with - * @def_gl{TEXTURE_COMPARE_FUNC} + * @see @ref setCompareMode(), @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{TEXTURE_COMPARE_FUNC} * @requires_gles30 Extension @es_extension{EXT,shadow_samplers} */ Texture& setCompareFunction(Sampler::CompareFunction function) { @@ -541,13 +549,15 @@ template class Texture: public AbstractTexture { * @return Reference to self (for method chaining) * * Selects which component of packed depth/stencil texture is used for - * texturing. If @extension{EXT,direct_state_access} is not available, - * the texture is bound to some texture unit before the operation. - * Initial value is @ref Sampler::DepthStencilMode::DepthComponent. + * texturing. If on OpenGL ES or neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). Initial value is @ref Sampler::DepthStencilMode::DepthComponent. * @note Depth textures can be only 1D or 2D. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} - * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} - * with @def_gl{DEPTH_STENCIL_TEXTURE_MODE} + * @see @fn_gl2{TextureParameter,TexParameter}, + * @fn_gl_extension{TextureParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexParameter} with @def_gl{DEPTH_STENCIL_TEXTURE_MODE} * @requires_gl43 Extension @extension{ARB,stencil_texturing} * @requires_gles31 Stencil texturing is not available in OpenGL ES 3.0 * and older. @@ -565,36 +575,52 @@ template class Texture: public AbstractTexture { * @param size Size of largest mip level * @return Reference to self (for method chaining) * - * Specifies entire structure of a texture at once, removing the need - * for additional consistency checks and memory reallocations when - * updating the data later. After calling this function the texture - * is immutable and calling @ref setStorage() or @ref setImage() is not - * allowed. - * - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. If - * @extension{ARB,texture_storage} (part of OpenGL 4.2), OpenGL ES 3.0 - * or @es_extension{EXT,texture_storage} in OpenGL ES 2.0 is not - * available, the feature is emulated with sequence of @ref setImage() - * calls. - * @see @ref maxSize(), @ref setMaxLevel(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and - * @fn_gl{TexStorage1D}/@fn_gl{TexStorage2D}/@fn_gl{TexStorage3D} - * or @fn_gl_extension{TextureStorage1D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}/ + * After calling this function the texture is immutable and calling + * @ref setStorage() or @ref setImage() is not allowed. + * + * If on OpenGL ES or neither @extension{ARB,direct_state_access} + * (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} is + * available, the texture is bound before the operation (if not + * already). If neither @extension{ARB,texture_storage} (part of OpenGL + * 4.2), OpenGL ES 3.0 nor @es_extension{EXT,texture_storage} in OpenGL + * ES 2.0 is available, the feature is emulated with sequence of + * @ref setImage() calls. + * @see @ref maxSize(), @ref setMaxLevel(), @fn_gl2{TextureStorage1D,TexStorage1D} / + * @fn_gl2{TextureStorage2D,TexStorage2D} / @fn_gl2{TextureStorage3D,TexStorage3D}, + * @fn_gl_extension{TextureStorage1D,EXT,direct_state_access} / + * @fn_gl_extension{TextureStorage2D,EXT,direct_state_access} / * @fn_gl_extension{TextureStorage3D,EXT,direct_state_access}, - * eventually @fn_gl{TexImage1D}/@fn_gl{TexImage2D}/@fn_gl{TexImage3D} - * or @fn_gl_extension{TextureImage1D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureImage3D,EXT,direct_state_access} + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexStorage1D}/@fn_gl{TexStorage2D}/@fn_gl{TexStorage3D} * @todo allow the user to specify ColorType explicitly to avoid * issues in WebGL (see setSubImage()) */ Texture& setStorage(Int levels, TextureFormat internalFormat, const VectorTypeFor& size) { - DataHelper::setStorage(*this, _target, levels, internalFormat, size); + DataHelper::setStorage(*this, levels, internalFormat, size); return *this; } + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Image size in given mip level + * + * The result is not cached in any way. If on OpenGL ES or neither + * @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor + * @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). + * @see @ref image(), @fn_gl2{GetTextureLevelParameter,GetTexLevelParameter}, + * @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{GetTexLevelParameter} with @def_gl{TEXTURE_WIDTH}, + * @def_gl{TEXTURE_HEIGHT}, @def_gl{TEXTURE_DEPTH} + * @requires_gles31 Texture image size queries are not available in + * OpenGL ES 3.0 and older. + */ + VectorTypeFor imageSize(Int level) { + return DataHelper::imageSize(*this, level); + } + #endif + #ifndef MAGNUM_TARGET_GLES /** * @brief Read given mip level of texture to image @@ -605,22 +631,26 @@ template class Texture: public AbstractTexture { * given image, image size is taken from the texture using * @ref imageSize(). * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. If - * @extension{ARB,robustness} is available, the operation is protected - * from buffer overflow. However, if both @extension{EXT,direct_state_access} - * and @extension{ARB,robustness} are available, the DSA version is - * used, because it is better for performance and there isn't any - * function combining both features. - * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} - * with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or @def_gl{TEXTURE_DEPTH}, - * then @fn_gl{GetTexImage}, @fn_gl_extension{GetTextureImage,EXT,direct_state_access} - * or @fn_gl_extension{GetnTexImage,ARB,robustness} + * If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) + * nor @extension{EXT,direct_state_access} is available, the texture is + * bound before the operation (if not already). If either + * @extension{ARB,direct_state_access} or @extension{ARB,robustness} + * is available, the operation is protected from buffer overflow. + * However, if @extension{ARB,direct_state_access} is not available and + * both @extension{EXT,direct_state_access} and @extension{ARB,robustness} + * are available, the robust operation is preferred over DSA. + * @see @fn_gl2{GetTextureLevelParameter,GetTexLevelParameter}, + * @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{GetTexLevelParameter} with @def_gl{TEXTURE_WIDTH}, + * @def_gl{TEXTURE_HEIGHT}, @def_gl{TEXTURE_DEPTH}, then + * @fn_gl2{GetTextureImage,GetTexImage}, + * @fn_gl_extension{GetnTexImage,ARB,robustness} or + * @fn_gl_extension{GetTextureImage,EXT,direct_state_access}, * @requires_gl Texture image queries are not available in OpenGL ES. */ void image(Int level, Image& image) { - AbstractTexture::image(_target, level, image); + AbstractTexture::image(level, image); } /** @@ -635,7 +665,7 @@ template class Texture: public AbstractTexture { * @extension{ARB,buffer_storage}, avoiding relocations...) */ void image(Int level, BufferImage& image, BufferUsage usage) { - AbstractTexture::image(_target, level, image, usage); + AbstractTexture::image(level, image, usage); } #endif @@ -653,24 +683,36 @@ template class Texture: public AbstractTexture { * equivalent in @extension{ARB,direct_state_access}, thus the texture * needs to be bound to some texture unit before the operation. * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexImage1D}/@fn_gl{TexImage2D}/@fn_gl{TexImage3D} + * @fn_gl{TexImage1D} / @fn_gl{TexImage2D} / @fn_gl{TexImage3D} * @deprecated_gl Prefer to use @ref Magnum::Texture::setStorage() "setStorage()" * and @ref Magnum::Texture::setSubImage() "setSubImage()" * instead. */ Texture& setImage(Int level, TextureFormat internalFormat, const ImageReference& image) { - DataHelper::setImage(*this, _target, level, internalFormat, image); + DataHelper::setImage(*this, level, internalFormat, image); return *this; } #ifndef MAGNUM_TARGET_GLES2 - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + * @deprecated_gl Prefer to use @ref Magnum::Texture::setStorage() "setStorage()" + * and @ref Magnum::Texture::setSubImage() "setSubImage()" + * instead. + */ Texture& setImage(Int level, TextureFormat internalFormat, BufferImage& image) { - DataHelper::setImage(*this, _target, level, internalFormat, image); + DataHelper::setImage(*this, level, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + * @deprecated_gl Prefer to use @ref Magnum::Texture::setStorage() "setStorage()" + * and @ref Magnum::Texture::setSubImage() "setSubImage()" + * instead. + */ Texture& setImage(Int level, TextureFormat internalFormat, BufferImage&& image) { return setImage(level, internalFormat, image); } @@ -684,33 +726,42 @@ template class Texture: public AbstractTexture { * @ref Trade::ImageData of the same dimension count * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). * * @attention In @ref MAGNUM_TARGET_WEBGL "WebGL" the @ref ColorType of * data passed in @p image must match the original one specified * in @ref setImage(). It means that you might not be able to use * @ref setStorage() as it uses implicit @ref ColorType value. * - * @see @ref setStorage(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} - * and @fn_gl{TexSubImage1D}/@fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D} - * or @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} + * @see @ref setStorage(), @fn_gl2{TextureSubImage1D,TexSubImage1D} / + * @fn_gl2{TextureSubImage2D,TexSubImage2D} / @fn_gl2{TextureSubImage3D,TexSubImage3D}, + * @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access} / + * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access} / + * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexSubImage1D} / @fn_gl{TexSubImage2D} / @fn_gl{TexSubImage3D} */ Texture& setSubImage(Int level, const VectorTypeFor& offset, const ImageReference& image) { - DataHelper::setSubImage(*this, _target, level, offset, image); + DataHelper::setSubImage(*this, level, offset, image); return *this; } #ifndef MAGNUM_TARGET_GLES2 - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + */ Texture& setSubImage(Int level, const VectorTypeFor& offset, BufferImage& image) { - DataHelper::setSubImage(*this, _target, level, offset, image); + DataHelper::setSubImage(*this, level, offset, image); return *this; } - /** @overload */ + /** @overload + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES + * 2.0. + */ Texture& setSubImage(Int level, const VectorTypeFor& offset, BufferImage&& image) { return setSubImage(level, offset, image); } @@ -720,11 +771,13 @@ template class Texture: public AbstractTexture { * @brief Generate mipmap * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. - * @see @ref setMinificationFilter(), @fn_gl{ActiveTexture}, - * @fn_gl{BindTexture} and @fn_gl{GenerateMipmap} or - * @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access} + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). + * @see @ref setMinificationFilter(), @fn_gl2{GenerateTextureMipmap,GenerateMipmap}, + * @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{GenerateMipmap} * @requires_gl30 Extension @extension{ARB,framebuffer_object} */ Texture& generateMipmap() { diff --git a/src/Magnum/TextureArray.h b/src/Magnum/TextureArray.h index c6f1d67f1..1b3ccdc2f 100644 --- a/src/Magnum/TextureArray.h +++ b/src/Magnum/TextureArray.h @@ -118,107 +118,179 @@ template class TextureArray: public AbstractTexture { */ explicit TextureArray(): AbstractTexture(Implementation::textureArrayTarget()) {} - #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& setBaseLevel(Int level) { AbstractTexture::setBaseLevel(level); return *this; } - #endif - /** @copydoc Texture::setMaxLevel() */ + /** + * @copybrief Texture::setMaxLevel() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxLevel() for more information. + */ TextureArray& setMaxLevel(Int level) { AbstractTexture::setMaxLevel(level); return *this; } - /** @copydoc Texture::setMinificationFilter() */ + /** + * @copybrief Texture::setMinificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMinificationFilter() for more information. + */ TextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { AbstractTexture::setMinificationFilter(filter, mipmap); return *this; } - /** @copydoc Texture::setMagnificationFilter() */ + /** + * @copybrief Texture::setMagnificationFilter() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMagnificationFilter() for more information. + */ TextureArray& setMagnificationFilter(Sampler::Filter filter) { AbstractTexture::setMagnificationFilter(filter); return *this; } - #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setMinLod() */ + /** + * @copybrief Texture::setMinLod() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMinLod() for more information. + */ TextureArray& setMinLod(Float lod) { AbstractTexture::setMinLod(lod); return *this; } - /** @copydoc Texture::setMaxLod() */ + /** + * @copybrief Texture::setMaxLod() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxLod() for more information. + */ TextureArray& setMaxLod(Float lod) { AbstractTexture::setMaxLod(lod); return *this; } - #endif #ifndef MAGNUM_TARGET_GLES - /** @copydoc Texture::setLodBias() */ + /** + * @copybrief Texture::setLodBias() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setLodBias() for more information. + * @requires_gl Texture LOD bias can be specified only directly in + * fragment shader in OpenGL ES. + */ TextureArray& setLodBias(Float bias) { AbstractTexture::setLodBias(bias); return *this; } #endif - /** @copydoc Texture::setWrapping() */ + /** + * @copybrief Texture::setWrapping() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setWrapping() for more information. + */ TextureArray& setWrapping(const Array& wrapping) { DataHelper::setWrapping(*this, wrapping); return *this; } - /** @copydoc Texture::setBorderColor(const Color4&) */ + /** + * @copybrief Texture::setBorderColor(const Color4&) + * @return Reference to self (for method chaining) + * + * See @ref Texture::setBorderColor(const Color4&) for more + * information. + * @requires_es_extension Extension @es_extension{NV,texture_border_clamp} + */ TextureArray& setBorderColor(const Color4& color) { AbstractTexture::setBorderColor(color); return *this; } #ifndef MAGNUM_TARGET_GLES - /** @copydoc Texture::setBorderColor(const Vector4ui&) */ + /** + * @copybrief Texture::setBorderColor(const Vector4ui&) + * @return Reference to self (for method chaining) + * + * See @ref Texture::setBorderColor(const Vector4ui&) for more + * information. + * @requires_gl30 Extension @extension{EXT,texture_integer} + * @requires_gl Border is available only for float textures in OpenGL + * ES. + */ TextureArray& setBorderColor(const Vector4ui& color) { AbstractTexture::setBorderColor(color); return *this; } - /** @copydoc Texture::setBorderColor(const Vector4i&) */ + /** @overload + * @requires_gl30 Extension @extension{EXT,texture_integer} + * @requires_gl Border is available only for float textures in OpenGL + * ES. + */ TextureArray& setBorderColor(const Vector4i& color) { AbstractTexture::setBorderColor(color); return *this; } #endif - /** @copydoc Texture::setMaxAnisotropy() */ + /** + * @copybrief Texture::setMaxAnisotropy() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setMaxAnisotropy() for more information. + */ TextureArray& setMaxAnisotropy(Float anisotropy) { AbstractTexture::setMaxAnisotropy(anisotropy); return *this; } - /** @copydoc Texture::setSRGBDecode() */ + /** + * @copybrief Texture::setSRGBDecode() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSRGBDecode() for more information. + * @requires_extension Extension @extension{EXT,texture_sRGB_decode} + * @requires_es_extension Extension @es_extension2{EXT,texture_sRGB_decode,texture_sRGB_decode} + */ TextureArray& setSRGBDecode(bool decode) { AbstractTexture::setSRGBDecode(decode); return *this; } - #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::setSwizzle() */ + /** + * @copybrief Texture::setSwizzle() + * @return Reference to self (for method chaining) + * + * See @ref Texture::setSwizzle() for more information. + * @requires_gl33 Extension @extension{ARB,texture_swizzle} + */ template TextureArray& setSwizzle() { AbstractTexture::setSwizzle(); return *this; } - #endif /** * @copybrief Texture::setCompareMode() * @return Reference to self (for method chaining) * * See @ref Texture::setCompareMode() for more information. - * @requires_gles30 Extension @es_extension{EXT,shadow_samplers} and - * @es_extension{NV,shadow_samplers_array} */ TextureArray& setCompareMode(Sampler::CompareMode mode) { AbstractTexture::setCompareMode(mode); @@ -230,113 +302,107 @@ template class TextureArray: public AbstractTexture { * @return Reference to self (for method chaining) * * See @ref Texture::setCompareFunction() for more information. - * @requires_gles30 Extension @es_extension{EXT,shadow_samplers} and - * @es_extension{NV,shadow_samplers_array} */ TextureArray& setCompareFunction(Sampler::CompareFunction function) { AbstractTexture::setCompareFunction(function); return *this; } - #ifndef MAGNUM_TARGET_GLES2 /** * @copybrief Texture::setDepthStencilMode() * @return Reference to self (for method chaining) * * See @ref Texture::setDepthStencilMode() for more information. + * @requires_gl43 Extension @extension{ARB,stencil_texturing} + * @requires_gles31 Stencil texturing is not available in OpenGL ES 3.0 + * and older. */ TextureArray& setDepthStencilMode(Sampler::DepthStencilMode mode) { AbstractTexture::setDepthStencilMode(mode); return *this; } - #endif - - #ifndef MAGNUM_TARGET_GLES2 - /** @copydoc Texture::imageSize() */ - VectorTypeFor imageSize(Int level) { - return DataHelper::imageSize(*this, _target, level); - } - #endif /** - * @brief Set storage - * @param levels Mip level count - * @param internalFormat Internal format - * @param size Size of largest mip level + * @copybrief Texture::setStorage() * @return Reference to self (for method chaining) * - * Specifies entire structure of a texture at once, removing the need - * for additional consistency checks and memory reallocations when - * updating the data later. After calling this function the texture - * is immutable and calling @ref setStorage() or @ref setImage() is not - * allowed. - * - * If @extension{EXT,direct_state_access} is not available, the texture - * is bound to some texture unit before the operation. If - * @extension{ARB,texture_storage} (part of OpenGL 4.2) or OpenGL ES - * 3.0 is not available, the feature is emulated with sequence of - * @ref setImage() calls. - * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexStorage2D}/@fn_gl{TexStorage3D} or - * @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureStorage3D,EXT,direct_state_access}, - * eventually @fn_gl{TexImage2D}/@fn_gl{TexImage3D} or - * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureImage3D,EXT,direct_state_access}. + * See @ref Texture::setStorage() for more information. + * @see @ref maxSize() */ TextureArray& setStorage(Int levels, TextureFormat internalFormat, const VectorTypeFor& size) { - DataHelper::setStorage(*this, _target, levels, internalFormat, size); + DataHelper::setStorage(*this, levels, internalFormat, size); return *this; } + /** + * @copybrief Texture::imageSize() + * + * See @ref Texture::imageSize() for more information. + * @requires_gles31 Texture image size queries are not available in + * OpenGL ES 3.0 and older. + */ + VectorTypeFor imageSize(Int level) { + return DataHelper::imageSize(*this, level); + } + #ifndef MAGNUM_TARGET_GLES - /** @copydoc Texture::image(Int, Image&) */ + /** + * @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& image) { - AbstractTexture::image(_target, level, image); + AbstractTexture::image(level, image); } - /** @copydoc Texture::imate(Int, BufferImage&, 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& image, BufferUsage usage) { - AbstractTexture::image(_target, level, image, usage); + AbstractTexture::image(level, image, usage); } #endif /** - * @brief Set image data - * @param level Mip level - * @param internalFormat Internal format - * @param image @ref Image, @ref ImageReference or - * @ref Trade::ImageData of the same dimension count + * @copybrief Texture::setImage() * @return Reference to self (for method chaining) * - * On platforms that support it prefer to use @ref setStorage() and - * @ref setSubImage() instead, as it avoids unnecessary reallocations - * and has better performance characteristics. This call also has no - * equivalent in @extension{ARB,direct_state_access}, thus the texture - * needs to be bound to some texture unit before the operation. - * @see @ref maxSize(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and - * @fn_gl{TexImage2D}/@fn_gl{TexImage3D} + * See @ref Texture::setImage() for more information. + * @see @ref maxSize() * @deprecated_gl Prefer to use @ref Magnum::TextureArray::setStorage() "setStorage()" * and @ref Magnum::TextureArray::setSubImage() "setSubImage()" * instead. */ TextureArray& setImage(Int level, TextureFormat internalFormat, const ImageReference& image) { - DataHelper::setImage(*this, _target, level, internalFormat, image); + DataHelper::setImage(*this, level, internalFormat, image); return *this; } - #ifndef MAGNUM_TARGET_GLES2 - /** @overload */ + /** @overload + * @deprecated_gl Prefer to use @ref Magnum::TextureArray::setStorage() "setStorage()" + * and @ref Magnum::TextureArray::setSubImage() "setSubImage()" + * instead. + */ TextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage& image) { - DataHelper::setImage(*this, _target, level, internalFormat, image); + DataHelper::setImage(*this, level, internalFormat, image); return *this; } - /** @overload */ + /** @overload + * @deprecated_gl Prefer to use @ref Magnum::TextureArray::setStorage() "setStorage()" + * and @ref Magnum::TextureArray::setSubImage() "setSubImage()" + * instead. + */ TextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage&& image) { return setImage(level, internalFormat, image); } - #endif /** * @brief Set image subdata @@ -346,22 +412,24 @@ template class TextureArray: public AbstractTexture { * @ref Trade::ImageData of the same dimension count * @return Reference to self (for method chaining) * - * If @extension{EXT,direct_state_access} is not available, the - * texture is bound to some texture unit before the operation. - * @see @ref setStorage(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} - * and @fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D} or + * If on OpenGL ES or neither @extension{ARB,direct_state_access} (part + * of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available, + * the texture is bound before the operation (if not already). + * @see @ref setStorage(), @fn_gl2{TextureSubImage2D,TexSubImage2D}/ + * @fn_gl2{TextureSubImage3D,TexSubImage3D}, * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ - * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} + * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access}, + * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and + * @fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D} */ TextureArray& setSubImage(Int level, const VectorTypeFor& offset, const ImageReference& image) { - DataHelper::setSubImage(*this, _target, level, offset, image); + DataHelper::setSubImage(*this, level, offset, image); return *this; } - #ifndef MAGNUM_TARGET_GLES2 /** @overload */ TextureArray& setSubImage(Int level, const VectorTypeFor& offset, BufferImage& image) { - DataHelper::setSubImage(*this, _target, level, offset, image); + DataHelper::setSubImage(*this, level, offset, image); return *this; } @@ -369,18 +437,33 @@ template class TextureArray: public AbstractTexture { TextureArray& setSubImage(Int level, const VectorTypeFor& offset, BufferImage&& 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& generateMipmap() { AbstractTexture::generateMipmap(); return *this; } - /** @copydoc Texture::invalidateImage() */ + /** + * @copybrief Texture::invalidateImage() + * @return Reference to self (for method chaining) + * + * See @ref Texture::invalidateImage() for more information. + */ void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); } - /** @copydoc Texture::invalidateSubImage() */ + /** + * @copybrief Texture::invalidateSubImage() + * @return Reference to self (for method chaining) + * + * See @ref Texture::invalidateSubImage() for more information. + */ void invalidateSubImage(Int level, const VectorTypeFor& offset, const VectorTypeFor& size) { DataHelper::invalidateSubImage(*this, level, offset, size); }