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); }