Browse Source

Compressed image support, part 15: compressed subimage download.

NVidia reports compressed block data size in bits instead of bytes, thus
all the test currently fail. (Another) workaround incoming.
pull/132/head
Vladimír Vondruš 11 years ago
parent
commit
645edecbcd
  1. 2
      doc/opengl-mapping.dox
  2. 2
      doc/opengl-support.dox
  3. 58
      src/Magnum/AbstractTexture.cpp
  4. 6
      src/Magnum/AbstractTexture.h
  5. 10
      src/Magnum/CubeMapTexture.cpp
  6. 44
      src/Magnum/CubeMapTexture.h
  7. 10
      src/Magnum/CubeMapTextureArray.cpp
  8. 44
      src/Magnum/CubeMapTextureArray.h
  9. 10
      src/Magnum/RectangleTexture.cpp
  10. 40
      src/Magnum/RectangleTexture.h
  11. 72
      src/Magnum/Test/CubeMapTextureArrayGLTest.cpp
  12. 78
      src/Magnum/Test/CubeMapTextureGLTest.cpp
  13. 12
      src/Magnum/Test/RectangleTextureGLTest.cpp
  14. 84
      src/Magnum/Test/TextureArrayGLTest.cpp
  15. 156
      src/Magnum/Test/TextureGLTest.cpp
  16. 10
      src/Magnum/Texture.cpp
  17. 55
      src/Magnum/Texture.h
  18. 10
      src/Magnum/TextureArray.cpp
  19. 44
      src/Magnum/TextureArray.h

2
doc/opengl-mapping.dox

@ -175,7 +175,7 @@ OpenGL function | Matching API
@fn_gl2{GetBufferPointer,GetBufferPointerv}, \n `glGetNamedBufferPointer()`, \n @fn_gl_extension{GetNamedBufferPointer,EXT,direct_state_access} | not queryable, @ref Buffer::map() setter only @fn_gl2{GetBufferPointer,GetBufferPointerv}, \n `glGetNamedBufferPointer()`, \n @fn_gl_extension{GetNamedBufferPointer,EXT,direct_state_access} | not queryable, @ref Buffer::map() setter only
@fn_gl{GetBufferSubData}, \n `glGetNamedBufferSubData()`, \n @fn_gl_extension{GetNamedBufferSubData,EXT,direct_state_access} | @ref Buffer::data(), \n @ref Buffer::subData() @fn_gl{GetBufferSubData}, \n `glGetNamedBufferSubData()`, \n @fn_gl_extension{GetNamedBufferSubData,EXT,direct_state_access} | @ref Buffer::data(), \n @ref Buffer::subData()
@fn_gl{GetCompressedTexImage}, \n `glGetnCompressedTexImage()`, \n @fn_gl_extension{GetnCompressedTexImage,ARB,robustness}, \n `glGetCompressedTextureImage()`, \n @fn_gl_extension{GetCompressedTextureImage,EXT,direct_state_access} | @ref Texture::compressedImage(), \n @ref TextureArray::compressedImage(), \n @ref CubeMapTexture::compressedImage(), \n @ref CubeMapTextureArray::compressedImage(), \n @ref RectangleTexture::compressedImage() @fn_gl{GetCompressedTexImage}, \n `glGetnCompressedTexImage()`, \n @fn_gl_extension{GetnCompressedTexImage,ARB,robustness}, \n `glGetCompressedTextureImage()`, \n @fn_gl_extension{GetCompressedTextureImage,EXT,direct_state_access} | @ref Texture::compressedImage(), \n @ref TextureArray::compressedImage(), \n @ref CubeMapTexture::compressedImage(), \n @ref CubeMapTextureArray::compressedImage(), \n @ref RectangleTexture::compressedImage()
@fn_gl{GetCompressedTextureSubImage} | | @fn_gl{GetCompressedTextureSubImage} | @ref Texture::compressedSubImage(), \n @ref TextureArray::compressedSubImage(), \n @ref CubeMapTexture::compressedImage(), \n @ref CubeMapTexture::compressedSubImage(), \n @ref CubeMapTextureArray::compressedSubImage(), \n @ref RectangleTexture::compressedSubImage()
@fn_gl{GetDebugMessageLog} | | @fn_gl{GetDebugMessageLog} | |
@fn_gl{GetError} | @ref Renderer::error() @fn_gl{GetError} | @ref Renderer::error()
@fn_gl{GetFragDataIndex}, @fn_gl{GetFragDataLocation} | not queryable, @ref AbstractShaderProgram::bindFragmentDataLocation() and \n @ref AbstractShaderProgram::bindFragmentDataLocationIndexed() setters only @fn_gl{GetFragDataIndex}, @fn_gl{GetFragDataLocation} | not queryable, @ref AbstractShaderProgram::bindFragmentDataLocation() and \n @ref AbstractShaderProgram::bindFragmentDataLocationIndexed() setters only

2
doc/opengl-support.dox

@ -222,7 +222,7 @@ GLSL 4.50 | done
@extension{ARB,cull_distance} | | @extension{ARB,cull_distance} | |
@extension{ARB,derivative_control} | done (shading language only) @extension{ARB,derivative_control} | done (shading language only)
@extension{ARB,direct_state_access} | done for implemented functionality (except VAOs) @extension{ARB,direct_state_access} | done for implemented functionality (except VAOs)
@extension{ARB,get_texture_sub_image} | missing compressed texture queries @extension{ARB,get_texture_sub_image} | done
@extension{ARB,shader_texture_image_samples} | done (shading language only) @extension{ARB,shader_texture_image_samples} | done (shading language only)
@extension{ARB,texture_barrier} | | @extension{ARB,texture_barrier} | |
@extension{KHR,context_flush_control} | | @extension{KHR,context_flush_control} | |

58
src/Magnum/AbstractTexture.cpp

@ -1629,6 +1629,64 @@ template<UnsignedInt dimensions> void AbstractTexture::subImage(const GLint leve
template void MAGNUM_EXPORT AbstractTexture::subImage<1>(GLint, const Range1Di&, BufferImage<1>&, BufferUsage); template void MAGNUM_EXPORT AbstractTexture::subImage<1>(GLint, const Range1Di&, BufferImage<1>&, BufferUsage);
template void MAGNUM_EXPORT AbstractTexture::subImage<2>(GLint, const Range2Di&, BufferImage<2>&, BufferUsage); template void MAGNUM_EXPORT AbstractTexture::subImage<2>(GLint, const Range2Di&, BufferImage<2>&, BufferUsage);
template void MAGNUM_EXPORT AbstractTexture::subImage<3>(GLint, const Range3Di&, BufferImage<3>&, BufferUsage); template void MAGNUM_EXPORT AbstractTexture::subImage<3>(GLint, const Range3Di&, BufferImage<3>&, BufferUsage);
template<UnsignedInt dimensions> std::size_t AbstractTexture::compressedSubImageSize(TextureFormat format, const Math::Vector<dimensions, Int>& size) {
/* Amount of blocks in given range (rounded up) multiplied by block
data size. The user is responsible for proper block-aligned size. */
const Math::Vector<dimensions, Int> blockSize = DataHelper<dimensions>::compressedBlockSize(_target, format);
return ((size + blockSize - Math::Vector<dimensions, Int>{1})/blockSize).product()*
compressedBlockDataSize(_target, format);
}
template<UnsignedInt dimensions> void AbstractTexture::compressedSubImage(const GLint level, const RangeTypeFor<dimensions, Int>& range, CompressedImage<dimensions>& image) {
createIfNotAlready();
const Math::Vector<dimensions, Int> size = range.size();
const Vector3i paddedOffset = Vector3i::pad(range.min());
const Vector3i paddedSize = Vector3i::pad(size, 1);
GLint format;
(this->*Context::current()->state().texture->getLevelParameterivImplementation)(level, GL_TEXTURE_INTERNAL_FORMAT, &format);
const std::size_t dataSize = Implementation::compressedImageDataSizeFor(image, size, compressedSubImageSize<dimensions>(TextureFormat(format), size));
/* Reallocate only if needed */
Containers::Array<char> data{image.release()};
if(data.size() < dataSize)
data = Containers::Array<char>{dataSize};
Buffer::unbindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
glGetCompressedTextureSubImage(_id, level, paddedOffset.x(), paddedOffset.y(), paddedOffset.z(), paddedSize.x(), paddedSize.y(), paddedSize.z(), data.size(), data);
image.setData(CompressedPixelFormat(format), size, std::move(data));
}
template void MAGNUM_EXPORT AbstractTexture::compressedSubImage<1>(GLint, const Range1Di&, CompressedImage<1>&);
template void MAGNUM_EXPORT AbstractTexture::compressedSubImage<2>(GLint, const Range2Di&, CompressedImage<2>&);
template void MAGNUM_EXPORT AbstractTexture::compressedSubImage<3>(GLint, const Range3Di&, CompressedImage<3>&);
template<UnsignedInt dimensions> void AbstractTexture::compressedSubImage(const GLint level, const RangeTypeFor<dimensions, Int>& range, CompressedBufferImage<dimensions>& image, const BufferUsage usage) {
createIfNotAlready();
const Math::Vector<dimensions, Int> size = range.size();
const Vector3i paddedOffset = Vector3i::pad(range.min());
const Vector3i paddedSize = Vector3i::pad(size, 1);
GLint format;
(this->*Context::current()->state().texture->getLevelParameterivImplementation)(level, GL_TEXTURE_INTERNAL_FORMAT, &format);
const std::size_t dataSize = Implementation::compressedImageDataSizeFor(image, size, compressedSubImageSize<dimensions>(TextureFormat(format), size));
/* Reallocate only if needed */
if(image.dataSize() < dataSize)
image.setData(image.storage(), CompressedPixelFormat(format), size, {nullptr, dataSize}, usage);
else
image.setData(image.storage(), CompressedPixelFormat(format), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
glGetCompressedTextureSubImage(_id, level, paddedOffset.x(), paddedOffset.y(), paddedOffset.z(), paddedSize.x(), paddedSize.y(), paddedSize.z(), dataSize, nullptr);
}
template void MAGNUM_EXPORT AbstractTexture::compressedSubImage<1>(GLint, const Range1Di&, CompressedBufferImage<1>&, BufferUsage);
template void MAGNUM_EXPORT AbstractTexture::compressedSubImage<2>(GLint, const Range2Di&, CompressedBufferImage<2>&, BufferUsage);
template void MAGNUM_EXPORT AbstractTexture::compressedSubImage<3>(GLint, const Range3Di&, CompressedBufferImage<3>&, BufferUsage);
#endif #endif
#endif #endif

6
src/Magnum/AbstractTexture.h

@ -409,6 +409,8 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
template<UnsignedInt dimensions> void compressedImage(GLint level, CompressedBufferImage<dimensions>& image, BufferUsage usage); template<UnsignedInt dimensions> void compressedImage(GLint level, CompressedBufferImage<dimensions>& image, BufferUsage usage);
template<UnsignedInt dimensions> void subImage(GLint level, const RangeTypeFor<dimensions, Int>& range, Image<dimensions>& image); template<UnsignedInt dimensions> void subImage(GLint level, const RangeTypeFor<dimensions, Int>& range, Image<dimensions>& image);
template<UnsignedInt dimensions> void subImage(GLint level, const RangeTypeFor<dimensions, Int>& range, BufferImage<dimensions>& image, BufferUsage usage); template<UnsignedInt dimensions> void subImage(GLint level, const RangeTypeFor<dimensions, Int>& range, BufferImage<dimensions>& image, BufferUsage usage);
template<UnsignedInt dimensions> void compressedSubImage(GLint level, const RangeTypeFor<dimensions, Int>& range, CompressedImage<dimensions>& image);
template<UnsignedInt dimensions> void compressedSubImage(GLint level, const RangeTypeFor<dimensions, Int>& range, CompressedBufferImage<dimensions>& image, BufferUsage usage);
#endif #endif
GLenum _target; GLenum _target;
@ -431,6 +433,10 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void MAGNUM_LOCAL createImplementationDSA(); void MAGNUM_LOCAL createImplementationDSA();
#endif #endif
#ifndef MAGNUM_TARGET_GLES
template<UnsignedInt dimensions> std::size_t MAGNUM_LOCAL compressedSubImageSize(TextureFormat format, const Math::Vector<dimensions, Int>& size);
#endif
void MAGNUM_LOCAL bindImplementationDefault(GLint textureUnit); void MAGNUM_LOCAL bindImplementationDefault(GLint textureUnit);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL bindImplementationMulti(GLint textureUnit); void MAGNUM_LOCAL bindImplementationMulti(GLint textureUnit);

10
src/Magnum/CubeMapTexture.cpp

@ -257,6 +257,16 @@ BufferImage3D CubeMapTexture::subImage(const Int level, const Range3Di& range, B
return std::move(image); return std::move(image);
} }
CompressedImage3D CubeMapTexture::compressedSubImage(const Int level, const Range3Di& range, CompressedImage3D&& image) {
compressedSubImage(level, range, image);
return std::move(image);
}
CompressedBufferImage3D CubeMapTexture::compressedSubImage(const Int level, const Range3Di& range, CompressedBufferImage3D&& image, const BufferUsage usage) {
compressedSubImage(level, range, image, usage);
return std::move(image);
}
CubeMapTexture& CubeMapTexture::setSubImage(const Int level, const Vector3i& offset, const ImageView3D& image) { CubeMapTexture& CubeMapTexture::setSubImage(const Int level, const Vector3i& offset, const ImageView3D& image) {
createIfNotAlready(); createIfNotAlready();

44
src/Magnum/CubeMapTexture.h

@ -721,6 +721,50 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
* @endcode * @endcode
*/ */
BufferImage3D subImage(Int level, const Range3Di& range, BufferImage3D&& image, BufferUsage usage); BufferImage3D subImage(Int level, const Range3Di& range, BufferImage3D&& image, BufferUsage usage);
/**
* @copybrief Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedImage&)
*
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedImage&)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() for possible workaround.
*/
void compressedSubImage(Int level, const Range3Di& range, CompressedImage3D& image) {
AbstractTexture::compressedSubImage<3>(level, range, image);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* CompressedImage3D image = texture.compressedSubImage(0, range, {});
* @endcode
*/
CompressedImage3D compressedSubImage(Int level, const Range3Di& range, CompressedImage3D&& image);
/**
* @copybrief Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
*
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() for possible workaround.
*/
void compressedSubImage(Int level, const Range3Di& range, CompressedBufferImage3D& image, BufferUsage usage) {
AbstractTexture::compressedSubImage<3>(level, range, image, usage);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* CompressedBufferImage3D image = texture.compressedSubImage(0, range, {}, BufferUsage::StaticRead);
* @endcode
*/
CompressedBufferImage3D compressedSubImage(Int level, const Range3Di& range, CompressedBufferImage3D&& image, BufferUsage usage);
#endif #endif
/** /**

10
src/Magnum/CubeMapTextureArray.cpp

@ -78,6 +78,16 @@ BufferImage3D CubeMapTextureArray::subImage(const Int level, const Range3Di& ran
this->subImage(level, range, image, usage); this->subImage(level, range, image, usage);
return std::move(image); return std::move(image);
} }
CompressedImage3D CubeMapTextureArray::compressedSubImage(const Int level, const Range3Di& range, CompressedImage3D&& image) {
compressedSubImage(level, range, image);
return std::move(image);
}
CompressedBufferImage3D CubeMapTextureArray::compressedSubImage(const Int level, const Range3Di& range, CompressedBufferImage3D&& image, const BufferUsage usage) {
compressedSubImage(level, range, image, usage);
return std::move(image);
}
#endif #endif
} }

44
src/Magnum/CubeMapTextureArray.h

@ -526,6 +526,50 @@ class MAGNUM_EXPORT CubeMapTextureArray: public AbstractTexture {
* @endcode * @endcode
*/ */
BufferImage3D subImage(Int level, const Range3Di& range, BufferImage3D&& image, BufferUsage usage); BufferImage3D subImage(Int level, const Range3Di& range, BufferImage3D&& image, BufferUsage usage);
/**
* @copybrief Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedImage&)
*
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedImage&)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES.
* See @ref Framebuffer::read() for possible workaround.
*/
void compressedSubImage(Int level, const Range3Di& range, CompressedImage3D& image) {
AbstractTexture::compressedSubImage<3>(level, range, image);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* CompressedImage3D image = texture.compressedSubImage(0, range, {});
* @endcode
*/
CompressedImage3D compressedSubImage(Int level, const Range3Di& range, CompressedImage3D&& image);
/**
* @copybrief Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
*
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES.
* See @ref Framebuffer::read() for possible workaround.
*/
void compressedSubImage(Int level, const Range3Di& range, CompressedBufferImage3D& image, BufferUsage usage) {
AbstractTexture::compressedSubImage<3>(level, range, image, usage);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* CompressedBufferImage3D image = texture.compressedSubImage(0, range, {}, BufferUsage::StaticRead);
* @endcode
*/
CompressedBufferImage3D compressedSubImage(Int level, const Range3Di& range, CompressedBufferImage3D&& image, BufferUsage usage);
#endif #endif
/** /**

10
src/Magnum/RectangleTexture.cpp

@ -78,5 +78,15 @@ BufferImage2D RectangleTexture::subImage(const Range2Di& range, BufferImage2D&&
return std::move(image); return std::move(image);
} }
CompressedImage2D RectangleTexture::compressedSubImage(const Range2Di& range, CompressedImage2D&& image) {
compressedSubImage(range, image);
return std::move(image);
}
CompressedBufferImage2D RectangleTexture::compressedSubImage(const Range2Di& range, CompressedBufferImage2D&& image, const BufferUsage usage) {
compressedSubImage(range, image, usage);
return std::move(image);
}
} }
#endif #endif

40
src/Magnum/RectangleTexture.h

@ -414,6 +414,46 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture {
*/ */
BufferImage2D subImage(const Range2Di& range, BufferImage2D&& image, BufferUsage usage); BufferImage2D subImage(const Range2Di& range, BufferImage2D&& image, BufferUsage usage);
/**
* @copybrief Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedImage&)
*
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedImage&)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
*/
void compressedSubImage(const Range2Di& range, CompressedImage2D& image) {
AbstractTexture::compressedSubImage<2>(0, range, image);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* CompressedImage2D image = texture.compressedSubImage(range, {});
* @endcode
*/
CompressedImage2D compressedSubImage(const Range2Di& range, CompressedImage2D&& image);
/**
* @copybrief Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
*
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
*/
void compressedSubImage(const Range2Di& range, CompressedBufferImage2D& image, BufferUsage usage) {
AbstractTexture::compressedSubImage<2>(0, range, image, usage);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* CompressedBufferImage2D image = texture.compressedSubImage(range, {}, BufferUsage::StaticRead);
* @endcode
*/
CompressedBufferImage2D compressedSubImage(const Range2Di& range, CompressedBufferImage2D&& image, BufferUsage usage);
/** /**
* @copybrief Texture::setImage() * @copybrief Texture::setImage()
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)

72
src/Magnum/Test/CubeMapTextureArrayGLTest.cpp

@ -66,7 +66,9 @@ struct CubeMapTextureArrayGLTest: AbstractOpenGLTester {
void compressedSubImageBuffer(); void compressedSubImageBuffer();
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void subImageQuery(); void subImageQuery();
void compressedSubImageQuery();
void subImageQueryBuffer(); void subImageQueryBuffer();
void compressedSubImageQueryBuffer();
#endif #endif
void generateMipmap(); void generateMipmap();
@ -109,7 +111,9 @@ CubeMapTextureArrayGLTest::CubeMapTextureArrayGLTest() {
&CubeMapTextureArrayGLTest::compressedSubImageBuffer, &CubeMapTextureArrayGLTest::compressedSubImageBuffer,
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
&CubeMapTextureArrayGLTest::subImageQuery, &CubeMapTextureArrayGLTest::subImageQuery,
&CubeMapTextureArrayGLTest::compressedSubImageQuery,
&CubeMapTextureArrayGLTest::subImageQueryBuffer, &CubeMapTextureArrayGLTest::subImageQueryBuffer,
&CubeMapTextureArrayGLTest::compressedSubImageQueryBuffer,
#endif #endif
&CubeMapTextureArrayGLTest::generateMipmap, &CubeMapTextureArrayGLTest::generateMipmap,
@ -840,6 +844,41 @@ void CubeMapTextureArrayGLTest::subImageQuery() {
Containers::ArrayView<const UnsignedByte>{SubData}, TestSuite::Compare::Container); Containers::ArrayView<const UnsignedByte>{SubData}, TestSuite::Compare::Container);
} }
void CubeMapTextureArrayGLTest::compressedSubImageQuery() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_cube_map_array>())
CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_compression_s3tc>())
CORRADE_SKIP(Extensions::GL::EXT::texture_compression_s3tc::string() + std::string(" is not supported."));
CubeMapTextureArray texture;
texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {12, 12, 6})
.setCompressedSubImage(0, {}, CompressedImageView3D{CompressedPixelFormat::RGBAS3tcDxt3, {12, 12, 6}, CompressedSubDataComplete});
MAGNUM_VERIFY_NO_ERROR();
/* Test also without compressed pixel storage to ensure that both size
computations work */
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::compressed_texture_pixel_storage>()) {
CompressedImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 4, 1}, Vector3i{4}), {});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i{4});
CORRADE_COMPARE_AS(
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}),
Containers::ArrayView<const UnsignedByte>{CompressedSubData}, TestSuite::Compare::Container);
}
CompressedImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 4, 1}, Vector3i{4}), {_compressedSubDataStorage});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i{4});
CORRADE_COMPARE_AS(
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(_compressedSubDataOffset)),
Containers::ArrayView<const UnsignedByte>{CompressedSubData}, TestSuite::Compare::Container);
}
void CubeMapTextureArrayGLTest::subImageQueryBuffer() { void CubeMapTextureArrayGLTest::subImageQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_cube_map_array>()) if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_cube_map_array>())
CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported."));
@ -862,6 +901,39 @@ void CubeMapTextureArrayGLTest::subImageQueryBuffer() {
CORRADE_COMPARE_AS(imageData.suffix(SubDataOffset), CORRADE_COMPARE_AS(imageData.suffix(SubDataOffset),
Containers::ArrayView<const UnsignedByte>{SubData}, TestSuite::Compare::Container); Containers::ArrayView<const UnsignedByte>{SubData}, TestSuite::Compare::Container);
} }
void CubeMapTextureArrayGLTest::compressedSubImageQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_cube_map_array>())
CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_compression_s3tc>())
CORRADE_SKIP(Extensions::GL::EXT::texture_compression_s3tc::string() + std::string(" is not supported."));
CubeMapTextureArray texture;
texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {12, 12, 6})
.setCompressedSubImage(0, {}, CompressedImageView3D{CompressedPixelFormat::RGBAS3tcDxt3, {12, 12, 6}, CompressedSubDataComplete});
MAGNUM_VERIFY_NO_ERROR();
/* Test also without compressed pixel storage to ensure that both size
computations work */
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::compressed_texture_pixel_storage>()) {
CompressedBufferImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 4, 1}, Vector3i{4}), {}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i{4});
CORRADE_COMPARE_AS(imageData, Containers::ArrayView<const UnsignedByte>{CompressedSubData}, TestSuite::Compare::Container);
}
CompressedBufferImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 4, 1}, Vector3i{4}), {_compressedSubDataStorage}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i{4});
CORRADE_COMPARE_AS(imageData.suffix(_compressedSubDataOffset), Containers::ArrayView<const UnsignedByte>{CompressedSubData}, TestSuite::Compare::Container);
}
#endif #endif
void CubeMapTextureArrayGLTest::generateMipmap() { void CubeMapTextureArrayGLTest::generateMipmap() {

78
src/Magnum/Test/CubeMapTextureGLTest.cpp

@ -90,7 +90,9 @@ struct CubeMapTextureGLTest: AbstractOpenGLTester {
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void subImageQuery(); void subImageQuery();
void compressedSubImageQuery();
void subImageQueryBuffer(); void subImageQueryBuffer();
void compressedSubImageQueryBuffer();
#endif #endif
void generateMipmap(); void generateMipmap();
@ -157,7 +159,9 @@ CubeMapTextureGLTest::CubeMapTextureGLTest() {
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
&CubeMapTextureGLTest::subImageQuery, &CubeMapTextureGLTest::subImageQuery,
&CubeMapTextureGLTest::compressedSubImageQuery,
&CubeMapTextureGLTest::subImageQueryBuffer, &CubeMapTextureGLTest::subImageQueryBuffer,
&CubeMapTextureGLTest::compressedSubImageQueryBuffer,
#endif #endif
&CubeMapTextureGLTest::generateMipmap, &CubeMapTextureGLTest::generateMipmap,
@ -991,6 +995,44 @@ void CubeMapTextureGLTest::subImageQuery() {
Containers::ArrayView<const UnsignedByte>{Data}, TestSuite::Compare::Container); Containers::ArrayView<const UnsignedByte>{Data}, TestSuite::Compare::Container);
} }
void CubeMapTextureGLTest::compressedSubImageQuery() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
/* I'm too lazy to call setSubImage() six times */
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::direct_state_access>())
CORRADE_SKIP(Extensions::GL::ARB::direct_state_access::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_compression_s3tc>())
CORRADE_SKIP(Extensions::GL::EXT::texture_compression_s3tc::string() + std::string(" is not supported."));
CubeMapTexture texture;
texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, Vector2i{12})
.setCompressedSubImage(0, {}, CompressedImageView3D{CompressedPixelFormat::RGBAS3tcDxt3, {12, 12, 1}, CompressedSubDataComplete});
MAGNUM_VERIFY_NO_ERROR();
/* Test also without compressed pixel storage to ensure that both size
computations work */
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::compressed_texture_pixel_storage>()) {
CompressedImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 4, 0}, {4, 4, 1}), {});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), (Vector3i{4, 4, 1}));
CORRADE_COMPARE_AS(
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}),
Containers::ArrayView<const UnsignedByte>{CompressedData}, TestSuite::Compare::Container);
}
CompressedImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 4, 0}, {4, 4, 1}), {_compressedDataStorage});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), (Vector3i{4, 4, 1}));
CORRADE_COMPARE_AS(
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(_compressedDataOffset)),
Containers::ArrayView<const UnsignedByte>{CompressedData}, TestSuite::Compare::Container);
}
void CubeMapTextureGLTest::subImageQueryBuffer() { void CubeMapTextureGLTest::subImageQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>()) if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
@ -1013,6 +1055,42 @@ void CubeMapTextureGLTest::subImageQueryBuffer() {
CORRADE_COMPARE(image.size(), Vector3i(2, 2, 1)); CORRADE_COMPARE(image.size(), Vector3i(2, 2, 1));
CORRADE_COMPARE_AS(imageData.suffix(_dataOffset), Containers::ArrayView<const UnsignedByte>{Data}, TestSuite::Compare::Container); CORRADE_COMPARE_AS(imageData.suffix(_dataOffset), Containers::ArrayView<const UnsignedByte>{Data}, TestSuite::Compare::Container);
} }
void CubeMapTextureGLTest::compressedSubImageQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
/* I'm too lazy to call setSubImage() six times */
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::direct_state_access>())
CORRADE_SKIP(Extensions::GL::ARB::direct_state_access::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_compression_s3tc>())
CORRADE_SKIP(Extensions::GL::EXT::texture_compression_s3tc::string() + std::string(" is not supported."));
CubeMapTexture texture;
texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, Vector2i{12})
.setCompressedSubImage(0, {}, CompressedImageView3D{CompressedPixelFormat::RGBAS3tcDxt3, {12, 12, 1}, CompressedSubDataComplete});
MAGNUM_VERIFY_NO_ERROR();
/* Test also without compressed pixel storage to ensure that both size
computations work */
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::compressed_texture_pixel_storage>()) {
CompressedBufferImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 4, 0}, {4, 4, 1}), {}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), (Vector3i{4, 4, 1}));
CORRADE_COMPARE_AS(imageData, Containers::ArrayView<const UnsignedByte>{CompressedData}, TestSuite::Compare::Container);
}
CompressedBufferImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 4, 0}, {4, 4, 1}), {_compressedDataStorage}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), (Vector3i{4, 4, 1}));
CORRADE_COMPARE_AS(imageData.suffix(_compressedDataOffset), Containers::ArrayView<const UnsignedByte>{CompressedData}, TestSuite::Compare::Container);
}
#endif #endif
void CubeMapTextureGLTest::generateMipmap() { void CubeMapTextureGLTest::generateMipmap() {

12
src/Magnum/Test/RectangleTextureGLTest.cpp

@ -64,7 +64,9 @@ struct RectangleTextureGLTest: AbstractOpenGLTester {
void subImageBuffer(); void subImageBuffer();
void compressedSubImageBuffer(); void compressedSubImageBuffer();
void subImageQuery(); void subImageQuery();
void compressedSubImageQuery();
void subImageQueryBuffer(); void subImageQueryBuffer();
void compressedSubImageQueryBuffer();
void invalidateImage(); void invalidateImage();
void invalidateSubImage(); void invalidateSubImage();
@ -95,7 +97,9 @@ RectangleTextureGLTest::RectangleTextureGLTest() {
&RectangleTextureGLTest::subImageBuffer, &RectangleTextureGLTest::subImageBuffer,
&RectangleTextureGLTest::compressedSubImageBuffer, &RectangleTextureGLTest::compressedSubImageBuffer,
&RectangleTextureGLTest::subImageQuery, &RectangleTextureGLTest::subImageQuery,
&RectangleTextureGLTest::compressedSubImageQuery,
&RectangleTextureGLTest::subImageQueryBuffer, &RectangleTextureGLTest::subImageQueryBuffer,
&RectangleTextureGLTest::compressedSubImageQueryBuffer,
&RectangleTextureGLTest::invalidateImage, &RectangleTextureGLTest::invalidateImage,
&RectangleTextureGLTest::invalidateSubImage}); &RectangleTextureGLTest::invalidateSubImage});
@ -398,6 +402,10 @@ void RectangleTextureGLTest::subImageQuery() {
Containers::ArrayView<const UnsignedByte>{Data}, TestSuite::Compare::Container); Containers::ArrayView<const UnsignedByte>{Data}, TestSuite::Compare::Container);
} }
void RectangleTextureGLTest::compressedSubImageQuery() {
CORRADE_SKIP("No rectangle texture compression format exists.");
}
void RectangleTextureGLTest::subImageQueryBuffer() { void RectangleTextureGLTest::subImageQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>()) if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));
@ -421,6 +429,10 @@ void RectangleTextureGLTest::subImageQueryBuffer() {
Containers::ArrayView<const UnsignedByte>{Data}, TestSuite::Compare::Container); Containers::ArrayView<const UnsignedByte>{Data}, TestSuite::Compare::Container);
} }
void RectangleTextureGLTest::compressedSubImageQueryBuffer() {
CORRADE_SKIP("No rectangle texture compression format exists.");
}
void RectangleTextureGLTest::invalidateImage() { void RectangleTextureGLTest::invalidateImage() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>()) if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));

84
src/Magnum/Test/TextureArrayGLTest.cpp

@ -117,7 +117,9 @@ struct TextureArrayGLTest: AbstractOpenGLTester {
void subImage1DBuffer(); void subImage1DBuffer();
void compressedSubImage1DBuffer(); void compressedSubImage1DBuffer();
void subImage1DQuery(); void subImage1DQuery();
void compressedSubImage1DQuery();
void subImage1DQueryBuffer(); void subImage1DQueryBuffer();
void compressedSubImage1DQueryBuffer();
#endif #endif
void subImage2D(); void subImage2D();
void compressedSubImage2D(); void compressedSubImage2D();
@ -125,7 +127,9 @@ struct TextureArrayGLTest: AbstractOpenGLTester {
void compressedSubImage2DBuffer(); void compressedSubImage2DBuffer();
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void subImage2DQuery(); void subImage2DQuery();
void compressedSubImage2DQuery();
void subImage2DQueryBuffer(); void subImage2DQueryBuffer();
void compressedSubImage2DQueryBuffer();
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -225,7 +229,9 @@ TextureArrayGLTest::TextureArrayGLTest() {
&TextureArrayGLTest::subImage1DBuffer, &TextureArrayGLTest::subImage1DBuffer,
&TextureArrayGLTest::compressedSubImage1DBuffer, &TextureArrayGLTest::compressedSubImage1DBuffer,
&TextureArrayGLTest::subImage1DQuery, &TextureArrayGLTest::subImage1DQuery,
&TextureArrayGLTest::compressedSubImage1DQuery,
&TextureArrayGLTest::subImage1DQueryBuffer, &TextureArrayGLTest::subImage1DQueryBuffer,
&TextureArrayGLTest::compressedSubImage1DQueryBuffer,
#endif #endif
&TextureArrayGLTest::subImage2D, &TextureArrayGLTest::subImage2D,
&TextureArrayGLTest::compressedSubImage2D, &TextureArrayGLTest::compressedSubImage2D,
@ -233,7 +239,9 @@ TextureArrayGLTest::TextureArrayGLTest() {
&TextureArrayGLTest::compressedSubImage2DBuffer, &TextureArrayGLTest::compressedSubImage2DBuffer,
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
&TextureArrayGLTest::subImage2DQuery, &TextureArrayGLTest::subImage2DQuery,
&TextureArrayGLTest::compressedSubImage2DQuery,
&TextureArrayGLTest::subImage2DQueryBuffer, &TextureArrayGLTest::subImage2DQueryBuffer,
&TextureArrayGLTest::compressedSubImage2DQueryBuffer,
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -967,6 +975,10 @@ void TextureArrayGLTest::subImage1DQuery() {
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(DataOffset1D)), Containers::ArrayView<const UnsignedByte>{Data1D}, TestSuite::Compare::Container); (Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(DataOffset1D)), Containers::ArrayView<const UnsignedByte>{Data1D}, TestSuite::Compare::Container);
} }
void TextureArrayGLTest::compressedSubImage1DQuery() {
CORRADE_SKIP("No 1D texture compression format exists.");
}
void TextureArrayGLTest::subImage1DQueryBuffer() { void TextureArrayGLTest::subImage1DQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>()) if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
@ -989,6 +1001,10 @@ void TextureArrayGLTest::subImage1DQueryBuffer() {
CORRADE_COMPARE_AS(imageData.suffix(DataOffset1D), CORRADE_COMPARE_AS(imageData.suffix(DataOffset1D),
Containers::ArrayView<const UnsignedByte>{Data1D}, TestSuite::Compare::Container); Containers::ArrayView<const UnsignedByte>{Data1D}, TestSuite::Compare::Container);
} }
void TextureArrayGLTest::compressedSubImage1DQueryBuffer() {
CORRADE_SKIP("No 1D texture compression format exists.");
}
#endif #endif
namespace { namespace {
@ -1252,6 +1268,44 @@ void TextureArrayGLTest::subImage2DQuery() {
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(DataOffset2D)), Containers::ArrayView<const UnsignedByte>{Data2D}, TestSuite::Compare::Container); (Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(DataOffset2D)), Containers::ArrayView<const UnsignedByte>{Data2D}, TestSuite::Compare::Container);
} }
void TextureArrayGLTest::compressedSubImage2DQuery() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_compression_s3tc>())
CORRADE_SKIP(Extensions::GL::EXT::texture_compression_s3tc::string() + std::string(" is not supported."));
Texture2DArray texture;
texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {12, 4, 4})
.setCompressedSubImage(0, {}, CompressedImageView3D{CompressedPixelFormat::RGBAS3tcDxt3,
{12, 4, 4}, CompressedSubData2DComplete});
MAGNUM_VERIFY_NO_ERROR();
/* Test also without compressed pixel storage to ensure that both size
computations work */
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::compressed_texture_pixel_storage>()) {
CompressedImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 0, 1}, {4, 4, 2}), {});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), (Vector3i{4, 4, 2}));
CORRADE_COMPARE_AS(
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}),
Containers::ArrayView<const UnsignedByte>{CompressedData2D}, TestSuite::Compare::Container);
}
CompressedImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 0, 1}, {4, 4, 2}), {_compressedDataStorage2D});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), (Vector3i{4, 4, 2}));
CORRADE_COMPARE_AS(
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(_compressedDataOffset2D)),
Containers::ArrayView<const UnsignedByte>{CompressedData2D}, TestSuite::Compare::Container);
}
void TextureArrayGLTest::subImage2DQueryBuffer() { void TextureArrayGLTest::subImage2DQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>()) if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
@ -1275,6 +1329,36 @@ void TextureArrayGLTest::subImage2DQueryBuffer() {
Containers::ArrayView<const UnsignedByte>{Data2D}, TestSuite::Compare::Container); Containers::ArrayView<const UnsignedByte>{Data2D}, TestSuite::Compare::Container);
} }
void TextureArrayGLTest::compressedSubImage2DQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_compression_s3tc>())
CORRADE_SKIP(Extensions::GL::EXT::texture_compression_s3tc::string() + std::string(" is not supported."));
Texture2DArray texture;
texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {12, 4, 4})
.setCompressedSubImage(0, {}, CompressedImageView3D{CompressedPixelFormat::RGBAS3tcDxt3,
{12, 4, 4}, CompressedSubData2DComplete});
MAGNUM_VERIFY_NO_ERROR();
CompressedBufferImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 0, 1}, {4, 4, 2}), {
#ifndef MAGNUM_TARGET_GLES
_compressedDataStorage2D
#endif
}, BufferUsage::StaticRead);
MAGNUM_VERIFY_NO_ERROR();
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), (Vector3i{4, 4, 2}));
CORRADE_COMPARE_AS(imageData.suffix(_compressedDataOffset2D), Containers::ArrayView<const UnsignedByte>{CompressedData2D}, TestSuite::Compare::Container);
}
void TextureArrayGLTest::generateMipmap1D() { void TextureArrayGLTest::generateMipmap1D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>()) if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported.")); CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported."));

156
src/Magnum/Test/TextureGLTest.cpp

@ -139,7 +139,9 @@ struct TextureGLTest: AbstractOpenGLTester {
void subImage1DBuffer(); void subImage1DBuffer();
void compressedSubImage1DBuffer(); void compressedSubImage1DBuffer();
void subImage1DQuery(); void subImage1DQuery();
void compressedSubImage1DQuery();
void subImage1DQueryBuffer(); void subImage1DQueryBuffer();
void compressedSubImage1DQueryBuffer();
#endif #endif
void subImage2D(); void subImage2D();
void compressedSubImage2D(); void compressedSubImage2D();
@ -149,7 +151,9 @@ struct TextureGLTest: AbstractOpenGLTester {
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void subImage2DQuery(); void subImage2DQuery();
void compressedSubImage2DQuery();
void subImage2DQueryBuffer(); void subImage2DQueryBuffer();
void compressedSubImage2DQueryBuffer();
#endif #endif
void subImage3D(); void subImage3D();
void compressedSubImage3D(); void compressedSubImage3D();
@ -159,7 +163,9 @@ struct TextureGLTest: AbstractOpenGLTester {
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void subImage3DQuery(); void subImage3DQuery();
void compressedSubImage3DQuery();
void subImage3DQueryBuffer(); void subImage3DQueryBuffer();
void compressedSubImage3DQueryBuffer();
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -286,7 +292,9 @@ TextureGLTest::TextureGLTest() {
&TextureGLTest::subImage1DBuffer, &TextureGLTest::subImage1DBuffer,
&TextureGLTest::compressedSubImage1DBuffer, &TextureGLTest::compressedSubImage1DBuffer,
&TextureGLTest::subImage1DQuery, &TextureGLTest::subImage1DQuery,
&TextureGLTest::compressedSubImage1DQuery,
&TextureGLTest::subImage1DQueryBuffer, &TextureGLTest::subImage1DQueryBuffer,
&TextureGLTest::compressedSubImage1DQueryBuffer,
#endif #endif
&TextureGLTest::subImage2D, &TextureGLTest::subImage2D,
&TextureGLTest::compressedSubImage2D, &TextureGLTest::compressedSubImage2D,
@ -296,7 +304,9 @@ TextureGLTest::TextureGLTest() {
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
&TextureGLTest::subImage2DQuery, &TextureGLTest::subImage2DQuery,
&TextureGLTest::compressedSubImage2DQuery,
&TextureGLTest::subImage2DQueryBuffer, &TextureGLTest::subImage2DQueryBuffer,
&TextureGLTest::compressedSubImage2DQueryBuffer,
#endif #endif
&TextureGLTest::subImage3D, &TextureGLTest::subImage3D,
&TextureGLTest::compressedSubImage3D, &TextureGLTest::compressedSubImage3D,
@ -306,7 +316,9 @@ TextureGLTest::TextureGLTest() {
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
&TextureGLTest::subImage3DQuery, &TextureGLTest::subImage3DQuery,
&TextureGLTest::compressedSubImage3DQuery,
&TextureGLTest::subImage3DQueryBuffer, &TextureGLTest::subImage3DQueryBuffer,
&TextureGLTest::compressedSubImage3DQueryBuffer,
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -1316,6 +1328,10 @@ void TextureGLTest::subImage1DQuery() {
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(DataOffset1D)), Containers::ArrayView<const UnsignedByte>{Data1D}, TestSuite::Compare::Container); (Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(DataOffset1D)), Containers::ArrayView<const UnsignedByte>{Data1D}, TestSuite::Compare::Container);
} }
void TextureGLTest::compressedSubImage1DQuery() {
CORRADE_SKIP("No 1D texture compression format exists.");
}
void TextureGLTest::subImage1DQueryBuffer() { void TextureGLTest::subImage1DQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>()) if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
@ -1336,6 +1352,10 @@ void TextureGLTest::subImage1DQueryBuffer() {
CORRADE_COMPARE_AS(imageData.suffix(DataOffset1D), CORRADE_COMPARE_AS(imageData.suffix(DataOffset1D),
Containers::ArrayView<const UnsignedByte>{Data1D}, TestSuite::Compare::Container); Containers::ArrayView<const UnsignedByte>{Data1D}, TestSuite::Compare::Container);
} }
void TextureGLTest::compressedSubImage1DQueryBuffer() {
CORRADE_SKIP("No 1D texture compression format exists.");
}
#endif #endif
namespace { namespace {
@ -1491,6 +1511,41 @@ void TextureGLTest::subImage2DQuery() {
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(_dataOffset2D)), Containers::ArrayView<const UnsignedByte>{Data2D}, TestSuite::Compare::Container); (Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(_dataOffset2D)), Containers::ArrayView<const UnsignedByte>{Data2D}, TestSuite::Compare::Container);
} }
void TextureGLTest::compressedSubImage2DQuery() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_compression_s3tc>())
CORRADE_SKIP(Extensions::GL::EXT::texture_compression_s3tc::string() + std::string(" is not supported."));
Texture2D texture;
texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {12, 4})
.setCompressedSubImage(0, {}, CompressedImageView2D{CompressedPixelFormat::RGBAS3tcDxt3, {12, 4}, CompressedSubData2DComplete});
MAGNUM_VERIFY_NO_ERROR();
/* Test also without compressed pixel storage to ensure that both size
computations work */
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::compressed_texture_pixel_storage>()) {
CompressedImage2D image = texture.compressedSubImage(0, Range2Di::fromSize({4, 0}, Vector2i{4}), {});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i{4});
CORRADE_COMPARE_AS(
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}),
Containers::ArrayView<const UnsignedByte>{CompressedData2D}, TestSuite::Compare::Container);
}
CompressedImage2D image = texture.compressedSubImage(0, Range2Di::fromSize({4, 0}, Vector2i{4}), {_compressedDataStorage2D});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i{4});
CORRADE_COMPARE_AS(
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(_compressedDataOffset2D)),
Containers::ArrayView<const UnsignedByte>{CompressedData2D}, TestSuite::Compare::Container);
}
void TextureGLTest::subImage2DQueryBuffer() { void TextureGLTest::subImage2DQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>()) if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
@ -1511,6 +1566,39 @@ void TextureGLTest::subImage2DQueryBuffer() {
CORRADE_COMPARE_AS(imageData.suffix(_dataOffset2D), CORRADE_COMPARE_AS(imageData.suffix(_dataOffset2D),
Containers::ArrayView<const UnsignedByte>{Data2D}, TestSuite::Compare::Container); Containers::ArrayView<const UnsignedByte>{Data2D}, TestSuite::Compare::Container);
} }
void TextureGLTest::compressedSubImage2DQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_compression_s3tc>())
CORRADE_SKIP(Extensions::GL::EXT::texture_compression_s3tc::string() + std::string(" is not supported."));
Texture2D texture;
texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {12, 4})
.setCompressedSubImage(0, {}, CompressedImageView2D{CompressedPixelFormat::RGBAS3tcDxt3, {12, 4}, CompressedSubData2DComplete});
MAGNUM_VERIFY_NO_ERROR();
/* Test also without compressed pixel storage to ensure that both size
computations work */
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::compressed_texture_pixel_storage>()) {
CompressedBufferImage2D image = texture.compressedSubImage(0, Range2Di::fromSize({4, 0}, Vector2i{4}), {}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i{4});
CORRADE_COMPARE_AS(imageData, Containers::ArrayView<const UnsignedByte>{CompressedData2D}, TestSuite::Compare::Container);
}
CompressedBufferImage2D image = texture.compressedSubImage(0, Range2Di::fromSize({4, 0}, Vector2i{4}), {_compressedDataStorage2D}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i{4});
CORRADE_COMPARE_AS(imageData.suffix(_compressedDataOffset2D), Containers::ArrayView<const UnsignedByte>{CompressedData2D}, TestSuite::Compare::Container);
}
#endif #endif
namespace { namespace {
@ -1707,6 +1795,41 @@ void TextureGLTest::subImage3DQuery() {
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(_dataOffset3D)), Containers::ArrayView<const UnsignedByte>{Data3D}, TestSuite::Compare::Container); (Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(_dataOffset3D)), Containers::ArrayView<const UnsignedByte>{Data3D}, TestSuite::Compare::Container);
} }
void TextureGLTest::compressedSubImage3DQuery() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_compression_bptc>())
CORRADE_SKIP(Extensions::GL::ARB::texture_compression_bptc::string() + std::string(" is not supported."));
Texture3D texture;
texture.setStorage(1, TextureFormat::CompressedRGBABptcUnorm, {12, 4, 4})
.setCompressedSubImage(0, {}, CompressedImageView3D{CompressedPixelFormat::RGBABptcUnorm, {12, 4, 4}, CompressedSubData3DComplete});
MAGNUM_VERIFY_NO_ERROR();
/* Test also without compressed pixel storage to ensure that both size
computations work */
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::compressed_texture_pixel_storage>()) {
CompressedImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 0, 0}, Vector3i{4}), {});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), (Vector3i{4}));
CORRADE_COMPARE_AS(
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}),
Containers::ArrayView<const UnsignedByte>{CompressedData3D}, TestSuite::Compare::Container);
}
CompressedImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 0, 0}, Vector3i{4}), {_compressedDataStorage3D});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), (Vector3i{4}));
CORRADE_COMPARE_AS(
(Containers::ArrayView<const UnsignedByte>{image.data<UnsignedByte>(), image.data().size()}.suffix(_compressedDataOffset3D)),
Containers::ArrayView<const UnsignedByte>{CompressedData3D}, TestSuite::Compare::Container);
}
void TextureGLTest::subImage3DQueryBuffer() { void TextureGLTest::subImage3DQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>()) if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
@ -1728,6 +1851,39 @@ void TextureGLTest::subImage3DQueryBuffer() {
Containers::ArrayView<const UnsignedByte>{Data3D}, TestSuite::Compare::Container); Containers::ArrayView<const UnsignedByte>{Data3D}, TestSuite::Compare::Container);
} }
void TextureGLTest::compressedSubImage3DQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_compression_bptc>())
CORRADE_SKIP(Extensions::GL::ARB::texture_compression_bptc::string() + std::string(" is not supported."));
Texture3D texture;
texture.setStorage(1, TextureFormat::CompressedRGBABptcUnorm, {12, 4, 4})
.setCompressedSubImage(0, {}, CompressedImageView3D{CompressedPixelFormat::RGBABptcUnorm, {12, 4, 4}, CompressedSubData3DComplete});
MAGNUM_VERIFY_NO_ERROR();
/* Test also without compressed pixel storage to ensure that both size
computations work */
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::compressed_texture_pixel_storage>()) {
CompressedBufferImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 0, 0}, Vector3i{4}), {}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i{4});
CORRADE_COMPARE_AS(imageData, Containers::ArrayView<const UnsignedByte>{CompressedData3D}, TestSuite::Compare::Container);
}
CompressedBufferImage3D image = texture.compressedSubImage(0, Range3Di::fromSize({4, 0, 0}, Vector3i{4}), {_compressedDataStorage3D}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i{4});
CORRADE_COMPARE_AS(imageData.suffix(_compressedDataOffset3D), Containers::ArrayView<const UnsignedByte>{CompressedData3D}, TestSuite::Compare::Container);
}
void TextureGLTest::generateMipmap1D() { void TextureGLTest::generateMipmap1D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>()) if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported.")); CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported."));

10
src/Magnum/Texture.cpp

@ -93,6 +93,16 @@ template<UnsignedInt dimensions> BufferImage<dimensions> Texture<dimensions>::su
return std::move(image); return std::move(image);
} }
template<UnsignedInt dimensions> CompressedImage<dimensions> Texture<dimensions>::compressedSubImage(const Int level, const RangeTypeFor<dimensions, Int>& range, CompressedImage<dimensions>&& image) {
compressedSubImage(level, range, image);
return std::move(image);
}
template<UnsignedInt dimensions> CompressedBufferImage<dimensions> Texture<dimensions>::compressedSubImage(const Int level, const RangeTypeFor<dimensions, Int>& range, CompressedBufferImage<dimensions>&& image, const BufferUsage usage) {
compressedSubImage(level, range, image, usage);
return std::move(image);
}
template class MAGNUM_EXPORT Texture<1>; template class MAGNUM_EXPORT Texture<1>;
template class MAGNUM_EXPORT Texture<2>; template class MAGNUM_EXPORT Texture<2>;
template class MAGNUM_EXPORT Texture<3>; template class MAGNUM_EXPORT Texture<3>;

55
src/Magnum/Texture.h

@ -860,6 +860,61 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @endcode * @endcode
*/ */
BufferImage<dimensions> subImage(Int level, const RangeTypeFor<dimensions, Int>& range, BufferImage<dimensions>&& image, BufferUsage usage); BufferImage<dimensions> subImage(Int level, const RangeTypeFor<dimensions, Int>& range, BufferImage<dimensions>&& image, BufferUsage usage);
/**
* @brief Read range of given compressed texture mip level to image
* @param level Mip level
* @param range Range to read
* @param image Image where to put the compressed data
*
* Compression format and data size are taken from the texture.
* @see @fn_gl2{GetTextureLevelParameter,GetTexLevelParameter},
* @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access},
* eventually @fn_gl{GetTexLevelParameter} with
* @def_gl{TEXTURE_COMPRESSED_IMAGE_SIZE}, @def_gl{TEXTURE_INTERNAL_FORMAT},
* then @fn_gl{GetCompressedTextureSubImage}
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() for possible workaround.
*/
void compressedSubImage(Int level, const RangeTypeFor<dimensions, Int>& range, CompressedImage<dimensions>& image) {
AbstractTexture::compressedSubImage<dimensions>(level, range, image);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* CompressedImage2D image = texture.compressedSubImage(0, rect, {});
* @endcode
*/
CompressedImage<dimensions> compressedSubImage(Int level, const RangeTypeFor<dimensions, Int>& range, CompressedImage<dimensions>&& image);
/**
* @brief Read range of given compressed texture mip level to buffer image
* @param level Mip level
* @param range Range to read
* @param image Buffer image where to put the compressed data
* @param usage Buffer usage
*
* See @ref compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() for possible workaround.
*/
void compressedSubImage(Int level, const RangeTypeFor<dimensions, Int>& range, CompressedBufferImage<dimensions>& image, BufferUsage usage) {
AbstractTexture::compressedSubImage<dimensions>(level, range, image, usage);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* CompressedBufferImage2D image = texture.compressedSubImage(0, rect, {}, BufferUsage::StaticRead);
* @endcode
*/
CompressedBufferImage<dimensions> compressedSubImage(Int level, const RangeTypeFor<dimensions, Int>& range, CompressedBufferImage<dimensions>&& image, BufferUsage usage);
#endif #endif
/** /**

10
src/Magnum/TextureArray.cpp

@ -84,6 +84,16 @@ template<UnsignedInt dimensions> BufferImage<dimensions+1> TextureArray<dimensio
this->subImage(level, range, image, usage); this->subImage(level, range, image, usage);
return std::move(image); return std::move(image);
} }
template<UnsignedInt dimensions> CompressedImage<dimensions+1> TextureArray<dimensions>::compressedSubImage(const Int level, const RangeTypeFor<dimensions+1, Int>& range, CompressedImage<dimensions+1>&& image) {
compressedSubImage(level, range, image);
return std::move(image);
}
template<UnsignedInt dimensions> CompressedBufferImage<dimensions+1> TextureArray<dimensions>::compressedSubImage(const Int level, const RangeTypeFor<dimensions+1, Int>& range, CompressedBufferImage<dimensions+1>&& image, const BufferUsage usage) {
compressedSubImage(level, range, image, usage);
return std::move(image);
}
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES

44
src/Magnum/TextureArray.h

@ -551,6 +551,50 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
* @endcode * @endcode
*/ */
BufferImage<dimensions+1> subImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, BufferImage<dimensions+1>&& image, BufferUsage usage); BufferImage<dimensions+1> subImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, BufferImage<dimensions+1>&& image, BufferUsage usage);
/**
* @copybrief Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedImage&)
*
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedImage&)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() for possible workaround.
*/
void compressedSubImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, CompressedImage<dimensions+1>& image) {
AbstractTexture::compressedSubImage<dimensions+1>(level, range, image);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* CompressedImage3D image = texture.compressedSubImage(0, range, {});
* @endcode
*/
CompressedImage<dimensions+1> compressedSubImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, CompressedImage<dimensions+1>&& image);
/**
* @copybrief Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
*
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() for possible workaround.
*/
void compressedSubImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, CompressedBufferImage<dimensions+1>& image, BufferUsage usage) {
AbstractTexture::compressedSubImage<dimensions+1>(level, range, image, usage);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* CompressedBufferImage3D image = texture.compressedSubImage(0, range, {}, BufferUsage::StaticRead);
* @endcode
*/
CompressedBufferImage<dimensions+1> compressedSubImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, CompressedBufferImage<dimensions+1>&& image, BufferUsage usage);
#endif #endif
/** /**

Loading…
Cancel
Save