Browse Source

Implemented *Framebuffer::copyImage() and copySubImage().

Default, ARB_DSA and EXT_DSA paths.
pull/158/head
Vladimír Vondruš 10 years ago
parent
commit
f68b40c5d9
  1. 4
      doc/opengl-mapping.dox
  2. 1
      doc/opengl-support.dox
  3. 160
      src/Magnum/AbstractFramebuffer.cpp
  4. 322
      src/Magnum/AbstractFramebuffer.h
  5. 1
      src/Magnum/AbstractTexture.h
  6. 19
      src/Magnum/Implementation/FramebufferState.cpp
  7. 10
      src/Magnum/Implementation/FramebufferState.h
  8. 556
      src/Magnum/Test/FramebufferGLTest.cpp
  9. 9
      src/Magnum/Texture.h

4
doc/opengl-mapping.dox

@ -101,8 +101,8 @@ OpenGL function | Matching API
@fn_gl{CompressedTexSubImage1D}, \n `glCompressedTextureSubImage1D()`, \n @fn_gl_extension{CompressedTextureSubImage1D,EXT,direct_state_access}, \n @fn_gl{CompressedTexSubImage2D}, \n `glCompressedTextureSubImage2D()`, \n @fn_gl_extension{CompressedTextureSubImage2D,EXT,direct_state_access}, \n @fn_gl{CompressedTexSubImage3D}, \n `glCompressedTextureSubImage3D()`, \n @fn_gl_extension{CompressedTextureSubImage3D,EXT,direct_state_access} | @ref Texture::setCompressedSubImage(), \n @ref TextureArray::setCompressedSubImage(), \n @ref CubeMapTexture::setCompressedSubImage(), \n @ref CubeMapTextureArray::setCompressedSubImage(), \n @ref RectangleTexture::setCompressedSubImage() @fn_gl{CompressedTexSubImage1D}, \n `glCompressedTextureSubImage1D()`, \n @fn_gl_extension{CompressedTextureSubImage1D,EXT,direct_state_access}, \n @fn_gl{CompressedTexSubImage2D}, \n `glCompressedTextureSubImage2D()`, \n @fn_gl_extension{CompressedTextureSubImage2D,EXT,direct_state_access}, \n @fn_gl{CompressedTexSubImage3D}, \n `glCompressedTextureSubImage3D()`, \n @fn_gl_extension{CompressedTextureSubImage3D,EXT,direct_state_access} | @ref Texture::setCompressedSubImage(), \n @ref TextureArray::setCompressedSubImage(), \n @ref CubeMapTexture::setCompressedSubImage(), \n @ref CubeMapTextureArray::setCompressedSubImage(), \n @ref RectangleTexture::setCompressedSubImage()
@fn_gl{CopyBufferSubData}, \n `glCopyNamedBufferSubData()`, \n @fn_gl_extension{NamedCopyBufferSubData,EXT,direct_state_access} | @ref Buffer::copy() @fn_gl{CopyBufferSubData}, \n `glCopyNamedBufferSubData()`, \n @fn_gl_extension{NamedCopyBufferSubData,EXT,direct_state_access} | @ref Buffer::copy()
@fn_gl{CopyImageSubData} | | @fn_gl{CopyImageSubData} | |
@fn_gl{CopyTexImage1D}, \n @fn_gl_extension{CopyTextureImage1D,EXT,direct_state_access}, \n @fn_gl{CopyTexImage2D}, \n @fn_gl_extension{CopyTextureImage2D,EXT,direct_state_access} | | @fn_gl{CopyTexImage1D}, \n @fn_gl{CopyTexImage2D} | @ref Framebuffer::copyImage()
@fn_gl{CopyTexSubImage1D}, \n `glCopyTextureSubImage1D()`, \n @fn_gl_extension{CopyTextureSubImage1D,EXT,direct_state_access}, \n @fn_gl{CopyTexSubImage2D}, \n `glCopyTextureSubImage2D()`, \n @fn_gl_extension{CopyTextureSubImage2D,EXT,direct_state_access}, \n @fn_gl{CopyTexSubImage3D}, \n `glCopyTextureSubImage3D()`, \n @fn_gl_extension{CopyTextureSubImage3D,EXT,direct_state_access} | | @fn_gl{CopyTexSubImage1D}, \n `glCopyTextureSubImage1D()`, \n @fn_gl_extension{CopyTextureSubImage1D,EXT,direct_state_access}, \n @fn_gl{CopyTexSubImage2D}, \n `glCopyTextureSubImage2D()`, \n @fn_gl_extension{CopyTextureSubImage2D,EXT,direct_state_access}, \n @fn_gl{CopyTexSubImage3D}, \n `glCopyTextureSubImage3D()`, \n @fn_gl_extension{CopyTextureSubImage3D,EXT,direct_state_access} | @ref Framebuffer::copySubImage()
@fn_gl{CreateProgram}, @fn_gl{DeleteProgram} | @ref AbstractShaderProgram constructor and destructor @fn_gl{CreateProgram}, @fn_gl{DeleteProgram} | @ref AbstractShaderProgram constructor and destructor
@fn_gl{CreateShader}, @fn_gl{DeleteShader} | @ref Shader constructor and destructor @fn_gl{CreateShader}, @fn_gl{DeleteShader} | @ref Shader constructor and destructor
@fn_gl{CreateShaderProgram} | | @fn_gl{CreateShaderProgram} | |

1
doc/opengl-support.dox

@ -40,7 +40,6 @@ The core subset of OpenGL 2.1 should be fully implemented, except for the
following: following:
- Proxy textures - Proxy textures
- Copying framebuffer to texture (@fn_gl{CopyTexImage2D} etc.)
- Some forgotten limit queries - Some forgotten limit queries
@subsection opengl-support-30 OpenGL 3.0 @subsection opengl-support-30 OpenGL 3.0

160
src/Magnum/AbstractFramebuffer.cpp

@ -29,8 +29,19 @@
#include "Magnum/BufferImage.h" #include "Magnum/BufferImage.h"
#endif #endif
#include "Magnum/Context.h" #include "Magnum/Context.h"
#include "Magnum/CubeMapTexture.h"
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
#include "Magnum/CubeMapTextureArray.h"
#endif
#include "Magnum/Extensions.h" #include "Magnum/Extensions.h"
#include "Magnum/Image.h" #include "Magnum/Image.h"
#ifndef MAGNUM_TARGET_GLES
#include "Magnum/RectangleTexture.h"
#endif
#include "Magnum/Texture.h"
#ifndef MAGNUM_TARGET_GLES2
#include "Magnum/TextureArray.h"
#endif
#include "Implementation/FramebufferState.h" #include "Implementation/FramebufferState.h"
#include "Implementation/State.h" #include "Implementation/State.h"
@ -331,6 +342,96 @@ BufferImage2D AbstractFramebuffer::read(const Range2Di& rectangle, BufferImage2D
} }
#endif #endif
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::copyImage(const Range2Di& rectangle, Texture1D& texture, const Int level, const TextureFormat internalFormat) {
CORRADE_ASSERT(rectangle.sizeY() == 1, "AbstractFramebuffer::copyImage(): height must be 1 for 1D textures", );
bindInternal(FramebufferTarget::Read);
texture.bindInternal();
glCopyTexImage1D(GL_TEXTURE_1D, level, GLenum(internalFormat), rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), 0);
}
#endif
void AbstractFramebuffer::copyImage(const Range2Di& rectangle, Texture2D& texture, const Int level, const TextureFormat internalFormat) {
bindInternal(FramebufferTarget::Read);
texture.bindInternal();
glCopyTexImage2D(GL_TEXTURE_2D, level, GLenum(internalFormat), rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY(), 0);
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::copyImage(const Range2Di& rectangle, RectangleTexture& texture, const TextureFormat internalFormat) {
bindInternal(FramebufferTarget::Read);
texture.bindInternal();
glCopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, GLenum(internalFormat), rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY(), 0);
}
#endif
void AbstractFramebuffer::copyImage(const Range2Di& rectangle, CubeMapTexture& texture, const CubeMapCoordinate coordinate, const Int level, const TextureFormat internalFormat) {
bindInternal(FramebufferTarget::Read);
texture.bindInternal();
glCopyTexImage2D(GLenum(coordinate), level, GLenum(internalFormat), rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY(), 0);
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::copyImage(const Range2Di& rectangle, Texture1DArray& texture, const Int level, const TextureFormat internalFormat) {
bindInternal(FramebufferTarget::Read);
texture.bindInternal();
glCopyTexImage2D(GL_TEXTURE_1D_ARRAY, level, GLenum(internalFormat), rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY(), 0);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::copySubImage(const Range2Di& rectangle, Texture1D& texture, const Int level, const Int offset) {
CORRADE_ASSERT(rectangle.sizeY() == 1, "AbstractFramebuffer::copyImage(): height must be 1 for 1D textures", );
bindInternal(FramebufferTarget::Read);
Context::current().state().framebuffer->copySub1DImplementation(rectangle, texture, level, offset);
}
#endif
void AbstractFramebuffer::copySubImage(const Range2Di& rectangle, Texture2D& texture, const Int level, const Vector2i& offset) {
bindInternal(FramebufferTarget::Read);
Context::current().state().framebuffer->copySub2DImplementation(rectangle, texture, GL_TEXTURE_2D, level, offset);
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::copySubImage(const Range2Di& rectangle, RectangleTexture& texture, const Vector2i& offset) {
bindInternal(FramebufferTarget::Read);
Context::current().state().framebuffer->copySub2DImplementation(rectangle, texture, GL_TEXTURE_RECTANGLE, 0, offset);
}
#endif
void AbstractFramebuffer::copySubImage(const Range2Di& rectangle, CubeMapTexture& texture, const Int level, const Vector3i& offset) {
bindInternal(FramebufferTarget::Read);
Context::current().state().framebuffer->copySubCubeMapImplementation(rectangle, texture, GL_TEXTURE_CUBE_MAP_POSITIVE_X + offset.z(), level, offset.xy());
}
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void AbstractFramebuffer::copySubImage(const Range2Di& rectangle, Texture3D& texture, const Int level, const Vector3i& offset) {
bindInternal(FramebufferTarget::Read);
Context::current().state().framebuffer->copySub3DImplementation(rectangle, texture, level, offset);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::copySubImage(const Range2Di& rectangle, Texture1DArray& texture, const Int level, const Vector2i& offset) {
bindInternal(FramebufferTarget::Read);
Context::current().state().framebuffer->copySub2DImplementation(rectangle, texture, GL_TEXTURE_1D_ARRAY, level, offset);
}
#endif
#ifndef MAGNUM_TARGET_GLES2
void AbstractFramebuffer::copySubImage(const Range2Di& rectangle, Texture2DArray& texture, const Int level, const Vector3i& offset) {
bindInternal(FramebufferTarget::Read);
Context::current().state().framebuffer->copySub3DImplementation(rectangle, texture, level, offset);
}
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void AbstractFramebuffer::copySubImage(const Range2Di& rectangle, CubeMapTextureArray& texture, const Int level, const Vector3i& offset) {
bindInternal(FramebufferTarget::Read);
Context::current().state().framebuffer->copySub3DImplementation(rectangle, texture, level, offset);
}
#endif
void AbstractFramebuffer::invalidateImplementationNoOp(GLsizei, const GLenum* const) {} void AbstractFramebuffer::invalidateImplementationNoOp(GLsizei, const GLenum* const) {}
void AbstractFramebuffer::invalidateImplementationDefault(const GLsizei count, const GLenum* const attachments) { void AbstractFramebuffer::invalidateImplementationDefault(const GLsizei count, const GLenum* const attachments) {
@ -497,4 +598,63 @@ void AbstractFramebuffer::readImplementationRobustness(const Range2Di& rectangle
} }
#endif #endif
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::copySub1DImplementationDefault(const Range2Di& rectangle, AbstractTexture& texture, const Int level, const Int offset) {
texture.bindInternal();
glCopyTexSubImage1D(texture._target, level, offset, rectangle.min().x(), rectangle.min().y(), rectangle.sizeX());
}
void AbstractFramebuffer::copySub1DImplementationDSA(const Range2Di& rectangle, AbstractTexture& texture, const Int level, const Int offset) {
glCopyTextureSubImage1D(texture._id, level, offset, rectangle.min().x(), rectangle.min().y(), rectangle.sizeX());
}
void AbstractFramebuffer::copySub1DImplementationDSAEXT(const Range2Di& rectangle, AbstractTexture& texture, const Int level, const Int offset) {
texture._flags |= ObjectFlag::Created;
glCopyTextureSubImage1DEXT(texture._id, texture._target, level, offset, rectangle.min().x(), rectangle.min().y(), rectangle.sizeX());
}
#endif
void AbstractFramebuffer::copySub2DImplementationDefault(const Range2Di& rectangle, AbstractTexture& texture, const GLenum target, const Int level, const Vector2i& offset) {
texture.bindInternal();
glCopyTexSubImage2D(target, level, offset.x(), offset.y(), rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY());
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::copySub2DImplementationDSA(const Range2Di& rectangle, AbstractTexture& texture, const GLenum, const Int level, const Vector2i& offset) {
glCopyTextureSubImage2D(texture._id, level, offset.x(), offset.y(), rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY());
}
void AbstractFramebuffer::copySubCubeMapImplementationDSA(const Range2Di& rectangle, AbstractTexture& texture, const GLenum target, const Int level, const Vector2i& offset) {
glCopyTextureSubImage3D(texture._id, level, offset.x(), offset.y(), target - GL_TEXTURE_CUBE_MAP_POSITIVE_X, rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY());
}
void AbstractFramebuffer::copySub2DImplementationDSAEXT(const Range2Di& rectangle, AbstractTexture& texture, const GLenum target, const Int level, const Vector2i& offset) {
texture._flags |= ObjectFlag::Created;
glCopyTextureSubImage2DEXT(texture._id, target, level, offset.x(), offset.y(), rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY());
}
#endif
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
void AbstractFramebuffer::copySub3DImplementationDefault(const Range2Di& rectangle, AbstractTexture& texture, const Int level, const Vector3i& offset) {
texture.bindInternal();
#ifndef MAGNUM_TARGET_GLES2
glCopyTexSubImage3D
#else
glCopyTexSubImage3DOES
#endif
(texture._target, level, offset.x(), offset.y(), offset.z(), rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY());
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::copySub3DImplementationDSA(const Range2Di& rectangle, AbstractTexture& texture, const Int level, const Vector3i& offset) {
glCopyTextureSubImage3D(texture._id, level, offset.x(), offset.y(), offset.z(), rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY());
}
void AbstractFramebuffer::copySub3DImplementationDSAEXT(const Range2Di& rectangle, AbstractTexture& texture, const Int level, const Vector3i& offset) {
texture._flags |= ObjectFlag::Created;
glCopyTextureSubImage3DEXT(texture._id, texture._target, level, offset.x(), offset.y(), offset.z(), rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY());
}
#endif
} }

322
src/Magnum/AbstractFramebuffer.h

@ -383,6 +383,307 @@ class MAGNUM_EXPORT AbstractFramebuffer {
#endif #endif
#endif #endif
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Copy block of pixels from framebuffer to 1D texture image
* @param rectangle Framebuffer rectangle to copy. Height must
* be `1`.
* @param texture Texture where to put the data
* @param level Texture mip level
* @param internalFormat Texture internal format
*
* On platforms that support it prefer to use @ref Texture1D::setStorage()
* and @ref copySubImage() instead, as it avoids unnecessary
* reallocations and has better performance characteristics. This call
* also has no equivalent in @extension{ARB,direct_state_access}, thus
* the texture needs to be bound to some texture unit before the
* operation.
* @see @ref Texture1D::maxSize(), @fn_gl{BindFramebuffer}, then
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexImage1D}
* @requires_gl 1D textures are not available in OpenGL ES or WebGL.
* @deprecated_gl Prefer to use @ref Texture1D::setStorage() and
* @ref copySubImage() instead.
*/
void copyImage(const Range2Di& rectangle, Texture1D& texture, Int level, TextureFormat internalFormat);
#endif
/**
* @brief Copy block of pixels from framebuffer to 2D texture image
* @param rectangle Framebuffer rectangle to copy
* @param texture Texture where to put the data
* @param level Texture mip level
* @param internalFormat Texture internal format
*
* On platforms that support it prefer to use @ref Texture2D::setStorage()
* and @ref copySubImage() instead, as it avoids unnecessary
* reallocations and has better performance characteristics. This call
* also has no equivalent in @extension{ARB,direct_state_access}, thus
* the texture needs to be bound to some texture unit before the
* operation.
* @see @ref Texture2D::maxSize(), @fn_gl{BindFramebuffer}, then
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexImage2D}
* @deprecated_gl Prefer to use @ref Texture2D::setStorage() and
* @ref copySubImage() instead.
*/
void copyImage(const Range2Di& rectangle, Texture2D& texture, Int level, TextureFormat internalFormat);
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Copy block of pixels from framebuffer to rectangle texture
* @param rectangle Framebuffer rectangle to copy
* @param texture Texture where to put the data
* @param internalFormat Texture internal format
*
* On platforms that support it prefer to use @ref RectangleTexture::setStorage()
* and @ref copySubImage() instead, as it avoids unnecessary
* reallocations and has better performance characteristics. This call
* also has no equivalent in @extension{ARB,direct_state_access}, thus
* the texture needs to be bound to some texture unit before the
* operation.
* @see @ref Texture2D::maxSize(), @fn_gl{BindFramebuffer}, then
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexImage2D}
* @requires_gl31 Extension @extension{ARB,texture_rectangle}
* @requires_gl Rectangle textures are not available in OpenGL ES and
* WebGL.
* @deprecated_gl Prefer to use @ref RectangleTexture::setStorage() and
* @ref copySubImage() instead.
*/
void copyImage(const Range2Di& rectangle, RectangleTexture& texture, TextureFormat internalFormat);
#endif
/**
* @brief Copy block of pixels from framebuffer to cube map texture image
* @param rectangle Framebuffer rectangle to copy
* @param texture Texture where to put the data
* @param level Texture mip level
* @param coordinate Cube map coordinate
* @param internalFormat Texture internal format
*
* On platforms that support it prefer to use @ref CubeMapTexture::setStorage()
* and @ref copySubImage() instead, as it avoids unnecessary
* reallocations and has better performance characteristics. This call
* also has no equivalent in @extension{ARB,direct_state_access}, thus
* the texture needs to be bound to some texture unit before the
* operation.
* @see @ref Texture2D::maxSize(), @fn_gl{BindFramebuffer}, then
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexImage2D}
* @deprecated_gl Prefer to use @ref CubeMapTexture::setStorage() and
* @ref copySubImage() instead.
*/
void copyImage(const Range2Di& rectangle, CubeMapTexture& texture, CubeMapCoordinate coordinate, Int level, TextureFormat internalFormat);
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Copy block of pixels from framebuffer to 1D texture array image
* @param rectangle Framebuffer rectangle to copy
* @param texture Texture where to put the data
* @param level Texture mip level
* @param internalFormat Texture internal format
*
* On platforms that support it prefer to use @ref Texture2D::setStorage()
* and @ref copySubImage() instead, as it avoids unnecessary
* reallocations and has better performance characteristics. This call
* also has no equivalent in @extension{ARB,direct_state_access}, thus
* the texture needs to be bound to some texture unit before the
* operation.
* @see @ref Texture2D::maxSize(), @fn_gl{BindFramebuffer}, then
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexImage2D}
* @requires_gl 1D array textures are not available in OpenGL ES or
* WebGL, only 2D ones.
* @deprecated_gl Prefer to use @ref Texture1DArray::setStorage() and
* @ref copySubImage() instead.
*/
void copyImage(const Range2Di& rectangle, Texture1DArray& texture, Int level, TextureFormat internalFormat);
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Copy block of pixels from framebuffer to 1D texture subimage
* @param rectangle Framebuffer rectangle to copy. Height must
* be `1`.
* @param texture Texture where to put the data
* @param level Texture mip level
* @param offset Offset inside the texture
*
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the texture is bound before the operation (if not
* already).
* @see @ref Texture1D::setStorage(), @fn_gl{BindFramebuffer}, then
* @fn_gl2{CopyTextureSubImage1D,CopyTexSubImage1D},
* @fn_gl_extension{CopyTextureSubImage1D,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexSubImage1D}
* @requires_gl 1D textures are not available in OpenGL ES or WebGL.
*/
void copySubImage(const Range2Di& rectangle, Texture1D& texture, Int level, Int offset);
#endif
/**
* @brief Copy block of pixels from framebuffer to 2D texture subimage
* @param rectangle Framebuffer rectangle to copy
* @param texture Texture where to put the data
* @param level Texture mip level
* @param offset Offset inside the texture
*
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the texture is bound before the operation (if not
* already).
* @see @ref Texture2D::setStorage(), @fn_gl{BindFramebuffer}, then
* @fn_gl2{CopyTextureSubImage2D,CopyTexSubImage2D},
* @fn_gl_extension{CopyTextureSubImage2D,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexSubImage2D}
*/
void copySubImage(const Range2Di& rectangle, Texture2D& texture, Int level, const Vector2i& offset);
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Copy block of pixels from framebuffer to rectangle texture subimage
* @param rectangle Framebuffer rectangle to copy
* @param texture Texture where to put the data
* @param offset Offset inside the texture
*
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the texture is bound before the operation (if not
* already).
* @see @ref RectangleTexture::setStorage(), @fn_gl{BindFramebuffer},
* then @fn_gl2{CopyTextureSubImage2D,CopyTexSubImage2D},
* @fn_gl_extension{CopyTextureSubImage2D,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexSubImage2D}
* @requires_gl Rectangle textures are not available in OpenGL ES and
* WebGL.
*/
void copySubImage(const Range2Di& rectangle, RectangleTexture& texture, const Vector2i& offset);
#endif
/**
* @brief Copy block of pixels from framebuffer to cube map texture subimage
* @param rectangle Framebuffer rectangle to copy
* @param texture Texture where to put the data
* @param level Texture mip level
* @param offset Offset inside the texture
*
* Z coordinate of the offset is equivalent to number of texture face,
* i.e. +X is `0` and so on, in order of (+X, -X, +Y, -Y, +Z, -Z). If
* neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) nor
* @extension{EXT,direct_state_access} desktop extension is available,
* the texture is bound before the operation (if not already).
* @see @ref CubeMapTexture::setStorage(), @fn_gl{BindFramebuffer},
* then @fn_gl2{CopyTextureSubImage3D,CopyTexSubImage3D},
* @fn_gl_extension{CopyTextureSubImage2D,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexSubImage2D}
*/
void copySubImage(const Range2Di& rectangle, CubeMapTexture& texture, Int level, const Vector3i& offset);
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/**
* @brief Copy block of pixels from framebuffer to 3D texture subimage
* @param rectangle Framebuffer rectangle to copy
* @param texture Texture where to put the data
* @param level Texture mip level
* @param offset Offset inside the texture
*
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the texture is bound before the operation (if not
* already).
* @see @ref Texture3D::setStorage(), @fn_gl{BindFramebuffer}, then
* @fn_gl2{CopyTextureSubImage3D,CopyTexSubImage3D},
* @fn_gl_extension{CopyTextureSubImage3D,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexSubImage3D}
* @requires_gles30 Extension @es_extension{OES,texture_3D} in OpenGL
* ES 2.0.
* @requires_webgl20 Only 2D textures are available in WebGL 1.0.
*/
void copySubImage(const Range2Di& rectangle, Texture3D& texture, Int level, const Vector3i& offset);
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Copy block of pixels from framebuffer to 1D texture array subimage
* @param rectangle Framebuffer rectangle to copy
* @param texture Texture where to put the data
* @param level Texture mip level
* @param offset Offset inside the texture
*
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the texture is bound before the operation (if not
* already).
* @see @ref Texture1DArray::setStorage(), @fn_gl{BindFramebuffer},
* then @fn_gl2{CopyTextureSubImage2D,CopyTexSubImage2D},
* @fn_gl_extension{CopyTextureSubImage2D,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexSubImage2D}
* @requires_gl 1D array textures are not available in OpenGL ES or
* WebGL, only 2D ones.
*/
void copySubImage(const Range2Di& rectangle, Texture1DArray& texture, Int level, const Vector2i& offset);
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Copy block of pixels from framebuffer to 2D texture array subimage
* @param rectangle Framebuffer rectangle to copy
* @param texture Texture where to put the data
* @param level Texture mip level
* @param offset Offset inside the texture
*
* If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5)
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the texture is bound before the operation (if not
* already).
* @see @ref Texture2DArray::setStorage(), @fn_gl{BindFramebuffer},
* then @fn_gl2{CopyTextureSubImage3D,CopyTexSubImage3D},
* @fn_gl_extension{CopyTextureSubImage3D,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexSubImage3D}
* @requires_gl30 Extension @extension{EXT,texture_array}
* @requires_gles30 Array textures are not available in OpenGL ES 2.0.
* @requires_webgl20 Array textures are not available in WebGL 1.0.
*/
void copySubImage(const Range2Di& rectangle, Texture2DArray& texture, Int level, const Vector3i& offset);
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/**
* @brief Copy block of pixels from framebuffer to cube map texture array subimage
* @param rectangle Framebuffer rectangle to copy
* @param texture Texture where to put the data
* @param level Texture mip level
* @param offset Offset inside the texture
*
* Z coordinate of the offset is equivalent to layer * 6 + number of
* texture face, i.e. +X is `0` and so on, in order of (+X, -X, +Y, -Y,
* +Z, -Z). If neither @extension{ARB,direct_state_access} (part of
* OpenGL 4.5) nor @extension{EXT,direct_state_access} desktop
* available, the texture is bound before the operation (if not
* already).
* @see @ref CubeMapTextureArray::setStorage(), @fn_gl{BindFramebuffer},
* then @fn_gl2{CopyTextureSubImage3D,CopyTexSubImage3D},
* @fn_gl_extension{CopyTextureSubImage3D,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{CopyTexSubImage3D}
* @requires_gl40 Extension @extension{ARB,texture_cube_map_array}
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_es_extension Extension @es_extension{ANDROID,extension_pack_es31a}/
* @es_extension{EXT,texture_cube_map_array}
* @requires_gles Cube map texture arrays are not available in WebGL.
*/
void copySubImage(const Range2Di& rectangle, CubeMapTextureArray& texture, Int level, const Vector3i& offset);
#endif
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
private: private:
#else #else
@ -462,6 +763,27 @@ class MAGNUM_EXPORT AbstractFramebuffer {
static void MAGNUM_LOCAL readImplementationRobustness(const Range2Di& rectangle, PixelFormat format, PixelType type, std::size_t dataSize, GLvoid* data); static void MAGNUM_LOCAL readImplementationRobustness(const Range2Di& rectangle, PixelFormat format, PixelType type, std::size_t dataSize, GLvoid* data);
#endif #endif
#ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL copySub1DImplementationDefault(const Range2Di& rectangle, AbstractTexture& texture, Int level, Int offset);
static void MAGNUM_LOCAL copySub1DImplementationDSA(const Range2Di& rectangle, AbstractTexture& texture, Int level, Int offset);
static void MAGNUM_LOCAL copySub1DImplementationDSAEXT(const Range2Di& rectangle, AbstractTexture& texture, Int level, Int offset);
#endif
static void MAGNUM_LOCAL copySub2DImplementationDefault(const Range2Di& rectangle, AbstractTexture& texture, GLenum textureTarget, Int level, const Vector2i& offset);
#ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL copySub2DImplementationDSA(const Range2Di& rectangle, AbstractTexture& texture, GLenum textureTarget, Int level, const Vector2i& offset);
static void MAGNUM_LOCAL copySubCubeMapImplementationDSA(const Range2Di& rectangle, AbstractTexture& texture, GLenum textureTarget, Int level, const Vector2i& offset);
static void MAGNUM_LOCAL copySub2DImplementationDSAEXT(const Range2Di& rectangle, AbstractTexture& texture, GLenum textureTarget, Int level, const Vector2i& offset);
#endif
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
static void MAGNUM_LOCAL copySub3DImplementationDefault(const Range2Di& rectangle, AbstractTexture& texture, Int level, const Vector3i& offset);
#endif
#ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL copySub3DImplementationDSA(const Range2Di& rectangle, AbstractTexture& texture, Int level, const Vector3i& offset);
static void MAGNUM_LOCAL copySub3DImplementationDSAEXT(const Range2Di& rectangle, AbstractTexture& texture, Int level, const Vector3i& offset);
#endif
void MAGNUM_LOCAL invalidateImplementationNoOp(GLsizei, const GLenum*); void MAGNUM_LOCAL invalidateImplementationNoOp(GLsizei, const GLenum*);
void MAGNUM_LOCAL invalidateImplementationDefault(GLsizei count, const GLenum* attachments); void MAGNUM_LOCAL invalidateImplementationDefault(GLsizei count, const GLenum* attachments);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES

1
src/Magnum/AbstractTexture.h

@ -133,6 +133,7 @@ functions do nothing.
*/ */
class MAGNUM_EXPORT AbstractTexture: public AbstractObject { class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
friend Implementation::TextureState; friend Implementation::TextureState;
friend AbstractFramebuffer;
friend CubeMapTexture; friend CubeMapTexture;
public: public:

19
src/Magnum/Implementation/FramebufferState.cpp

@ -68,6 +68,11 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDSA; drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDSA;
readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSA; readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSA;
copySub1DImplementation = &AbstractFramebuffer::copySub1DImplementationDSA;
copySub2DImplementation = &AbstractFramebuffer::copySub2DImplementationDSA;
copySubCubeMapImplementation = &AbstractFramebuffer::copySubCubeMapImplementationDSA;
copySub3DImplementation = &AbstractFramebuffer::copySub3DImplementationDSA;
renderbufferImplementation = &Framebuffer::renderbufferImplementationDSA; renderbufferImplementation = &Framebuffer::renderbufferImplementationDSA;
/* The 1D implementation uses the same function as the layered attachment */ /* The 1D implementation uses the same function as the layered attachment */
texture1DImplementation = &Framebuffer::textureImplementationDSA; texture1DImplementation = &Framebuffer::textureImplementationDSA;
@ -88,6 +93,11 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDSAEXT; drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDSAEXT;
readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSAEXT; readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSAEXT;
copySub1DImplementation = &AbstractFramebuffer::copySub1DImplementationDSAEXT;
copySub2DImplementation = &AbstractFramebuffer::copySub2DImplementationDSAEXT;
copySubCubeMapImplementation = &AbstractFramebuffer::copySub2DImplementationDSAEXT;
copySub3DImplementation = &AbstractFramebuffer::copySub3DImplementationDSAEXT;
renderbufferImplementation = &Framebuffer::renderbufferImplementationDSAEXT; renderbufferImplementation = &Framebuffer::renderbufferImplementationDSAEXT;
texture1DImplementation = &Framebuffer::texture1DImplementationDSAEXT; texture1DImplementation = &Framebuffer::texture1DImplementationDSAEXT;
/* The EXT_DSA implementation is the same for both 2D and cube map textures */ /* The EXT_DSA implementation is the same for both 2D and cube map textures */
@ -111,6 +121,15 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDefault; readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDefault;
#endif #endif
#ifndef MAGNUM_TARGET_GLES
copySub1DImplementation = &AbstractFramebuffer::copySub1DImplementationDefault;
#endif
copySub2DImplementation = &AbstractFramebuffer::copySub2DImplementationDefault;
copySubCubeMapImplementation = &AbstractFramebuffer::copySub2DImplementationDefault;
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
copySub3DImplementation = &AbstractFramebuffer::copySub3DImplementationDefault;
#endif
renderbufferImplementation = &Framebuffer::renderbufferImplementationDefault; renderbufferImplementation = &Framebuffer::renderbufferImplementationDefault;
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
texture1DImplementation = &Framebuffer::texture1DImplementationDefault; texture1DImplementation = &Framebuffer::texture1DImplementationDefault;

10
src/Magnum/Implementation/FramebufferState.h

@ -56,6 +56,16 @@ struct FramebufferState {
#endif #endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void(AbstractFramebuffer::*readBufferImplementation)(GLenum); void(AbstractFramebuffer::*readBufferImplementation)(GLenum);
#endif
#ifndef MAGNUM_TARGET_GLES
void(*copySub1DImplementation)(const Range2Di&, AbstractTexture&, Int, Int);
#endif
void(*copySub2DImplementation)(const Range2Di&, AbstractTexture&, GLenum, Int, const Vector2i&);
void(*copySubCubeMapImplementation)(const Range2Di&, AbstractTexture&, GLenum, Int, const Vector2i&);
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
void(*copySub3DImplementation)(const Range2Di&, AbstractTexture&, Int, const Vector3i&);
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void(AbstractFramebuffer::*invalidateImplementation)(GLsizei, const GLenum*); void(AbstractFramebuffer::*invalidateImplementation)(GLsizei, const GLenum*);
#endif #endif
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2

556
src/Magnum/Test/FramebufferGLTest.cpp

@ -23,7 +23,8 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include "Magnum/configure.h" #include <Corrade/TestSuite/Compare/Container.h>
#include "Magnum/Context.h" #include "Magnum/Context.h"
#include "Magnum/CubeMapTexture.h" #include "Magnum/CubeMapTexture.h"
#include "Magnum/Extensions.h" #include "Magnum/Extensions.h"
@ -110,6 +111,35 @@ struct FramebufferGLTest: AbstractOpenGLTester {
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
void readBuffer(); void readBuffer();
#endif #endif
#ifndef MAGNUM_TARGET_GLES
void copyImageTexture1D();
#endif
void copyImageTexture2D();
#ifndef MAGNUM_TARGET_GLES
void copyImageTexture1DArray();
#endif
#ifndef MAGNUM_TARGET_GLES
void copyImageRectangleTexture();
#endif
void copyImageCubeMapTexture();
#ifndef MAGNUM_TARGET_GLES
void copySubImageTexture1D();
#endif
void copySubImageTexture2D();
void copySubImageTexture3D();
#ifndef MAGNUM_TARGET_GLES
void copySubImageTexture1DArray();
#endif
#ifndef MAGNUM_TARGET_GLES2
void copySubImageTexture2DArray();
#endif
#ifndef MAGNUM_TARGET_GLES
void copySubImageRectangleTexture();
#endif
void copySubImageCubeMapTexture();
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void copySubImageCubeMapTextureArray();
#endif
void blit(); void blit();
#ifdef MAGNUM_TARGET_GLES2 #ifdef MAGNUM_TARGET_GLES2
@ -175,6 +205,35 @@ FramebufferGLTest::FramebufferGLTest() {
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
&FramebufferGLTest::readBuffer, &FramebufferGLTest::readBuffer,
#endif #endif
#ifndef MAGNUM_TARGET_GLES
&FramebufferGLTest::copyImageTexture1D,
#endif
&FramebufferGLTest::copyImageTexture2D,
#ifndef MAGNUM_TARGET_GLES
&FramebufferGLTest::copyImageTexture1DArray,
#endif
#ifndef MAGNUM_TARGET_GLES
&FramebufferGLTest::copyImageRectangleTexture,
#endif
&FramebufferGLTest::copyImageCubeMapTexture,
#ifndef MAGNUM_TARGET_GLES
&FramebufferGLTest::copySubImageTexture1D,
#endif
&FramebufferGLTest::copySubImageTexture2D,
&FramebufferGLTest::copySubImageTexture3D,
#ifndef MAGNUM_TARGET_GLES
&FramebufferGLTest::copySubImageTexture1DArray,
#endif
#ifndef MAGNUM_TARGET_GLES2
&FramebufferGLTest::copySubImageTexture2DArray,
#endif
#ifndef MAGNUM_TARGET_GLES
&FramebufferGLTest::copySubImageRectangleTexture,
#endif
&FramebufferGLTest::copySubImageCubeMapTexture,
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
&FramebufferGLTest::copySubImageCubeMapTextureArray,
#endif
&FramebufferGLTest::blit}); &FramebufferGLTest::blit});
#ifdef MAGNUM_TARGET_GLES2 #ifdef MAGNUM_TARGET_GLES2
@ -1157,6 +1216,501 @@ void FramebufferGLTest::readBuffer() {
} }
#endif #endif
namespace {
constexpr char StorageData[]{
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
};
constexpr char ZeroStorage[4*4*4*6]{};
}
#ifndef MAGNUM_TARGET_GLES
void FramebufferGLTest::copyImageTexture1D() {
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
Texture2D storage;
storage.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
Texture1D texture;
fb.copyImage(Range2Di::fromSize(Vector2i{1}, {2, 1}), texture, 0, TextureFormat::RGBA8);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(texture.imageSize(0)[0], 2);
CORRADE_COMPARE_AS(texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b),
TestSuite::Compare::Container);
}
#endif
void FramebufferGLTest::copyImageTexture2D() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
#endif
Texture2D storage;
storage.setStorage(1,
#ifndef MAGNUM_TARGET_GLES2
TextureFormat::RGBA8,
#else
rgbaFormatES2,
#endif
Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
Texture2D texture;
fb.copyImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), texture, 0,
#ifndef MAGNUM_TARGET_GLES2
TextureFormat::RGBA8
#else
rgbaFormatES2
#endif
);
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(texture.imageSize(0), Vector2i{2});
CORRADE_COMPARE_AS(texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b),
TestSuite::Compare::Container);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void FramebufferGLTest::copyImageTexture1DArray() {
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
if(!Context::current().isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not available."));
Texture2D storage;
storage.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
Texture1DArray texture;
fb.copyImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), texture, 0, TextureFormat::RGBA8);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(texture.imageSize(0), Vector2i{2});
CORRADE_COMPARE_AS(texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b),
TestSuite::Compare::Container);
}
void FramebufferGLTest::copyImageRectangleTexture() {
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not available."));
Texture2D storage;
storage.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
RectangleTexture texture;
fb.copyImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), texture, TextureFormat::RGBA8);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(texture.imageSize(), Vector2i{2});
CORRADE_COMPARE_AS(texture.image({PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b),
TestSuite::Compare::Container);
}
#endif
void FramebufferGLTest::copyImageCubeMapTexture() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
#endif
Texture2D storage;
storage.setStorage(1,
#ifndef MAGNUM_TARGET_GLES2
TextureFormat::RGBA8,
#else
rgbaFormatES2,
#endif
Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
CubeMapTexture texture;
fb.copyImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), texture, CubeMapCoordinate::PositiveX, 0,
#ifndef MAGNUM_TARGET_GLES2
TextureFormat::RGBA8
#else
rgbaFormatES2
#endif
);
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(texture.imageSize(0), Vector2i{2});
CORRADE_COMPARE_AS(texture.image(CubeMapCoordinate::PositiveX, 0, {PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b),
TestSuite::Compare::Container);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void FramebufferGLTest::copySubImageTexture1D() {
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
Texture2D storage;
storage.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
Texture1D texture;
texture.setStorage(1, TextureFormat::RGBA8, 4)
.setSubImage(0, {}, ImageView1D{PixelFormat::RGBA, PixelType::UnsignedByte, 4, ZeroStorage});
fb.copySubImage(Range2Di::fromSize(Vector2i{1}, {2, 1}), texture, 0, 1);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE_AS(texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(
0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x00, 0x00, 0x00, 0x00),
TestSuite::Compare::Container);
}
#endif
void FramebufferGLTest::copySubImageTexture2D() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
#endif
Texture2D storage;
storage.setStorage(1,
#ifndef MAGNUM_TARGET_GLES2
TextureFormat::RGBA8,
#else
rgbaFormatES2,
#endif
Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
Texture2D texture;
texture.setStorage(1,
#ifndef MAGNUM_TARGET_GLES2
TextureFormat::RGBA8,
#else
rgbaFormatES2,
#endif
Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, ZeroStorage});
fb.copySubImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), texture, 0, Vector2i{1});
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
TestSuite::Compare::Container);
#endif
}
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
void FramebufferGLTest::copySubImageTexture3D() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
#elif defined(MAGNUM_TARGET_GLES2)
if(!Context::current().isExtensionSupported<Extensions::GL::OES::texture_3D>())
CORRADE_SKIP(Extensions::GL::OES::texture_3D::string() + std::string(" is not available."));
#endif
Texture2D storage;
storage.setStorage(1,
#ifndef MAGNUM_TARGET_GLES2
TextureFormat::RGBA8,
#else
rgbaFormatES2,
#endif
Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
Texture3D texture;
texture.setStorage(1,
#ifndef MAGNUM_TARGET_GLES2
TextureFormat::RGBA8,
#else
rgbaFormatES2,
#endif
{4, 4, 2})
.setSubImage(0, {}, ImageView3D{PixelFormat::RGBA, PixelType::UnsignedByte, {4, 4, 2}, ZeroStorage});
fb.copySubImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), texture, 0, Vector3i{1});
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
TestSuite::Compare::Container);
#endif
}
#endif
#ifndef MAGNUM_TARGET_GLES
void FramebufferGLTest::copySubImageTexture1DArray() {
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
if(!Context::current().isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not available."));
Texture2D storage;
storage.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
Texture1DArray texture;
texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, ZeroStorage});
fb.copySubImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), texture, 0, Vector2i{1});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE_AS(texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
TestSuite::Compare::Container);
}
#endif
#ifndef MAGNUM_TARGET_GLES2
void FramebufferGLTest::copySubImageTexture2DArray() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
if(!Context::current().isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not available."));
#endif
Texture2D storage;
storage.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
Texture2DArray texture;
texture.setStorage(1, TextureFormat::RGBA8, {4, 4, 2})
.setSubImage(0, {}, ImageView3D{PixelFormat::RGBA, PixelType::UnsignedByte, {4, 4, 2}, ZeroStorage});
fb.copySubImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), texture, 0, Vector3i{1});
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
TestSuite::Compare::Container);
#endif
}
#endif
#ifndef MAGNUM_TARGET_GLES
void FramebufferGLTest::copySubImageRectangleTexture() {
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not available."));
Texture2D storage;
storage.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
RectangleTexture texture;
texture.setStorage(TextureFormat::RGBA8, Vector2i{4})
.setSubImage({}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, ZeroStorage});
fb.copySubImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), texture, Vector2i{1});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE_AS(texture.image({PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
TestSuite::Compare::Container);
}
#endif
void FramebufferGLTest::copySubImageCubeMapTexture() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
#endif
Texture2D storage;
storage.setStorage(1,
#ifndef MAGNUM_TARGET_GLES2
TextureFormat::RGBA8,
#else
rgbaFormatES2,
#endif
Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
CubeMapTexture texture;
texture.setStorage(1,
#ifndef MAGNUM_TARGET_GLES2
TextureFormat::RGBA8,
#else
rgbaFormatES2,
#endif
Vector2i{4})
.setSubImage(CubeMapCoordinate::NegativeY, 0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, ZeroStorage});
fb.copySubImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), texture, 0, {1, 1, 3});
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(texture.image(CubeMapCoordinate::NegativeY, 0, {PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
TestSuite::Compare::Container);
#endif
}
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void FramebufferGLTest::copySubImageCubeMapTextureArray() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
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 available."));
#else
if(!Context::current().isExtensionSupported<Extensions::GL::EXT::texture_cube_map_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_cube_map_array::string() + std::string(" is not available."));
#endif
Texture2D storage;
storage.setStorage(1, TextureFormat::RGBA8, Vector2i{4})
.setSubImage(0, {}, ImageView2D{PixelFormat::RGBA, PixelType::UnsignedByte, Vector2i{4}, StorageData});
Framebuffer fb{{{}, Vector2i{4}}};
fb.attachTexture(Framebuffer::ColorAttachment{0}, storage, 0);
CubeMapTextureArray texture;
texture.setStorage(1, TextureFormat::RGBA8, {4, 4, 6})
.setSubImage(0, {}, ImageView3D{PixelFormat::RGBA, PixelType::UnsignedByte, {4, 4, 6}, ZeroStorage});
fb.copySubImage(Range2Di::fromSize(Vector2i{1}, Vector2i{2}), texture, 0, {1, 1, 3});
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}).release(),
Containers::Array<char>::from(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
TestSuite::Compare::Container);
#endif
}
#endif
void FramebufferGLTest::blit() { void FramebufferGLTest::blit() {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>()) if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())

9
src/Magnum/Texture.h

@ -1014,9 +1014,9 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* and has better performance characteristics. This call also has no * and has better performance characteristics. This call also has no
* equivalent in @extension{ARB,direct_state_access}, thus the texture * equivalent in @extension{ARB,direct_state_access}, thus the texture
* needs to be bound to some texture unit before the operation. * needs to be bound to some texture unit before the operation.
* @see @ref maxSize(), @fn_gl{PixelStore}, then @fn_gl{ActiveTexture}, * @see @ref maxSize(), @ref Framebuffer::copyImage(), @fn_gl{PixelStore},
* @fn_gl{BindTexture} and @fn_gl{TexImage1D} / @fn_gl{TexImage2D} * then @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexImage1D}
* / @fn_gl{TexImage3D} * / @fn_gl{TexImage2D} / @fn_gl{TexImage3D}
* @deprecated_gl Prefer to use @ref setStorage() and @ref setSubImage() * @deprecated_gl Prefer to use @ref setStorage() and @ref setSubImage()
* instead. * instead.
*/ */
@ -1115,7 +1115,8 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* nor @extension{EXT,direct_state_access} desktop extension is * nor @extension{EXT,direct_state_access} desktop extension is
* available, the texture is bound before the operation (if not * available, the texture is bound before the operation (if not
* already). * already).
* @see @ref setStorage(), @fn_gl{PixelStore}, @fn_gl2{TextureSubImage1D,TexSubImage1D} / * @see @ref setStorage(), @ref Framebuffer::copySubImage(),
* @fn_gl{PixelStore}, @fn_gl2{TextureSubImage1D,TexSubImage1D} /
* @fn_gl2{TextureSubImage2D,TexSubImage2D} / @fn_gl2{TextureSubImage3D,TexSubImage3D}, * @fn_gl2{TextureSubImage2D,TexSubImage2D} / @fn_gl2{TextureSubImage3D,TexSubImage3D},
* @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access} / * @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access} /
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access} / * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access} /

Loading…
Cancel
Save