Browse Source

Split Texture into TextureArray, MultisampleTexture and RectangleTexture.

Each texture has slightly different usage requirements and having
everything under one generic class is not worth the additional runtime
checks and whatnot. The current way with Texture::Target enum
(hopefully not too widely used) is now deprecated and will be removed in
some future release. However general Texture1D/2D/3D usage is not
changed in any way.
pull/51/head
Vladimír Vondruš 12 years ago
parent
commit
959d40a02d
  1. 8
      doc/opengl-mapping.dox
  2. 25
      src/Magnum/AbstractTexture.cpp
  3. 143
      src/Magnum/AbstractTexture.h
  4. 9
      src/Magnum/BufferTexture.h
  5. 7
      src/Magnum/CMakeLists.txt
  6. 63
      src/Magnum/CubeMapTexture.h
  7. 65
      src/Magnum/CubeMapTextureArray.h
  8. 18
      src/Magnum/Magnum.h
  9. 116
      src/Magnum/MultisampleTexture.h
  10. 323
      src/Magnum/RectangleTexture.h
  11. 3
      src/Magnum/Test/CMakeLists.txt
  12. 3
      src/Magnum/Test/CubeMapTextureArrayGLTest.cpp
  13. 3
      src/Magnum/Test/CubeMapTextureGLTest.cpp
  14. 1
      src/Magnum/Test/MeshGLTest.cpp
  15. 212
      src/Magnum/Test/MultisampleTextureGLTest.cpp
  16. 250
      src/Magnum/Test/RectangleTextureGLTest.cpp
  17. 683
      src/Magnum/Test/TextureArrayGLTest.cpp
  18. 1061
      src/Magnum/Test/TextureGLTest.cpp
  19. 1
      src/Magnum/Text/AbstractFont.cpp
  20. 1
      src/Magnum/Text/Renderer.cpp
  21. 1
      src/Magnum/Text/Test/AbstractFontTest.cpp
  22. 369
      src/Magnum/Texture.h
  23. 302
      src/Magnum/TextureArray.h

8
doc/opengl-mapping.dox

@ -137,7 +137,7 @@ OpenGL function | Matching API
@fn_gl{GenTextures}, @fn_gl{DeleteTextures} | @ref AbstractTexture constructor and destructor
@fn_gl{GenTransformFeedbacks}, @fn_gl{DeleteTransformFeedbacks} | |
@fn_gl{GenVertexArrays}, @fn_gl{DeleteVertexArrays} | @ref Mesh constructor and destructor
@fn_gl{GenerateMipmap}, \n @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access} | @ref AbstractTexture::generateMipmap()
@fn_gl{GenerateMipmap}, \n @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access} | @ref Texture::generateMipmap(), \n @ref TextureArray::generateMipmap(), \n @ref CubeMapTexture::generateMipmap(), \n @ref CubeMapTextureArray::generateMipmap()
@fn_gl{Get} | see @ref opengl-mapping-state "table below"
@fn_gl2{GetActiveAtomicCounterBuffer,GetActiveAtomicCounterBufferiv} | not queryable
@fn_gl{GetActiveAttrib}, \n @fn_gl{GetActiveSubroutineName}, \n @fn_gl{GetActiveSubroutineUniform}, \n @fn_gl{GetActiveSubroutineUniformName}, \n @fn_gl{GetActiveUniform}, \n @fn_gl{GetActiveUniformBlock}, \n @fn_gl{GetActiveUniformBlockName}, \n @fn_gl{GetActiveUniformName}, \n @fn_gl{GetActiveUniforms} | not queryable
@ -193,8 +193,8 @@ OpenGL function | Matching API
@fn_gl{InvalidateBufferSubData} | @ref Buffer::invalidateSubData()
@fn_gl{InvalidateFramebuffer}, \n @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer} | @ref DefaultFramebuffer::invalidate(), \n @ref Framebuffer::invalidate()
@fn_gl{InvalidateSubFramebuffer}, \n @fn_gles_extension{DiscardSubFramebuffer,EXT,discard_framebuffer} | @ref DefaultFramebuffer::invalidate(), \n @ref Framebuffer::invalidate()
@fn_gl{InvalidateTexImage} | @ref AbstractTexture::invalidateImage()
@fn_gl{InvalidateTexSubImage} | @ref Texture::invalidateSubImage(),\n @ref CubeMapTexture::invalidateSubImage(), \n @ref CubeMapTextureArray::invalidateSubImage()
@fn_gl{InvalidateTexImage} | @ref Texture::invalidateImage(), \n @ref TextureArray::invalidateImage(), \n @ref CubeMapTexture::invalidateImage(), \n @ref CubeMapTextureArray::invalidateImage(), \n @ref MultisampleTexture::invalidateImage(), \n @ref RectangleTexture::invalidateImage()
@fn_gl{InvalidateTexSubImage} | @ref Texture::invalidateSubImage(), \n @ref TextureArray::invalidateSubImage(), \n @ref CubeMapTexture::invalidateSubImage(), \n @ref CubeMapTextureArray::invalidateSubImage(), \n @ref MultisampleTexture::invalidateSubImage(), \n @ref RectangleTexture::invalidateSubImage()
@fn_gl{IsBuffer}, \n @fn_gl{IsFramebuffer}, \n @fn_gl{IsProgram}, \n @fn_gl{IsProgramPipeline}, \n @fn_gl{IsQuery}, \n @fn_gl{IsRenderbuffer}, \n @fn_gl{IsSampler}, \n @fn_gl{IsShader}, \n @fn_gl{IsSync}, \n @fn_gl{IsTexture}, \n @fn_gl{IsTransformFeedback}, \n @fn_gl{IsVertexArray} | not needed, objects are strongly typed
@fn_gl{IsEnabled} | not queryable, @ref Renderer::setFeature() setter only
@fn_gl{LineWidth} | @ref Renderer::setLineWidth()
@ -239,7 +239,7 @@ OpenGL function | Matching API
@fn_gl{TexBuffer}, \n @fn_gl_extension{TextureBuffer,EXT,direct_state_access}, \n @fn_gl{TexBufferRange}, \n @fn_gl_extension{TextureBufferRange,EXT,direct_state_access} | @ref BufferTexture::setBuffer()
@fn_gl{TexImage1D}, \n @fn_gl_extension{TextureImage1D,EXT,direct_state_access} \n @fn_gl{TexImage2D}, \n @fn_gl_extension{TextureImage2D,EXT,direct_state_access}, \n @fn_gl{TexImage3D}, \n @fn_gl_extension{TextureImage3D,EXT,direct_state_access} | @ref Texture::setImage(), \n @ref CubeMapTexture::setImage(), \n @ref CubeMapTextureArray::setImage()
@fn_gl{TexImage2DMultisample}, \n @fn_gl{TexImage3DMultisample} | |
@fn_gl{TexParameter}, \n @fn_gl_extension{TextureParameter,EXT,direct_state_access} | @ref AbstractTexture::setMinificationFilter(), \n @ref AbstractTexture::setMagnificationFilter(), \n @ref AbstractTexture::setBorderColor(), \n @ref AbstractTexture::setMaxAnisotropy(), \n @ref Texture::setWrapping(), \n @ref CubeMapTexture::setWrapping(), \n @ref CubeMapTextureArray::setWrapping()
@fn_gl{TexParameter}, \n @fn_gl_extension{TextureParameter,EXT,direct_state_access} | @ref Texture::setMinificationFilter(), \n @ref TextureArray::setMinificationFilter(), \n @ref CubeMapTexture::setMinificationFilter(), \n @ref CubeMapTextureArray::setMinificationFilter(), \n @ref RectangleTexture::setMinificationFilter(), \n @ref Texture::setMagnificationFilter(), \n @ref TextureArray::setMagnificationFilter(), \n @ref CubeMapTexture::setMagnificationFilter(), \n @ref CubeMapTextureArray::setMagnificationFilter(), \n @ref RectangleTexture::setMagnificationFilter(), \n @ref Texture::setBorderColor(), \n @ref TextureArray::setBorderColor(), \n @ref CubeMapTexture::setBorderColor(), \n @ref CubeMapTextureArray::setBorderColor(), \n @ref RectangleTexture::setBorderColor(), \n @ref Texture::setMaxAnisotropy(), \n @ref TextureArray::setMaxAnisotropy(), \n @ref CubeMapTexture::setMaxAnisotropy(), \n @ref CubeMapTextureArray::setMaxAnisotropy(), \n @ref RectangleTexture::setMaxAnisotropy(), \n @ref Texture::setWrapping(), \n @ref TextureArray::setWrapping(), \n @ref CubeMapTexture::setWrapping(), \n @ref CubeMapTextureArray::setWrapping(), \n @ref RectangleTexture::setWrapping()
@fn_gl{TexStorage1D}, \n @fn_gl_extension{TextureStorage1D,EXT,direct_state_access}, \n @fn_gl{TexStorage2D}, \n @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}, \n @fn_gl{TexStorage3D}, \n @fn_gl_extension{TextureStorage3D,EXT,direct_state_access} | @ref Texture::setStorage(), \n @ref CubeMapTexture::setStorage(), \n @ref CubeMapTextureArray::setStorage()
@fn_gl{TexStorage2DMultisample}, \n @fn_gl{TexStorage3DMultisample} | |
@fn_gl{TexSubImage1D}, \n @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}, \n @fn_gl{TexSubImage2D}, \n @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}, \n @fn_gl{TexSubImage3D}, \n @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} | @ref Texture::setSubImage(), \n @ref CubeMapTexture::setSubImage(), \n @ref CubeMapTextureArray::setSubImage()

25
src/Magnum/AbstractTexture.cpp

@ -28,6 +28,8 @@
#ifndef MAGNUM_TARGET_GLES2
#include "Magnum/BufferImage.h"
#endif
#include "Magnum/Array.h"
#include "Magnum/Color.h"
#include "Magnum/ColorFormat.h"
#include "Magnum/Context.h"
#include "Magnum/Extensions.h"
@ -134,45 +136,32 @@ void AbstractTexture::bindImplementationDSA(GLint layer) {
}
#endif
AbstractTexture& AbstractTexture::setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap) {
#ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Sampler::Mipmap::Base, "AbstractTexture: rectangle textures cannot have mipmaps", *this);
#endif
void AbstractTexture::setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap) {
(this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_MIN_FILTER, GLint(filter)|GLint(mipmap));
return *this;
}
AbstractTexture& AbstractTexture::setMagnificationFilter(const Sampler::Filter filter) {
void AbstractTexture::setMagnificationFilter(const Sampler::Filter filter) {
(this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_MAG_FILTER, GLint(filter));
return *this;
}
AbstractTexture& AbstractTexture::setBorderColor(const Color4& color) {
void AbstractTexture::setBorderColor(const Color4& color) {
#ifndef MAGNUM_TARGET_GLES
(this->*Context::current()->state().texture->parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR, color.data());
#else
(this->*Context::current()->state().texture->parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR_NV, color.data());
#endif
return *this;
}
AbstractTexture& AbstractTexture::setMaxAnisotropy(const Float anisotropy) {
void AbstractTexture::setMaxAnisotropy(const Float anisotropy) {
(this->*Context::current()->state().texture->setMaxAnisotropyImplementation)(anisotropy);
return *this;
}
void AbstractTexture::invalidateImage(const Int level) {
(this->*Context::current()->state().texture->invalidateImageImplementation)(level);
}
AbstractTexture& AbstractTexture::generateMipmap() {
#ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", *this);
#endif
void AbstractTexture::generateMipmap() {
(this->*Context::current()->state().texture->mipmapImplementation)();
return *this;
}
void AbstractTexture::mipmapImplementationDefault() {

143
src/Magnum/AbstractTexture.h

@ -29,8 +29,6 @@
* @brief Class @ref Magnum::AbstractTexture
*/
#include "Magnum/Array.h"
#include "Magnum/Color.h"
#include "Magnum/Sampler.h"
#include "Magnum/AbstractObject.h"
@ -81,7 +79,7 @@ OpenGL ES 3.0 or @es_extension{EXT,texture_storage} in OpenGL ES 2.0 is not
available, the feature is emulated with sequence of @ref Texture::setImage() "setImage()"
calls.
You can use functions @ref invalidateImage() and
You can use functions @ref Texture::invalidateImage() and
@ref Texture::invalidateSubImage() "invalidateSubImage()" if you don't need
texture data anymore to avoid unnecessary memory operations performed by OpenGL
in order to preserve the data. If running on OpenGL ES or extension
@ -158,6 +156,14 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
static Int maxIntegerSamples();
#endif
/**
* @brief Destructor
*
* Deletes associated OpenGL texture.
* @see @fn_gl{DeleteTextures}
*/
~AbstractTexture();
/** @brief Copying is not allowed */
AbstractTexture(const AbstractTexture&) = delete;
@ -211,116 +217,6 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
*/
void bind(Int layer);
/**
* @brief Set minification filter
* @param filter Filter
* @param mipmap Mipmap filtering. If set to anything else than
* @ref Sampler::Mipmap::Base, make sure textures for all mip
* levels are set or call @ref generateMipmap().
* @return Reference to self (for method chaining)
*
* Sets filter used when the object pixel size is smaller than the
* texture size. If @extension{EXT,direct_state_access} is not
* available, the texture is bound to some layer before the operation.
* Initial value is (@ref Sampler::Filter::Nearest, @ref Sampler::Mipmap::Linear).
* @attention For rectangle textures only some modes are supported,
* see @ref Sampler::Filter and @ref Sampler::Mipmap documentation
* for more information.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_MIN_FILTER}
*/
AbstractTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base);
/**
* @brief Set magnification filter
* @param filter Filter
* @return Reference to self (for method chaining)
*
* Sets filter used when the object pixel size is larger than largest
* texture size. If @extension{EXT,direct_state_access} is not
* available, the texture is bound to some layer before the operation.
* Initial value is @ref Sampler::Filter::Linear.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_MAG_FILTER}
*/
AbstractTexture& setMagnificationFilter(Sampler::Filter filter);
/**
* @brief Set border color
* @return Reference to self (for method chaining)
*
* Border color when wrapping is set to @ref Sampler::Wrapping::ClampToBorder.
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some layer before the operation. Initial value is
* `{0.0f, 0.0f, 0.0f, 0.0f}`.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_BORDER_COLOR}
* @requires_es_extension %Extension @es_extension{NV,texture_border_clamp}
*/
AbstractTexture& setBorderColor(const Color4& color);
/**
* @brief Set max anisotropy
* @return Reference to self (for method chaining)
*
* Default value is `1.0f`, which means no anisotropy. Set to value
* greater than `1.0f` for anisotropic filtering. If extension
* @extension{EXT,texture_filter_anisotropic} (desktop or ES) is not
* available, this function does nothing. If
* @extension{EXT,direct_state_access} is not available, the texture is
* bound to some layer before the operation.
* @see @ref Sampler::maxMaxAnisotropy(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_MAX_ANISOTROPY_EXT}
*/
AbstractTexture& setMaxAnisotropy(Float anisotropy);
/**
* @brief Invalidate texture image
* @param level Mip level
*
* If running on OpenGL ES or extension @extension{ARB,invalidate_subdata}
* (part of OpenGL 4.3) is not available, this function does nothing.
* @see @ref Texture::invalidateSubImage() "invalidateSubImage()",
* @fn_gl{InvalidateTexImage}
*/
void invalidateImage(Int level);
/**
* @brief Generate mipmap
* @return Reference to self (for method chaining)
*
* Can not be used for rectangle textures. If
* @extension{EXT,direct_state_access} is not available, the texture
* is bound to some layer before the operation.
* @see setMinificationFilter(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{GenerateMipmap} or
* @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access}
* @requires_gl30 %Extension @extension{ARB,framebuffer_object}
*/
AbstractTexture& generateMipmap();
protected:
/**
* @brief Constructor
*
* Creates new OpenGL texture.
* @see @fn_gl{GenTextures}
*/
explicit AbstractTexture(GLenum target);
/**
* @brief Destructor
*
* Deletes assigned OpenGL texture.
* @see @fn_gl{DeleteTextures}
*/
~AbstractTexture();
#ifdef DOXYGEN_GENERATING_OUTPUT
private:
#else
@ -328,9 +224,18 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
#endif
template<UnsignedInt textureDimensions> struct DataHelper {};
explicit AbstractTexture(GLenum target);
/* Unlike bind() this also sets the binding layer as active */
void MAGNUM_LOCAL bindInternal();
void setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap);
void setMagnificationFilter(Sampler::Filter filter);
void setBorderColor(const Color4& color);
void setMaxAnisotropy(Float anisotropy);
void invalidateImage(Int level);
void generateMipmap();
#ifndef MAGNUM_TARGET_GLES
template<UnsignedInt dimensions> void image(GLenum target, GLint level, Image<dimensions>& image);
template<UnsignedInt dimensions> void image(GLenum target, GLint level, BufferImage<dimensions>& image, BufferUsage usage);
@ -445,11 +350,11 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES
template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<1> {
#ifdef MAGNUM_BUILD_DEPRECATED
enum class Target: GLenum {
Texture1D = GL_TEXTURE_1D
};
constexpr static Target target() { return Target::Texture1D; }
#endif
static Math::Vector<1, GLint> imageSize(AbstractTexture& texture, GLenum target, GLint level);
@ -467,6 +372,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<1> {
};
#endif
template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
#ifdef MAGNUM_BUILD_DEPRECATED
enum class Target: GLenum {
Texture2D = GL_TEXTURE_2D,
#ifndef MAGNUM_TARGET_GLES
@ -475,8 +381,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
Rectangle = GL_TEXTURE_RECTANGLE
#endif
};
constexpr static Target target() { return Target::Texture2D; }
#endif
#ifndef MAGNUM_TARGET_GLES
static Vector2i imageSize(AbstractTexture& texture, GLenum target, GLint level);
@ -499,6 +404,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
static void invalidateSubImage(AbstractTexture& texture, GLint level, const Vector2i& offset, const Vector2i& size);
};
template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
#ifdef MAGNUM_BUILD_DEPRECATED
enum class Target: GLenum {
#ifndef MAGNUM_TARGET_GLES2
Texture3D = GL_TEXTURE_3D,
@ -510,8 +416,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
Texture3D = GL_TEXTURE_3D_OES
#endif
};
constexpr static Target target() { return Target::Texture3D; }
#endif
#ifndef MAGNUM_TARGET_GLES
static Vector3i imageSize(AbstractTexture& texture, GLenum target, GLint level);

9
src/Magnum/BufferTexture.h

@ -195,7 +195,8 @@ functions use DSA to avoid unnecessary calls to @fn_gl{ActiveTexture} and
@ref AbstractTexture-performance-optimization "relevant section in AbstractTexture documentation"
and respective function documentation for more information.
@see @ref Texture, @ref CubeMapTexture, @ref CubeMapTextureArray
@see @ref Texture, @ref TextureArray, @ref CubeMapTexture,
@ref CubeMapTextureArray, @ref MultisampleTexture, @ref RectangleTexture
@requires_gl31 %Extension @extension{ARB,texture_buffer_object}
@requires_gl Texture buffers are not available in OpenGL ES.
*/
@ -216,6 +217,12 @@ class MAGNUM_EXPORT BufferTexture: private AbstractTexture {
*/
static Int offsetAlignment();
/**
* @brief Constructor
*
* Creates new OpenGL texture object.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_BUFFER}
*/
explicit BufferTexture(): AbstractTexture(GL_TEXTURE_BUFFER) {}
/** @copydoc AbstractTexture::id() */

7
src/Magnum/CMakeLists.txt

@ -138,14 +138,17 @@ endif()
if(NOT TARGET_GLES)
set(Magnum_HEADERS ${Magnum_HEADERS}
BufferTexture.h
CubeMapTextureArray.h)
CubeMapTextureArray.h
MultisampleTexture.h
RectangleTexture.h)
set(Magnum_SRCS ${Magnum_SRCS} $<TARGET_OBJECTS:MagnumGLLoadGenObjects>)
endif()
# Not-ES2 headers
if(NOT TARGET_GLES2)
set(Magnum_HEADERS ${Magnum_HEADERS}
BufferImage.h)
BufferImage.h
TextureArray.h)
endif()
# Files shared between main library and math unit test library

63
src/Magnum/CubeMapTexture.h

@ -30,6 +30,8 @@
*/
#include "Magnum/AbstractTexture.h"
#include "Magnum/Array.h"
#include "Magnum/Math/Vector2.h"
namespace Magnum {
@ -92,21 +94,41 @@ class CubeMapTexture: public AbstractTexture {
/**
* @brief Constructor
*
* Creates one cube map OpenGL texture.
* Creates new OpenGL texture object.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP}
*/
explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {}
/**
* @brief Set wrapping
*
* See @ref Texture::setWrapping() for more information.
*/
/** @copydoc Texture::setMinificationFilter() */
CubeMapTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;
}
/** @copydoc Texture::setMagnificationFilter() */
CubeMapTexture& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return *this;
}
/** @copydoc Texture::setWrapping() */
CubeMapTexture& setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
DataHelper<3>::setWrapping(*this, wrapping);
return *this;
}
/** @copydoc Texture::setBorderColor() */
CubeMapTexture& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
/** @copydoc Texture::setMaxAnisotropy() */
CubeMapTexture& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return *this;
}
#ifndef MAGNUM_TARGET_GLES
/**
* @brief %Image size in given mip level
@ -220,6 +242,15 @@ class CubeMapTexture: public AbstractTexture {
}
#endif
/** @copydoc Texture::generateMipmap() */
CubeMapTexture& generateMipmap() {
AbstractTexture::generateMipmap();
return *this;
}
/** @copydoc Texture::invalidateImage() */
void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); }
/**
* @brief Invalidate texture subimage
* @param level Mip level
@ -242,26 +273,6 @@ class CubeMapTexture: public AbstractTexture {
AbstractTexture::setLabel(label);
return *this;
}
CubeMapTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;
}
CubeMapTexture& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return *this;
}
CubeMapTexture& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
CubeMapTexture& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return *this;
}
CubeMapTexture& generateMipmap() {
AbstractTexture::generateMipmap();
return *this;
}
#endif
};

65
src/Magnum/CubeMapTextureArray.h

@ -32,6 +32,8 @@
#endif
#include "Magnum/AbstractTexture.h"
#include "Magnum/Array.h"
#include "Magnum/Math/Vector2.h"
#ifndef MAGNUM_TARGET_GLES
namespace Magnum {
@ -83,21 +85,41 @@ class CubeMapTextureArray: public AbstractTexture {
/**
* @brief Constructor
*
* Creates one cube map OpenGL texture.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP}
* Creates new OpenGL texture object.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP_ARRAY}
*/
explicit CubeMapTextureArray(): AbstractTexture(GL_TEXTURE_CUBE_MAP_ARRAY) {}
/**
* @brief Set wrapping
*
* See @ref Texture::setWrapping() for more information.
*/
/** @copydoc Texture::setMinificationFilter() */
CubeMapTextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;
}
/** @copydoc Texture::setMagnificationFilter() */
CubeMapTextureArray& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return *this;
}
/** @copydoc Texture::setWrapping() */
CubeMapTextureArray& setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
DataHelper<3>::setWrapping(*this, wrapping);
return *this;
}
/** @copydoc Texture::setBorderColor() */
CubeMapTextureArray& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
/** @copydoc Texture::setMaxAnisotropy() */
CubeMapTextureArray& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return *this;
}
/**
* @brief %Image size in given mip level
* @param level Mip level
@ -207,6 +229,15 @@ class CubeMapTextureArray: public AbstractTexture {
return setSubImage(level, offset, image);
}
/** @copydoc Texture::generateMipmap() */
CubeMapTextureArray& generateMipmap() {
AbstractTexture::generateMipmap();
return *this;
}
/** @copydoc Texture::invalidateImage() */
void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); }
/**
* @brief Invalidate texture subimage
* @param level Mip level
@ -228,26 +259,6 @@ class CubeMapTextureArray: public AbstractTexture {
AbstractTexture::setLabel(label);
return *this;
}
CubeMapTextureArray& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;
}
CubeMapTextureArray& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return *this;
}
CubeMapTextureArray& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
CubeMapTextureArray& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return *this;
}
CubeMapTextureArray& generateMipmap() {
AbstractTexture::generateMipmap();
return *this;
}
#endif
};

18
src/Magnum/Magnum.h

@ -560,8 +560,8 @@ typedef ColorFormat ImageFormat;
typedef ColorType ColorType;
class Context;
class CubeMapTexture;
class CubeMapTexture;
#ifndef MAGNUM_TARGET_GLES
class CubeMapTextureArray;
#endif
@ -588,11 +588,19 @@ enum class MeshPrimitive: GLenum;
class Mesh;
class MeshView;
#ifndef MAGNUM_TARGET_GLES
template<UnsignedInt> class MultisampleTexture;
typedef MultisampleTexture<2> MultisampleTexture2D;
typedef MultisampleTexture<3> MultisampleTexture2DArray;
#endif
/* AbstractQuery is not used directly */
class PrimitiveQuery;
class SampleQuery;
class TimeQuery;
class RectangleTexture;
class Renderbuffer;
enum class RenderbufferFormat: GLenum;
@ -613,6 +621,14 @@ typedef Texture<1> Texture1D;
typedef Texture<2> Texture2D;
typedef Texture<3> Texture3D;
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt> class TextureArray;
#ifndef MAGNUM_TARGET_GLES
typedef TextureArray<1> Texture1DArray;
#endif
typedef TextureArray<2> Texture2DArray;
#endif
enum class TextureFormat: GLenum;
class Timeline;

116
src/Magnum/MultisampleTexture.h

@ -0,0 +1,116 @@
#ifndef Magnum_MultisampleTexture_h
#define Magnum_MultisampleTexture_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef MAGNUM_TARGET_GLES
/** @file
* @brief Class @ref Magnum::MultisampleTexture, typedef @ref Magnum::MultisampleTexture2D, @ref Magnum::MultisampleTexture2DArray
*/
#endif
#include "Magnum/AbstractTexture.h"
#include "Magnum/DimensionTraits.h"
#include "Magnum/Math/Vector3.h"
#ifndef MAGNUM_TARGET_GLES
namespace Magnum {
namespace Implementation {
template<UnsignedInt> constexpr GLenum multisampleTextureTarget();
template<> inline constexpr GLenum multisampleTextureTarget<2>() { return GL_TEXTURE_2D_MULTISAMPLE; }
template<> inline constexpr GLenum multisampleTextureTarget<3>() { return GL_TEXTURE_2D_MULTISAMPLE_ARRAY; }
}
/**
@brief Mulitsample texture
Template class for 2D mulitsample texture and 2D multisample texture array. See
also @ref AbstractTexture documentation for more information.
@todoc Finish when fully implemented
The texture is bound to layer specified by shader via @ref bind(). In shader,
the texture is used via `sampler2DMS`/`sampler2DMSArray`,
`isampler2DMS`/`isampler2DMSArray` or `usampler2DMS`/`usampler2DMSArray`. See
@ref AbstractShaderProgram documentation for more information about usage in
shaders.
@requires_gl32 %Extension @extension{ARB,texture_multisample}
@requires_gl Multisample textures are not available in OpenGL ES.
@see @ref MultisampleTexture2D, @ref MultisampleTexture2DArray, @ref Texture,
@ref TextureArray, @ref BufferTexture, @ref CubeMapTexture,
@ref CubeMapTextureArray, @ref RectangleTexture
*/
template<UnsignedInt dimensions> class MultisampleTexture: public AbstractTexture {
public:
static const UnsignedInt Dimensions = dimensions; /**< @brief %Texture dimension count */
/**
* @brief Constructor
*
* Creates new OpenGL texture object.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_2D_MULTISAMPLE} or
* @def_gl{TEXTURE_2D_MULTISAMPLE_ARRAY}
*/
explicit MultisampleTexture(): AbstractTexture(Implementation::multisampleTextureTarget<dimensions>()) {}
#ifndef MAGNUM_TARGET_GLES
/** @copydoc Texture::imageSize() */
typename DimensionTraits<dimensions, Int>::VectorType imageSize(Int level) {
return DataHelper<dimensions>::imageSize(*this, _target, level);
}
#endif
/** @copydoc Texture::invalidateImage() */
void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); }
/** @copydoc Texture::invalidateSubImage() */
void invalidateSubImage(Int level, const typename DimensionTraits<dimensions, Int>::VectorType& offset, const typename DimensionTraits<dimensions, Int>::VectorType& size) {
DataHelper<dimensions>::invalidateSubImage(*this, level, offset, size);
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
MultisampleTexture<dimensions>& setLabel(const std::string& label) {
AbstractTexture::setLabel(label);
return *this;
}
#endif
};
/** @brief Two-dimensional multisample texture */
typedef MultisampleTexture<2> MultisampleTexture2D;
/** @brief Two-dimensional multisample texture array */
typedef MultisampleTexture<3> MultisampleTexture2DArray;
}
#else
#error this header is available only on desktop OpenGL build
#endif
#endif

323
src/Magnum/RectangleTexture.h

@ -0,0 +1,323 @@
#ifndef Magnum_RectangleTexture_h
#define Magnum_RectangleTexture_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef MAGNUM_TARGET_GLES
/** @file
* @brief Class @ref Magnum::RectangleTexture
*/
#endif
#include "Magnum/AbstractTexture.h"
#include "Magnum/Array.h"
#include "Magnum/Math/Vector2.h"
#ifndef MAGNUM_TARGET_GLES
namespace Magnum {
/**
@brief Rectangle texture
See also @ref AbstractTexture documentation for more information.
@section RectangleTexture-usage Usage
Common usage is to fully configure all texture parameters and then set the
data from e.g. @ref Image2D. Example configuration:
@code
Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte, {526, 137}, data);
RectangleTexture texture;
texture.setMagnificationFilter(Sampler::Filter::Linear)
.setMinificationFilter(Sampler::Filter::Linear)
.setWrapping(Sampler::Wrapping::ClampToEdge)
.setMaxAnisotropy(Sampler::maxMaxAnisotropy())
.setStorage(TextureFormat::RGBA8, {526, 137})
.setSubImage({}, image);
@endcode
The texture is bound to layer specified by shader via @ref bind(). In shader,
the texture is used via sampler2DRect`, `sampler2DRectShadow`, `isampler2DRect`
or `usampler2DRect`. See @ref AbstractShaderProgram documentation for more
information about usage in shaders.
@requires_gl31 %Extension @extension{ARB,texture_rectangle}
@requires_gl Rectangle textures are not available in OpenGL ES.
@see @ref Texture, @ref TextureArray, @ref BufferTexture, @ref CubeMapTexture,
@ref CubeMapTextureArray, @ref MultisampleTexture
*/
class RectangleTexture: public AbstractTexture {
public:
/**
* @brief Constructor
*
* Creates new OpenGL texture object.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_RECTANGLE}
*/
explicit RectangleTexture(): AbstractTexture(GL_TEXTURE_RECTANGLE) {}
/**
* @brief Set minification filter
* @param filter Filter
* @return Reference to self (for method chaining)
*
* Sets filter used when the object pixel size is smaller than the
* texture size. If @extension{EXT,direct_state_access} is not
* available, the texture is bound to some layer before the operation.
* Initial value is @ref Sampler::Filter::Linear.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_MIN_FILTER}
*/
RectangleTexture& setMinificationFilter(Sampler::Filter filter) {
AbstractTexture::setMinificationFilter(filter, Sampler::Mipmap::Base);
return *this;
}
/** @copydoc Texture::setMagnificationFilter() */
RectangleTexture& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return *this;
}
#ifndef MAGNUM_TARGET_GLES
/**
* @brief %Image size
*
* The result is not cached in any way. If
* @extension{EXT,direct_state_access} is not available, the texture
* is bound to some layer before the operation.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_WIDTH} and @def_gl{TEXTURE_HEIGHT}
* @requires_gl %Texture image queries are not available in OpenGL ES.
*/
Vector2i imageSize() { return DataHelper<2>::imageSize(*this, _target, 0); }
#endif
/**
* @brief Set wrapping
* @param wrapping Wrapping type for all texture dimensions
* @return Reference to self (for method chaining)
*
* Sets wrapping type for coordinates out of (0, textureSizeInGivenDirection-1)
* range for rectangle textures. If @extension{EXT,direct_state_access}
* is not available, the texture is bound to some layer before the
* operation. Initial value is @ref Sampler::Wrapping::ClampToEdge.
* @attention Only @ref Sampler::Wrapping::ClampToEdge and
* @ref Sampler::Wrapping::ClampToBorder is supported on this
* texture type.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T},
* @def_gl{TEXTURE_WRAP_R}
*/
RectangleTexture& setWrapping(const Array2D<Sampler::Wrapping>& wrapping) {
DataHelper<2>::setWrapping(*this, wrapping);
return *this;
}
/** @copydoc Texture::setBorderColor() */
RectangleTexture& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
/** @copydoc Texture::setMaxAnisotropy() */
RectangleTexture& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return *this;
}
/**
* @brief Set storage
* @param internalFormat Internal format
* @param size Size
* @return Reference to self (for method chaining)
*
* Specifies entire structure of a texture at once, removing the need
* for additional consistency checks and memory reallocations when
* updating the data later. After calling this function the texture
* is immutable and calling @ref setStorage() or @ref setImage() is not
* allowed.
*
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some layer before the operation. If OpenGL 4.2,
* @extension{ARB,texture_storage}, OpenGL ES 3.0 or
* @es_extension{EXT,texture_storage} in OpenGL ES 2.0 is not
* available, the feature is emulated with @ref setImage() call.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexStorage2D}
* or @fn_gl_extension{TextureStorage2D,EXT,direct_state_access},
* eventually @fn_gl{TexImage2D} or
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}.
*/
RectangleTexture& setStorage(TextureFormat internalFormat, const Vector2i& size) {
DataHelper<2>::setStorage(*this, _target, 1, internalFormat, size);
return *this;
}
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Read texture to image
* @param image %Image where to put the data
*
* %Image parameters like format and type of pixel data are taken from
* given image, image size is taken from the texture using
* @ref imageSize().
*
* If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some layer before the operation. If
* @extension{ARB,robustness} is available, the operation is protected
* from buffer overflow. However, if both @extension{EXT,direct_state_access}
* and @extension{ARB,robustness} are available, the DSA version is
* used, because it is better for performance and there isn't any
* function combining both features.
* @requires_gl %Texture image queries are not available in OpenGL ES.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{GetTexLevelParameter} or @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_WIDTH} and @def_gl{TEXTURE_HEIGHT}, then
* @fn_gl{GetTexImage}, @fn_gl_extension{GetTextureImage,EXT,direct_state_access}
* or @fn_gl_extension{GetnTexImage,ARB,robustness}
*/
void image(Image2D& image) {
AbstractTexture::image<2>(_target, 0, image);
}
/**
* @brief Read given mip level of texture to buffer image
* @param image %Buffer image where to put the data
* @param usage %Buffer usage
*
* See @ref image(Image2D&) for more information.
* @requires_gl %Texture image queries are not available in OpenGL ES.
*/
void image(BufferImage2D& image, BufferUsage usage) {
AbstractTexture::image<2>(_target, 0, image, usage);
}
#endif
/**
* @brief Set image data
* @param internalFormat Internal format
* @param image @ref Image2D, @ref ImageReference2D or
* @ref Trade::ImageData2D
* @return Reference to self (for method chaining)
*
* For better performance when calling @ref setImage() more than once
* use @ref setStorage() and @ref setSubImage() instead.
*
* If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some layer before the operation.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexImage2D}
* or @fn_gl_extension{TextureImage2D,EXT,direct_state_access}
*/
RectangleTexture& setImage(TextureFormat internalFormat, const ImageReference2D& image) {
DataHelper<2>::setImage(*this, _target, 0, internalFormat, image);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
RectangleTexture& setImage(TextureFormat internalFormat, BufferImage2D& image) {
DataHelper<2>::setImage(*this, _target, 0, internalFormat, image);
return *this;
}
/** @overload */
RectangleTexture& setImage(TextureFormat internalFormat, BufferImage2D&& image) {
return setImage(internalFormat, image);
}
#endif
/**
* @brief Set image subdata
* @param offset Offset where to put data in the texture
* @param image @ref Image2D, @ref ImageReference2D or
* @ref Trade::ImageData2D
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some layer before the operation.
* @see @ref setStorage(), @ref setImage(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexSubImage2D} or
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}
*/
RectangleTexture& setSubImage(const Vector2i& offset, const ImageReference2D& image) {
DataHelper<2>::setSubImage(*this, _target, 0, offset, image);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
RectangleTexture& setSubImage(const Vector2i& offset, BufferImage2D& image) {
DataHelper<2>::setSubImage(*this, _target, 0, offset, image);
return *this;
}
/** @overload */
RectangleTexture& setSubImage(const Vector2i& offset, BufferImage2D&& image) {
return setSubImage(offset, image);
}
#endif
/**
* @brief Invalidate texture image
*
* If running on OpenGL ES or extension @extension{ARB,invalidate_subdata}
* (part of OpenGL 4.3) is not available, this function does nothing.
* @see @ref invalidateSubImage(), @fn_gl{InvalidateTexImage}
*/
void invalidateImage() { AbstractTexture::invalidateImage(0); }
/**
* @brief Invalidate texture subimage
* @param offset Offset into the texture
* @param size Size of invalidated data
*
* If running on OpenGL ES or extension @extension{ARB,invalidate_subdata}
* (part of OpenGL 4.3) is not available, this function does nothing.
* @see @ref invalidateImage(), @fn_gl{InvalidateTexSubImage}
*/
void invalidateSubImage(const Vector2i& offset, const Vector2i& size) {
DataHelper<2>::invalidateSubImage(*this, 0, offset, size);
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
RectangleTexture& setLabel(const std::string& label) {
AbstractTexture::setLabel(label);
return *this;
}
#endif
};
}
#else
#error this header is available only on desktop OpenGL build
#endif
#endif

3
src/Magnum/Test/CMakeLists.txt

@ -77,12 +77,15 @@ if(BUILD_GL_TESTS)
corrade_add_test(ShaderGLTest ShaderGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
if(NOT MAGNUM_TARGET_GLES2)
corrade_add_test(TextureArrayGLTest TextureArrayGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(BufferImageGLTest BufferImageGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
endif()
if(NOT MAGNUM_TARGET_GLES)
corrade_add_test(BufferTextureGLTest BufferTextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(CubeMapTextureArrayGLTest CubeMapTextureArrayGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(MultisampleTextureGLTest MultisampleTextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
corrade_add_test(RectangleTextureGLTest RectangleTextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES})
endif()
endif()

3
src/Magnum/Test/CubeMapTextureArrayGLTest.cpp

@ -26,9 +26,10 @@
#include <Corrade/TestSuite/Compare/Container.h>
#include "Magnum/BufferImage.h"
#include "Magnum/Color.h"
#include "Magnum/ColorFormat.h"
#include "Magnum/Image.h"
#include "Magnum/CubeMapTextureArray.h"
#include "Magnum/Image.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Test/AbstractOpenGLTester.h"

3
src/Magnum/Test/CubeMapTextureGLTest.cpp

@ -29,9 +29,10 @@
#ifndef MAGNUM_TARGET_GLES2
#include "Magnum/BufferImage.h"
#endif
#include "Magnum/Color.h"
#include "Magnum/ColorFormat.h"
#include "Magnum/Image.h"
#include "Magnum/CubeMapTexture.h"
#include "Magnum/Image.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Test/AbstractOpenGLTester.h"

1
src/Magnum/Test/MeshGLTest.cpp

@ -24,6 +24,7 @@
*/
#include "Magnum/Buffer.h"
#include "Magnum/Color.h"
#include "Magnum/ColorFormat.h"
#include "Magnum/Framebuffer.h"
#include "Magnum/Image.h"

212
src/Magnum/Test/MultisampleTextureGLTest.cpp

@ -0,0 +1,212 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <Corrade/TestSuite/Compare/Container.h>
#include "Magnum/MultisampleTexture.h"
#include "Magnum/Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
class MultisampleTextureGLTest: public AbstractOpenGLTester {
public:
explicit MultisampleTextureGLTest();
void construct2D();
void construct2DArray();
void storage2D();
void storage2DArray();
void image2D();
void image2DBuffer();
void image2DArray();
void image2DArrayBuffer();
void subImage2D();
void subImage2DBuffer();
void subImage2DArray();
void subImage2DArrayBuffer();
void invalidateImage2D();
void invalidateImage2DArray();
void invalidateSubImage2D();
void invalidateSubImage2DArray();
};
MultisampleTextureGLTest::MultisampleTextureGLTest() {
addTests({&MultisampleTextureGLTest::construct2D,
&MultisampleTextureGLTest::construct2DArray,
&MultisampleTextureGLTest::storage2D,
&MultisampleTextureGLTest::storage2DArray,
&MultisampleTextureGLTest::image2D,
&MultisampleTextureGLTest::image2DBuffer,
&MultisampleTextureGLTest::image2DArray,
&MultisampleTextureGLTest::image2DArrayBuffer,
&MultisampleTextureGLTest::subImage2D,
&MultisampleTextureGLTest::subImage2DBuffer,
&MultisampleTextureGLTest::subImage2DArray,
&MultisampleTextureGLTest::subImage2DArrayBuffer,
&MultisampleTextureGLTest::invalidateImage2D,
&MultisampleTextureGLTest::invalidateImage2DArray,
&MultisampleTextureGLTest::invalidateSubImage2D,
&MultisampleTextureGLTest::invalidateSubImage2DArray});
}
void MultisampleTextureGLTest::construct2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
{
MultisampleTexture2D texture;
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(texture.id() > 0);
}
MAGNUM_VERIFY_NO_ERROR();
}
void MultisampleTextureGLTest::construct2DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
{
MultisampleTexture2DArray texture;
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(texture.id() > 0);
}
MAGNUM_VERIFY_NO_ERROR();
}
void MultisampleTextureGLTest::storage2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Not implemented yet.");
}
void MultisampleTextureGLTest::storage2DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Not implemented yet.");
}
void MultisampleTextureGLTest::image2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Not implemented yet.");
}
void MultisampleTextureGLTest::image2DBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Not implemented yet.");
}
void MultisampleTextureGLTest::image2DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Not implemented yet.");
}
void MultisampleTextureGLTest::image2DArrayBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Not implemented yet.");
}
void MultisampleTextureGLTest::subImage2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Not implemented yet.");
}
void MultisampleTextureGLTest::subImage2DBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Not implemented yet.");
}
void MultisampleTextureGLTest::subImage2DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Not implemented yet.");
}
void MultisampleTextureGLTest::subImage2DArrayBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Not implemented yet.");
}
void MultisampleTextureGLTest::invalidateImage2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Multisample storage is not implemented yet.");
}
void MultisampleTextureGLTest::invalidateImage2DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Multisample storage is not implemented yet.");
}
void MultisampleTextureGLTest::invalidateSubImage2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Multisample storage is not implemented yet.");
}
void MultisampleTextureGLTest::invalidateSubImage2DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Multisample storage is not implemented yet.");
}
}}
CORRADE_TEST_MAIN(Magnum::Test::MultisampleTextureGLTest)

250
src/Magnum/Test/RectangleTextureGLTest.cpp

@ -0,0 +1,250 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <Corrade/TestSuite/Compare/Container.h>
#include "Magnum/configure.h"
#include "Magnum/BufferImage.h"
#include "Magnum/Color.h"
#include "Magnum/ColorFormat.h"
#include "Magnum/Image.h"
#include "Magnum/RectangleTexture.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
class TextureGLTest: public AbstractOpenGLTester {
public:
explicit TextureGLTest();
void construct();
void sampling();
void storage();
void image();
void imageBuffer();
void subImage();
void subImageBuffer();
void invalidateImage();
void invalidateSubImage();
};
TextureGLTest::TextureGLTest() {
addTests({&TextureGLTest::construct,
&TextureGLTest::sampling,
&TextureGLTest::storage,
&TextureGLTest::image,
&TextureGLTest::imageBuffer,
&TextureGLTest::subImage,
&TextureGLTest::subImageBuffer,
&TextureGLTest::invalidateImage,
&TextureGLTest::invalidateSubImage});
}
void TextureGLTest::construct() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));
{
RectangleTexture texture;
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(texture.id() > 0);
}
MAGNUM_VERIFY_NO_ERROR();
}
void TextureGLTest::sampling() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));
RectangleTexture texture;
texture.setMinificationFilter(Sampler::Filter::Linear)
.setMagnificationFilter(Sampler::Filter::Linear)
.setWrapping(Sampler::Wrapping::ClampToBorder)
.setBorderColor(Color3(0.5f))
.setMaxAnisotropy(Sampler::maxMaxAnisotropy());
MAGNUM_VERIFY_NO_ERROR();
}
void TextureGLTest::storage() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));
RectangleTexture texture;
texture.setStorage(TextureFormat::RGBA8, Vector2i(32));
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(texture.imageSize(), Vector2i(32));
MAGNUM_VERIFY_NO_ERROR();
}
void TextureGLTest::image() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));
constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f };
RectangleTexture texture;
texture.setImage(TextureFormat::RGBA8,
ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data));
MAGNUM_VERIFY_NO_ERROR();
Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte);
texture.image(image);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i(2));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(image.data(), image.data()+image.pixelSize()*image.size().product()),
std::vector<UnsignedByte>(data, data + 16), TestSuite::Compare::Container);
}
void TextureGLTest::imageBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));
constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f };
RectangleTexture texture;
texture.setImage(TextureFormat::RGBA8,
BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data, BufferUsage::StaticDraw));
MAGNUM_VERIFY_NO_ERROR();
BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte);
texture.image(image, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i(2));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(imageData.begin(), imageData.end()),
std::vector<UnsignedByte>(data, data+16), TestSuite::Compare::Container);
}
void TextureGLTest::subImage() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));
constexpr UnsignedByte zero[4*4*4] = {};
constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f };
RectangleTexture texture;
texture.setImage(TextureFormat::RGBA8,
ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero));
texture.setSubImage(Vector2i(1),
ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData));
MAGNUM_VERIFY_NO_ERROR();
Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte);
texture.image(image);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i(4));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector<UnsignedByte>{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0,
0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}), TestSuite::Compare::Container);
}
void TextureGLTest::subImageBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));
constexpr UnsignedByte zero[4*4*4] = {};
constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f };
RectangleTexture texture;
texture.setImage(TextureFormat::RGBA8,
ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero));
texture.setSubImage(Vector2i(1),
BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData, BufferUsage::StaticDraw));
MAGNUM_VERIFY_NO_ERROR();
BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte);
texture.image(image, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i(4));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(imageData.begin(), imageData.end()), (std::vector<UnsignedByte>{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0,
0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}), TestSuite::Compare::Container);
}
void TextureGLTest::invalidateImage() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));
RectangleTexture texture;
texture.setStorage(TextureFormat::RGBA8, Vector2i(32));
texture.invalidateImage();
MAGNUM_VERIFY_NO_ERROR();
}
void TextureGLTest::invalidateSubImage() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_rectangle>())
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));
RectangleTexture texture;
texture.setStorage(TextureFormat::RGBA8, Vector2i(32));
texture.invalidateSubImage(Vector2i(4), Vector2i(16));
MAGNUM_VERIFY_NO_ERROR();
}
}}
CORRADE_TEST_MAIN(Magnum::Test::TextureGLTest)

683
src/Magnum/Test/TextureArrayGLTest.cpp

@ -0,0 +1,683 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <Corrade/TestSuite/Compare/Container.h>
#include "Magnum/configure.h"
#include "Magnum/BufferImage.h"
#include "Magnum/Color.h"
#include "Magnum/ColorFormat.h"
#include "Magnum/Image.h"
#include "Magnum/TextureArray.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
class TextureGLTest: public AbstractOpenGLTester {
public:
explicit TextureGLTest();
#ifndef MAGNUM_TARGET_GLES
void construct1DArray();
#endif
void construct2DArray();
#ifndef MAGNUM_TARGET_GLES
void sampling1DArray();
#endif
void sampling2DArray();
#ifdef MAGNUM_TARGET_GLES
void samplingBorder2DArray();
#endif
#ifndef MAGNUM_TARGET_GLES
void storage1DArray();
#endif
void storage2DArray();
#ifndef MAGNUM_TARGET_GLES
void image1DArray();
void image1DArrayBuffer();
#endif
#ifndef MAGNUM_TARGET_GLES2
void image2DArray();
void image2DArrayBuffer();
#endif
#ifndef MAGNUM_TARGET_GLES
void subImage1DArray();
void subImage1DArrayBuffer();
#endif
void subImage2DArray();
void subImage2DArrayBuffer();
#ifndef MAGNUM_TARGET_GLES
void generateMipmap1DArray();
#endif
void generateMipmap2DArray();
#ifndef MAGNUM_TARGET_GLES
void invalidateImage1DArray();
#endif
void invalidateImage2DArray();
#ifndef MAGNUM_TARGET_GLES
void invalidateSubImage1DArray();
#endif
void invalidateSubImage2DArray();
};
TextureGLTest::TextureGLTest() {
addTests({
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::construct1DArray,
#endif
&TextureGLTest::construct2DArray,
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::sampling1DArray,
#endif
&TextureGLTest::sampling2DArray,
#ifdef MAGNUM_TARGET_GLES
&TextureGLTest::samplingBorder2DArray,
#endif
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::storage1DArray,
#endif
&TextureGLTest::storage2DArray,
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::image1DArray,
&TextureGLTest::image1DArrayBuffer,
#endif
&TextureGLTest::image2DArray,
&TextureGLTest::image2DArrayBuffer,
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::subImage1DArray,
&TextureGLTest::subImage1DArrayBuffer,
#endif
&TextureGLTest::subImage2DArray,
&TextureGLTest::subImage2DArrayBuffer,
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::generateMipmap1DArray,
#endif
&TextureGLTest::generateMipmap2DArray,
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::invalidateImage1DArray,
#endif
&TextureGLTest::invalidateImage2DArray,
#ifndef MAGNUM_TARGET_GLES
&TextureGLTest::invalidateSubImage1DArray,
#endif
&TextureGLTest::invalidateSubImage2DArray
});
}
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::construct1DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
{
Texture1DArray texture;
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(texture.id() > 0);
}
MAGNUM_VERIFY_NO_ERROR();
}
#endif
void TextureGLTest::construct2DArray() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
#endif
{
Texture2DArray texture;
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(texture.id() > 0);
}
MAGNUM_VERIFY_NO_ERROR();
}
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::sampling1DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
Texture1DArray texture;
texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
.setMagnificationFilter(Sampler::Filter::Linear)
.setWrapping(Sampler::Wrapping::ClampToBorder)
.setBorderColor(Color3(0.5f))
.setMaxAnisotropy(Sampler::maxMaxAnisotropy());
MAGNUM_VERIFY_NO_ERROR();
}
#endif
void TextureGLTest::sampling2DArray() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
#endif
Texture2DArray texture;
texture.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
.setMagnificationFilter(Sampler::Filter::Linear)
#ifndef MAGNUM_TARGET_GLES
.setWrapping(Sampler::Wrapping::ClampToBorder)
.setBorderColor(Color3(0.5f))
#else
.setWrapping(Sampler::Wrapping::ClampToEdge)
#endif
.setMaxAnisotropy(Sampler::maxMaxAnisotropy());
MAGNUM_VERIFY_NO_ERROR();
}
#ifdef MAGNUM_TARGET_GLES
void TextureGLTest::samplingBorder2DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::NV::texture_border_clamp>())
CORRADE_SKIP(Extensions::GL::NV::texture_border_clamp::string() + std::string(" is not supported."));
Texture2DArray texture;
texture.setWrapping(Sampler::Wrapping::ClampToBorder)
.setBorderColor(Color3(0.5f));
MAGNUM_VERIFY_NO_ERROR();
}
#endif
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::storage1DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
Texture1DArray texture;
texture.setStorage(5, TextureFormat::RGBA8, Vector2i(32));
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(texture.imageSize(0), Vector2i(32, 32));
CORRADE_COMPARE(texture.imageSize(1), Vector2i(16, 32));
CORRADE_COMPARE(texture.imageSize(2), Vector2i( 8, 32));
CORRADE_COMPARE(texture.imageSize(3), Vector2i( 4, 32));
CORRADE_COMPARE(texture.imageSize(4), Vector2i( 2, 32));
CORRADE_COMPARE(texture.imageSize(5), Vector2i( 0, 0)); /* not available */
MAGNUM_VERIFY_NO_ERROR();
}
#endif
void TextureGLTest::storage2DArray() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
#endif
Texture2DArray texture;
texture.setStorage(5, TextureFormat::RGBA8, Vector3i(32));
MAGNUM_VERIFY_NO_ERROR();
/** @todo How to test this on ES? */
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(texture.imageSize(0), Vector3i(32, 32, 32));
CORRADE_COMPARE(texture.imageSize(1), Vector3i(16, 16, 32));
CORRADE_COMPARE(texture.imageSize(2), Vector3i( 8, 8, 32));
CORRADE_COMPARE(texture.imageSize(3), Vector3i( 4, 4, 32));
CORRADE_COMPARE(texture.imageSize(4), Vector3i( 2, 2, 32));
CORRADE_COMPARE(texture.imageSize(5), Vector3i( 0, 0, 0)); /* not available */
MAGNUM_VERIFY_NO_ERROR();
#endif
}
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::image1DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f };
Texture1DArray texture;
texture.setImage(0, TextureFormat::RGBA8,
ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data));
MAGNUM_VERIFY_NO_ERROR();
Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte);
texture.image(0, image);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i(2));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(image.data(), image.data()+image.pixelSize()*image.size().product()),
std::vector<UnsignedByte>(data, data + 16), TestSuite::Compare::Container);
}
void TextureGLTest::image1DArrayBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
constexpr UnsignedByte data[] = { 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f };
Texture1DArray texture;
texture.setImage(0, TextureFormat::RGBA8,
BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), data, BufferUsage::StaticDraw));
MAGNUM_VERIFY_NO_ERROR();
BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte);
texture.image(0, image, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i(2));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(imageData.begin(), imageData.end()),
std::vector<UnsignedByte>(data, data + 16), TestSuite::Compare::Container);
}
#endif
void TextureGLTest::image2DArray() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
#endif
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 };
Texture2DArray texture;
texture.setImage(0, TextureFormat::RGBA8,
ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), data));
MAGNUM_VERIFY_NO_ERROR();
/** @todo How to test this on ES? */
#ifndef MAGNUM_TARGET_GLES
Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte);
texture.image(0, image);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i(2));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(image.data(), image.data()+image.pixelSize()*image.size().product()),
std::vector<UnsignedByte>(data, data + 32), TestSuite::Compare::Container);
#endif
}
void TextureGLTest::image2DArrayBuffer() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
#endif
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 };
Texture2DArray texture;
texture.setImage(0, TextureFormat::RGBA8,
BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), data, BufferUsage::StaticDraw));
MAGNUM_VERIFY_NO_ERROR();
/** @todo How to test this on ES? */
#ifndef MAGNUM_TARGET_GLES
BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte);
texture.image(0, image, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i(2));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(imageData.begin(), imageData.end()),
std::vector<UnsignedByte>(data, data + 32), TestSuite::Compare::Container);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::subImage1DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
constexpr UnsignedByte zero[4*4*4] = {};
constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f };
Texture1DArray texture;
texture.setImage(0, TextureFormat::RGBA8,
ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero));
texture.setSubImage(0, Vector2i(1),
ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData));
MAGNUM_VERIFY_NO_ERROR();
Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte);
texture.image(0, image);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i(4));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector<UnsignedByte>{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0,
0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}), TestSuite::Compare::Container);
}
void TextureGLTest::subImage1DArrayBuffer() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
constexpr UnsignedByte zero[4*4*4] = {};
constexpr UnsignedByte subData[] = { 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f };
Texture1DArray texture;
texture.setImage(0, TextureFormat::RGBA8,
ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(4), zero));
texture.setSubImage(0, Vector2i(1),
BufferImage2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(2), subData, BufferUsage::StaticDraw));
MAGNUM_VERIFY_NO_ERROR();
BufferImage2D image(ColorFormat::RGBA, ColorType::UnsignedByte);
texture.image(0, image, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector2i(4));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(imageData.begin(), imageData.end()), (std::vector<UnsignedByte>{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0,
0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}), TestSuite::Compare::Container);
}
#endif
void TextureGLTest::subImage2DArray() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
#endif
constexpr UnsignedByte zero[4*4*4*4] = {};
constexpr UnsignedByte subData[] = { 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 };
Texture2DArray texture;
texture.setImage(0, TextureFormat::RGBA8,
ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), zero));
texture.setSubImage(0, Vector3i(1),
ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), subData));
MAGNUM_VERIFY_NO_ERROR();
/** @todo How to test this on ES? */
#ifndef MAGNUM_TARGET_GLES
Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte);
texture.image(0, image);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i(4));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(image.data(), image.data()+image.pixelSize()*image.size().product()), (std::vector<UnsignedByte>{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0,
0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0, 0, 0, 0,
0, 0, 0, 0, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}), TestSuite::Compare::Container);
#endif
}
void TextureGLTest::subImage2DArrayBuffer() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
#endif
constexpr UnsignedByte zero[4*4*4*4] = {};
constexpr UnsignedByte subData[] = { 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 };
Texture2DArray texture;
texture.setImage(0, TextureFormat::RGBA8,
ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(4), zero));
texture.setSubImage(0, Vector3i(1),
BufferImage3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(2), subData, BufferUsage::StaticDraw));
MAGNUM_VERIFY_NO_ERROR();
/** @todo How to test this on ES? */
#ifndef MAGNUM_TARGET_GLES
BufferImage3D image(ColorFormat::RGBA, ColorType::UnsignedByte);
texture.image(0, image, BufferUsage::StaticRead);
const auto imageData = image.buffer().data<UnsignedByte>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(image.size(), Vector3i(4));
CORRADE_COMPARE_AS(std::vector<UnsignedByte>(imageData.begin(), imageData.end()), (std::vector<UnsignedByte>{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0, 0, 0, 0,
0, 0, 0, 0, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0, 0, 0, 0,
0, 0, 0, 0, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}), TestSuite::Compare::Container);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::generateMipmap1DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
Texture1DArray texture;
texture.setImage(0, TextureFormat::RGBA8,
ImageReference2D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector2i(32)));
CORRADE_COMPARE(texture.imageSize(0), Vector2i(32));
CORRADE_COMPARE(texture.imageSize(1), Vector2i( 0));
texture.generateMipmap();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(texture.imageSize(0), Vector2i(32, 32));
CORRADE_COMPARE(texture.imageSize(1), Vector2i(16, 32));
CORRADE_COMPARE(texture.imageSize(2), Vector2i( 8, 32));
CORRADE_COMPARE(texture.imageSize(3), Vector2i( 4, 32));
CORRADE_COMPARE(texture.imageSize(4), Vector2i( 2, 32));
CORRADE_COMPARE(texture.imageSize(5), Vector2i( 1, 32));
MAGNUM_VERIFY_NO_ERROR();
}
#endif
void TextureGLTest::generateMipmap2DArray() {
#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 supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
#endif
Texture2DArray texture;
texture.setImage(0, TextureFormat::RGBA8,
ImageReference3D(ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i(32)));
/** @todo How to test this on ES? */
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(texture.imageSize(0), Vector3i(32));
CORRADE_COMPARE(texture.imageSize(1), Vector3i( 0));
#endif
texture.generateMipmap();
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(texture.imageSize(0), Vector3i(32, 32, 32));
CORRADE_COMPARE(texture.imageSize(1), Vector3i(16, 16, 32));
CORRADE_COMPARE(texture.imageSize(2), Vector3i( 8, 8, 32));
CORRADE_COMPARE(texture.imageSize(3), Vector3i( 4, 4, 32));
CORRADE_COMPARE(texture.imageSize(4), Vector3i( 2, 2, 32));
CORRADE_COMPARE(texture.imageSize(5), Vector3i( 1, 1, 32));
MAGNUM_VERIFY_NO_ERROR();
#endif
}
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::invalidateImage1DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
Texture1DArray texture;
texture.setStorage(2, TextureFormat::RGBA8, Vector2i(32));
texture.invalidateImage(1);
MAGNUM_VERIFY_NO_ERROR();
}
#endif
void TextureGLTest::invalidateImage2DArray() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
#endif
Texture2DArray texture;
texture.setStorage(2, TextureFormat::RGBA8, Vector3i(32));
texture.invalidateImage(1);
MAGNUM_VERIFY_NO_ERROR();
}
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::invalidateSubImage1DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
Texture1DArray texture;
texture.setStorage(2, TextureFormat::RGBA8, Vector2i(32));
texture.invalidateSubImage(1, Vector2i(2), Vector2i(8));
MAGNUM_VERIFY_NO_ERROR();
}
#endif
void TextureGLTest::invalidateSubImage2DArray() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
#endif
Texture2DArray texture;
texture.setStorage(2, TextureFormat::RGBA8, Vector3i(32));
texture.invalidateSubImage(1, Vector3i(2), Vector3i(8));
MAGNUM_VERIFY_NO_ERROR();
}
}}
CORRADE_TEST_MAIN(Magnum::Test::TextureGLTest)

1061
src/Magnum/Test/TextureGLTest.cpp

File diff suppressed because it is too large Load Diff

1
src/Magnum/Text/AbstractFont.cpp

@ -29,6 +29,7 @@
#include <Corrade/Utility/Directory.h>
#include <Corrade/Utility/Unicode.h>
#include "Magnum/Math/Functions.h"
#include "Magnum/Text/GlyphCache.h"
namespace Magnum { namespace Text {

1
src/Magnum/Text/Renderer.cpp

@ -28,6 +28,7 @@
#include "Magnum/Context.h"
#include "Magnum/Extensions.h"
#include "Magnum/Mesh.h"
#include "Magnum/Math/Functions.h"
#include "Magnum/Shaders/AbstractVector.h"
#include "Magnum/Text/AbstractFont.h"

1
src/Magnum/Text/Test/AbstractFontTest.cpp

@ -27,6 +27,7 @@
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/Directory.h>
#include "Magnum/Math/Vector2.h"
#include "Magnum/Text/AbstractFont.h"
#include "configure.h"

369
src/Magnum/Texture.h

@ -29,11 +29,30 @@
* @brief Class @ref Magnum::Texture, typedef @ref Magnum::Texture1D, @ref Magnum::Texture2D, @ref Magnum::Texture3D
*/
#include <Corrade/Utility/Macros.h>
#include "Magnum/AbstractTexture.h"
#include "Magnum/Array.h"
#include "Magnum/DimensionTraits.h"
#include "Magnum/Math/Vector3.h"
namespace Magnum {
namespace Implementation {
template<UnsignedInt> constexpr GLenum textureTarget();
#ifndef MAGNUM_TARGET_GLES
template<> inline constexpr GLenum textureTarget<1>() { return GL_TEXTURE_1D; }
#endif
template<> inline constexpr GLenum textureTarget<2>() { return GL_TEXTURE_2D; }
template<> inline constexpr GLenum textureTarget<3>() {
#ifndef MAGNUM_TARGET_GLES2
return GL_TEXTURE_3D;
#else
return GL_TEXTURE_3D_OES;
#endif
}
}
/**
@brief %Texture
@ -58,180 +77,95 @@ texture.setMagnificationFilter(Sampler::Filter::Linear)
.generateMipmap();
@endcode
@attention Don't forget to fully configure the texture before use. Note that
default configuration (if @ref setMinificationFilter() is not called with
another value) is to use mipmaps, so be sure to either call @ref setMinificationFilter(),
explicitly specify all mip levels with @ref setStorage() and @ref setImage()
or call @ref generateMipmap(). If using rectangle texture, you must also
call @ref setWrapping(), because the initial value is not supported on
rectangle textures. See also @ref setMagnificationFilter() and
@ref setBorderColor().
@attention Note that default configuration (if @ref setMinificationFilter() is
not called with another value) is to use mipmaps, so be sure to either call
@ref setMinificationFilter(), explicitly specify all mip levels with
@ref setStorage() and @ref setImage() or call @ref generateMipmap().
The texture is bound to layer specified by shader via @ref bind(). In shader,
the texture is used via `sampler2D` and friends, see @ref Target enum
documentation for more information. See also AbstractShaderProgram
documentation for more information about usage in shaders.
@section Texture-array Texture arrays
You can create texture arrays by passing
@ref Target::Texture1DArray "Texture2D::Target::Texture1DArray" or
@ref Target::Texture2DArray "Texture3D::Target::Texture2DArray" to constructor.
It is possible to specify each layer separately using @ref setSubImage(), but
you have to allocate the memory for all layers first by calling @ref setStorage().
Example: 2D texture array with 16 layers of 64x64 images:
@code
Texture3D texture(Texture3D::Target::Texture2DArray);
texture.setMagnificationFilter(Sampler::Filter::Linear)
// ...
.setStorage(levels, TextureFormat::RGBA8, {64, 64,16});
for(std::size_t i = 0; i != 16; ++i) {
// ...
Image2D image(ColorFormat::RGBA, ColorType::UnsignedByte, {64, 64}, data[i]);
texture.setSubImage(0, Vector3i::zAxis(i), image);
}
// ...
@endcode
Similar approach can be used for any other texture types (e.g. setting
@ref Texture3D data using 2D layers, @ref Texture2D data using one-dimensional
chunks etc.).
@requires_gl30 %Extension @extension{EXT,texture_array} for texture arrays.
@requires_gles30 %Array textures are not available in OpenGL ES 2.0.
@section Texture-multisample Multisample textures
You can create multisample textures by passing
@ref Target::Texture2DMultisample "Texture2D::Target::Texture2DMultisample" or
@ref Target::Texture2DMultisampleArray "Texture3D::Target::Texture2DMultisampleArray"
to constructor.
@todoc finish this when fully implemented
@requires_gl32 %Extension @extension{ARB,texture_multisample} for multisample
textures.
@requires_gl Multisample textures are not available in OpenGL ES.
@section Texture-rectangle Rectangle textures
Rectangle texture is created by passing @ref Target::Rectangle "Texture2D::Target::Rectangle"
to constructor. In shader, the texture is used via `sampler2DRect` and friends.
Unlike `sampler2D`, which accepts coordinates between 0 and 1, `sampler2DRect`
accepts coordinates between 0 and `textureSizeInGivenDirection-1`. Note that
rectangle textures don't support mipmapping and repeating wrapping modes, see
@ref Sampler::Filter, @ref Sampler::Mipmap and @ref generateMipmap()
documentation for more information.
@requires_gl31 %Extension @extension{ARB,texture_rectangle} for rectangle
textures.
@requires_gl Rectangle textures are not available in OpenGL ES.
@see @ref Texture1D, @ref Texture2D, @ref Texture3D, @ref CubeMapTexture,
@ref CubeMapTextureArray, @ref BufferTexture
@todo @extension{AMD,sparse_texture}
@todo Separate multisample, array and rectangle texture classes to avoid confusion, then remove Target enum
the texture is used via `sampler1D`/`sampler2D`/`sampler3D`,
`sampler1DShadow`/`sampler2DShadow`/`sampler3DShadow`,
`isampler1D`/`isampler2D`/`isampler3D` or `usampler1D`/`usampler2D`/`usampler3D`.
See @ref AbstractShaderProgram documentation for more information about usage
in shaders.
@requires_gles30 %Extension @es_extension{OES,texture_3D} for 3D textures.
@requires_gl 1D textures are not available in OpenGL ES, only 2D and 3D ones.
@see @ref Texture1D, @ref Texture2D, @ref Texture3D, @ref TextureArray,
@ref BufferTexture, @ref CubeMapTexture, @ref CubeMapTextureArray,
@ref MultisampleTexture, @ref RectangleTexture
*/
template<UnsignedInt dimensions> class Texture: public AbstractTexture {
public:
static const UnsignedInt Dimensions = dimensions; /**< @brief %Texture dimension count */
#ifdef DOXYGEN_GENERATING_OUTPUT
#ifdef MAGNUM_BUILD_DEPRECATED
/**
* @brief %Texture target
*
* Each dimension has its own unique subset of these targets.
* @deprecated Use dedicated classes instead, see documentation of
* particular enum value for more information.
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
enum class Target: GLenum {
/**
* One-dimensional texture. Use `sampler1D`, `sampler1DShadow`,
* `isampler1D` or `usampler1D` in shader.
* @requires_gl Only 2D and 3D textures are available in OpenGL
* ES.
*/
/** @deprecated Used implicitly in @ref Magnum::Texture1D "Texture1D" class. */
Texture1D = GL_TEXTURE_1D,
/**
* Two-dimensional texture. Use `sampler2D`, `sampler2DShadow`,
* `isampler2D` or `usampler2D` in shader.
*/
/** @deprecated Used implicitly in @ref Magnum::Texture2D "Texture2D" class. */
Texture2D = GL_TEXTURE_2D,
/**
* Three-dimensional texture. Use `sampler3D`, `isampler3D` or
* `usampler3D` in shader.
* @requires_gles30 %Extension @es_extension{OES,texture_3D}
*/
/** @deprecated Used implicitly in @ref Magnum::Texture3D "Texture3D" class. */
Texture3D = GL_TEXTURE_3D,
/**
* One-dimensional texture array (i.e. two dimensions in total).
* Use `sampler1DArray`, `sampler1DArrayShadow`, `isampler1DArray`
* or `usampler1DArray` in shader.
* @requires_gl30 %Extension @extension{EXT,texture_array}
* @requires_gl Only 2D and 3D textures are available in OpenGL
* ES.
*/
/** @deprecated Use @ref Magnum::Texture1DArray "Texture1DArray" class instead. */
Texture1DArray = GL_TEXTURE_1D_ARRAY,
/**
* Two-dimensional texture array (i.e. three dimensions in total).
* Use `sampler2DArray`, `sampler2DArrayShadow`, `isampler2DArray`
* or `usampler2DArray` in shader.
* @requires_gl30 %Extension @extension{EXT,texture_array}
* @requires_gles30 %Array textures are not available in OpenGL ES
* 2.0.
*/
/** @deprecated Use @ref Magnum::Texture2DArray "Texture2DArray" class instead. */
Texture2DArray = GL_TEXTURE_2D_ARRAY,
/**
* Multisampled two-dimensional texture. Use `sampler2DMS`,
* `isampler2DMS` or `usampler2DMS` in shader.
* @requires_gl32 %Extension @extension{ARB,texture_multisample}
* @requires_gl Multisample textures are not available in OpenGL
* ES.
*/
/** @deprecated Use @ref Magnum::MultisampleTexture2D "MultisampleTexture2D" class instead. */
Texture2DMultisample = GL_TEXTURE_2D_MULTISAMPLE,
/**
* Multisampled two-dimensional texture array (i.e. three
* dimensions in total). Use `sampler2DMSArray`,
* `isampler2DMSArray` or `usampler2DMSArray` in shader.
* @requires_gl32 %Extension @extension{ARB,texture_multisample}
* @requires_gl Multisample textures are not available in OpenGL
* ES.
*/
/** @deprecated Use @ref Magnum::MultisampleTexture2DArray "MultisampleTexture2DArray" class instead. */
Texture2DMultisampleArray = GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
/**
* Rectangle texture (i.e. two dimensions). Use `sampler2DRect`,
* `sampler2DRectShadow`, `isampler2DRect` or `usampler2DRect` in
* shader.
* @requires_gl31 %Extension @extension{ARB,texture_rectangle}
* @requires_gl Rectangle textures are not available in OpenGL ES.
*/
/** @deprecated Use @ref Magnum::RectangleTexture "RectangleTexture" class instead. */
Rectangle = GL_TEXTURE_RECTANGLE
};
#else
typedef typename DataHelper<Dimensions>::Target Target; /**< @brief %Texture target */
typedef typename DataHelper<Dimensions>::Target Target;
#endif
#endif
/**
* @brief Constructor
* @param target %Texture target. If not set, default value
* is `Target::Texture1D`, `Target::Texture2D` or
* `Target::Texture3D` based on dimension count.
*
* Creates new OpenGL texture.
* @see @fn_gl{GenTextures}
* Creates new OpenGL texture object.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_1D}, @def_gl{TEXTURE_2D}
* or @def_gl{TEXTURE_3D}
*/
explicit Texture(Target target = DataHelper<Dimensions>::target()): AbstractTexture(GLenum(target)) {}
/** @brief %Texture target */
constexpr Target target() const { return static_cast<Target>(_target); }
explicit Texture(): AbstractTexture(Implementation::textureTarget<dimensions>()) {}
#ifdef MAGNUM_BUILD_DEPRECATED
/** @copybrief Texture()
* @deprecated Use the parameterless @ref Magnum::Texture::Texture() "Texture()"
* constructor or dedicated @ref Magnum::TextureArray "TextureArray",
* @ref Magnum::MultisampleTexture "MultisampleTexture",
* @ref Magnum::RectangleTexture "RectangleTexture" classes
* instead.
*/
explicit CORRADE_DEPRECATED("use the parameterless constructor or dedicated TextureArray, MultisampleTexture, RectangleTexture classes instead") Texture(Target target): AbstractTexture(GLenum(target)) {}
/** @brief %Texture target
* @deprecated Use dedicated @ref Magnum::Texture "Texture",
* @ref Magnum::TextureArray "TextureArray",
* @ref Magnum::MultisampleTexture "MultisampleTexture",
* @ref Magnum::RectangleTexture "RectangleTexture" classes
* instead.
*/
constexpr CORRADE_DEPRECATED("use dedicated Texture, TextureArray, MultisampleTexture, RectangleTexture classes instead") Target target() const { return static_cast<Target>(_target); }
#endif
#ifndef MAGNUM_TARGET_GLES
/**
@ -245,11 +179,50 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or @def_gl{TEXTURE_DEPTH}.
* @requires_gl %Texture image queries are not available in OpenGL ES.
*/
typename DimensionTraits<Dimensions, Int>::VectorType imageSize(Int level) {
return DataHelper<Dimensions>::imageSize(*this, _target, level);
typename DimensionTraits<dimensions, Int>::VectorType imageSize(Int level) {
return DataHelper<dimensions>::imageSize(*this, _target, level);
}
#endif
/**
* @brief Set minification filter
* @param filter Filter
* @param mipmap Mipmap filtering. If set to anything else than
* @ref Sampler::Mipmap::Base, make sure textures for all mip
* levels are set or call @ref generateMipmap().
* @return Reference to self (for method chaining)
*
* Sets filter used when the object pixel size is smaller than the
* texture size. If @extension{EXT,direct_state_access} is not
* available, the texture is bound to some layer before the operation.
* Initial value is (@ref Sampler::Filter::Nearest, @ref Sampler::Mipmap::Linear).
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_MIN_FILTER}
*/
Texture<dimensions>& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;
}
/**
* @brief Set magnification filter
* @param filter Filter
* @return Reference to self (for method chaining)
*
* Sets filter used when the object pixel size is larger than largest
* texture size. If @extension{EXT,direct_state_access} is not
* available, the texture is bound to some layer before the operation.
* Initial value is @ref Sampler::Filter::Linear.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_MAG_FILTER}
*/
Texture<dimensions>& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return *this;
}
/**
* @brief Set wrapping
* @param wrapping Wrapping type for all texture dimensions
@ -260,15 +233,51 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* textures. If @extension{EXT,direct_state_access} is not available,
* the texture is bound to some layer before the operation. Initial
* value is @ref Sampler::Wrapping::Repeat.
* @attention For rectangle textures only some modes are supported,
* see @ref Sampler::Wrapping documentation for more information.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T},
* @def_gl{TEXTURE_WRAP_R}
*/
Texture<Dimensions>& setWrapping(const Array<Dimensions, Sampler::Wrapping>& wrapping) {
DataHelper<Dimensions>::setWrapping(*this, wrapping);
Texture<dimensions>& setWrapping(const Array<dimensions, Sampler::Wrapping>& wrapping) {
DataHelper<dimensions>::setWrapping(*this, wrapping);
return *this;
}
/**
* @brief Set border color
* @return Reference to self (for method chaining)
*
* Border color when wrapping is set to @ref Sampler::Wrapping::ClampToBorder.
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some layer before the operation. Initial value is
* `{0.0f, 0.0f, 0.0f, 0.0f}`.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter}
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_BORDER_COLOR}
* @requires_es_extension %Extension @es_extension{NV,texture_border_clamp}
*/
Texture<dimensions>& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
/**
* @brief Set max anisotropy
* @return Reference to self (for method chaining)
*
* Default value is `1.0f`, which means no anisotropy. Set to value
* greater than `1.0f` for anisotropic filtering. If extension
* @extension{EXT,texture_filter_anisotropic} (desktop or ES) is not
* available, this function does nothing. If
* @extension{EXT,direct_state_access} is not available, the texture is
* bound to some layer before the operation.
* @see @ref Sampler::maxMaxAnisotropy(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_MAX_ANISOTROPY_EXT}
*/
Texture<dimensions>& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return *this;
}
@ -301,8 +310,8 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage3D,EXT,direct_state_access}.
*/
Texture<Dimensions>& setStorage(Int levels, TextureFormat internalFormat, const typename DimensionTraits<Dimensions, Int>::VectorType& size) {
DataHelper<Dimensions>::setStorage(*this, _target, levels, internalFormat, size);
Texture<dimensions>& setStorage(Int levels, TextureFormat internalFormat, const typename DimensionTraits<dimensions, Int>::VectorType& size) {
DataHelper<dimensions>::setStorage(*this, _target, levels, internalFormat, size);
return *this;
}
@ -368,20 +377,20 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage3D,EXT,direct_state_access}
*/
Texture<Dimensions>& setImage(Int level, TextureFormat internalFormat, const ImageReference<dimensions>& image) {
DataHelper<Dimensions>::setImage(*this, _target, level, internalFormat, image);
Texture<dimensions>& setImage(Int level, TextureFormat internalFormat, const ImageReference<dimensions>& image) {
DataHelper<dimensions>::setImage(*this, _target, level, internalFormat, image);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
Texture<Dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions>& image) {
DataHelper<Dimensions>::setImage(*this, _target, level, internalFormat, image);
Texture<dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions>& image) {
DataHelper<dimensions>::setImage(*this, _target, level, internalFormat, image);
return *this;
}
/** @overload */
Texture<Dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions>&& image) {
Texture<dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions>&& image) {
return setImage(level, internalFormat, image);
}
#endif
@ -403,24 +412,50 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access}
*/
Texture<Dimensions>& setSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, const ImageReference<dimensions>& image) {
Texture<dimensions>& setSubImage(Int level, const typename DimensionTraits<dimensions, Int>::VectorType& offset, const ImageReference<dimensions>& image) {
DataHelper<Dimensions>::setSubImage(*this, _target, level, offset, image);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
Texture<Dimensions>& setSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, BufferImage<dimensions>& image) {
Texture<dimensions>& setSubImage(Int level, const typename DimensionTraits<dimensions, Int>::VectorType& offset, BufferImage<dimensions>& image) {
DataHelper<Dimensions>::setSubImage(*this, _target, level, offset, image);
return *this;
}
/** @overload */
Texture<Dimensions>& setSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, BufferImage<dimensions>&& image) {
Texture<dimensions>& setSubImage(Int level, const typename DimensionTraits<dimensions, Int>::VectorType& offset, BufferImage<dimensions>&& image) {
return setSubImage(level, offset, image);
}
#endif
/**
* @brief Generate mipmap
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some layer before the operation.
* @see setMinificationFilter(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{GenerateMipmap} or
* @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access}
* @requires_gl30 %Extension @extension{ARB,framebuffer_object}
*/
Texture<dimensions>& generateMipmap() {
AbstractTexture::generateMipmap();
return *this;
}
/**
* @brief Invalidate texture image
* @param level Mip level
*
* If running on OpenGL ES or extension @extension{ARB,invalidate_subdata}
* (part of OpenGL 4.3) is not available, this function does nothing.
* @see @ref invalidateSubImage(), @fn_gl{InvalidateTexImage}
*/
void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); }
/**
* @brief Invalidate texture subimage
* @param level Mip level
@ -431,36 +466,16 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* (part of OpenGL 4.3) is not available, this function does nothing.
* @see @ref invalidateImage(), @fn_gl{InvalidateTexSubImage}
*/
void invalidateSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, const typename DimensionTraits<Dimensions, Int>::VectorType& size) {
void invalidateSubImage(Int level, const typename DimensionTraits<dimensions, Int>::VectorType& offset, const typename DimensionTraits<dimensions, Int>::VectorType& size) {
DataHelper<dimensions>::invalidateSubImage(*this, level, offset, size);
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
Texture<Dimensions>& setLabel(const std::string& label) {
Texture<dimensions>& setLabel(const std::string& label) {
AbstractTexture::setLabel(label);
return *this;
}
Texture<Dimensions>& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;
}
Texture<Dimensions>& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return *this;
}
Texture<Dimensions>& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
Texture<Dimensions>& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return *this;
}
Texture<Dimensions>& generateMipmap() {
AbstractTexture::generateMipmap();
return *this;
}
#endif
};

302
src/Magnum/TextureArray.h

@ -0,0 +1,302 @@
#ifndef Magnum_TextureArray_h
#define Magnum_TextureArray_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef MAGNUM_TARGET_GLES2
/** @file
* @brief Class @ref Magnum::TextureArray, typedef @ref Magnum::Texture1DArray, @ref Magnum::Texture2DArray
*/
#endif
#include "Magnum/AbstractTexture.h"
#include "Magnum/Array.h"
#include "Magnum/DimensionTraits.h"
#include "Magnum/Math/Vector3.h"
#ifndef MAGNUM_TARGET_GLES2
namespace Magnum {
namespace Implementation {
template<UnsignedInt> constexpr GLenum textureArrayTarget();
#ifndef MAGNUM_TARGET_GLES
template<> inline constexpr GLenum textureArrayTarget<1>() { return GL_TEXTURE_1D_ARRAY; }
#endif
template<> inline constexpr GLenum textureArrayTarget<2>() { return GL_TEXTURE_2D_ARRAY; }
}
/**
@brief %Texture array
Template class for one- and two-dimensional texture arrays. See also
@ref AbstractTexture documentation for more information.
@section Texture-usage Usage
Common usage is to fully configure all texture parameters and then set the
data. Example configuration:
@code
Texture2DArray texture;
texture.setMagnificationFilter(Sampler::Filter::Linear)
.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
.setWrapping(Sampler::Wrapping::ClampToEdge)
.setMaxAnisotropy(Sampler::maxMaxAnisotropy());;
@endcode
It is often more convenient to first allocate the memory for all layers by
calling @ref setStorage() and then specify each layer separately using
@ref setSubImage():
@code
texture.setStorage(levels, TextureFormat::RGBA8, {64, 64, 16});
for(std::size_t i = 0; i != 16; ++i) {
Image3D image(ColorFormat::RGBA, ColorType::UnsignedByte, {64, 64, 1}, ...);
texture.setSubImage(0, Vector3i::zAxis(i), image);
}
@endcode
@attention Note that default configuration (if @ref setMinificationFilter() is
not called with another value) is to use mipmaps, so be sure to either call
@ref setMinificationFilter(), explicitly specify all mip levels with
@ref setStorage() and @ref setImage() or call @ref generateMipmap().
The texture is bound to layer specified by shader via @ref bind(). In shader,
the texture is used via `sampler1DArray`/`sampler2DArray`,
`sampler1DArrayShadow`/`sampler1DArrayShadow`, `isampler1DArray`/`isampler2DArray`
or `usampler1DArray`/`usampler2DArray`. See @ref AbstractShaderProgram
documentation for more information about usage in shaders.
@requires_gl30 %Extension @extension{EXT,texture_array}
@requires_gles30 %Array textures are not available in OpenGL ES 2.0.
@requires_gl 1D array textures are not available in OpenGL ES, only 2D ones.
@see @ref Texture1DArray, @ref Texture2DArray, @ref Texture, @ref BufferTexture,
@ref CubeMapTexture, @ref CubeMapTextureArray, @ref MultisampleTexture,
@ref RectangleTexture
*/
template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
public:
static const UnsignedInt Dimensions = dimensions; /**< @brief %Texture dimension count */
/**
* @brief Constructor
*
* Creates new OpenGL texture object.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_1D_ARRAY} or @def_gl{TEXTURE_2D_ARRAY}
*/
explicit TextureArray(): AbstractTexture(Implementation::textureArrayTarget<dimensions>()) {}
/** @copydoc Texture::setMinificationFilter() */
TextureArray<dimensions>& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return *this;
}
/** @copydoc Texture::setMagnificationFilter() */
TextureArray<dimensions>& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return *this;
}
/** @copydoc Texture::setWrapping() */
TextureArray<dimensions>& setWrapping(const Array<dimensions+1, Sampler::Wrapping>& wrapping) {
DataHelper<dimensions+1>::setWrapping(*this, wrapping);
return *this;
}
/** @copydoc Texture::setBorderColor() */
TextureArray<dimensions>& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return *this;
}
/** @copydoc Texture::setMaxAnisotropy() */
TextureArray<dimensions>& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return *this;
}
#ifndef MAGNUM_TARGET_GLES
/** @copydoc Texture::imageSize() */
typename DimensionTraits<dimensions+1, Int>::VectorType imageSize(Int level) {
return DataHelper<dimensions+1>::imageSize(*this, _target, level);
}
#endif
/**
* @brief Set storage
* @param levels Mip level count
* @param internalFormat Internal format
* @param size Size of largest mip level
* @return Reference to self (for method chaining)
*
* Specifies entire structure of a texture at once, removing the need
* for additional consistency checks and memory reallocations when
* updating the data later. After calling this function the texture
* is immutable and calling @ref setStorage() or @ref setImage() is not
* allowed.
*
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some layer before the operation. If
* @extension{ARB,texture_storage} (part of OpenGL 4.2) or OpenGL ES
* 3.0 is not available, the feature is emulated with sequence of
* @ref setImage() calls.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexStorage2D}/@fn_gl{TexStorage3D} or
* @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureStorage3D,EXT,direct_state_access},
* eventually @fn_gl{TexImage2D}/@fn_gl{TexImage3D} or
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage3D,EXT,direct_state_access}.
*/
TextureArray<dimensions>& setStorage(Int levels, TextureFormat internalFormat, const typename DimensionTraits<dimensions+1, Int>::VectorType& size) {
DataHelper<dimensions+1>::setStorage(*this, _target, levels, internalFormat, size);
return *this;
}
#ifndef MAGNUM_TARGET_GLES
/** @copydoc Texture::image(Int, Image<dimensions>&) */
void image(Int level, Image<dimensions+1>& image) {
AbstractTexture::image<dimensions+1>(_target, level, image);
}
/** @copydoc Texture::imate(Int, BufferImage<dimensions>&, BufferUsage) */
void image(Int level, BufferImage<dimensions+1>& image, BufferUsage usage) {
AbstractTexture::image<dimensions+1>(_target, level, image, usage);
}
#endif
/**
* @brief Set image data
* @param level Mip level
* @param internalFormat Internal format
* @param image @ref Image, @ref ImageReference or
* @ref Trade::ImageData of the same dimension count
* @return Reference to self (for method chaining)
*
* For better performance when generating mipmaps using
* @ref generateMipmap() or calling @ref setImage() more than once use
* @ref setStorage() and @ref setSubImage() instead.
*
* If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some layer before the operation.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl{TexImage2D}/@fn_gl{TexImage3D} or
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage3D,EXT,direct_state_access}
*/
TextureArray<dimensions>& setImage(Int level, TextureFormat internalFormat, const ImageReference<dimensions+1>& image) {
DataHelper<dimensions+1>::setImage(*this, _target, level, internalFormat, image);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
TextureArray<dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions+1>& image) {
DataHelper<dimensions+1>::setImage(*this, _target, level, internalFormat, image);
return *this;
}
/** @overload */
TextureArray<dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions+1>&& image) {
return setImage(level, internalFormat, image);
}
#endif
/**
* @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)
*
* If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some layer before the operation.
* @see @ref setStorage(), @ref setImage(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D}
* or @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access}
*/
TextureArray<dimensions>& setSubImage(Int level, const typename DimensionTraits<dimensions+1, Int>::VectorType& offset, const ImageReference<dimensions+1>& image) {
DataHelper<dimensions+1>::setSubImage(*this, _target, level, offset, image);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
TextureArray<dimensions>& setSubImage(Int level, const typename DimensionTraits<dimensions+1, Int>::VectorType& offset, BufferImage<dimensions+1>& image) {
DataHelper<dimensions+1>::setSubImage(*this, _target, level, offset, image);
return *this;
}
/** @overload */
TextureArray<dimensions>& setSubImage(Int level, const typename DimensionTraits<dimensions+1, Int>::VectorType& offset, BufferImage<dimensions+1>&& image) {
return setSubImage(level, offset, image);
}
#endif
/** @copydoc Texture::generateMipmap() */
TextureArray<dimensions>& generateMipmap() {
AbstractTexture::generateMipmap();
return *this;
}
/** @copydoc Texture::invalidateImage() */
void invalidateImage(Int level) { AbstractTexture::invalidateImage(level); }
/** @copydoc Texture::invalidateSubImage() */
void invalidateSubImage(Int level, const typename DimensionTraits<dimensions+1, Int>::VectorType& offset, const typename DimensionTraits<dimensions+1, Int>::VectorType& size) {
DataHelper<dimensions+1>::invalidateSubImage(*this, level, offset, size);
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
TextureArray<dimensions>& setLabel(const std::string& label) {
AbstractTexture::setLabel(label);
return *this;
}
#endif
};
#ifndef MAGNUM_TARGET_GLES
/**
@brief One-dimensional texture array
@requires_gl Only @ref Magnum::Texture2DArray "Texture2DArray" is available in
OpenGL ES.
*/
typedef TextureArray<1> Texture1DArray;
#endif
/** @brief Two-dimensional texture array */
typedef TextureArray<2> Texture2DArray;
}
#else
#error this header is not available on OpenGL ES 2.0 build
#endif
#endif
Loading…
Cancel
Save