Browse Source

Ability to create {Compressed,}BufferImage from an existing Buffer.

One use case might be data reinterpreting in combination with
{Compressed,}BufferImage::release().
pull/193/head
Vladimír Vondruš 9 years ago
parent
commit
44b2ae72bb
  1. 14
      src/Magnum/BufferImage.cpp
  2. 43
      src/Magnum/BufferImage.h
  3. 68
      src/Magnum/Test/BufferImageGLTest.cpp

14
src/Magnum/BufferImage.cpp

@ -33,6 +33,10 @@ template<UnsignedInt dimensions> BufferImage<dimensions>::BufferImage(const Pixe
_buffer.setData(data, usage); _buffer.setData(data, usage);
} }
template<UnsignedInt dimensions> BufferImage<dimensions>::BufferImage(const PixelStorage storage, const PixelFormat format, const PixelType type, const VectorTypeFor<dimensions, Int>& size, Buffer&& buffer, const std::size_t dataSize) noexcept: _storage{storage}, _format{format}, _type{type}, _size{size}, _buffer{std::move(buffer)}, _dataSize{dataSize} {
CORRADE_ASSERT(Implementation::imageDataSize(*this) <= dataSize, "BufferImage::BufferImage(): bad image data size, got" << dataSize << "but expected at least" << Implementation::imageDataSize(*this), );
}
template<UnsignedInt dimensions> BufferImage<dimensions>::BufferImage(const PixelStorage storage, const PixelFormat format, const PixelType type): _storage{storage}, _format{format}, _type{type}, _buffer{Buffer::TargetHint::PixelPack}, _dataSize{0} {} template<UnsignedInt dimensions> BufferImage<dimensions>::BufferImage(const PixelStorage storage, const PixelFormat format, const PixelType type): _storage{storage}, _format{format}, _type{type}, _buffer{Buffer::TargetHint::PixelPack}, _dataSize{0} {}
template<UnsignedInt dimensions> void BufferImage<dimensions>::setData(const PixelStorage storage, const PixelFormat format, const PixelType type, const VectorTypeFor<dimensions, Int>& size, Containers::ArrayView<const void> const data, const BufferUsage usage) { template<UnsignedInt dimensions> void BufferImage<dimensions>::setData(const PixelStorage storage, const PixelFormat format, const PixelType type, const VectorTypeFor<dimensions, Int>& size, Containers::ArrayView<const void> const data, const BufferUsage usage) {
@ -64,6 +68,16 @@ template<UnsignedInt dimensions> CompressedBufferImage<dimensions>::CompressedBu
_buffer.setData(data, usage); _buffer.setData(data, usage);
} }
template<UnsignedInt dimensions> CompressedBufferImage<dimensions>::CompressedBufferImage(
#ifndef MAGNUM_TARGET_GLES
const CompressedPixelStorage storage,
#endif
const CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, Buffer&& buffer, const std::size_t dataSize) noexcept:
#ifndef MAGNUM_TARGET_GLES
_storage{storage},
#endif
_format{format}, _size{size}, _buffer{std::move(buffer)}, _dataSize{dataSize} {}
template<UnsignedInt dimensions> CompressedBufferImage<dimensions>::CompressedBufferImage( template<UnsignedInt dimensions> CompressedBufferImage<dimensions>::CompressedBufferImage(
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
const CompressedPixelStorage storage const CompressedPixelStorage storage

43
src/Magnum/BufferImage.h

@ -74,6 +74,25 @@ template<UnsignedInt dimensions> class BufferImage {
*/ */
explicit BufferImage(PixelFormat format, PixelType type, const VectorTypeFor<dimensions, Int>& size, Containers::ArrayView<const void> data, BufferUsage usage): BufferImage{{}, format, type, size, data, usage} {} explicit BufferImage(PixelFormat format, PixelType type, const VectorTypeFor<dimensions, Int>& size, Containers::ArrayView<const void> data, BufferUsage usage): BufferImage{{}, format, type, size, data, usage} {}
/**
* @brief Construct from existing buffer
* @param storage Storage of pixel data
* @param format Format of pixel data
* @param type Data type of pixel data
* @param size Image size
* @param buffer Buffer
* @param dataSize Buffer data size
*
* If @p dataSize is 0, the buffer is unconditionally reallocated on
* the first call to @ref setData().
*/
explicit BufferImage(PixelStorage storage, PixelFormat format, PixelType type, const VectorTypeFor<dimensions, Int>& size, Buffer&& buffer, std::size_t dataSize) noexcept;
/** @overload
* Similar to the above, but uses default @ref PixelStorage parameters.
*/
explicit BufferImage(PixelFormat format, PixelType type, const VectorTypeFor<dimensions, Int>& size, Buffer&& buffer, std::size_t dataSize) noexcept: BufferImage{{}, format, type, size, std::move(buffer), dataSize} {}
#ifdef MAGNUM_BUILD_DEPRECATED #ifdef MAGNUM_BUILD_DEPRECATED
/** @copybrief BufferImage(PixelFormat, PixelType, const VectorTypeFor<dimensions, Int>&, Containers::ArrayView<const void>, BufferUsage) /** @copybrief BufferImage(PixelFormat, PixelType, const VectorTypeFor<dimensions, Int>&, Containers::ArrayView<const void>, BufferUsage)
* @deprecated Use @ref BufferImage(PixelFormat, PixelType, const VectorTypeFor<dimensions, Int>&, Containers::ArrayView<const void>, BufferUsage) * @deprecated Use @ref BufferImage(PixelFormat, PixelType, const VectorTypeFor<dimensions, Int>&, Containers::ArrayView<const void>, BufferUsage)
@ -282,6 +301,28 @@ template<UnsignedInt dimensions> class CompressedBufferImage {
*/ */
explicit CompressedBufferImage(CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, Containers::ArrayView<const void> data, BufferUsage usage); explicit CompressedBufferImage(CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, Containers::ArrayView<const void> data, BufferUsage usage);
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Constructor
* @param storage Storage of compressed pixel data
* @param format Format of compressed pixel data
* @param size Image size
* @param data Image data
* @param usage Image buffer usage
*
* @requires_gl42 Extension @extension{ARB,compressed_texture_pixel_storage}
* @requires_gl Compressed pixel storage is hardcoded in OpenGL ES and
* WebGL.
*/
explicit CompressedBufferImage(CompressedPixelStorage storage, CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, Buffer&& buffer, std::size_t dataSize) noexcept;
#endif
/** @overload
* Similar the above, but uses default @ref CompressedPixelStorage
* parameters (or the hardcoded ones in OpenGL ES and WebGL).
*/
explicit CompressedBufferImage(CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, Buffer&& buffer, std::size_t dataSize) noexcept;
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Constructor * @brief Constructor
@ -460,6 +501,8 @@ template<UnsignedInt dimensions> inline CompressedBufferImage<dimensions>& Compr
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
template<UnsignedInt dimensions> inline CompressedBufferImage<dimensions>::CompressedBufferImage(const CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, const Containers::ArrayView<const void> data, const BufferUsage usage): CompressedBufferImage{{}, format, size, data, usage} {} template<UnsignedInt dimensions> inline CompressedBufferImage<dimensions>::CompressedBufferImage(const CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, const Containers::ArrayView<const void> data, const BufferUsage usage): CompressedBufferImage{{}, format, size, data, usage} {}
template<UnsignedInt dimensions> inline CompressedBufferImage<dimensions>::CompressedBufferImage(const CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, Buffer&& buffer, const std::size_t dataSize) noexcept: CompressedBufferImage{{}, format, size, std::move(buffer), dataSize} {}
template<UnsignedInt dimensions> inline CompressedBufferImage<dimensions>::CompressedBufferImage(): CompressedBufferImage{CompressedPixelStorage{}} {} template<UnsignedInt dimensions> inline CompressedBufferImage<dimensions>::CompressedBufferImage(): CompressedBufferImage{CompressedPixelStorage{}} {}
template<UnsignedInt dimensions> inline void CompressedBufferImage<dimensions>::setData(const CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, const Containers::ArrayView<const void> data, const BufferUsage usage) { template<UnsignedInt dimensions> inline void CompressedBufferImage<dimensions>::setData(const CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, const Containers::ArrayView<const void> data, const BufferUsage usage) {

68
src/Magnum/Test/BufferImageGLTest.cpp

@ -36,6 +36,8 @@ struct BufferImageGLTest: OpenGLTester {
void construct(); void construct();
void constructCompressed(); void constructCompressed();
void constructBuffer();
void constructBufferCompressed();
void constructCopy(); void constructCopy();
void constructCopyCompressed(); void constructCopyCompressed();
void constructMove(); void constructMove();
@ -51,6 +53,8 @@ struct BufferImageGLTest: OpenGLTester {
BufferImageGLTest::BufferImageGLTest() { BufferImageGLTest::BufferImageGLTest() {
addTests({&BufferImageGLTest::construct, addTests({&BufferImageGLTest::construct,
&BufferImageGLTest::constructCompressed, &BufferImageGLTest::constructCompressed,
&BufferImageGLTest::constructBuffer,
&BufferImageGLTest::constructBufferCompressed,
&BufferImageGLTest::constructCopy, &BufferImageGLTest::constructCopy,
&BufferImageGLTest::constructCopyCompressed, &BufferImageGLTest::constructCopyCompressed,
&BufferImageGLTest::constructMove, &BufferImageGLTest::constructMove,
@ -115,6 +119,70 @@ void BufferImageGLTest::constructCompressed() {
#endif #endif
} }
void BufferImageGLTest::constructBuffer() {
const char data[] = { 'a', 'b', 'c' };
Buffer buffer;
buffer.setData(data, BufferUsage::StaticDraw);
const UnsignedInt id = buffer.id();
BufferImage2D a{PixelStorage{}.setAlignment(1),
PixelFormat::Red, PixelType::UnsignedByte, {1, 3}, std::move(buffer), sizeof(data)};
#ifndef MAGNUM_TARGET_GLES
const auto imageData = a.buffer().data();
#endif
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(!buffer.id());
CORRADE_COMPARE(a.buffer().id(), id);
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), PixelFormat::Red);
CORRADE_COMPARE(a.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(a.size(), Vector2i(1, 3));
/** @todo How to verify the contents in ES? */
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(imageData, Containers::ArrayView<const char>{data},
TestSuite::Compare::Container);
#endif
}
void BufferImageGLTest::constructBufferCompressed() {
const char data[] = { 'a', 0, 0, 0, 'b', 0, 0, 0 };
Buffer buffer;
buffer.setData(data, BufferUsage::StaticDraw);
const UnsignedInt id = buffer.id();
CompressedBufferImage2D a{
#ifndef MAGNUM_TARGET_GLES
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
#endif
CompressedPixelFormat::RGBAS3tcDxt1,
{4, 4}, std::move(buffer), sizeof(data)};
#ifndef MAGNUM_TARGET_GLES
const auto imageData = a.buffer().data();
#endif
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
#endif
CORRADE_VERIFY(!buffer.id());
CORRADE_COMPARE(a.buffer().id(), id);
CORRADE_COMPARE(a.format(), CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(a.size(), Vector2i(4, 4));
CORRADE_COMPARE(a.dataSize(), 8);
/** @todo How to verify the contents in ES? */
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(imageData, Containers::ArrayView<const char>{data},
TestSuite::Compare::Container);
#endif
}
void BufferImageGLTest::constructCopy() { void BufferImageGLTest::constructCopy() {
CORRADE_VERIFY(!(std::is_constructible<BufferImage2D, const BufferImage2D&>{})); CORRADE_VERIFY(!(std::is_constructible<BufferImage2D, const BufferImage2D&>{}));
CORRADE_VERIFY(!(std::is_assignable<BufferImage2D, const BufferImage2D&>{})); CORRADE_VERIFY(!(std::is_assignable<BufferImage2D, const BufferImage2D&>{}));

Loading…
Cancel
Save