Browse Source

Support for ARB_get_texture_sub_image.

Only thing missing are compressed texture queries, but that needs a lot
more work.
pull/94/head
Vladimír Vondruš 11 years ago
parent
commit
9619bf08b6
  1. 2
      doc/opengl-mapping.dox
  2. 2
      doc/opengl-support.dox
  3. 37
      src/Magnum/AbstractTexture.cpp
  4. 5
      src/Magnum/AbstractTexture.h
  5. 10
      src/Magnum/CubeMapTexture.cpp
  6. 42
      src/Magnum/CubeMapTexture.h
  7. 10
      src/Magnum/CubeMapTextureArray.cpp
  8. 40
      src/Magnum/CubeMapTextureArray.h
  9. 10
      src/Magnum/RectangleTexture.cpp
  10. 40
      src/Magnum/RectangleTexture.h
  11. 48
      src/Magnum/Test/CubeMapTextureArrayGLTest.cpp
  12. 56
      src/Magnum/Test/CubeMapTextureGLTest.cpp
  13. 48
      src/Magnum/Test/RectangleTextureGLTest.cpp
  14. 97
      src/Magnum/Test/TextureArrayGLTest.cpp
  15. 137
      src/Magnum/Test/TextureGLTest.cpp
  16. 22
      src/Magnum/Texture.cpp
  17. 50
      src/Magnum/Texture.h
  18. 10
      src/Magnum/TextureArray.cpp
  19. 42
      src/Magnum/TextureArray.h

2
doc/opengl-mapping.dox

@ -209,7 +209,7 @@ OpenGL function | Matching API
@fn_gl{GetTexImage}, \n `glGetnTexImage()`, \n @fn_gl_extension{GetnTexImage,ARB,robustness}, \n `glGetTextureImage()`, \n @fn_gl_extension{GetTextureImage,EXT,direct_state_access} | @ref Texture::image(), \n @ref TextureArray::image(), \n @ref CubeMapTexture::image(), \n @ref CubeMapTextureArray::image(), \n @ref RectangleTexture::image()
@fn_gl{GetTexLevelParameter}, \n `glGetTextureLevelParameter()`, \n @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} | @ref Texture::imageSize(), \n @ref TextureArray::imageSize(), \n @ref CubeMapTexture::imageSize(), \n @ref CubeMapTextureArray::imageSize(), \n @ref RectangleTexture::imageSize()
@fn_gl{GetTexParameter}, \n `glGetTextureParameter()`, \n @fn_gl_extension{GetTextureParameter,EXT,direct_state_access} | |
@fn_gl{GetTextureSubImage} | @ref CubeMapTexture::image()
@fn_gl{GetTextureSubImage} | @ref Texture::subImage(), \n @ref TextureArray::subImage(), \n @ref CubeMapTexture::image(), \n @ref CubeMapTexture::subImage(), \n @ref CubeMapTextureArray::subImage(), \n @ref RectangleTexture::subImage()
@fn_gl{GetTransformFeedback} | not queryable, @ref TransformFeedback::attachBuffer() and @ref TransformFeedback::attachBuffers() setters only
@fn_gl{GetTransformFeedbackVarying} | not queryable, @ref AbstractShaderProgram::setTransformFeedbackOutputs() setter only
@fn_gl{GetUniform}, \n `glGetnUniform()`, \n @fn_gl_extension{GetnUniform,ARB,robustness} | not queryable, @ref AbstractShaderProgram::setUniform() setter only

2
doc/opengl-support.dox

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

37
src/Magnum/AbstractTexture.cpp

@ -35,6 +35,7 @@
#include "Magnum/Extensions.h"
#include "Magnum/Image.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Math/Range.h"
#ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/Shader.h"
@ -1255,6 +1256,42 @@ template<UnsignedInt dimensions> void AbstractTexture::image(GLint level, Buffer
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);
template<UnsignedInt dimensions> void AbstractTexture::subImage(const GLint level, const RangeTypeFor<dimensions, Int>& range, Image<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);
const std::size_t dataSize = image.dataSize(size);
char* data = new char[dataSize];
Buffer::unbindInternal(Buffer::TargetHint::PixelPack);
glGetTextureSubImage(_id, level, paddedOffset.x(), paddedOffset.y(), paddedOffset.z(), paddedSize.x(), paddedSize.y(), paddedSize.z(), GLenum(image.format()), GLenum(image.type()), dataSize, data);
image.setData(image.format(), image.type(), size, data);
}
template void MAGNUM_EXPORT AbstractTexture::subImage<1>(GLint, const Range1Di&, Image<1>&);
template void MAGNUM_EXPORT AbstractTexture::subImage<2>(GLint, const Range2Di&, Image<2>&);
template void MAGNUM_EXPORT AbstractTexture::subImage<3>(GLint, const Range3Di&, Image<3>&);
template<UnsignedInt dimensions> void AbstractTexture::subImage(const GLint level, const RangeTypeFor<dimensions, Int>& range, BufferImage<dimensions>& image, const BufferUsage usage) {
createIfNotAlready();
const Math::Vector<dimensions, Int> size = range.size();
const std::size_t dataSize = image.dataSize(size);
const Vector3i paddedOffset = Vector3i::pad(range.min());
const Vector3i paddedSize = Vector3i::pad(size, 1);
if(image.size() != size)
image.setData(image.format(), image.type(), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
glGetTextureSubImage(_id, level, paddedOffset.x(), paddedOffset.y(), paddedOffset.z(), paddedSize.x(), paddedSize.y(), paddedSize.z(), GLenum(image.format()), GLenum(image.type()), dataSize, nullptr);
}
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<3>(GLint, const Range3Di&, BufferImage<3>&, BufferUsage);
#endif
#endif

5
src/Magnum/AbstractTexture.h

@ -31,8 +31,9 @@
#include <Corrade/Containers/Array.h>
#include "Magnum/Sampler.h"
#include "Magnum/AbstractObject.h"
#include "Magnum/DimensionTraits.h"
#include "Magnum/Sampler.h"
namespace Magnum {
@ -369,6 +370,8 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
#ifndef MAGNUM_TARGET_GLES
template<UnsignedInt dimensions> void image(GLint level, Image<dimensions>& image);
template<UnsignedInt dimensions> void image(GLint level, BufferImage<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, BufferImage<dimensions>& image, BufferUsage usage);
#endif
GLenum _target;

10
src/Magnum/CubeMapTexture.cpp

@ -114,6 +114,16 @@ BufferImage2D CubeMapTexture::image(const Coordinate coordinate, const Int level
return std::move(image);
}
Image3D CubeMapTexture::subImage(const Int level, const Range3Di& range, Image3D&& image) {
this->subImage(level, range, image);
return std::move(image);
}
BufferImage3D CubeMapTexture::subImage(const Int level, const Range3Di& range, BufferImage3D&& image, const BufferUsage usage) {
this->subImage(level, range, image, usage);
return std::move(image);
}
CubeMapTexture& CubeMapTexture::setSubImage(const Int level, const Vector3i& offset, const ImageReference3D& image) {
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
glTextureSubImage3D(_id, level, offset.x(), offset.y(), offset.z(), image.size().x(), image.size().y(), image.size().z(), GLenum(image.format()), GLenum(image.type()), image.data());

42
src/Magnum/CubeMapTexture.h

@ -472,6 +472,48 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
* @endcode
*/
BufferImage2D image(Coordinate coordinate, Int level, BufferImage2D&& image, BufferUsage usage);
/**
* @copybrief Texture::subImage(Int, const RangeTypeFor<dimensions, Int>&, Image&)
*
* See @ref Texture::subImage(Int, const RangeTypeFor<dimensions, Int>&, Image&)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void subImage(Int level, const Range3Di& range, Image3D& image) {
AbstractTexture::subImage<3>(level, range, image);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* Image3D image = texture.subImage(0, range, {ColorFormat::RGBA, ColorType::UnsignedByte});
* @endcode
*/
Image3D subImage(Int level, const Range3Di& range, Image3D&& image);
/**
* @copybrief Texture::subImage(Int, const RangeTypeFor<dimensions, Int>&, BufferImage&, BufferUsage)
*
* See @ref Texture::subImage(Int, const RangeTypeFor<dimensions, Int>&, BufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void subImage(Int level, const Range3Di& range, BufferImage3D& image, BufferUsage usage) {
AbstractTexture::subImage<3>(level, range, image, usage);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* BufferImage3D image = texture.subImage(0, range, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
* @endcode
*/
BufferImage3D subImage(Int level, const Range3Di& range, BufferImage3D&& image, BufferUsage usage);
#endif
/**

10
src/Magnum/CubeMapTextureArray.cpp

@ -53,5 +53,15 @@ BufferImage3D CubeMapTextureArray::image(const Int level, BufferImage3D&& image,
return std::move(image);
}
Image3D CubeMapTextureArray::subImage(const Int level, const Range3Di& range, Image3D&& image) {
this->subImage(level, range, image);
return std::move(image);
}
BufferImage3D CubeMapTextureArray::subImage(const Int level, const Range3Di& range, BufferImage3D&& image, const BufferUsage usage) {
this->subImage(level, range, image, usage);
return std::move(image);
}
}
#endif

40
src/Magnum/CubeMapTextureArray.h

@ -356,6 +356,46 @@ class MAGNUM_EXPORT CubeMapTextureArray: public AbstractTexture {
*/
BufferImage3D image(Int level, BufferImage3D&& image, BufferUsage usage);
/**
* @copybrief Texture::subImage(Int, const RangeTypeFor<dimensions, Int>&, Image&)
*
* See @ref Texture::subImage(Int, const RangeTypeFor<dimensions, Int>&, Image&)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
*/
void subImage(Int level, const Range3Di& range, Image3D& image) {
AbstractTexture::subImage<3>(level, range, image);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* Image3D image = texture.subImage(0, range, {ColorFormat::RGBA, ColorType::UnsignedByte});
* @endcode
*/
Image3D subImage(Int level, const Range3Di& range, Image3D&& image);
/**
* @copybrief Texture::subImage(Int, const RangeTypeFor<dimensions, Int>&, BufferImage&, BufferUsage)
*
* See @ref Texture::subImage(Int, const RangeTypeFor<dimensions, Int>&, BufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
*/
void subImage(Int level, const Range3Di& range, BufferImage3D& image, BufferUsage usage) {
AbstractTexture::subImage<3>(level, range, image, usage);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* BufferImage3D image = texture.subImage(0, range, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
* @endcode
*/
BufferImage3D subImage(Int level, const Range3Di& range, BufferImage3D&& image, BufferUsage usage);
/**
* @copybrief Texture::setImage()
* @return Reference to self (for method chaining)

10
src/Magnum/RectangleTexture.cpp

@ -58,5 +58,15 @@ BufferImage2D RectangleTexture::image(BufferImage2D&& image, const BufferUsage u
return std::move(image);
}
Image2D RectangleTexture::subImage(const Range2Di& range, Image2D&& image) {
this->subImage(range, image);
return std::move(image);
}
BufferImage2D RectangleTexture::subImage(const Range2Di& range, BufferImage2D&& image, const BufferUsage usage) {
this->subImage(range, image, usage);
return std::move(image);
}
}
#endif

40
src/Magnum/RectangleTexture.h

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

48
src/Magnum/Test/CubeMapTextureArrayGLTest.cpp

@ -31,6 +31,7 @@
#include "Magnum/CubeMapTextureArray.h"
#include "Magnum/Image.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Math/Range.h"
#include "Magnum/Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
@ -53,6 +54,8 @@ struct CubeMapTextureArrayGLTest: AbstractOpenGLTester {
void imageBuffer();
void subImage();
void subImageBuffer();
void subImageQuery();
void subImageQueryBuffer();
void generateMipmap();
@ -76,6 +79,8 @@ CubeMapTextureArrayGLTest::CubeMapTextureArrayGLTest() {
&CubeMapTextureArrayGLTest::imageBuffer,
&CubeMapTextureArrayGLTest::subImage,
&CubeMapTextureArrayGLTest::subImageBuffer,
&CubeMapTextureArrayGLTest::subImageQuery,
&CubeMapTextureArrayGLTest::subImageQueryBuffer,
&CubeMapTextureArrayGLTest::generateMipmap,
@ -365,6 +370,49 @@ void CubeMapTextureArrayGLTest::subImageBuffer() {
CORRADE_COMPARE_AS(imageData, Containers::ArrayReference<const UnsignedByte>{SubDataComplete}, TestSuite::Compare::Container);
}
void CubeMapTextureArrayGLTest::subImageQuery() {
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::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
CubeMapTextureArray texture;
texture.setStorage(1, TextureFormat::RGBA8, {4, 4, 6})
.setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 6}, SubDataComplete});
MAGNUM_VERIFY_NO_ERROR();
Image3D image = texture.subImage(0, Range3Di::fromSize(Vector3i{1}, {2, 2, 4}), {ColorFormat::RGBA, ColorType::UnsignedByte});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i(2, 2, 4));
CORRADE_COMPARE_AS(
Containers::ArrayReference<const UnsignedByte>(image.data<UnsignedByte>(), image.pixelSize()*image.size().product()),
Containers::ArrayReference<const UnsignedByte>{SubData}, TestSuite::Compare::Container);
}
void CubeMapTextureArrayGLTest::subImageQueryBuffer() {
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::ARB::get_texture_sub_image>())
CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported."));
CubeMapTextureArray texture;
texture.setStorage(1, TextureFormat::RGBA8, {4, 4, 6})
.setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 6}, SubDataComplete});
MAGNUM_VERIFY_NO_ERROR();
BufferImage3D image = texture.subImage(0, Range3Di::fromSize(Vector3i{1}, {2, 2, 4}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i(2, 2, 4));
CORRADE_COMPARE_AS(imageData, Containers::ArrayReference<const UnsignedByte>{SubData}, TestSuite::Compare::Container);
}
void CubeMapTextureArrayGLTest::generateMipmap() {
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."));

56
src/Magnum/Test/CubeMapTextureGLTest.cpp

@ -34,6 +34,7 @@
#include "Magnum/CubeMapTexture.h"
#include "Magnum/Image.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Math/Range.h"
#include "Magnum/Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
@ -74,6 +75,10 @@ struct CubeMapTextureGLTest: AbstractOpenGLTester {
#ifndef MAGNUM_TARGET_GLES2
void subImageBuffer();
#endif
#ifndef MAGNUM_TARGET_GLES
void subImageQuery();
void subImageQueryBuffer();
#endif
void generateMipmap();
@ -110,6 +115,10 @@ CubeMapTextureGLTest::CubeMapTextureGLTest() {
#ifndef MAGNUM_TARGET_GLES2
&CubeMapTextureGLTest::imageBuffer,
#endif
#ifndef MAGNUM_TARGET_GLES
&CubeMapTextureGLTest::subImageQuery,
&CubeMapTextureGLTest::subImageQueryBuffer,
#endif
&CubeMapTextureGLTest::subImage,
#ifndef MAGNUM_TARGET_GLES2
@ -460,6 +469,53 @@ void CubeMapTextureGLTest::subImageBuffer() {
}
#endif
#ifndef MAGNUM_TARGET_GLES
void CubeMapTextureGLTest::subImageQuery() {
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."));
CubeMapTexture texture;
texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 1}, SubDataComplete});
MAGNUM_VERIFY_NO_ERROR();
Image3D image = texture.subImage(0, Range3Di::fromSize({1, 1, 0}, {2, 2, 1}), {ColorFormat::RGBA, ColorType::UnsignedByte});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i(2, 2, 1));
CORRADE_COMPARE_AS(
Containers::ArrayReference<const UnsignedByte>(image.data<UnsignedByte>(), image.pixelSize()*image.size().product()),
Containers::ArrayReference<const UnsignedByte>{Data}, TestSuite::Compare::Container);
}
void CubeMapTextureGLTest::subImageQueryBuffer() {
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."));
CubeMapTexture texture;
texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 1}, SubDataComplete});
MAGNUM_VERIFY_NO_ERROR();
BufferImage3D image = texture.subImage(0, Range3Di::fromSize({1, 1, 0}, {2, 2, 1}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i(2, 2, 1));
CORRADE_COMPARE_AS(imageData, Containers::ArrayReference<const UnsignedByte>{Data}, TestSuite::Compare::Container);
}
#endif
void CubeMapTextureGLTest::generateMipmap() {
CubeMapTexture texture;
texture.setImage(CubeMapTexture::Coordinate::PositiveX, 0, TextureFormat::RGBA8,

48
src/Magnum/Test/RectangleTextureGLTest.cpp

@ -32,6 +32,7 @@
#include "Magnum/Image.h"
#include "Magnum/RectangleTexture.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Math/Range.h"
#include "Magnum/Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
@ -54,6 +55,8 @@ struct RectangleTextureGLTest: AbstractOpenGLTester {
void imageBuffer();
void subImage();
void subImageBuffer();
void subImageQuery();
void subImageQueryBuffer();
void invalidateImage();
void invalidateSubImage();
@ -76,6 +79,8 @@ RectangleTextureGLTest::RectangleTextureGLTest() {
&RectangleTextureGLTest::subImage,
&RectangleTextureGLTest::subImageBuffer,
&RectangleTextureGLTest::subImageQuery,
&RectangleTextureGLTest::subImageQueryBuffer,
&RectangleTextureGLTest::invalidateImage,
&RectangleTextureGLTest::invalidateSubImage});
@ -299,6 +304,49 @@ void RectangleTextureGLTest::subImageBuffer() {
CORRADE_COMPARE_AS(imageData, Containers::ArrayReference<const UnsignedByte>{SubDataComplete}, TestSuite::Compare::Container);
}
void RectangleTextureGLTest::subImageQuery() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::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."));
RectangleTexture texture;
texture.setStorage(TextureFormat::RGBA8, Vector2i{4})
.setSubImage({}, ImageReference2D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i{4}, SubDataComplete});
MAGNUM_VERIFY_NO_ERROR();
Image2D image = texture.subImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i{2});
CORRADE_COMPARE_AS(
Containers::ArrayReference<const UnsignedByte>(image.data<UnsignedByte>(), image.pixelSize()*image.size().product()),
Containers::ArrayReference<const UnsignedByte>{Data}, TestSuite::Compare::Container);
}
void RectangleTextureGLTest::subImageQueryBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::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."));
RectangleTexture texture;
texture.setStorage(TextureFormat::RGBA8, Vector2i{4})
.setSubImage({}, ImageReference2D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i{4}, SubDataComplete});
MAGNUM_VERIFY_NO_ERROR();
BufferImage2D image = texture.subImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i{2});
CORRADE_COMPARE_AS(imageData, Containers::ArrayReference<const UnsignedByte>{Data}, TestSuite::Compare::Container);
}
void RectangleTextureGLTest::invalidateImage() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));

97
src/Magnum/Test/TextureArrayGLTest.cpp

@ -32,6 +32,7 @@
#include "Magnum/Image.h"
#include "Magnum/TextureArray.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Math/Range.h"
#include "Magnum/Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
@ -98,9 +99,15 @@ struct TextureArrayGLTest: AbstractOpenGLTester {
#ifndef MAGNUM_TARGET_GLES
void subImage1D();
void subImage1DBuffer();
void subImage1DQuery();
void subImage1DQueryBuffer();
#endif
void subImage2D();
void subImage2DBuffer();
#ifndef MAGNUM_TARGET_GLES
void subImage2DQuery();
void subImage2DQueryBuffer();
#endif
#ifndef MAGNUM_TARGET_GLES
void generateMipmap1D();
@ -173,9 +180,15 @@ TextureArrayGLTest::TextureArrayGLTest() {
#ifndef MAGNUM_TARGET_GLES
&TextureArrayGLTest::subImage1D,
&TextureArrayGLTest::subImage1DBuffer,
&TextureArrayGLTest::subImage1DQuery,
&TextureArrayGLTest::subImage1DQueryBuffer,
#endif
&TextureArrayGLTest::subImage2D,
&TextureArrayGLTest::subImage2DBuffer,
#ifndef MAGNUM_TARGET_GLES
&TextureArrayGLTest::subImage2DQuery,
&TextureArrayGLTest::subImage2DQueryBuffer,
#endif
#ifndef MAGNUM_TARGET_GLES
&TextureArrayGLTest::generateMipmap1D,
@ -699,6 +712,48 @@ void TextureArrayGLTest::subImage1DBuffer() {
CORRADE_COMPARE(image.size(), Vector2i(4));
CORRADE_COMPARE_AS(imageData, Containers::ArrayReference<const UnsignedByte>{SubData1DComplete}, TestSuite::Compare::Container);
}
void TextureArrayGLTest::subImage1DQuery() {
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."));
Texture1DArray texture;
texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageReference2D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i{4}, SubData1DComplete});
MAGNUM_VERIFY_NO_ERROR();
Image2D image = texture.subImage(0, Range2Di::fromSize(Vector2i{1}, Vector2i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i{2});
CORRADE_COMPARE_AS(
Containers::ArrayReference<const UnsignedByte>(image.data<UnsignedByte>(), image.pixelSize()*image.size().product()), Containers::ArrayReference<const UnsignedByte>{Data1D}, TestSuite::Compare::Container);
}
void TextureArrayGLTest::subImage1DQueryBuffer() {
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."));
Texture1DArray texture;
texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageReference2D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i{4}, SubData1DComplete});
MAGNUM_VERIFY_NO_ERROR();
BufferImage2D image = texture.subImage(0, Range2Di::fromSize(Vector2i{1}, Vector2i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i{2});
CORRADE_COMPARE_AS(imageData, Containers::ArrayReference<const UnsignedByte>{Data1D}, TestSuite::Compare::Container);
}
#endif
namespace {
@ -787,6 +842,48 @@ void TextureArrayGLTest::subImage2DBuffer() {
}
#ifndef MAGNUM_TARGET_GLES
void TextureArrayGLTest::subImage2DQuery() {
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."));
Texture2DArray texture;
texture.setStorage(1, TextureFormat::RGBA8, Vector3i{4})
.setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{4}, SubData2DComplete});
MAGNUM_VERIFY_NO_ERROR();
Image3D image = texture.subImage(0, Range3Di::fromSize(Vector3i{1}, Vector3i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i{2});
CORRADE_COMPARE_AS(
Containers::ArrayReference<const UnsignedByte>(image.data<UnsignedByte>(), image.pixelSize()*image.size().product()), Containers::ArrayReference<const UnsignedByte>{Data2D}, TestSuite::Compare::Container);
}
void TextureArrayGLTest::subImage2DQueryBuffer() {
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."));
Texture2DArray texture;
texture.setStorage(1, TextureFormat::RGBA8, Vector3i{4})
.setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{4}, SubData2DComplete});
MAGNUM_VERIFY_NO_ERROR();
BufferImage3D image = texture.subImage(0, Range3Di::fromSize(Vector3i{1}, Vector3i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i{2});
CORRADE_COMPARE_AS(imageData, Containers::ArrayReference<const UnsignedByte>{Data2D}, TestSuite::Compare::Container);
}
void TextureArrayGLTest::generateMipmap1D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported."));

137
src/Magnum/Test/TextureGLTest.cpp

@ -34,6 +34,7 @@
#include "Magnum/Image.h"
#include "Magnum/Texture.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Math/Range.h"
#include "Magnum/Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
@ -115,15 +116,25 @@ struct TextureGLTest: AbstractOpenGLTester {
#ifndef MAGNUM_TARGET_GLES
void subImage1D();
void subImage1DBuffer();
void subImage1DQuery();
void subImage1DQueryBuffer();
#endif
void subImage2D();
#ifndef MAGNUM_TARGET_GLES2
void subImage2DBuffer();
#endif
#ifndef MAGNUM_TARGET_GLES
void subImage2DQuery();
void subImage2DQueryBuffer();
#endif
void subImage3D();
#ifndef MAGNUM_TARGET_GLES2
void subImage3DBuffer();
#endif
#ifndef MAGNUM_TARGET_GLES
void subImage3DQuery();
void subImage3DQueryBuffer();
#endif
#ifndef MAGNUM_TARGET_GLES
void generateMipmap1D();
@ -218,15 +229,25 @@ TextureGLTest::TextureGLTest() {
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::subImage1D,
&TextureGLTest::subImage1DBuffer,
&TextureGLTest::subImage1DQuery,
&TextureGLTest::subImage1DQueryBuffer,
#endif
&TextureGLTest::subImage2D,
#ifndef MAGNUM_TARGET_GLES2
&TextureGLTest::subImage2DBuffer,
#endif
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::subImage2DQuery,
&TextureGLTest::subImage2DQueryBuffer,
#endif
&TextureGLTest::subImage3D,
#ifndef MAGNUM_TARGET_GLES2
&TextureGLTest::subImage3DBuffer,
#endif
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::subImage3DQuery,
&TextureGLTest::subImage3DQueryBuffer,
#endif
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::generateMipmap1D,
@ -903,6 +924,44 @@ void TextureGLTest::subImage1DBuffer() {
CORRADE_COMPARE(image.size(), 4);
CORRADE_COMPARE_AS(imageData, Containers::ArrayReference<const UnsignedByte>{SubData1DComplete}, TestSuite::Compare::Container);
}
void TextureGLTest::subImage1DQuery() {
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."));
Texture1D texture;
texture.setStorage(1, TextureFormat::RGBA8, 4)
.setSubImage(0, {}, ImageReference1D{ColorFormat::RGBA, ColorType::UnsignedByte, 4, SubData1DComplete});
MAGNUM_VERIFY_NO_ERROR();
Image1D image = texture.subImage(0, Range1Di::fromSize(1, 2), {ColorFormat::RGBA, ColorType::UnsignedByte});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), 2);
CORRADE_COMPARE_AS(
Containers::ArrayReference<const UnsignedByte>(image.data<UnsignedByte>(), image.pixelSize()*image.size().product()), Containers::ArrayReference<const UnsignedByte>{Data1D}, TestSuite::Compare::Container);
}
void TextureGLTest::subImage1DQueryBuffer() {
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."));
Texture1D texture;
texture.setStorage(1, TextureFormat::RGBA8, 4)
.setSubImage(0, {}, ImageReference1D{ColorFormat::RGBA, ColorType::UnsignedByte, 4, SubData1DComplete});
MAGNUM_VERIFY_NO_ERROR();
BufferImage1D image = texture.subImage(0, Range1Di::fromSize(1, 2), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), 2);
CORRADE_COMPARE_AS(imageData, Containers::ArrayReference<const UnsignedByte>{Data1D}, TestSuite::Compare::Container);
}
#endif
namespace {
@ -960,6 +1019,46 @@ void TextureGLTest::subImage2DBuffer() {
}
#endif
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::subImage2DQuery() {
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."));
Texture2D texture;
texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageReference2D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i{4}, SubData2DComplete});
MAGNUM_VERIFY_NO_ERROR();
Image2D image = texture.subImage(0, Range2Di::fromSize(Vector2i{1}, Vector2i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i{2});
CORRADE_COMPARE_AS(
Containers::ArrayReference<const UnsignedByte>(image.data<UnsignedByte>(), image.pixelSize()*image.size().product()), Containers::ArrayReference<const UnsignedByte>{Data2D}, TestSuite::Compare::Container);
}
void TextureGLTest::subImage2DQueryBuffer() {
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."));
Texture2D texture;
texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageReference2D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i{4}, SubData2DComplete});
MAGNUM_VERIFY_NO_ERROR();
BufferImage2D image = texture.subImage(0, Range2Di::fromSize(Vector2i{1}, Vector2i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i{2});
CORRADE_COMPARE_AS(imageData, Containers::ArrayReference<const UnsignedByte>{Data2D}, TestSuite::Compare::Container);
}
#endif
namespace {
constexpr UnsignedByte Zero3D[4*4*4*4] = {};
constexpr UnsignedByte SubData3DComplete[] = {
@ -1036,6 +1135,44 @@ void TextureGLTest::subImage3DBuffer() {
#endif
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::subImage3DQuery() {
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."));
Texture3D texture;
texture.setStorage(1, TextureFormat::RGBA8, Vector3i{4})
.setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{4}, SubData3DComplete});
MAGNUM_VERIFY_NO_ERROR();
Image3D image = texture.subImage(0, Range3Di::fromSize(Vector3i{1}, Vector3i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i{2});
CORRADE_COMPARE_AS(
Containers::ArrayReference<const UnsignedByte>(image.data<UnsignedByte>(), image.pixelSize()*image.size().product()), Containers::ArrayReference<const UnsignedByte>{Data3D}, TestSuite::Compare::Container);
}
void TextureGLTest::subImage3DQueryBuffer() {
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."));
Texture3D texture;
texture.setStorage(1, TextureFormat::RGBA8, Vector3i{4})
.setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{4}, SubData3DComplete});
MAGNUM_VERIFY_NO_ERROR();
BufferImage3D image = texture.subImage(0, Range3Di::fromSize(Vector3i{1}, Vector3i{2}), {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i{2});
CORRADE_COMPARE_AS(imageData, Containers::ArrayReference<const UnsignedByte>{Data3D}, TestSuite::Compare::Container);
}
void TextureGLTest::generateMipmap1D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported."));

22
src/Magnum/Texture.cpp

@ -82,6 +82,28 @@ template MAGNUM_EXPORT BufferImage<1> Texture<1>::image(Int, BufferImage<1>&&, B
template MAGNUM_EXPORT BufferImage<2> Texture<2>::image(Int, BufferImage<2>&&, BufferUsage);
template MAGNUM_EXPORT BufferImage<3> Texture<3>::image(Int, BufferImage<3>&&, BufferUsage);
#endif
template<UnsignedInt dimensions> Image<dimensions> Texture<dimensions>::subImage(const Int level, const RangeTypeFor<dimensions, Int>& range, Image<dimensions>&& image) {
this->subImage(level, range, image);
return std::move(image);
}
#ifndef DOXYGEN_GENERATING_OUTPUT
template MAGNUM_EXPORT Image<1> Texture<1>::subImage(Int, const Range1Di&, Image<1>&&);
template MAGNUM_EXPORT Image<2> Texture<2>::subImage(Int, const Range2Di&, Image<2>&&);
template MAGNUM_EXPORT Image<3> Texture<3>::subImage(Int, const Range3Di&, Image<3>&&);
#endif
template<UnsignedInt dimensions> BufferImage<dimensions> Texture<dimensions>::subImage(const Int level, const RangeTypeFor<dimensions, Int>& range, BufferImage<dimensions>&& image, const BufferUsage usage) {
this->subImage(level, range, image, usage);
return std::move(image);
}
#ifndef DOXYGEN_GENERATING_OUTPUT
template MAGNUM_EXPORT BufferImage<1> Texture<1>::subImage(Int, const Range1Di&, BufferImage<1>&&, BufferUsage);
template MAGNUM_EXPORT BufferImage<2> Texture<2>::subImage(Int, const Range2Di&, BufferImage<2>&&, BufferUsage);
template MAGNUM_EXPORT BufferImage<3> Texture<3>::subImage(Int, const Range3Di&, BufferImage<3>&&, BufferUsage);
#endif
#endif
}

50
src/Magnum/Texture.h

@ -686,6 +686,56 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @endcode
*/
BufferImage<dimensions> image(Int level, BufferImage<dimensions>&& image, BufferUsage usage);
/**
* @brief Read range of given texture mip level to image
* @param level Mip level
* @param range Range to read
* @param image Image where to put the data
*
* Image parameters like format and type of pixel data are taken from
* given image.
* @see @fn_gl{GetTextureSubImage}
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void subImage(Int level, const RangeTypeFor<dimensions, Int>& range, Image<dimensions>& image) {
AbstractTexture::subImage<dimensions>(level, range, image);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* Image2D image = texture.subImage(0, rect, {ColorFormat::RGBA, ColorType::UnsignedByte});
* @endcode
*/
Image<dimensions> subImage(Int level, const RangeTypeFor<dimensions, Int>& range, Image<dimensions>&& image);
/**
* @brief Read range of given texture mip level to buffer image
* @param level Mip level
* @param range Range to read
* @param image Buffer image where to put the data
* @param usage Buffer usage
*
* See @ref subImage(Int, const RangeTypeFor<dimensions, Int>&, Image&)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void subImage(Int level, const RangeTypeFor<dimensions, Int>& range, BufferImage<dimensions>& image, BufferUsage usage) {
AbstractTexture::subImage<dimensions>(level, range, image, usage);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* BufferImage2D image = texture.subImage(0, rect, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
* @endcode
*/
BufferImage<dimensions> subImage(Int level, const RangeTypeFor<dimensions, Int>& range, BufferImage<dimensions>&& image, BufferUsage usage);
#endif
/**

10
src/Magnum/TextureArray.cpp

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

42
src/Magnum/TextureArray.h

@ -386,6 +386,48 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
* @endcode
*/
BufferImage<dimensions+1> image(Int level, BufferImage<dimensions+1>&& image, BufferUsage usage);
/**
* @copybrief Texture::subImage(Int, const RangeTypeFor<dimensions, Int>&, Image&)
*
* See @ref Texture::subImage(Int, const RangeTypeFor<dimensions, Int>&, Image&)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void subImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, Image<dimensions+1>& image) {
AbstractTexture::subImage<dimensions+1>(level, range, image);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* Image3D image = texture.subImage(0, range, {ColorFormat::RGBA, ColorType::UnsignedByte});
* @endcode
*/
Image<dimensions+1> subImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, Image<dimensions+1>&& image);
/**
* @copybrief Texture::subImage(Int, const RangeTypeFor<dimensions, Int>&, BufferImage&, BufferUsage)
*
* See @ref Texture::subImage(Int, const RangeTypeFor<dimensions, Int>&, BufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void subImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, BufferImage<dimensions+1>& image, BufferUsage usage) {
AbstractTexture::subImage<dimensions+1>(level, range, image, usage);
}
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* BufferImage3D image = texture.subImage(0, range, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
* @endcode
*/
BufferImage<dimensions+1> subImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, BufferImage<dimensions+1>&& image, BufferUsage usage);
#endif
/**

Loading…
Cancel
Save