Browse Source

Split the OpenGL layer out, pt 8: move out GL-specific PixelStorage parts.

The general part stays in the root namespace, while the GL-specific
stuff goes to the GL namespace. Also all GL-specific documentation was
moved to relevant APIs in the GL namespace. This finally allows me to
build PixelStorage.cpp as part of the root namespace.

The PixelStorage::pixelSize() function and
PixelStorage::dataProperties() taking a pair of GL::PixelFormat /
GL::PixelType enums is deprecated, use GL::pixelSize() and
dataProperties() taking pixel size directly instead. A lot of code is
still using these, including images; the deprecated aliases are inlined
in the header to avoid a compile-time dependency on the GL library.
pull/233/head
Vladimír Vondruš 8 years ago
parent
commit
ddbf220c30
  1. 6
      doc/changelog.dox
  2. 1
      src/Magnum/CMakeLists.txt
  3. 7
      src/Magnum/GL/AbstractFramebuffer.cpp
  4. 15
      src/Magnum/GL/AbstractFramebuffer.h
  5. 65
      src/Magnum/GL/AbstractTexture.cpp
  6. 13
      src/Magnum/GL/AbstractTexture.h
  7. 2
      src/Magnum/GL/BufferImage.h
  8. 1
      src/Magnum/GL/CMakeLists.txt
  9. 33
      src/Magnum/GL/CubeMapTexture.cpp
  10. 52
      src/Magnum/GL/CubeMapTexture.h
  11. 30
      src/Magnum/GL/CubeMapTextureArray.h
  12. 105
      src/Magnum/GL/Implementation/RendererState.cpp
  13. 22
      src/Magnum/GL/Implementation/RendererState.h
  14. 126
      src/Magnum/GL/PixelFormat.cpp
  15. 9
      src/Magnum/GL/PixelFormat.h
  16. 12
      src/Magnum/GL/RectangleTexture.h
  17. 52
      src/Magnum/GL/Texture.h
  18. 38
      src/Magnum/GL/TextureArray.h
  19. 256
      src/Magnum/PixelStorage.cpp
  20. 197
      src/Magnum/PixelStorage.h
  21. 2
      src/Magnum/Trade/ImageData.h

6
doc/changelog.dox

@ -128,6 +128,12 @@ See also:
@ref Magnum namespace were moved to @ref Magnum/GL directory and
@ref Magnum::GL namespace. See their documentation for information about
particular files, classes, enums, typedefs, values and functions.
- @ref PixelStorage::pixelSize() was deprecated, use @ref GL::pixelSize()
instead
- `PixelStorage::dataProperties(GL::PixelFormat, GL::PixelSize, const Vector3i&)`
was deprecated for being too GL-specific, use
@ref PixelStorage::dataProperties(std::size_t, const Vector3i&) const
together with @ref GL::pixelSize() instead
- `Audio::Buffer::Format` is deprecated, use `Audio::BufferFormat` instead
- `setData()` functions in the @ref Image and @ref CompressedImage classes
are deprecated because they don't offer anything extra over simple

1
src/Magnum/CMakeLists.txt

@ -28,6 +28,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake
# Files shared between main library and unit test library
set(Magnum_SRCS
PixelStorage.cpp
Resource.cpp
Timeline.cpp)

7
src/Magnum/GL/AbstractFramebuffer.cpp

@ -43,6 +43,7 @@
#include "Magnum/GL/TextureArray.h"
#endif
#include "Magnum/GL/Implementation/FramebufferState.h"
#include "Magnum/GL/Implementation/RendererState.h"
#include "Magnum/GL/Implementation/State.h"
namespace Magnum { namespace GL {
@ -306,10 +307,10 @@ void AbstractFramebuffer::read(const Range2Di& rectangle, Image2D& image) {
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelPack);
#endif
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
(Context::current().state().framebuffer->readImplementation)(rectangle, image.format(), image.type(), data.size(), data
#ifdef MAGNUM_TARGET_GLES2
+ Implementation::pixelStorageSkipOffsetFor(image, rectangle.size())
+ Magnum::Implementation::pixelStorageSkipOffsetFor(image, rectangle.size())
#endif
);
image = Image2D{image.storage(), image.format(), image.type(), rectangle.size(), std::move(data)};
@ -332,7 +333,7 @@ void AbstractFramebuffer::read(const Range2Di& rectangle, BufferImage2D& image,
image.setData(image.storage(), image.format(), image.type(), rectangle.size(), nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
(Context::current().state().framebuffer->readImplementation)(rectangle, image.format(), image.type(), dataSize, nullptr);
}

15
src/Magnum/GL/AbstractFramebuffer.h

@ -152,6 +152,12 @@ switching framebuffers. Framebuffer limits and implementation-defined values
in repeated @fn_gl{Get} calls. See also @ref Context::resetState() and
@ref Context::State::Framebuffers.
Pixel storage mode defined by @ref PixelStorage is applied either right before
doing image download via @ref read() using @fn_gl{PixelStore} with
@def_gl{PACK_*}. The engine tracks currently used pixel pack parameters to
avoid unnecessary calls to @fn_gl{PixelStore}. See also @ref Context::resetState()
and @ref Context::State::PixelStorage.
If extension @extension{ARB,direct_state_access} (part of OpenGL 4.5) is
available, @ref blit(), @ref clearDepth(), @ref clearStencil() and
@ref clearDepthStencil() functions use DSA to avoid unnecessary call to
@ -342,13 +348,20 @@ class MAGNUM_GL_EXPORT AbstractFramebuffer {
*
* Image parameters like format and type of pixel data are taken from
* given image. The storage is not reallocated if it is large enough to
* contain the new data.
* contain the new data. On OpenGL ES 2.0 and WebGL 1.0, if
* @ref PixelStorage::skip() is set, the functionality is emulated by
* adjusting the data pointer.
*
* If @extension{ARB,robustness} is available, the operation is
* protected from buffer overflow.
* @see @fn_gl{BindFramebuffer}, then @fn_gl{PixelStore} and
* @fn_gl_keyword{ReadPixels} or
* @fn_gl_extension_keyword{ReadnPixels,ARB,robustness}
* @requires_gles30 Extension @extension{EXT,unpack_subimage}/
* @extension{NV,pack_subimage} in OpenGL ES 2.0 if
* @ref PixelStorage::rowLength() is set to a non-zero value.
* @requires_webgl20 Non-zero @ref PixelStorage::rowLength() is not
* supported in WebGL 1.0.
*/
void read(const Range2Di& rectangle, Image2D& image);

65
src/Magnum/GL/AbstractTexture.cpp

@ -39,6 +39,7 @@
#ifndef MAGNUM_TARGET_WEBGL
#include "Magnum/GL/Implementation/DebugState.h"
#endif
#include "Magnum/GL/Implementation/RendererState.h"
#include "Magnum/GL/Implementation/State.h"
#include "Magnum/GL/Implementation/TextureState.h"
#include "Magnum/Math/Color.h"
@ -1699,7 +1700,7 @@ template<UnsignedInt dimensions> void AbstractTexture::image(GLint level, Image<
data = Containers::Array<char>{dataSize};
Buffer::unbindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
(this->*Context::current().state().texture->getImageImplementation)(level, image.format(), image.type(), data.size(), data);
image = Image<dimensions>{image.storage(), image.format(), image.type(), size, std::move(data)};
}
@ -1719,7 +1720,7 @@ template<UnsignedInt dimensions> void AbstractTexture::image(GLint level, Buffer
image.setData(image.storage(), image.format(), image.type(), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
(this->*Context::current().state().texture->getImageImplementation)(level, image.format(), image.type(), dataSize, nullptr);
}
@ -1749,7 +1750,7 @@ template<UnsignedInt dimensions> void AbstractTexture::compressedImage(const GLi
data = Containers::Array<char>{dataSize};
Buffer::unbindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
(this->*Context::current().state().texture->getCompressedImageImplementation)(level, data.size(), data);
image = CompressedImage<dimensions>{image.storage(), CompressedPixelFormat(format), size, std::move(data)};
}
@ -1781,7 +1782,7 @@ template<UnsignedInt dimensions> void AbstractTexture::compressedImage(const GLi
image.setData(image.storage(), CompressedPixelFormat(format), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
(this->*Context::current().state().texture->getCompressedImageImplementation)(level, dataSize, nullptr);
}
@ -1803,7 +1804,7 @@ template<UnsignedInt dimensions> void AbstractTexture::subImage(const GLint leve
data = Containers::Array<char>{dataSize};
Buffer::unbindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
glGetTextureSubImage(_id, level, paddedOffset.x(), paddedOffset.y(), paddedOffset.z(), paddedSize.x(), paddedSize.y(), paddedSize.z(), GLenum(image.format()), GLenum(image.type()), data.size(), data);
image = Image<dimensions>{image.storage(), image.format(), image.type(), size, std::move(data)};
}
@ -1827,7 +1828,7 @@ template<UnsignedInt dimensions> void AbstractTexture::subImage(const GLint leve
image.setData(image.storage(), image.format(), image.type(), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
glGetTextureSubImage(_id, level, paddedOffset.x(), paddedOffset.y(), paddedOffset.z(), paddedSize.x(), paddedSize.y(), paddedSize.z(), GLenum(image.format()), GLenum(image.type()), dataSize, nullptr);
}
@ -1868,7 +1869,7 @@ template<UnsignedInt dimensions> void AbstractTexture::compressedSubImage(const
data = Containers::Array<char>{dataSize};
Buffer::unbindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
glGetCompressedTextureSubImage(_id, level, paddedOffset.x(), paddedOffset.y(), paddedOffset.z(), paddedSize.x(), paddedSize.y(), paddedSize.z(), data.size(), data);
image = CompressedImage<dimensions>{CompressedPixelFormat(format), size, std::move(data)};
}
@ -1903,7 +1904,7 @@ template<UnsignedInt dimensions> void AbstractTexture::compressedSubImage(const
image.setData(image.storage(), CompressedPixelFormat(format), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
glGetCompressedTextureSubImage(_id, level, paddedOffset.x(), paddedOffset.y(), paddedOffset.z(), paddedSize.x(), paddedSize.y(), paddedSize.z(), dataSize, nullptr);
}
@ -1992,53 +1993,53 @@ void AbstractTexture::DataHelper<3>::setStorageMultisample(AbstractTexture& text
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, const ImageView1D& image) {
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
texture.bindInternal();
glTexImage1D(texture._target, level, GLint(internalFormat), image.size()[0], 0, GLenum(image.format()), GLenum(image.type()), image.data());
}
void AbstractTexture::DataHelper<1>::setCompressedImage(AbstractTexture& texture, const GLint level, const CompressedImageView1D& image) {
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
texture.bindInternal();
glCompressedTexImage1D(texture._target, level, GLenum(image.format()), image.size()[0], 0, Magnum::Implementation::occupiedCompressedImageDataSize(image, image.data().size()), image.data());
}
void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, BufferImage1D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
texture.bindInternal();
glTexImage1D(texture._target, level, GLint(internalFormat), image.size()[0], 0, GLenum(image.format()), GLenum(image.type()), nullptr);
}
void AbstractTexture::DataHelper<1>::setCompressedImage(AbstractTexture& texture, const GLint level, CompressedBufferImage1D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
texture.bindInternal();
glCompressedTexImage1D(texture._target, level, GLenum(image.format()), image.size()[0], 0, Magnum::Implementation::occupiedCompressedImageDataSize(image, image.dataSize()), nullptr);
}
void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLint level, const Math::Vector<1, GLint>& offset, const ImageView1D& image) {
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(texture.*Context::current().state().texture->subImage1DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data());
}
void AbstractTexture::DataHelper<1>::setCompressedSubImage(AbstractTexture& texture, const GLint level, const Math::Vector<1, GLint>& offset, const CompressedImageView1D& image) {
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(texture.*Context::current().state().texture->compressedSubImage1DImplementation)(level, offset, image.size(), image.format(), image.data(), Magnum::Implementation::occupiedCompressedImageDataSize(image, image.data().size()));
}
void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(texture.*Context::current().state().texture->subImage1DImplementation)(level, offset, image.size(), image.format(), image.type(), nullptr);
}
void AbstractTexture::DataHelper<1>::setCompressedSubImage(AbstractTexture& texture, const GLint level, const Math::Vector<1, GLint>& offset, CompressedBufferImage1D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(texture.*Context::current().state().texture->compressedSubImage1DImplementation)(level, offset, image.size(), image.format(), nullptr, Magnum::Implementation::occupiedCompressedImageDataSize(image, image.dataSize()));
}
#endif
@ -2047,7 +2048,7 @@ void AbstractTexture::DataHelper<2>::setImage(AbstractTexture& texture, const GL
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(texture.*Context::current().state().texture->image2DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), image.data()
#ifdef MAGNUM_TARGET_GLES2
+ Magnum::Implementation::pixelStorageSkipOffset(image)
@ -2062,7 +2063,7 @@ void AbstractTexture::DataHelper<2>::setCompressedImage(AbstractTexture& texture
#ifndef MAGNUM_TARGET_GLES
/* Pixel storage is completely ignored for compressed images on ES, no need
to reset anything */
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
#endif
texture.bindInternal();
glCompressedTexImage2D(target, level, GLenum(image.format()), image.size().x(), image.size().y(), 0, Magnum::Implementation::occupiedCompressedImageDataSize(image, image.data().size()), image.data());
@ -2071,7 +2072,7 @@ void AbstractTexture::DataHelper<2>::setCompressedImage(AbstractTexture& texture
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::DataHelper<2>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage2D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
texture.bindInternal();
glTexImage2D(target, level, GLint(internalFormat), image.size().x(), image.size().y(), 0, GLenum(image.format()), GLenum(image.type()), nullptr);
}
@ -2081,7 +2082,7 @@ void AbstractTexture::DataHelper<2>::setCompressedImage(AbstractTexture& texture
#ifndef MAGNUM_TARGET_GLES
/* Pixel storage is completely ignored for compressed images on ES, no need
to reset anything */
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
#endif
texture.bindInternal();
glCompressedTexImage2D(target, level, GLenum(image.format()), image.size().x(), image.size().y(), 0, Magnum::Implementation::occupiedCompressedImageDataSize(image, image.dataSize()), nullptr);
@ -2092,7 +2093,7 @@ void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(texture.*Context::current().state().texture->subImage2DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data()
#ifdef MAGNUM_TARGET_GLES2
+ Magnum::Implementation::pixelStorageSkipOffset(image)
@ -2107,7 +2108,7 @@ void AbstractTexture::DataHelper<2>::setCompressedSubImage(AbstractTexture& text
#ifndef MAGNUM_TARGET_GLES
/* Pixel storage is completely ignored for compressed images on ES, no need
to reset anything */
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
#endif
(texture.*Context::current().state().texture->compressedSubImage2DImplementation)(level, offset, image.size(), image.format(), image.data(), Magnum::Implementation::occupiedCompressedImageDataSize(image, image.data().size()));
}
@ -2115,7 +2116,7 @@ void AbstractTexture::DataHelper<2>::setCompressedSubImage(AbstractTexture& text
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLint level, const Vector2i& offset, BufferImage2D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(texture.*Context::current().state().texture->subImage2DImplementation)(level, offset, image.size(), image.format(), image.type(), nullptr, image.storage());
}
@ -2124,7 +2125,7 @@ void AbstractTexture::DataHelper<2>::setCompressedSubImage(AbstractTexture& text
#ifndef MAGNUM_TARGET_GLES
/* Pixel storage is completely ignored for compressed images on ES, no need
to reset anything */
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
#endif
(texture.*Context::current().state().texture->compressedSubImage2DImplementation)(level, offset, image.size(), image.format(), nullptr, Magnum::Implementation::occupiedCompressedImageDataSize(image, image.dataSize()));
}
@ -2135,7 +2136,7 @@ void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GL
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(texture.*Context::current().state().texture->image3DImplementation)(level, internalFormat, image.size(), image.format(), image.type(), image.data()
#ifdef MAGNUM_TARGET_GLES2
+ Magnum::Implementation::pixelStorageSkipOffset(image)
@ -2150,7 +2151,7 @@ void AbstractTexture::DataHelper<3>::setCompressedImage(AbstractTexture& texture
#ifndef MAGNUM_TARGET_GLES
/* Pixel storage is completely ignored for compressed images on ES, no need
to reset anything */
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
#endif
texture.bindInternal();
#ifndef MAGNUM_TARGET_GLES2
@ -2164,7 +2165,7 @@ void AbstractTexture::DataHelper<3>::setCompressedImage(AbstractTexture& texture
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLint level, const TextureFormat internalFormat, BufferImage3D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
texture.bindInternal();
glTexImage3D(texture._target, level, GLint(internalFormat), image.size().x(), image.size().y(), image.size().z(), 0, GLenum(image.format()), GLenum(image.type()), nullptr);
}
@ -2174,7 +2175,7 @@ void AbstractTexture::DataHelper<3>::setCompressedImage(AbstractTexture& texture
#ifndef MAGNUM_TARGET_GLES
/* Pixel storage is completely ignored for compressed images on ES, no need
to reset anything */
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
#endif
texture.bindInternal();
glCompressedTexImage3D(texture._target, level, GLenum(image.format()), image.size().x(), image.size().y(), image.size().z(), 0, Magnum::Implementation::occupiedCompressedImageDataSize(image, image.dataSize()), nullptr);
@ -2186,7 +2187,7 @@ void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(texture.*Context::current().state().texture->subImage3DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data()
#ifdef MAGNUM_TARGET_GLES2
+ Magnum::Implementation::pixelStorageSkipOffset(image)
@ -2201,7 +2202,7 @@ void AbstractTexture::DataHelper<3>::setCompressedSubImage(AbstractTexture& text
#ifndef MAGNUM_TARGET_GLES
/* Pixel storage is completely ignored for compressed images on ES, no need
to reset anything */
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
#endif
(texture.*Context::current().state().texture->compressedSubImage3DImplementation)(level, offset, image.size(), image.format(), image.data(), Magnum::Implementation::occupiedCompressedImageDataSize(image, image.data().size()));
}
@ -2210,7 +2211,7 @@ void AbstractTexture::DataHelper<3>::setCompressedSubImage(AbstractTexture& text
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLint level, const Vector3i& offset, BufferImage3D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(texture.*Context::current().state().texture->subImage3DImplementation)(level, offset, image.size(), image.format(), image.type(), nullptr, image.storage());
}
@ -2219,7 +2220,7 @@ void AbstractTexture::DataHelper<3>::setCompressedSubImage(AbstractTexture& text
#ifndef MAGNUM_TARGET_GLES
/* Pixel storage is completely ignored for compressed images on ES, no need
to reset anything */
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
#endif
(texture.*Context::current().state().texture->compressedSubImage3DImplementation)(level, offset, image.size(), image.format(), nullptr, Magnum::Implementation::occupiedCompressedImageDataSize(image, image.dataSize()));
}

13
src/Magnum/GL/AbstractTexture.h

@ -105,6 +105,19 @@ However, if @extension{ARB,direct_state_access} is not available and both
@extension{EXT,direct_state_access} and @extension{ARB,robustness} are
available, the robust version is preferred over DSA.
Pixel storage mode defined by @ref PixelStorage and @ref CompressedPixelStorage
is applied either right before doing image upload (such as various
@ref Texture::setImage() "setImage()", @ref Texture::setSubImage() "setSubImage()",
@ref Texture::setCompressedImage() "setCompressedImage()" or
@ref Texture::setCompressedSubImage() "setCompressedSubImage()" functions)
using @fn_gl_keyword{PixelStore} with @def_gl{UNPACK_*} parameters or right
before doing image download (such as various @ref Texture::image() "image()",
@ref Texture::subImage() "subImage()", @ref Texture::compressedImage() "compressedImage()",
or @ref Texture::compressedSubImage() "compressedSubImage()" functions) using
@fn_gl{PixelStore} with @def_gl{PACK_*}. The engine tracks currently used pixel
pack/unpack parameters to avoid unnecessary calls to @fn_gl{PixelStore}. See
also @ref Context::resetState() and @ref Context::State::PixelStorage.
To achieve least state changes, fully configure each texture in one run --
method chaining comes in handy --- and try to have often used textures in
dedicated units, not occupied by other textures. First configure the texture

2
src/Magnum/GL/BufferImage.h

@ -147,7 +147,7 @@ template<UnsignedInt dimensions> class BufferImage {
/**
* @brief Pixel size (in bytes)
*
* @see @ref PixelStorage::pixelSize()
* @see @ref Magnum::pixelSize(), @ref GL::pixelSize()
*/
std::size_t pixelSize() const { return PixelStorage::pixelSize(_format, _type); }

1
src/Magnum/GL/CMakeLists.txt

@ -40,7 +40,6 @@ set(MagnumGL_SRCS
MeshView.cpp
OpenGL.cpp
PixelFormat.cpp
../PixelStorage.cpp # temporary
Renderbuffer.cpp
Renderer.cpp
Sampler.cpp

33
src/Magnum/GL/CubeMapTexture.cpp

@ -31,6 +31,7 @@
#endif
#include "Magnum/GL/Context.h"
#include "Magnum/GL/Implementation/maxTextureSize.h"
#include "Magnum/GL/Implementation/RendererState.h"
#include "Magnum/GL/Implementation/State.h"
#include "Magnum/GL/Implementation/TextureState.h"
@ -72,7 +73,7 @@ void CubeMapTexture::image(const Int level, Image3D& image) {
data = Containers::Array<char>{dataSize};
Buffer::unbindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
glGetTextureImage(_id, level, GLenum(image.format()), GLenum(image.type()), data.size(), data);
image = Image3D{image.storage(), image.format(), image.type(), size, std::move(data)};
}
@ -95,7 +96,7 @@ void CubeMapTexture::image(const Int level, BufferImage3D& image, const BufferUs
image.setData(image.storage(), image.format(), image.type(), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
glGetTextureImage(_id, level, GLenum(image.format()), GLenum(image.type()), dataSize, nullptr);
}
@ -127,7 +128,7 @@ void CubeMapTexture::compressedImage(const Int level, CompressedImage3D& image)
data = Containers::Array<char>{dataOffset + dataSize};
Buffer::unbindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
(this->*Context::current().state().texture->getFullCompressedCubeImageImplementation)(level, size.xy(), dataOffset, dataSize, data);
image = CompressedImage3D{image.storage(), CompressedPixelFormat(format), size, std::move(data)};
}
@ -161,7 +162,7 @@ void CubeMapTexture::compressedImage(const Int level, CompressedBufferImage3D& i
image.setData(image.storage(), CompressedPixelFormat(format), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
(this->*Context::current().state().texture->getFullCompressedCubeImageImplementation)(level, size.xy(), dataOffset, dataSize, nullptr);
}
@ -180,7 +181,7 @@ void CubeMapTexture::image(const CubeMapCoordinate coordinate, const Int level,
data = Containers::Array<char>{dataSize};
Buffer::unbindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
(this->*Context::current().state().texture->getCubeImageImplementation)(coordinate, level, size, image.format(), image.type(), data.size(), data);
image = Image2D{image.storage(), image.format(), image.type(), size, std::move(data)};
}
@ -201,7 +202,7 @@ void CubeMapTexture::image(const CubeMapCoordinate coordinate, const Int level,
image.setData(image.storage(), image.format(), image.type(), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
(this->*Context::current().state().texture->getCubeImageImplementation)(coordinate, level, size, image.format(), image.type(), dataSize, nullptr);
}
@ -231,7 +232,7 @@ void CubeMapTexture::compressedImage(const CubeMapCoordinate coordinate, const I
data = Containers::Array<char>{dataSize};
Buffer::unbindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
(this->*Context::current().state().texture->getCompressedCubeImageImplementation)(coordinate, level, size, data.size(), data);
image = CompressedImage2D{image.storage(), CompressedPixelFormat(format), size, std::move(data)};
}
@ -263,7 +264,7 @@ void CubeMapTexture::compressedImage(const CubeMapCoordinate coordinate, const I
image.setData(image.storage(), CompressedPixelFormat(format), size, nullptr, usage);
image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
image.storage().applyPack();
Context::current().state().renderer->applyPixelStoragePack(image.storage());
(this->*Context::current().state().texture->getCompressedCubeImageImplementation)(coordinate, level, size, dataSize, nullptr);
}
@ -296,7 +297,7 @@ CubeMapTexture& CubeMapTexture::setSubImage(const Int level, const Vector3i& off
createIfNotAlready();
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(this->*Context::current().state().texture->cubeSubImage3DImplementation)(level, offset, image.size(), image.format(), image.type(), image.data(), image.storage());
return *this;
}
@ -305,7 +306,7 @@ CubeMapTexture& CubeMapTexture::setSubImage(const Int level, const Vector3i& off
createIfNotAlready();
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
glTextureSubImage3D(_id, level, offset.x(), offset.y(), offset.z(), image.size().x(), image.size().y(), image.size().z(), GLenum(image.format()), GLenum(image.type()), nullptr);
return *this;
}
@ -314,7 +315,7 @@ CubeMapTexture& CubeMapTexture::setCompressedSubImage(const Int level, const Vec
createIfNotAlready();
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
glCompressedTextureSubImage3D(_id, level, offset.x(), offset.y(), offset.z(), image.size().x(), image.size().y(), image.size().z(), GLenum(image.format()), Magnum::Implementation::occupiedCompressedImageDataSize(image, image.data().size()), image.data());
return *this;
}
@ -323,7 +324,7 @@ CubeMapTexture& CubeMapTexture::setCompressedSubImage(const Int level, const Vec
createIfNotAlready();
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
glCompressedTextureSubImage3D(_id, level, offset.x(), offset.y(), offset.z(), image.size().x(), image.size().y(), image.size().z(), GLenum(image.format()), Magnum::Implementation::occupiedCompressedImageDataSize(image, image.dataSize()), nullptr);
return *this;
}
@ -333,7 +334,7 @@ CubeMapTexture& CubeMapTexture::setSubImage(const CubeMapCoordinate coordinate,
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(this->*Context::current().state().texture->cubeSubImageImplementation)(coordinate, level, offset, image.size(), image.format(), image.type(), image.data()
#ifdef MAGNUM_TARGET_GLES2
+ Magnum::Implementation::pixelStorageSkipOffset(image)
@ -345,7 +346,7 @@ CubeMapTexture& CubeMapTexture::setSubImage(const CubeMapCoordinate coordinate,
#ifndef MAGNUM_TARGET_GLES2
CubeMapTexture& CubeMapTexture::setSubImage(const CubeMapCoordinate coordinate, const Int level, const Vector2i& offset, BufferImage2D& image) {
image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
(this->*Context::current().state().texture->cubeSubImageImplementation)(coordinate, level, offset, image.size(), image.format(), image.type(), nullptr);
return *this;
}
@ -358,7 +359,7 @@ CubeMapTexture& CubeMapTexture::setCompressedSubImage(const CubeMapCoordinate co
#ifndef MAGNUM_TARGET_GLES
/* Pixel storage is completely ignored for compressed images on ES, no need
to reset anything */
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
#endif
(this->*Context::current().state().texture->cubeCompressedSubImageImplementation)(coordinate, level, offset, image.size(), image.format(), image.data(), Magnum::Implementation::occupiedCompressedImageDataSize(image, image.data().size()));
return *this;
@ -370,7 +371,7 @@ CubeMapTexture& CubeMapTexture::setCompressedSubImage(const CubeMapCoordinate co
#ifndef MAGNUM_TARGET_GLES
/* Pixel storage is completely ignored for compressed images on ES, no need
to reset anything */
image.storage().applyUnpack();
Context::current().state().renderer->applyPixelStorageUnpack(image.storage());
#endif
(this->*Context::current().state().texture->cubeCompressedSubImageImplementation)(coordinate, level, offset, image.size(), image.format(), nullptr, Magnum::Implementation::occupiedCompressedImageDataSize(image, image.dataSize()));
return *this;

52
src/Magnum/GL/CubeMapTexture.h

@ -567,6 +567,8 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
* @def_gl{TEXTURE_INTERNAL_FORMAT}, @def_gl{TEXTURE_WIDTH},
* @def_gl{TEXTURE_HEIGHT}, then
* @fn_gl2_keyword{GetCompressedTextureImage,GetCompressedTexImage}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl45 Extension @extension{ARB,direct_state_access}
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() or @ref DebugTools::textureSubImage()
@ -589,6 +591,8 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
* information. The storage is not reallocated if it is large enough to
* contain the new data, which means that @p usage might get ignored.
* @requires_gl45 Extension @extension{ARB,direct_state_access}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() or @ref DebugTools::textureSubImage()
* for possible workarounds.
@ -689,6 +693,8 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
* @fn_gl_extension_keyword{GetnCompressedTexImage,ARB,robustness},
* @fn_gl_extension_keyword{GetCompressedTextureImage,EXT,direct_state_access},
* eventually @fn_gl_keyword{GetCompressedTexImage}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() or @ref DebugTools::textureSubImage()
* for possible workarounds.
@ -710,6 +716,8 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
* for more information. The storage is not reallocated if it is large
* enough to contain the new data, which means that @p usage might get
* ignored.
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() or @ref DebugTools::textureSubImage()
* for possible workarounds.
@ -774,6 +782,8 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedImage&)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl43 Extension @extension{ARB,internalformat_query2} if
* @ref CompressedPixelStorage::compressedBlockSize() and
* @ref CompressedPixelStorage::compressedBlockDataSize() are not
@ -800,6 +810,8 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl43 Extension @extension{ARB,internalformat_query2} if
* @ref CompressedPixelStorage::compressedBlockSize() and
* @ref CompressedPixelStorage::compressedBlockDataSize() are not
@ -827,6 +839,11 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
*
* See @ref Texture::setImage() for more information.
* @see @ref maxSize()
* @requires_gles30 Extension @extension{EXT,unpack_subimage}/
* @extension{NV,pack_subimage} in OpenGL ES 2.0 if
* @ref PixelStorage::rowLength() is set to a non-zero value.
* @requires_webgl20 Non-zero @ref PixelStorage::rowLength() is not
* supported in WebGL 1.0.
* @deprecated_gl Prefer to use @ref setStorage() and @ref setSubImage()
* instead.
*/
@ -868,6 +885,10 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
*
* See @ref Texture::setCompressedImage() for more information.
* @see @ref maxSize()
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @deprecated_gl Prefer to use @ref setStorage() and
* @ref setCompressedSubImage() instead.
*/
@ -878,6 +899,10 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
#ifndef MAGNUM_TARGET_GLES2
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @requires_webgl20 Pixel buffer objects are not available in WebGL
@ -891,6 +916,10 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
}
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @requires_webgl20 Pixel buffer objects are not available in WebGL
@ -945,6 +974,8 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
*
* @see @ref setStorage(), @fn_gl2{CompressedTextureSubImage3D,CompressedTexSubImage3D}
* @requires_gl45 Extension @extension{ARB,direct_state_access}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl In OpenGL ES and WebGL you need to set image for each
* face separately.
*/
@ -952,6 +983,8 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
/** @overload
* @requires_gl45 Extension @extension{ARB,direct_state_access}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl In OpenGL ES and WebGL you need to set image for each
* face separately.
*/
@ -959,6 +992,8 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
/** @overload
* @requires_gl45 Extension @extension{ARB,direct_state_access}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl In OpenGL ES and WebGL you need to set image for each
* face separately.
*/
@ -972,6 +1007,11 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* See @ref Texture::setSubImage() for more information.
* @requires_gles30 Extension @extension{EXT,unpack_subimage}/
* @extension{NV,pack_subimage} in OpenGL ES 2.0 if
* @ref PixelStorage::rowLength() is set to a non-zero value.
* @requires_webgl20 Non-zero @ref PixelStorage::rowLength() is not
* supported in WebGL 1.0.
*/
CubeMapTexture& setSubImage(CubeMapCoordinate coordinate, Int level, const Vector2i& offset, const ImageView2D& image);
@ -1000,11 +1040,19 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* See @ref Texture::setCompressedSubImage() for more information.
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
*/
CubeMapTexture& setCompressedSubImage(CubeMapCoordinate coordinate, Int level, const Vector2i& offset, const CompressedImageView2D& image);
#ifndef MAGNUM_TARGET_GLES2
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @requires_webgl20 Pixel buffer objects are not available in WebGL
@ -1013,6 +1061,10 @@ class MAGNUM_GL_EXPORT CubeMapTexture: public AbstractTexture {
CubeMapTexture& setCompressedSubImage(CubeMapCoordinate coordinate, Int level, const Vector2i& offset, CompressedBufferImage2D& image);
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @requires_webgl20 Pixel buffer objects are not available in WebGL

30
src/Magnum/GL/CubeMapTextureArray.h

@ -473,6 +473,8 @@ class MAGNUM_GL_EXPORT CubeMapTextureArray: public AbstractTexture {
*
* See @ref Texture::compressedImage(Int, CompressedImage&) for more
* information.
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Texture image queries are not available in OpenGL ES.
* See @ref Framebuffer::read() or @ref DebugTools::textureSubImage()
* for possible workarounds.
@ -494,6 +496,8 @@ class MAGNUM_GL_EXPORT CubeMapTextureArray: public AbstractTexture {
*
* See @ref Texture::compressedImage(Int, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Texture image queries are not available in OpenGL ES.
* See @ref Framebuffer::read() or @ref DebugTools::textureSubImage()
* for possible workarounds.
@ -560,6 +564,8 @@ class MAGNUM_GL_EXPORT CubeMapTextureArray: public AbstractTexture {
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedImage&)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl43 Extension @extension{ARB,internalformat_query2} if
* @ref CompressedPixelStorage::compressedBlockSize() and
* @ref CompressedPixelStorage::compressedBlockDataSize() are not
@ -586,6 +592,8 @@ class MAGNUM_GL_EXPORT CubeMapTextureArray: public AbstractTexture {
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl43 Extension @extension{ARB,internalformat_query2} if
* @ref CompressedPixelStorage::compressedBlockSize() and
* @ref CompressedPixelStorage::compressedBlockDataSize() are not
@ -654,6 +662,10 @@ class MAGNUM_GL_EXPORT CubeMapTextureArray: public AbstractTexture {
*
* See @ref Texture::setCompressedImage() for more information.
* @see @ref maxSize()
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES.
* @deprecated_gl Prefer to use @ref setStorage() and
* @ref setCompressedSubImage() instead.
*/
@ -714,19 +726,33 @@ class MAGNUM_GL_EXPORT CubeMapTextureArray: public AbstractTexture {
* -Z).
*
* See @ref Texture::setCompressedSubImage() for more information.
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES.
*/
CubeMapTextureArray& setCompressedSubImage(Int level, const Vector3i& offset, const CompressedImageView3D& image) {
DataHelper<3>::setCompressedSubImage(*this, level, offset, image);
return *this;
}
/** @overload */
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES.
*/
CubeMapTextureArray& setCompressedSubImage(Int level, const Vector3i& offset, CompressedBufferImage3D& image) {
DataHelper<3>::setCompressedSubImage(*this, level, offset, image);
return *this;
}
/** @overload */
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES.
*/
CubeMapTextureArray& setCompressedSubImage(Int level, const Vector3i& offset, CompressedBufferImage3D&& image) {
return setCompressedSubImage(level, offset, image);
}

105
src/Magnum/GL/Implementation/RendererState.cpp

@ -25,6 +25,7 @@
#include "RendererState.h"
#include "Magnum/PixelStorage.h"
#include "Magnum/GL/Context.h"
#include "Magnum/GL/Extensions.h"
@ -118,4 +119,108 @@ void RendererState::PixelStorage::reset() {
#endif
}
void RendererState::applyPixelStorageInternal(const Magnum::PixelStorage& storage, const bool isUnpack) {
PixelStorage& state = isUnpack ? unpackPixelStorage : packPixelStorage;
/* Alignment */
if(state.alignment == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.alignment != storage.alignment())
glPixelStorei(isUnpack ? GL_UNPACK_ALIGNMENT : GL_PACK_ALIGNMENT,
state.alignment = storage.alignment());
/* Row length */
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
if(state.rowLength == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.rowLength != storage.rowLength())
{
/** @todo Use real value for GL_PACK_ROW_LENGTH_NV when it is in headers */
#ifndef MAGNUM_TARGET_GLES2
glPixelStorei(isUnpack ? GL_UNPACK_ROW_LENGTH : GL_PACK_ROW_LENGTH,
state.rowLength = storage.rowLength());
#elif !defined(MAGNUM_TARGET_WEBGL)
glPixelStorei(isUnpack ? GL_UNPACK_ROW_LENGTH_EXT : 0xD02 /*GL_PACK_ROW_LENGTH_NV*/,
state.rowLength = storage.rowLength());
#endif
}
#else
CORRADE_ASSERT(!storage.rowLength(),
"GL: non-default PixelStorage::rowLength() is not supported in WebGL 1.0", );
#endif
#ifndef MAGNUM_TARGET_GLES
/* Image height (on ES for unpack only, taken care of below) */
if(state.imageHeight == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.imageHeight != storage.imageHeight())
glPixelStorei(isUnpack ? GL_UNPACK_IMAGE_HEIGHT : GL_PACK_IMAGE_HEIGHT,
state.imageHeight = storage.imageHeight());
#else
CORRADE_ASSERT(!storage.imageHeight(),
"GL: non-default PixelStorage::imageHeight() is not supported in OpenGL ES", );
#endif
/* On ES2 done by modifying data pointer */
#ifndef MAGNUM_TARGET_GLES2
/* Skip pixels */
if(state.skip.x() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.skip.x() != storage.skip().x())
glPixelStorei(isUnpack ? GL_UNPACK_SKIP_PIXELS : GL_PACK_SKIP_PIXELS,
state.skip.x() = storage.skip().x());
/* Skip rows */
if(state.skip.y() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.skip.y() != storage.skip().y())
glPixelStorei(isUnpack ? GL_UNPACK_SKIP_ROWS : GL_PACK_SKIP_ROWS,
state.skip.y() = storage.skip().y());
#ifndef MAGNUM_TARGET_GLES
/* Skip images (on ES for unpack only, taken care of below) */
if(state.skip.z() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.skip.z() != storage.skip().z())
glPixelStorei(isUnpack ? GL_UNPACK_SKIP_IMAGES : GL_PACK_SKIP_IMAGES,
state.skip.z() = storage.skip().z());
#endif
#endif
}
void RendererState::applyPixelStorageUnpack(const Magnum::PixelStorage& storage) {
applyPixelStorageInternal(storage, true);
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2)
PixelStorage& state = unpackPixelStorage;
/* Image height (on ES for unpack only) */
if(state.imageHeight == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.imageHeight != storage.imageHeight())
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, state.imageHeight = storage.imageHeight());
/* Skip images (on ES for unpack only) */
if(state.skip.z() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.skip.z() != storage.skip().z())
glPixelStorei(GL_UNPACK_SKIP_IMAGES, state.skip.z() = storage.skip().z());
#endif
}
void RendererState::applyPixelStorageInternal(const CompressedPixelStorage& storage, const bool isUnpack) {
applyPixelStorageInternal(static_cast<const Magnum::PixelStorage&>(storage), isUnpack);
PixelStorage& state = isUnpack ? unpackPixelStorage : packPixelStorage;
/* Compressed block width */
if(state.compressedBlockSize.x() == PixelStorage::DisengagedValue ||
state.compressedBlockSize.x() != storage.compressedBlockSize().x())
glPixelStorei(isUnpack ? GL_UNPACK_COMPRESSED_BLOCK_WIDTH : GL_PACK_COMPRESSED_BLOCK_WIDTH,
state.compressedBlockSize.x() = storage.compressedBlockSize().x());
/* Compressed block height */
if(state.compressedBlockSize.y() == PixelStorage::DisengagedValue ||
state.compressedBlockSize.y() != storage.compressedBlockSize().y())
glPixelStorei(isUnpack ? GL_UNPACK_COMPRESSED_BLOCK_HEIGHT : GL_PACK_COMPRESSED_BLOCK_HEIGHT,
state.compressedBlockSize.y() = storage.compressedBlockSize().y());
/* Compressed block depth */
if(state.compressedBlockSize.z() == PixelStorage::DisengagedValue ||
state.compressedBlockSize.z() != storage.compressedBlockSize().z())
glPixelStorei(isUnpack ? GL_UNPACK_COMPRESSED_BLOCK_DEPTH : GL_PACK_COMPRESSED_BLOCK_DEPTH,
state.compressedBlockSize.z() = storage.compressedBlockSize().z());
/* Compressed block size */
if(state.compressedBlockDataSize == PixelStorage::DisengagedValue ||
state.compressedBlockDataSize != storage.compressedBlockDataSize())
glPixelStorei(isUnpack ? GL_UNPACK_COMPRESSED_BLOCK_SIZE : GL_PACK_COMPRESSED_BLOCK_SIZE,
state.compressedBlockDataSize = storage.compressedBlockDataSize());
}
}}}

22
src/Magnum/GL/Implementation/RendererState.h

@ -69,6 +69,28 @@ struct RendererState {
};
PixelStorage packPixelStorage, unpackPixelStorage;
/* Bool parameter is ugly, but this is implementation detail of internal
API so who cares */
void applyPixelStorageInternal(const Magnum::PixelStorage& storage, bool unpack);
/* Used internally in *Texture::image(), *Texture::subImage(),
*Texture::setImage(), *Texture::setSubImage() and *Framebuffer::read() */
void applyPixelStoragePack(const Magnum::PixelStorage& storage) {
applyPixelStorageInternal(storage, false);
}
void applyPixelStorageUnpack(const Magnum::PixelStorage& storage);
/* Bool parameter is ugly, but this is implementation detail of internal
API so who cares */
void applyPixelStorageInternal(const CompressedPixelStorage& storage, bool unpack);
/* Used internally in *Texture::compressedImage(), *Texture::compressedSubImage(),
*Texture::setCompressedImage() and *Texture::setCompressedSubImage() */
void applyPixelStoragePack(const CompressedPixelStorage& storage) {
applyPixelStorageInternal(storage, false);
}
void applyPixelStorageUnpack(const CompressedPixelStorage& storage) {
applyPixelStorageInternal(storage, true);
}
};
}}}

126
src/Magnum/GL/PixelFormat.cpp

@ -25,10 +25,136 @@
#include "PixelFormat.h"
#include <Corrade/Utility/Assert.h>
#include <Corrade/Utility/Debug.h>
namespace Magnum { namespace GL {
std::size_t pixelSize(const PixelFormat format, const PixelType type) {
std::size_t size = 0;
switch(type) {
case PixelType::UnsignedByte:
#ifndef MAGNUM_TARGET_GLES2
case PixelType::Byte:
#endif
size = 1; break;
case PixelType::UnsignedShort:
#ifndef MAGNUM_TARGET_GLES2
case PixelType::Short:
#endif
case PixelType::HalfFloat:
size = 2; break;
case PixelType::UnsignedInt:
#ifndef MAGNUM_TARGET_GLES2
case PixelType::Int:
#endif
case PixelType::Float:
size = 4; break;
#ifndef MAGNUM_TARGET_GLES
case PixelType::UnsignedByte332:
case PixelType::UnsignedByte233Rev:
return 1;
#endif
case PixelType::UnsignedShort565:
#ifndef MAGNUM_TARGET_GLES
case PixelType::UnsignedShort565Rev:
#endif
case PixelType::UnsignedShort4444:
#ifndef MAGNUM_TARGET_WEBGL
case PixelType::UnsignedShort4444Rev:
#endif
case PixelType::UnsignedShort5551:
#ifndef MAGNUM_TARGET_WEBGL
case PixelType::UnsignedShort1555Rev:
#endif
return 2;
#ifndef MAGNUM_TARGET_GLES
case PixelType::UnsignedInt8888:
case PixelType::UnsignedInt8888Rev:
case PixelType::UnsignedInt1010102:
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
case PixelType::UnsignedInt2101010Rev:
#endif
#ifndef MAGNUM_TARGET_GLES2
case PixelType::UnsignedInt10F11F11FRev:
case PixelType::UnsignedInt5999Rev:
#endif
case PixelType::UnsignedInt248:
return 4;
#ifndef MAGNUM_TARGET_GLES2
case PixelType::Float32UnsignedInt248Rev:
return 8;
#endif
}
switch(format) {
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
case PixelFormat::Red:
#endif
#ifndef MAGNUM_TARGET_GLES2
case PixelFormat::RedInteger:
#endif
#ifndef MAGNUM_TARGET_GLES
case PixelFormat::Green:
case PixelFormat::Blue:
case PixelFormat::GreenInteger:
case PixelFormat::BlueInteger:
#endif
#ifdef MAGNUM_TARGET_GLES2
case PixelFormat::Luminance:
#endif
case PixelFormat::DepthComponent:
#ifndef MAGNUM_TARGET_WEBGL
case PixelFormat::StencilIndex:
#endif
return 1*size;
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
case PixelFormat::RG:
#endif
#ifndef MAGNUM_TARGET_GLES2
case PixelFormat::RGInteger:
#endif
#ifdef MAGNUM_TARGET_GLES2
case PixelFormat::LuminanceAlpha:
#endif
return 2*size;
case PixelFormat::RGB:
#ifndef MAGNUM_TARGET_GLES2
case PixelFormat::RGBInteger:
#endif
#ifndef MAGNUM_TARGET_GLES
case PixelFormat::BGR:
case PixelFormat::BGRInteger:
#endif
#ifdef MAGNUM_TARGET_GLES2
case PixelFormat::SRGB:
#endif
return 3*size;
case PixelFormat::RGBA:
#ifndef MAGNUM_TARGET_GLES2
case PixelFormat::RGBAInteger:
#endif
#ifndef MAGNUM_TARGET_WEBGL
case PixelFormat::BGRA:
#endif
#ifdef MAGNUM_TARGET_GLES2
case PixelFormat::SRGBAlpha:
#endif
#ifndef MAGNUM_TARGET_GLES
case PixelFormat::BGRAInteger:
#endif
return 4*size;
/* Handled above */
case PixelFormat::DepthStencil:
CORRADE_ASSERT(false, "GL::pixelSize(): invalid GL::PixelType specified for depth/stencil GL::PixelFormat", 0);
}
CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
}
#ifndef DOXYGEN_GENERATING_OUTPUT
Debug& operator<<(Debug& debug, const PixelFormat value) {
switch(value) {

9
src/Magnum/GL/PixelFormat.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Enum @ref Magnum::GL::PixelFormat, @ref Magnum::GL::PixelType, @ref Magnum::GL::CompressedPixelFormat
* @brief Enum @ref Magnum::GL::PixelFormat, @ref Magnum::GL::PixelType, @ref Magnum::GL::CompressedPixelFormat, function @ref Magnum::GL::pixelSize()
*/
#include "Magnum/Magnum.h"
@ -1234,6 +1234,13 @@ enum class CompressedPixelFormat: GLenum {
#endif
};
/**
@brief Pixel size for given format/type combination (in bytes)
@see @ref PixelStorage::dataProperties()
*/
MAGNUM_GL_EXPORT std::size_t pixelSize(PixelFormat format, PixelType type);
/** @debugoperatorenum{PixelFormat} */
MAGNUM_GL_EXPORT Debug& operator<<(Debug& debug, PixelFormat value);

12
src/Magnum/GL/RectangleTexture.h

@ -354,6 +354,8 @@ class MAGNUM_GL_EXPORT RectangleTexture: public AbstractTexture {
*
* See @ref Texture::compressedImage(Int, CompressedImage&) for more
* information.
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
*/
void compressedImage(CompressedImage2D& image) {
AbstractTexture::compressedImage<2>(0, image);
@ -372,6 +374,8 @@ class MAGNUM_GL_EXPORT RectangleTexture: public AbstractTexture {
*
* See @ref Texture::compressedImage(Int, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
*/
void compressedImage(CompressedBufferImage2D& image, BufferUsage usage) {
AbstractTexture::compressedImage<2>(0, image, usage);
@ -429,6 +433,8 @@ class MAGNUM_GL_EXPORT RectangleTexture: public AbstractTexture {
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedImage&)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl43 Extension @extension{ARB,internalformat_query2} if
* @ref CompressedPixelStorage::compressedBlockSize() and
* @ref CompressedPixelStorage::compressedBlockDataSize() are not
@ -452,6 +458,8 @@ class MAGNUM_GL_EXPORT RectangleTexture: public AbstractTexture {
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl43 Extension @extension{ARB,internalformat_query2} if
* @ref CompressedPixelStorage::compressedBlockSize() and
* @ref CompressedPixelStorage::compressedBlockDataSize() are not
@ -506,6 +514,8 @@ class MAGNUM_GL_EXPORT RectangleTexture: public AbstractTexture {
*
* See @ref Texture::setCompressedImage() for more information.
* @see @ref maxSize()
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @deprecated_gl Prefer to use @ref setStorage() and
* @ref setCompressedSubImage() instead.
*/
@ -558,6 +568,8 @@ class MAGNUM_GL_EXPORT RectangleTexture: public AbstractTexture {
* @return Reference to self (for method chaining)
*
* See @ref Texture::setCompressedSubImage() for more information.
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
*/
RectangleTexture& setCompressedSubImage(const Vector2i& offset, const CompressedImageView2D& image) {
DataHelper<2>::setCompressedSubImage(*this, 0, offset, image);

52
src/Magnum/GL/Texture.h

@ -842,6 +842,8 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl_extension_keyword{GetnCompressedTexImage,ARB,robustness},
* @fn_gl_extension_keyword{GetCompressedTextureImage,EXT,direct_state_access},
* eventually @fn_gl_keyword{GetCompressedTexImage}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() or @ref DebugTools::textureSubImage()
* for possible workarounds.
@ -867,6 +869,8 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* See @ref compressedImage(Int, CompressedImage&) for more
* information. The storage is not reallocated if it is large enough to
* contain the new data, which means that @p usage might get ignored.
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() or @ref DebugTools::textureSubImage()
* for possible workarounds.
@ -956,6 +960,8 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @def_gl{TEXTURE_COMPRESSED_BLOCK_HEIGHT}, then
* @fn_gl_keyword{GetCompressedTextureSubImage}
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl43 Extension @extension{ARB,internalformat_query2} if
* @ref CompressedPixelStorage::compressedBlockSize() and
* @ref CompressedPixelStorage::compressedBlockDataSize() are not
@ -986,6 +992,8 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* See @ref compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl43 Extension @extension{ARB,internalformat_query2} if
* @ref CompressedPixelStorage::compressedBlockSize() and
* @ref CompressedPixelStorage::compressedBlockDataSize() are not
@ -1020,10 +1028,20 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* and has better performance characteristics. This call also has no
* equivalent in @extension{ARB,direct_state_access}, thus the texture
* needs to be bound to some texture unit before the operation.
*
* On OpenGL ES 2.0 and WebGL 1.0, if @ref PixelStorage::skip() is set,
* the functionality is emulated by adjusting the data pointer.
* @see @ref maxSize(), @ref Framebuffer::copyImage(), @fn_gl{PixelStore},
* then @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl_keyword{TexImage1D} / @fn_gl_keyword{TexImage2D} /
* @fn_gl_keyword{TexImage3D}
* @requires_gles30 Extension @extension{EXT,unpack_subimage}/
* @extension{NV,pack_subimage} in OpenGL ES 2.0 if
* @ref PixelStorage::rowLength() is set to a non-zero value.
* @requires_gles30 Non-zero @ref PixelStorage::imageHeight() for 3D
* images is not available in OpenGL ES 2.0.
* @requires_webgl20 Non-zero @ref PixelStorage::rowLength() is not
* supported in WebGL 1.0.
* @deprecated_gl Prefer to use @ref setStorage() and @ref setSubImage()
* instead.
*/
@ -1076,6 +1094,10 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl{BindTexture} and @fn_gl_keyword{CompressedTexImage1D} /
* @fn_gl_keyword{CompressedTexImage2D} /
* @fn_gl_keyword{CompressedTexImage3D}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @deprecated_gl Prefer to use @ref setStorage() and
* @ref setCompressedSubImage() instead.
*/
@ -1086,6 +1108,10 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
#ifndef MAGNUM_TARGET_GLES2
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @requires_webgl20 Pixel buffer objects are not available in WebGL
@ -1099,6 +1125,10 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
}
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @requires_webgl20 Pixel buffer objects are not available in WebGL
@ -1123,6 +1153,9 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* nor @extension{EXT,direct_state_access} desktop extension is
* available, the texture is bound before the operation (if not
* already).
*
* On OpenGL ES 2.0 and WebGL 1.0, if @ref PixelStorage::skip() is set,
* the functionality is emulated by adjusting the data pointer.
* @see @ref setStorage(), @ref Framebuffer::copySubImage(),
* @fn_gl{PixelStore}, @fn_gl2_keyword{TextureSubImage1D,TexSubImage1D} /
* @fn_gl2_keyword{TextureSubImage2D,TexSubImage2D} /
@ -1133,6 +1166,13 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl_keyword{TexSubImage1D} / @fn_gl_keyword{TexSubImage2D} /
* @fn_gl_keyword{TexSubImage3D}
* @requires_gles30 Extension @extension{EXT,unpack_subimage}/
* @extension{NV,pack_subimage} in OpenGL ES 2.0 if
* @ref PixelStorage::rowLength() is set to a non-zero value.
* @requires_gles30 Non-zero @ref PixelStorage::imageHeight() for 3D
* images is not available in OpenGL ES 2.0.
* @requires_webgl20 Non-zero @ref PixelStorage::rowLength() is not
* supported in WebGL 1.0.
* @requires_gles In @ref MAGNUM_TARGET_WEBGL "WebGL" the @ref PixelType
* of data passed in @p image must match the original one
* specified in @ref setImage(). It means that you might not be
@ -1190,6 +1230,10 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl_keyword{CompressedTexSubImage1D} /
* @fn_gl_keyword{CompressedTexSubImage2D} /
* @fn_gl_keyword{CompressedTexSubImage3D}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
*/
Texture<dimensions>& setCompressedSubImage(Int level, const VectorTypeFor<dimensions, Int>& offset, const CompressedImageView<dimensions>& image) {
DataHelper<Dimensions>::setCompressedSubImage(*this, level, offset, image);
@ -1198,6 +1242,10 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
#ifndef MAGNUM_TARGET_GLES2
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @requires_webgl20 Pixel buffer objects are not available in WebGL
@ -1209,6 +1257,10 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
}
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES
* 2.0.
* @requires_webgl20 Pixel buffer objects are not available in WebGL

38
src/Magnum/GL/TextureArray.h

@ -510,6 +510,8 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
*
* See @ref Texture::compressedImage(Int, CompressedImage&) for more
* information.
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() or @ref DebugTools::textureSubImage()
* for possible workarounds.
@ -531,6 +533,8 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
*
* See @ref Texture::compressedImage(Int, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Texture image queries are not available in OpenGL ES or
* WebGL. See @ref Framebuffer::read() or @ref DebugTools::textureSubImage()
* for possible workarounds.
@ -597,6 +601,8 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedImage&)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl43 Extension @extension{ARB,internalformat_query2} if
* @ref CompressedPixelStorage::compressedBlockSize() and
* @ref CompressedPixelStorage::compressedBlockDataSize() are not
@ -623,6 +629,8 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
* See @ref Texture::compressedSubImage(Int, const RangeTypeFor<dimensions, Int>&, CompressedBufferImage&, BufferUsage)
* for more information.
* @requires_gl45 Extension @extension{ARB,get_texture_sub_image}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl43 Extension @extension{ARB,internalformat_query2} if
* @ref CompressedPixelStorage::compressedBlockSize() and
* @ref CompressedPixelStorage::compressedBlockDataSize() are not
@ -681,6 +689,10 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
*
* See @ref Texture::setCompressedImage() for more information.
* @see @ref maxSize()
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @deprecated_gl Prefer to use @ref setStorage() and
* @ref setCompressedSubImage() instead.
*/
@ -690,6 +702,10 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
}
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @deprecated_gl Prefer to use @ref setStorage() and
* @ref setCompressedSubImage() instead.
*/
@ -699,6 +715,10 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
}
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
* @deprecated_gl Prefer to use @ref setStorage() and
* @ref setCompressedSubImage() instead.
*/
@ -761,19 +781,33 @@ template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
* @fn_gl_extension_keyword{CompressedTextureSubImage3D,EXT,direct_state_access},
* eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and
* @fn_gl_keyword{CompressedTexSubImage2D} / @fn_gl_keyword{CompressedTexSubImage3D}
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
*/
TextureArray<dimensions>& setCompressedSubImage(Int level, const VectorTypeFor<dimensions+1, Int>& offset, const CompressedImageView<dimensions+1>& image) {
DataHelper<dimensions+1>::setCompressedSubImage(*this, level, offset, image);
return *this;
}
/** @overload */
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
*/
TextureArray<dimensions>& setCompressedSubImage(Int level, const VectorTypeFor<dimensions+1, Int>& offset, CompressedBufferImage<dimensions+1>& image) {
DataHelper<dimensions+1>::setCompressedSubImage(*this, level, offset, image);
return *this;
}
/** @overload */
/** @overload
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* for non-default @ref CompressedPixelStorage
* @requires_gl Non-default @ref CompressedPixelStorage is not
* available in OpenGL ES and WebGL.
*/
TextureArray<dimensions>& setCompressedSubImage(Int level, const VectorTypeFor<dimensions+1, Int>& offset, CompressedBufferImage<dimensions+1>&& image) {
return setCompressedSubImage(level, offset, image);
}

256
src/Magnum/PixelStorage.cpp

@ -27,173 +27,29 @@
#include <Corrade/Utility/Assert.h>
#include "Magnum/GL/Context.h"
#include "Magnum/GL/Extensions.h"
#include "Magnum/GL/PixelFormat.h"
#include "Magnum/Math/Vector4.h"
#include "Magnum/GL/Implementation/RendererState.h"
#include "Magnum/GL/Implementation/State.h"
#include "Magnum/Math/Vector3.h"
namespace Magnum {
std::size_t PixelStorage::pixelSize(GL::PixelFormat format, GL::PixelType type) {
std::size_t size = 0;
switch(type) {
case GL::PixelType::UnsignedByte:
#ifndef MAGNUM_TARGET_GLES2
case GL::PixelType::Byte:
#endif
size = 1; break;
case GL::PixelType::UnsignedShort:
#ifndef MAGNUM_TARGET_GLES2
case GL::PixelType::Short:
#endif
case GL::PixelType::HalfFloat:
size = 2; break;
case GL::PixelType::UnsignedInt:
#ifndef MAGNUM_TARGET_GLES2
case GL::PixelType::Int:
#endif
case GL::PixelType::Float:
size = 4; break;
#ifndef MAGNUM_TARGET_GLES
case GL::PixelType::UnsignedByte332:
case GL::PixelType::UnsignedByte233Rev:
return 1;
#endif
case GL::PixelType::UnsignedShort565:
#ifndef MAGNUM_TARGET_GLES
case GL::PixelType::UnsignedShort565Rev:
#endif
case GL::PixelType::UnsignedShort4444:
#ifndef MAGNUM_TARGET_WEBGL
case GL::PixelType::UnsignedShort4444Rev:
#endif
case GL::PixelType::UnsignedShort5551:
#ifndef MAGNUM_TARGET_WEBGL
case GL::PixelType::UnsignedShort1555Rev:
#endif
return 2;
#ifndef MAGNUM_TARGET_GLES
case GL::PixelType::UnsignedInt8888:
case GL::PixelType::UnsignedInt8888Rev:
case GL::PixelType::UnsignedInt1010102:
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
case GL::PixelType::UnsignedInt2101010Rev:
#endif
#ifndef MAGNUM_TARGET_GLES2
case GL::PixelType::UnsignedInt10F11F11FRev:
case GL::PixelType::UnsignedInt5999Rev:
#endif
case GL::PixelType::UnsignedInt248:
return 4;
#ifndef MAGNUM_TARGET_GLES2
case GL::PixelType::Float32UnsignedInt248Rev:
return 8;
#endif
}
switch(format) {
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
case GL::PixelFormat::Red:
#endif
#ifndef MAGNUM_TARGET_GLES2
case GL::PixelFormat::RedInteger:
#endif
#ifndef MAGNUM_TARGET_GLES
case GL::PixelFormat::Green:
case GL::PixelFormat::Blue:
case GL::PixelFormat::GreenInteger:
case GL::PixelFormat::BlueInteger:
#endif
#ifdef MAGNUM_TARGET_GLES2
case GL::PixelFormat::Luminance:
#endif
case GL::PixelFormat::DepthComponent:
#ifndef MAGNUM_TARGET_WEBGL
case GL::PixelFormat::StencilIndex:
#endif
return 1*size;
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
case GL::PixelFormat::RG:
#endif
#ifndef MAGNUM_TARGET_GLES2
case GL::PixelFormat::RGInteger:
#endif
#ifdef MAGNUM_TARGET_GLES2
case GL::PixelFormat::LuminanceAlpha:
#endif
return 2*size;
case GL::PixelFormat::RGB:
#ifndef MAGNUM_TARGET_GLES2
case GL::PixelFormat::RGBInteger:
#endif
#ifndef MAGNUM_TARGET_GLES
case GL::PixelFormat::BGR:
case GL::PixelFormat::BGRInteger:
#endif
#ifdef MAGNUM_TARGET_GLES2
case GL::PixelFormat::SRGB:
#endif
return 3*size;
case GL::PixelFormat::RGBA:
#ifndef MAGNUM_TARGET_GLES2
case GL::PixelFormat::RGBAInteger:
#endif
#ifndef MAGNUM_TARGET_WEBGL
case GL::PixelFormat::BGRA:
#endif
#ifdef MAGNUM_TARGET_GLES2
case GL::PixelFormat::SRGBAlpha:
#endif
#ifndef MAGNUM_TARGET_GLES
case GL::PixelFormat::BGRAInteger:
#endif
return 4*size;
/* Handled above */
case GL::PixelFormat::DepthStencil:
CORRADE_ASSERT(false, "PixelStorage::pixelSize(): invalid PixelType specified for depth/stencil PixelFormat", 0);
}
CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
}
bool PixelStorage::operator==(const PixelStorage& other) const {
return
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
_rowLength == other._rowLength &&
#endif
#ifndef MAGNUM_TARGET_GLES2
_imageHeight == other._imageHeight &&
#endif
_skip == other._skip &&
_alignment == other._alignment;
}
std::tuple<Math::Vector3<std::size_t>, Math::Vector3<std::size_t>, std::size_t> PixelStorage::dataProperties(const GL::PixelFormat format, const GL::PixelType type, const Vector3i& size) const {
const std::size_t pixelSize = PixelStorage::pixelSize(format, type);
std::pair<Math::Vector3<std::size_t>, Math::Vector3<std::size_t>> PixelStorage::dataProperties(const std::size_t pixelSize, const Vector3i& size) const {
const Math::Vector3<std::size_t> dataSize{
std::size_t((((
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
_rowLength ? _rowLength*pixelSize :
#endif
size[0]*pixelSize) + _alignment - 1)/_alignment)*_alignment),
#ifndef MAGNUM_TARGET_GLES2
std::size_t((((_rowLength ? _rowLength*pixelSize : size[0]*pixelSize) +
_alignment - 1)/_alignment)*_alignment),
std::size_t(_imageHeight ? _imageHeight : size.y()),
#else
std::size_t(size.y()),
#endif
std::size_t(size.z())};
return std::make_tuple(Math::Vector3<std::size_t>{pixelSize, dataSize.x(), dataSize.xy().product()}*Math::Vector3<std::size_t>{_skip},
size.product() ? dataSize : Math::Vector3<std::size_t>{}, pixelSize);
return {Math::Vector3<std::size_t>{pixelSize, dataSize.x(), dataSize.xy().product()}*Math::Vector3<std::size_t>{_skip},
size.product() ? dataSize : Math::Vector3<std::size_t>{}};
}
#ifndef MAGNUM_TARGET_GLES
std::tuple<Math::Vector3<std::size_t>, Math::Vector3<std::size_t>, std::size_t> CompressedPixelStorage::dataProperties(const Vector3i& size) const {
CORRADE_ASSERT(_blockDataSize && _blockSize.product(), "CompressedPixelStorage::dataProperties(): expected non-zero storage parameters", {});
@ -208,111 +64,11 @@ std::tuple<Math::Vector3<std::size_t>, Math::Vector3<std::size_t>, std::size_t>
return std::make_tuple(offset, size.product() ? dataSize : Math::Vector3<std::size_t>{}, _blockDataSize);
}
#endif
void PixelStorage::applyInternal(const bool isUnpack) {
GL::Implementation::RendererState::PixelStorage& state = isUnpack ?
Context::current().state().renderer->unpackPixelStorage :
Context::current().state().renderer->packPixelStorage;
/* Alignment */
if(state.alignment == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.alignment != _alignment)
glPixelStorei(isUnpack ? GL_UNPACK_ALIGNMENT : GL_PACK_ALIGNMENT,
state.alignment = _alignment);
/* Row length */
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
if(state.rowLength == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.rowLength != _rowLength)
{
/** @todo Use real value for GL_PACK_ROW_LENGTH_NV when it is in headers */
#ifndef MAGNUM_TARGET_GLES2
glPixelStorei(isUnpack ? GL_UNPACK_ROW_LENGTH : GL_PACK_ROW_LENGTH,
state.rowLength = _rowLength);
#elif !defined(MAGNUM_TARGET_WEBGL)
glPixelStorei(isUnpack ? GL_UNPACK_ROW_LENGTH_EXT : 0xD02 /*GL_PACK_ROW_LENGTH_NV*/,
state.rowLength = _rowLength);
#endif
}
#endif
#ifndef MAGNUM_TARGET_GLES
/* Image height (on ES for unpack only, taken care of below) */
if(state.imageHeight == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.imageHeight != _imageHeight)
glPixelStorei(isUnpack ? GL_UNPACK_IMAGE_HEIGHT : GL_PACK_IMAGE_HEIGHT,
state.imageHeight = _imageHeight);
#endif
/* On ES2 done by modifying data pointer */
#ifndef MAGNUM_TARGET_GLES2
/* Skip pixels */
if(state.skip.x() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.skip.x() != _skip.x())
glPixelStorei(isUnpack ? GL_UNPACK_SKIP_PIXELS : GL_PACK_SKIP_PIXELS,
state.skip.x() = _skip.x());
/* Skip rows */
if(state.skip.y() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.skip.y() != _skip.y())
glPixelStorei(isUnpack ? GL_UNPACK_SKIP_ROWS : GL_PACK_SKIP_ROWS,
state.skip.y() = _skip.y());
#ifndef MAGNUM_TARGET_GLES
/* Skip images (on ES for unpack only, taken care of below) */
if(state.skip.z() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.skip.z() != _skip.z())
glPixelStorei(isUnpack ? GL_UNPACK_SKIP_IMAGES : GL_PACK_SKIP_IMAGES,
state.skip.z() = _skip.z());
#endif
#endif
}
void PixelStorage::applyUnpack() {
applyInternal(true);
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2)
Implementation::RendererState::PixelStorage& state = Context::current().state().renderer->unpackPixelStorage;
/* Image height (on ES for unpack only) */
if(state.imageHeight == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.imageHeight != _imageHeight)
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, state.imageHeight = _imageHeight);
/* Skip images (on ES for unpack only) */
if(state.skip.z() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.skip.z() != _skip.z())
glPixelStorei(GL_UNPACK_SKIP_IMAGES, state.skip.z() = _skip.z());
#endif
}
#ifndef MAGNUM_TARGET_GLES
bool CompressedPixelStorage::operator==(const CompressedPixelStorage& other) const {
return PixelStorage::operator==(other) &&
_blockSize == other._blockSize &&
_blockDataSize == other._blockDataSize;
}
void CompressedPixelStorage::applyInternal(const bool isUnpack) {
PixelStorage::applyInternal(isUnpack);
GL::Implementation::RendererState::PixelStorage& state = isUnpack ?
Context::current().state().renderer->unpackPixelStorage :
Context::current().state().renderer->packPixelStorage;
/* Compressed block width */
if(state.compressedBlockSize.x() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.compressedBlockSize.x() != _blockSize.x())
glPixelStorei(isUnpack ? GL_UNPACK_COMPRESSED_BLOCK_WIDTH : GL_PACK_COMPRESSED_BLOCK_WIDTH,
state.compressedBlockSize.x() = _blockSize.x());
/* Compressed block height */
if(state.compressedBlockSize.y() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.compressedBlockSize.y() != _blockSize.y())
glPixelStorei(isUnpack ? GL_UNPACK_COMPRESSED_BLOCK_HEIGHT : GL_PACK_COMPRESSED_BLOCK_HEIGHT,
state.compressedBlockSize.y() = _blockSize.y());
/* Compressed block depth */
if(state.compressedBlockSize.z() == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.compressedBlockSize.z() != _blockSize.z())
glPixelStorei(isUnpack ? GL_UNPACK_COMPRESSED_BLOCK_DEPTH : GL_PACK_COMPRESSED_BLOCK_DEPTH,
state.compressedBlockSize.z() = _blockSize.z());
/* Compressed block size */
if(state.compressedBlockDataSize == GL::Implementation::RendererState::PixelStorage::DisengagedValue || state.compressedBlockDataSize != _blockDataSize)
glPixelStorei(isUnpack ? GL_UNPACK_COMPRESSED_BLOCK_SIZE : GL_PACK_COMPRESSED_BLOCK_SIZE,
state.compressedBlockDataSize = _blockDataSize);
}
#endif
}

197
src/Magnum/PixelStorage.h

@ -33,44 +33,30 @@
#include <tuple>
#include "Magnum/Magnum.h"
#include "Magnum/GL/GL.h"
#include "Magnum/GL/visibility.h"
#include "Magnum/Math/Vector3.h"
#if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL)
#include "Magnum/GL/PixelFormat.h"
#endif
namespace Magnum {
/**
@brief Pixel storage parameters
Descibes how to interpret data which are read from or stored into @ref Image,
@ref ImageView, @ref BufferImage and @ref Trade::ImageData using
@ref Texture::setImage() "*Texture::setImage()", @ref Texture::setSubImage() "*Texture::setSubImage()",
@ref Texture::image() "*Texture::image()", @ref Texture::subImage() "*Texture::subImage()"
and @ref AbstractFramebuffer::read() "*Framebuffer::read()".
@section PixelFormat-performance-optimizations Performance optimizations
The storage mode is applied either right before doing image upload using
@fn_gl_keyword{PixelStore} with @def_gl{UNPACK_*} parameters or right before
doing image download using @fn_gl{PixelStore} with @def_gl{PACK_*}. The engine
tracks currently used pixel pack/unpack parameters to avoid unnecessary calls
to @fn_gl{PixelStore}. See also @ref Context::resetState() and
@ref Context::State::PixelStorage.
@ref ImageView, @ref Trade::ImageData or for example @ref GL::BufferImage.
@see @ref CompressedPixelStorage
*/
class MAGNUM_GL_EXPORT PixelStorage {
friend GL::AbstractFramebuffer;
friend GL::AbstractTexture;
friend GL::CubeMapTexture;
class MAGNUM_EXPORT PixelStorage {
public:
/**
* @brief Pixel size for given format/type combination (in bytes)
*
* @see @ref dataProperties()
#if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL)
/** @brief @copybrief GL::pixelSize()
* @deprecated Use @ref GL::pixelSize() instead.
*/
static std::size_t pixelSize(GL::PixelFormat format, GL::PixelType type);
static CORRADE_DEPRECATED("use GL::pixelSize() instead") std::size_t pixelSize(GL::PixelFormat format, GL::PixelType type);
#endif
/**
* @brief Default constructor
@ -97,73 +83,39 @@ class MAGNUM_GL_EXPORT PixelStorage {
* Not applicable for @ref CompressedPixelStorage. Valid values are
* @cpp 1 @ce, @cpp 2 @ce, @cpp 4 @ce and @cpp 8 @ce. Default is
* @cpp 4 @ce.
* @see @fn_gl{PixelStore} with @def_gl_keyword{PACK_ALIGNMENT}/
* @def_gl_keyword{UNPACK_ALIGNMENT}
*/
PixelStorage& setAlignment(Int alignment) {
_alignment = alignment;
return *this;
}
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
/**
* @brief Row length
*
* @requires_gles30 Extension @extension{EXT,unpack_subimage}/
* @extension{NV,pack_subimage} in OpenGL ES 2.0.
* @requires_webgl20 Row length specification is not available in WebGL
* 1.0.
*/
/** @brief Row length */
constexpr Int rowLength() const { return _rowLength; }
/**
* @brief Set row length
*
* Used only on 2D and 3D images. If set to @cpp 0 @ce, size
* information from actual image is used. Default is @cpp 0 @ce.
* @see @fn_gl{PixelStore} with @def_gl_keyword{UNPACK_ROW_LENGTH}/
* @def_gl_keyword{PACK_ROW_LENGTH}
* @requires_gles30 Extension @extension{EXT,unpack_subimage}/
* @extension{NV,pack_subimage} in OpenGL ES 2.0.
* @requires_webgl20 Row length specification is not available in WebGL
* 1.0.
* information from the actual image is used. Default is @cpp 0 @ce.
*/
PixelStorage& setRowLength(Int length) {
_rowLength = length;
return *this;
}
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Image height
*
* @requires_gles30 Image height specification is not available in
* OpenGL ES 2.0
* @requires_webgl20 Image height specification is not available in
* WebGL 1.0.
*/
/** @brief Image height */
constexpr Int imageHeight() const { return _imageHeight; }
/**
* @brief Set image height
*
* Used only on 3D images. If set to @cpp 0 @ce, size information from
* actual image is used. Default is @cpp 0 @ce.
* @see @fn_gl{PixelStore} with @def_gl_keyword{UNPACK_IMAGE_HEIGHT}/
* @def_gl_keyword{PACK_IMAGE_HEIGHT}
* @requires_gles30 Image height specification is not available in
* OpenGL ES 2.0
* @requires_webgl20 Image height specification is not available in
* WebGL 1.0.
* @requires_gl Image height specification is available only for unpack
* in OpenGL ES and WebGL.
* the actual image is used. Default is @cpp 0 @ce.
*/
PixelStorage& setImageHeight(Int height) {
_imageHeight = height;
return *this;
}
#endif
/** @brief Pixel, row and image skipping */
constexpr Vector3i skip() const { return _skip; }
@ -172,15 +124,7 @@ class MAGNUM_GL_EXPORT PixelStorage {
* @brief Set pixel, row and image skipping
*
* The Y value is used only for 2D and 3D images, the Z value is used
* only for 3D images. Default is @cpp 0 @ce. On OpenGL ES 2.0 and
* WebGL 1.0 the functionality is emulated by increasing the data
* pointer.
* @see @fn_gl{PixelStore} with @def_gl_keyword{UNPACK_SKIP_PIXELS}/
* @def_gl_keyword{PACK_SKIP_PIXELS}, @def_gl_keyword{UNPACK_SKIP_ROWS}/
* @def_gl_keyword{PACK_SKIP_ROWS}, @def_gl_keyword{UNPACK_SKIP_IMAGES}/
* @def_gl_keyword{PACK_SKIP_IMAGES}
* @requires_gl Image skip specification is available only for unpack
* in OpenGL ES and WebGL.
* only for 3D images. Default is @cpp 0 @ce.
*/
PixelStorage& setSkip(const Vector3i& skip) {
_skip = skip;
@ -189,64 +133,52 @@ class MAGNUM_GL_EXPORT PixelStorage {
/**
* @brief Data properties for given parameters
*
* Returns byte offset in each direction and @cpp {rowLength, rowCount, layerCount} @ce
* for image of given @p size with current pixel storage parameters,
* and given @p pixelSize. The offset reflects the @ref skip()
* parameter. Sum of the byte offset vector gives the byte offset of
* first pixel in the data array.
* @see @ref GL::pixelSize()
*/
std::pair<Math::Vector3<std::size_t>, Math::Vector3<std::size_t>> dataProperties(std::size_t pixelSize, const Vector3i& size) const;
#if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL)
/** @brief @copybrief dataProperties(std::size_t, const Vector3i&) const
*
* Returns byte offset in each direction, (row length, row count, layer
* count) and pixel size for image of given @p size with current pixel
* storage parameters, @p format and @p type. The offset reflects the
* @ref skip() parameter. Sum of the byte offset vector gives the
* byte offset of first pixel in the data array.
* @see @ref pixelSize()
* storage parameters, @p format and @p type.
* @deprecated Use @ref dataProperties(std::size_t, const Vector3i&) const
* instead.
*/
std::tuple<Math::Vector3<std::size_t>, Math::Vector3<std::size_t>, std::size_t> dataProperties(GL::PixelFormat format, GL::PixelType type, const Vector3i& size) const;
CORRADE_DEPRECATED("use dataProperties(std::size_t, const Vector3i&) instead") std::tuple<Math::Vector3<std::size_t>, Math::Vector3<std::size_t>, std::size_t> dataProperties(GL::PixelFormat format, GL::PixelType type, const Vector3i& size) const;
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/* Bool parameter is ugly, but this is implementation detail of
internal API so who cares */
void MAGNUM_GL_LOCAL applyInternal(bool isUnpack);
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
Int _rowLength;
#endif
#ifndef MAGNUM_TARGET_GLES2
Int _imageHeight;
#endif
Int _rowLength,
_imageHeight;
Vector3i _skip;
private:
/* Used internally in *Texture::image(), *Texture::subImage(),
*Texture::setImage(), *Texture::setSubImage() and
*Framebuffer::read() */
void MAGNUM_GL_LOCAL applyUnpack();
void MAGNUM_GL_LOCAL applyPack() { applyInternal(false); }
Int _alignment;
};
#ifndef MAGNUM_TARGET_GLES
/**
@brief Compressed pixel storage parameters
Descibes how to interpret data which are read from or stored into
@ref CompressedImage, @ref CompressedImageView, @ref CompressedBufferImage and
@ref Trade::ImageData using @ref Texture::setCompressedImage() "*Texture::setCompressedImage(),
@ref Texture::setCompressedSubImage() "*Texture::setCompressedSubImage()",
@ref Texture::compressedImage() "*Texture::compressedImage()" and
@ref Texture::compressedSubImage() "*Texture::compressedSubImage()".
@ref CompressedImage, @ref CompressedImageView, @ref Trade::ImageData or for
example @ref GL::CompressedBufferImage.
Includes all parameters from @ref PixelStorage, except for @ref alignment(),
which is ignored for compressed images.
@requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
@requires_gl Compressed pixel storage is hardcoded in OpenGL ES and WebGL.
*/
class MAGNUM_GL_EXPORT CompressedPixelStorage: public PixelStorage {
friend GL::AbstractTexture;
friend GL::CubeMapTexture;
class MAGNUM_EXPORT CompressedPixelStorage: public PixelStorage {
public:
/**
* @brief Default constructor
@ -330,29 +262,26 @@ class MAGNUM_GL_EXPORT CompressedPixelStorage: public PixelStorage {
using PixelStorage::alignment;
using PixelStorage::setAlignment;
/* Bool parameter is ugly, but this is implementation detail of
internal API so who cares */
void MAGNUM_GL_LOCAL applyInternal(bool isUnpack);
/* Used internally in *Texture::compressedImage(), *Texture::compressedSubImage(),
*Texture::setCompressedImage() and *Texture::setCompressedSubImage() */
void MAGNUM_GL_LOCAL applyUnpack() { applyInternal(true); }
void MAGNUM_GL_LOCAL applyPack() { applyInternal(false); }
Vector3i _blockSize;
Int _blockDataSize;
};
#endif
constexpr PixelStorage::PixelStorage() noexcept:
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
_rowLength{0},
#endif
#ifndef MAGNUM_TARGET_GLES2
_imageHeight{0},
#endif
_skip{0},
_alignment{4} {}
constexpr PixelStorage::PixelStorage() noexcept: _rowLength{0}, _imageHeight{0}, _skip{0}, _alignment{4} {}
#if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL)
/* These have to be in the header because GL::pixelSize() is in Magnum::GL and
putting that in the source would mean undefined reference */
inline std::size_t PixelStorage::pixelSize(const GL::PixelFormat format, const GL::PixelType type) {
return GL::pixelSize(format, type);
}
inline std::tuple<Math::Vector3<std::size_t>, Math::Vector3<std::size_t>, std::size_t> PixelStorage::dataProperties(const GL::PixelFormat format, const GL::PixelType type, const Vector3i& size) const {
const std::size_t pixelSize = GL::pixelSize(format, type);
Math::Vector3<std::size_t> offset, dataSize;
std::tie(offset, dataSize) = dataProperties(pixelSize, size);
return std::make_tuple(offset, dataSize, pixelSize);
}
#endif
namespace Implementation {
/* Used in *Image::dataProperties() */
@ -363,7 +292,6 @@ namespace Implementation {
return std::make_tuple(Math::Vector<dimensions, std::size_t>::pad(offset), Math::Vector<dimensions, std::size_t>::pad(dataSize), pixelSize);
}
#ifndef MAGNUM_TARGET_GLES2
/* Used in Compressed*Image::dataProperties() */
template<std::size_t dimensions, class T> std::tuple<Math::Vector<dimensions, std::size_t>, Math::Vector<dimensions, std::size_t>, std::size_t> compressedImageDataProperties(const T& image) {
Math::Vector3<std::size_t> offset, blockCount;
@ -371,7 +299,6 @@ namespace Implementation {
std::tie(offset, blockCount, blockSize) = image.storage().dataProperties(Vector3i::pad(image.size(), 1));
return std::make_tuple(Math::Vector<dimensions, std::size_t>::pad(offset), Math::Vector<dimensions, std::size_t>::pad(blockCount), blockSize);
}
#endif
/* Used in image query functions */
template<std::size_t dimensions, class T> std::size_t imageDataSizeFor(const T& image, const Math::Vector<dimensions, Int>& size) {
@ -384,19 +311,11 @@ namespace Implementation {
if(offset.z())
dataOffset += offset.z();
else if(offset.y()) {
#ifndef MAGNUM_TARGET_GLES2
if(!image.storage().imageHeight())
#endif
{
dataOffset += offset.y();
}
} else if(offset.x()) {
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
if(!image.storage().rowLength())
#endif
{
dataOffset += offset.x();
}
}
return dataOffset + dataSize.product();
}
@ -406,7 +325,6 @@ namespace Implementation {
return imageDataSizeFor(image, image.size());
}
#ifndef MAGNUM_TARGET_GLES
template<std::size_t dimensions, class T> std::pair<std::size_t, std::size_t> compressedImageDataOffsetSizeFor(const T& image, const Math::Vector<dimensions, Int>& size) {
CORRADE_INTERNAL_ASSERT(image.storage().compressedBlockSize().product() && image.storage().compressedBlockDataSize());
@ -430,20 +348,13 @@ namespace Implementation {
return image.storage().compressedBlockSize().product() && image.storage().compressedBlockDataSize()
? compressedImageDataOffsetSizeFor(image, image.size()).second : dataSize;
}
#else
template<class T> std::size_t occupiedCompressedImageDataSize(const T&, std::size_t dataSize) {
return dataSize;
}
#endif
#ifdef MAGNUM_TARGET_GLES2
template<std::size_t dimensions, class T> std::ptrdiff_t pixelStorageSkipOffsetFor(const T& image, const Math::Vector<dimensions, Int>& size) {
return std::get<0>(image.storage().dataProperties(image.format(), image.type(), Vector3i::pad(size, 1))).sum();
}
template<class T> std::ptrdiff_t pixelStorageSkipOffset(const T& image) {
return pixelStorageSkipOffsetFor(image, image.size());
}
#endif
}
}

2
src/Magnum/Trade/ImageData.h

@ -190,7 +190,7 @@ template<UnsignedInt dimensions> class ImageData {
* @brief Pixel size (in bytes)
*
* The image is expected to be uncompressed.
* @see @ref isCompressed(), @ref PixelStorage::pixelSize()
* @see @ref isCompressed(), @ref Magnum::pixelSize()
*/
std::size_t pixelSize() const;

Loading…
Cancel
Save