Browse Source

Added CubeMapTexture::{image,subImage}() for all six faces together.

Requires ARB_direct_state_access.
pull/94/head
Vladimír Vondruš 11 years ago
parent
commit
e07454b1ee
  1. 2
      doc/opengl-mapping.dox
  2. 41
      src/Magnum/CubeMapTexture.cpp
  3. 74
      src/Magnum/CubeMapTexture.h
  4. 81
      src/Magnum/Test/CubeMapTextureGLTest.cpp

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} | |
@fn_gl{GetTextureSubImage} | @ref CubeMapTexture::image()
@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

41
src/Magnum/CubeMapTexture.cpp

@ -56,6 +56,35 @@ Vector2i CubeMapTexture::imageSize(const Int level) {
#endif
#ifndef MAGNUM_TARGET_GLES
void CubeMapTexture::image(const Int level, Image3D& image) {
const Vector3i size{imageSize(level), 6};
const std::size_t dataSize = image.dataSize(size);
char* data = new char[dataSize];
Buffer::unbindInternal(Buffer::TargetHint::PixelPack);
glGetTextureImage(_id, level, GLenum(image.format()), GLenum(image.type()), dataSize, data);
image.setData(image.format(), image.type(), size, data);
}
Image3D CubeMapTexture::image(const Int level, Image3D&& image) {
this->image(level, image);
return std::move(image);
}
void CubeMapTexture::image(const Int level, BufferImage3D& image, const BufferUsage usage) {
const Vector3i size{imageSize(level), 6};
const std::size_t dataSize = image.dataSize(size);
if(image.size() != size)
image.setData(image.format(), image.type(), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
glGetTextureImage(_id, level, GLenum(image.format()), GLenum(image.type()), dataSize, nullptr);
}
BufferImage3D CubeMapTexture::image(const Int level, BufferImage3D&& image, const BufferUsage usage) {
this->image(level, image, usage);
return std::move(image);
}
void CubeMapTexture::image(const Coordinate coordinate, const Int level, Image2D& image) {
const Vector2i size = imageSize(level);
const std::size_t dataSize = image.dataSize(size);
@ -84,6 +113,18 @@ BufferImage2D CubeMapTexture::image(const Coordinate coordinate, const Int level
this->image(coordinate, level, 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());
return *this;
}
CubeMapTexture& CubeMapTexture::setSubImage(const Int level, const Vector3i& offset, BufferImage3D& image) {
image.buffer().bindInternal(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()), nullptr);
return *this;
}
#endif
CubeMapTexture& CubeMapTexture::setSubImage(const Coordinate coordinate, const Int level, const Vector2i& offset, const ImageReference2D& image) {

74
src/Magnum/CubeMapTexture.h

@ -378,6 +378,47 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Read given mip level of texture to image
*
* Image parameters like format and type of pixel data are taken from
* given image, image size is taken from the texture using
* @ref imageSize().
* @see @fn_gl2{GetTextureLevelParameter,GetTexLevelParameter} with
* @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT}, then
* @fn_gl{GetTextureImage}
* @requires_gl45 Extension @extension{ARB,direct_state_access}
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void image(Int level, Image3D& image);
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte});
* @endcode
*/
Image3D image(Int level, Image3D&& image);
/**
* @brief Read given mip level of texture to buffer image
*
* See @ref image(Int, Image3D&) for more information.
* @requires_gl45 Extension @extension{ARB,direct_state_access}
* @requires_gl Texture image queries are not available in OpenGL ES.
*/
void image(Int level, BufferImage3D& image, BufferUsage usage);
/** @overload
*
* Convenience alternative to the above, example usage:
* @code
* BufferImage3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
* @endcode
*/
BufferImage3D image(Int level, BufferImage3D&& image, BufferUsage usage);
/**
* @brief Read given mip level and coordinate of texture to image
*
@ -473,6 +514,39 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
}
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Set image subdata
* @param level Mip level
* @param offset Offset where to put data in the texture
* @param image @ref Image, @ref ImageReference or
* @ref Trade::ImageData of the same dimension count
* @return Reference to self (for method chaining)
*
* @see @ref setStorage(), @fn_gl2{TextureSubImage3D,TexSubImage3D}
* @requires_gl45 Extension @extension{ARB,direct_state_access}
* @requires_gl In OpenGL ES you need to set image for each face
* separately.
*/
CubeMapTexture& setSubImage(Int level, const Vector3i& offset, const ImageReference3D& image);
/** @overload
* @requires_gl45 Extension @extension{ARB,direct_state_access}
* @requires_gl In OpenGL ES you need to set image for each face
* separately.
*/
CubeMapTexture& setSubImage(Int level, const Vector3i& offset, BufferImage3D& image);
/** @overload
* @requires_gl45 Extension @extension{ARB,direct_state_access}
* @requires_gl In OpenGL ES you need to set image for each face
* separately.
*/
CubeMapTexture& setSubImage(Int level, const Vector3i& offset, BufferImage3D&& image) {
return setSubImage(level, offset, image);
}
#endif
/**
* @copybrief Texture::setSubImage()
* @return Reference to self (for method chaining)

81
src/Magnum/Test/CubeMapTextureGLTest.cpp

@ -61,6 +61,10 @@ struct CubeMapTextureGLTest: AbstractOpenGLTester {
void storage();
#ifndef MAGNUM_TARGET_GLES
void imageFull();
void imageFullBuffer();
#endif
void image();
#ifndef MAGNUM_TARGET_GLES2
void imageBuffer();
@ -98,6 +102,10 @@ CubeMapTextureGLTest::CubeMapTextureGLTest() {
&CubeMapTextureGLTest::storage,
#ifndef MAGNUM_TARGET_GLES
&CubeMapTextureGLTest::imageFull,
&CubeMapTextureGLTest::imageFullBuffer,
#endif
&CubeMapTextureGLTest::image,
#ifndef MAGNUM_TARGET_GLES2
&CubeMapTextureGLTest::imageBuffer,
@ -276,6 +284,79 @@ void CubeMapTextureGLTest::storage() {
#endif
}
namespace {
constexpr UnsignedByte Data[] = { 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b,
0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b,
0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43,
0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b,
0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53,
0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b,
0x5c, 0x5d, 0x5e, 0x5f };
}
#ifndef MAGNUM_TARGET_GLES
void CubeMapTextureGLTest::imageFull() {
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{2, 2})
.setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{2, 2, 6}, Data});
MAGNUM_VERIFY_NO_ERROR();
Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i(2, 2, 6));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(image.data(), image.data()+image.pixelSize()*image.size().product()),
std::vector<UnsignedByte>(Data, Data+96), TestSuite::Compare::Container);
}
void CubeMapTextureGLTest::imageFullBuffer() {
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{2})
.setSubImage(0, {}, BufferImage3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{2, 2, 6}, Data, BufferUsage::StaticDraw});
MAGNUM_VERIFY_NO_ERROR();
BufferImage3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}, BufferUsage::StaticRead);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i(2, 2, 6));
const auto imageData = image.buffer().data<UnsignedByte>();
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(imageData.begin(), imageData.end()),
std::vector<UnsignedByte>(Data, Data+96), TestSuite::Compare::Container);
}
#endif
void CubeMapTextureGLTest::image() {
constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,

Loading…
Cancel
Save