Browse Source

Rework of image classes, added missing image formats.

* Framebuffer related functions moved to Framebuffer class, thus
   simplifying the data setting functions - removed setDimensions(),
   more flexible setData() function.
 * Allow to set data with explicit format specification, reorganized
   function parameters to make these two setData() more similar.
 * Now using new AbstractType::ComponentType enum instead of basic Type,
   updated TypeTraits to return the new enum from imageType() function.
vectorfields
Vladimír Vondruš 14 years ago
parent
commit
8b9b161c5a
  1. 51
      src/AbstractImage.cpp
  2. 177
      src/AbstractImage.h
  3. 14
      src/AbstractTexture.h
  4. 25
      src/BufferedImage.cpp
  5. 78
      src/BufferedImage.h
  6. 2
      src/CMakeLists.txt
  7. 16
      src/Framebuffer.cpp
  8. 23
      src/Framebuffer.h
  9. 24
      src/Image.cpp
  10. 95
      src/Image.h
  11. 25
      src/Trade/ImageData.h
  12. 18
      src/TypeTraits.h

51
src/AbstractImage.cpp

@ -14,21 +14,56 @@
*/
#include "AbstractImage.h"
#include "TypeTraits.h"
namespace Magnum {
size_t AbstractImage::pixelSize(ColorFormat format, Type type) {
size_t size = TypeInfo::sizeOf(type);
size_t AbstractImage::pixelSize(Components format, ComponentType type) {
size_t size;
switch(type) {
case ComponentType::RGB332:
case ComponentType::BGR233:
return 1;
case ComponentType::RGB565:
case ComponentType::BGR565:
case ComponentType::RGBA4:
case ComponentType::ABGR4:
case ComponentType::RGB5Alpha1:
case ComponentType::Alpha1BGR5:
return 2;
case ComponentType::RGBA8:
case ComponentType::ABGR8:
case ComponentType::RGB10Alpha2:
case ComponentType::Alpha2RGB10:
case ComponentType::Depth24Stencil8:
case ComponentType::B10GR11Float:
case ComponentType::Exponent5RGB9:
return 4;
case ComponentType::Depth32FloatStencil8:
return 8;
case ComponentType::UnsignedByte:
case ComponentType::Byte:
size = 1; break;
case ComponentType::UnsignedShort:
case ComponentType::Short:
case ComponentType::HalfFloat:
size = 2; break;
case ComponentType::UnsignedInt:
case ComponentType::Int:
case ComponentType::Float:
size = 4; break;
}
switch(format) {
case ColorFormat::Red:
case Components::Red:
return 1*size;
case ColorFormat::RedGreen:
case Components::RedGreen:
return 2*size;
case ColorFormat::RGB:
case ColorFormat::BGR:
case Components::RGB:
case Components::BGR:
return 3*size;
case ColorFormat::RGBA:
case ColorFormat::BGRA:
case Components::RGBA:
case Components::BGRA:
return 4*size;
default:
return 0;

177
src/AbstractImage.h

@ -20,7 +20,6 @@
*/
#include "Magnum.h"
#include "TypeTraits.h"
namespace Magnum {
@ -36,42 +35,182 @@ class AbstractImage {
AbstractImage& operator=(AbstractImage&& other) = delete;
public:
/** @brief Color format */
enum class ColorFormat: GLenum {
Red = GL_RED, /**< One-component (red channel) */
RedGreen = GL_RG, /**< Two-component (red and green channel) */
RGB = GL_RGB, /**< Three-component (RGB) */
RGBA = GL_RGBA, /**< Four-component (RGBA) */
BGR = GL_BGR, /**< Three-component (BGR) */
BGRA = GL_BGRA /**< Four-component (BGRA) */
/**
* @{ @name Image formats
*
* Note that some formats can be used only for framebuffer reading
* (using Framebuffer::read()) and some only for texture data (using
* Texture::setData() and others).
*/
/** @brief Color components */
enum class Components: GLenum {
Red = GL_RED, /**< One-component (red channel) */
/** One-component (green channel). For framebuffer reading only. */
Green = GL_GREEN,
/** One-component (green channel). For framebuffer reading only. */
Blue = GL_BLUE,
/** Two-component (red and green channel). For texture data only. */
RedGreen = GL_RG,
RGB = GL_RGB, /**< Three-component RGB */
BGR = GL_BGR, /**< Three-component BGR */
RGBA = GL_RGBA, /**< Four-component RGBA */
BGRA = GL_BGRA, /**< Four-component BGRA */
/** Depth component. For framebuffer reading only. */
Depth = GL_DEPTH_COMPONENT,
/** Stencil index. For framebuffer reading only. */
StencilIndex = GL_STENCIL_INDEX,
/** Depth and stencil component. For framebuffer reading only. */
DepthStencil = GL_DEPTH_STENCIL
};
/** @brief Data type */
enum class ComponentType: GLenum {
UnsignedByte = GL_UNSIGNED_BYTE, /**< Each component unsigned byte */
Byte = GL_BYTE, /**< Each component byte */
UnsignedShort = GL_UNSIGNED_SHORT, /**< Each component unsigned short */
Short = GL_SHORT, /**< Each component short */
UnsignedInt = GL_UNSIGNED_INT, /**< Each component unsigned int */
Int = GL_INT, /**< Each component int */
/** Each component half float (16bit). For framebuffer reading only. */
HalfFloat = GL_HALF_FLOAT,
Float = GL_FLOAT, /**< Each component float (32bit) */
/**
* Three-component RGB, unsigned normalized, red and green 3bit,
* blue 2bit, 8bit total.
*/
RGB332 = GL_UNSIGNED_BYTE_3_3_2,
/**
* Three-component BGR, unsigned normalized, red and green 3bit,
* blue 2bit, 8bit total.
*/
BGR233 = GL_UNSIGNED_BYTE_2_3_3_REV,
/**
* Three-component RGB, unsigned normalized, red and blue 5bit,
* green 6bit, 16bit total.
*/
RGB565 = GL_UNSIGNED_SHORT_5_6_5,
/**
* Three-component BGR, unsigned normalized, red and blue 5bit,
* green 6bit, 16bit total.
*/
BGR565 = GL_UNSIGNED_SHORT_5_6_5_REV,
/**
* Four-component RGBA, unsigned normalized, each component 4bit,
* 16bit total.
*/
RGBA4 = GL_UNSIGNED_SHORT_4_4_4_4,
/**
* Four-component ABGR, unsigned normalized, each component 4bit,
* 16bit total.
*/
ABGR4 = GL_UNSIGNED_SHORT_4_4_4_4_REV,
/**
* Four-component RGBA, unsigned normalized, each RGB component
* 5bit, alpha 1bit, 16bit total.
*/
RGB5Alpha1 = GL_UNSIGNED_SHORT_5_5_5_1,
/**
* Four-component ABGR, unsigned normalized, each RGB component
* 5bit, alpha 1bit, 16bit total.
*/
Alpha1BGR5 = GL_UNSIGNED_SHORT_1_5_5_5_REV,
/**
* Four-component RGBA, unsigned normalized, each component 8bit,
* 32bit total.
*/
RGBA8 = GL_UNSIGNED_INT_8_8_8_8,
/**
* Four-component ABGR, unsigned normalized, each component 8bit,
* 32bit total.
*/
ABGR8 = GL_UNSIGNED_INT_8_8_8_8_REV,
/**
* Four-component RGBA, unsigned normalized, each RGB component
* 10bit, alpha 2bit, 32bit total.
*/
RGB10Alpha2 = GL_UNSIGNED_INT_10_10_10_2,
/**
* Four-component ABGR, unsigned normalized, each RGB component
* 10bit, alpha 2bit, 32bit total.
*/
Alpha2RGB10 = GL_UNSIGNED_INT_2_10_10_10_REV,
/**
* Three-component BGR, float, red and green 11bit, blue 10bit,
* 32bit total. For framebuffer reading only.
*/
B10GR11Float = GL_UNSIGNED_INT_10F_11F_11F_REV,
/**
* Three-component BGR, unsigned integers with exponent, each
* component 9bit, exponent 5bit, 32bit total. For framebuffer
* reading only.
*/
Exponent5RGB9 = GL_UNSIGNED_INT_5_9_9_9_REV,
/**
* 24bit depth and 8bit stencil component, 32bit total. For
* framebuffer reading only.
*/
Depth24Stencil8 = GL_UNSIGNED_INT_24_8,
/**
* 32bit float depth component and 8bit stencil component, 64bit
* total. For framebuffer reading only.
*/
Depth32FloatStencil8 = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
};
/*@}*/
/**
* @brief Pixel size (in bytes)
* @param format Color format
* @param type Data type per color channel
* @param components Color components
* @param type Data type
*/
static size_t pixelSize(ColorFormat format, Type type);
static size_t pixelSize(Components components, ComponentType type);
/**
* @brief Constructor
* @param colorFormat Color format of passed data
* @param components Color components of passed data
* @param type %Image data type
*/
inline AbstractImage(ColorFormat colorFormat, Type type): _colorFormat(colorFormat), _type(type) {}
inline AbstractImage(Components components, ComponentType type): _components(components), _type(type) {}
/** @brief Destructor */
inline virtual ~AbstractImage() {}
/** @brief Color format */
inline ColorFormat colorFormat() const { return _colorFormat; }
/** @brief Color components */
inline Components components() const { return _components; }
/** @brief Data type */
inline Type type() const { return _type; }
inline ComponentType type() const { return _type; }
protected:
ColorFormat _colorFormat; /**< @brief Color format */
Type _type; /**< @brief Data type per color channel */
Components _components; /**< @brief Color components */
ComponentType _type; /**< @brief Data type */
};
}

14
src/AbstractTexture.h

@ -94,7 +94,7 @@ class MAGNUM_EXPORT AbstractTexture {
/** @{ @name Internal texture formats */
/** @brief Number of components for each value */
/** @brief Color components */
enum class Components {
/**
* Red component only. Green and blue are set to `0`, alpha is set
@ -536,11 +536,11 @@ template<> struct AbstractTexture::DataHelper<1> {
}
template<class T> inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) {
glTexImage1D(static_cast<GLenum>(target), mipLevel, internalFormat, image->dimensions().at(0), 0, static_cast<GLenum>(image->colorFormat()), static_cast<GLenum>(image->type()), image->data());
glTexImage1D(static_cast<GLenum>(target), mipLevel, internalFormat, image->dimensions().at(0), 0, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
}
template<class T> inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 1>& offset, T* image) {
glTexSubImage1D(static_cast<GLenum>(target), mipLevel, offset.at(0), image->dimensions().at(0), static_cast<GLenum>(image->colorFormat()), static_cast<GLenum>(image->type()), image->data());
glTexSubImage1D(static_cast<GLenum>(target), mipLevel, offset.at(0), image->dimensions().at(0), static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
}
};
template<> struct AbstractTexture::DataHelper<2> {
@ -565,11 +565,11 @@ template<> struct AbstractTexture::DataHelper<2> {
}
template<class T> inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) {
glTexImage2D(static_cast<GLenum>(target), mipLevel, internalFormat, image->dimensions().at(0), image->dimensions().at(1), 0, static_cast<GLenum>(image->colorFormat()), static_cast<GLenum>(image->type()), image->data());
glTexImage2D(static_cast<GLenum>(target), mipLevel, internalFormat, image->dimensions().at(0), image->dimensions().at(1), 0, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
}
template<class T> inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 2>& offset, T* image) {
glTexSubImage2D(static_cast<GLenum>(target), mipLevel, offset.at(0), offset.at(1), image->dimensions().at(0), image->dimensions().at(1), static_cast<GLenum>(image->colorFormat()), static_cast<GLenum>(image->type()), image->data());
glTexSubImage2D(static_cast<GLenum>(target), mipLevel, offset.at(0), offset.at(1), image->dimensions().at(0), image->dimensions().at(1), static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
}
};
template<> struct AbstractTexture::DataHelper<3> {
@ -587,11 +587,11 @@ template<> struct AbstractTexture::DataHelper<3> {
}
template<class T> inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) {
glTexImage3D(static_cast<GLenum>(target), mipLevel, internalFormat, image->dimensions().at(0), image->dimensions().at(1), image->dimensions().at(2), 0, static_cast<GLenum>(image->colorFormat()), static_cast<GLenum>(image->type()), image->data());
glTexImage3D(static_cast<GLenum>(target), mipLevel, internalFormat, image->dimensions().at(0), image->dimensions().at(1), image->dimensions().at(2), 0, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
}
template<class T> inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 3>& offset, T* image) {
glTexSubImage3D(static_cast<GLenum>(target), mipLevel, offset.at(0), offset.at(1), offset.at(2), image->dimensions().at(0), image->dimensions().at(1), image->dimensions().at(2), static_cast<GLenum>(image->colorFormat()), static_cast<GLenum>(image->type()), image->data());
glTexSubImage3D(static_cast<GLenum>(target), mipLevel, offset.at(0), offset.at(1), offset.at(2), image->dimensions().at(0), image->dimensions().at(1), image->dimensions().at(2), static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
}
};
#endif

25
src/BufferedImage.cpp

@ -1,25 +0,0 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "BufferedImage.h"
namespace Magnum {
void BufferedImage2D::setDataFromFramebuffer(const Math::Vector2<GLint>& offset) {
_buffer.bind(Buffer::Target::PixelPack);
glReadPixels(offset.at(0), offset.at(1), _dimensions.at(0), _dimensions.at(1), static_cast<GLenum>(_colorFormat), static_cast<GLenum>(_type), nullptr);
}
}

78
src/BufferedImage.h

@ -21,6 +21,7 @@
#include "AbstractImage.h"
#include "Buffer.h"
#include "TypeTraits.h"
namespace Magnum {
@ -28,8 +29,7 @@ namespace Magnum {
@brief %Buffered image
Class for storing image data in GPU memory. Can be replaced with Image, which
stores image data in client memory, or for example with Trade::ImageData. See
also BufferedImage2D, which has additional data updating functions.
stores image data in client memory, or for example with Trade::ImageData.
*/
template<size_t imageDimensions> class BufferedImage: public AbstractImage {
public:
@ -37,27 +37,17 @@ template<size_t imageDimensions> class BufferedImage: public AbstractImage {
/**
* @brief Constructor
* @param colorFormat Color format of the data.
* @param type Data type per color channel
* @param components Color components
* @param type Data type
*
* Dimensions and buffer are empty, call setData() to fill the image
* with data.
*/
BufferedImage(ColorFormat colorFormat, Type type): AbstractImage(colorFormat, type), _buffer(Buffer::Target::PixelPack) {}
BufferedImage(Components components, ComponentType type): AbstractImage(components, type), _buffer(Buffer::Target::PixelPack) {}
/** @brief %Image dimensions */
inline Math::Vector<GLsizei, Dimensions> dimensions() const { return _dimensions; }
/**
* @brief Set image dimensions
* @param dimensions %Image dimensions
* @param usage %Image buffer usage
*
* Saves the dimensions and resizes the buffer to be able to hold
* given pixmap size.
*/
void setDimensions(const Math::Vector<GLsizei, Dimensions>& dimensions, Buffer::Usage usage) {
_dimensions = dimensions;
_buffer.setData(Buffer::Target::PixelPack, pixelSize(_colorFormat, _type)*dimensions.product(), nullptr, usage);
}
/**
* @brief Data
*
@ -75,20 +65,35 @@ template<size_t imageDimensions> class BufferedImage: public AbstractImage {
/**
* @brief Set image data
* @param dimensions %Image dimensions
* @param components Color components. Data type is detected
* from passed data array.
* @param data %Image data
* @param usage %Image buffer usage
*
* Updates the image buffer with given data. The data are not deleted
* after filling the buffer. Note that the data must have the right
* size and type of passed data must be the same as data type passed
* in constructor.
* after filling the buffer.
*/
template<class T> void setData(const T* data) {
if(TypeTraits<T>::imageType() != _type) {
Corrade::Utility::Error() << "BufferedImage: Passed data have wrong type";
return;
}
template<class T> inline void setData(const Math::Vector<GLsizei, Dimensions>& dimensions, Components components, const T* data, Buffer::Usage usage) {
setData(dimensions, components, TypeTraits<T>::imageType(), data, usage);
}
_buffer.setSubData(Buffer::Target::PixelPack, 0, pixelSize(_colorFormat, _type)*_dimensions.product(), data);
/**
* @brief Set image data
* @param dimensions %Image dimensions
* @param components Color components
* @param type Data type
* @param data %Image data
* @param usage %Image buffer usage
*
* Updates the image buffer with given data. The data are not deleted
* after filling the buffer.
*/
void setData(const Math::Vector<GLsizei, Dimensions>& dimensions, Components components, ComponentType type, const GLvoid* data, Buffer::Usage usage) {
_components = components;
_type = type;
_dimensions = dimensions;
_buffer.setData(Buffer::Target::PixelPack, pixelSize(_components, _type)*dimensions.product(), data, usage);
}
protected:
@ -100,24 +105,7 @@ template<size_t imageDimensions> class BufferedImage: public AbstractImage {
typedef BufferedImage<1> BufferedImage1D;
/** @brief Two-dimensional buffered image */
class MAGNUM_EXPORT BufferedImage2D: public BufferedImage<2> {
public:
/**
* @brief Constructor
* @param colorFormat Color format of the data.
* @param type Data type per color channel
*/
/* doxygen: @copydoc BufferedImage::BufferedImage doesn't work */
inline BufferedImage2D(ColorFormat colorFormat, Type type): BufferedImage(colorFormat, type) {}
/**
* @brief Set image data from current framebuffer
* @param offset Offset of the pixamp to read
*
* Reads pixmap from given offset with already set dimensions.
*/
void setDataFromFramebuffer(const Math::Vector2<GLint>& offset);
};
typedef BufferedImage<2> BufferedImage2D;
/** @brief Three-dimensional buffered image */
typedef BufferedImage<3> BufferedImage3D;

2
src/CMakeLists.txt

@ -12,9 +12,7 @@ set(Magnum_SRCS
AbstractImage.cpp
AbstractTexture.cpp
AbstractShaderProgram.cpp
BufferedImage.cpp
Camera.cpp
Image.cpp
Framebuffer.cpp
IndexedMesh.cpp
Light.cpp

16
src/Framebuffer.cpp

@ -37,4 +37,20 @@ void Framebuffer::mapForDraw(std::initializer_list<int> colorAttachments) {
delete[] attachments;
}
void Framebuffer::read(const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image) {
char* data = new char[AbstractImage::pixelSize(components, type)*dimensions.product()];
glReadPixels(offset.x(), offset.y(), dimensions.x(), dimensions.y(), static_cast<GLenum>(components), static_cast<GLenum>(type), data);
image->setData(dimensions, components, type, data);
}
void Framebuffer::read(const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage) {
/* If the buffer doesn't have sufficient size, resize it */
/** @todo Explicitly reset also when buffer usage changes */
if(image->dimensions() != dimensions || image->components() != components || image->type() != type)
image->setData(dimensions, components, type, nullptr, usage);
image->buffer()->bind(Buffer::Target::PixelPack);
glReadPixels(offset.x(), offset.y(), dimensions.x(), dimensions.y(), static_cast<GLenum>(components), static_cast<GLenum>(type), nullptr);
}
}

23
src/Framebuffer.h

@ -19,7 +19,9 @@
* @brief Class Magnum::Framebuffer
*/
#include "BufferedImage.h"
#include "CubeMapTexture.h"
#include "Image.h"
#include "Renderbuffer.h"
namespace Magnum {
@ -167,6 +169,27 @@ class MAGNUM_EXPORT Framebuffer {
glBlitFramebuffer(bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), static_cast<GLbitfield>(blitMask), static_cast<GLenum>(AbstractTexture::Filter::NearestNeighbor));
}
/**
* @brief Read block of pixels from framebuffer to image
* @param offset Offset in the framebuffer
* @param dimensions Image dimensions
* @param components Color components
* @param type Data type
* @param image %Image where to put the data
*/
static void read(const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image);
/**
* @brief Read block of pixels from framebuffer to buffered image
* @param offset Offset in the framebuffer
* @param dimensions Image dimensions
* @param components Color components
* @param type Data type
* @param image Buffered image where to put the data
* @param usage %Buffer usage
*/
static void read(const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage);
/**
* @brief Constructor
*

24
src/Image.cpp

@ -1,24 +0,0 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "Image.h"
namespace Magnum {
void Image2D::setDataFromFramebuffer(const Math::Vector2<GLint>& offset) {
glReadPixels(offset.at(0), offset.at(1), _dimensions.at(0), _dimensions.at(1), static_cast<GLenum>(_colorFormat), static_cast<GLenum>(_type), _data);
}
}

95
src/Image.h

@ -20,6 +20,7 @@
*/
#include "AbstractImage.h"
#include "TypeTraits.h"
namespace Magnum {
@ -28,8 +29,7 @@ namespace Magnum {
Class for storing image data on client memory. Can be replaced with
BufferedImage, which stores image data in GPU memory, or for example with
Trade::ImageData. See also Image2D, which has additional data updating
functions.
Trade::ImageData.
*/
template<size_t imageDimensions> class Image: public AbstractImage {
public:
@ -37,25 +37,37 @@ template<size_t imageDimensions> class Image: public AbstractImage {
/**
* @brief Constructor
* @param colorFormat Color format of passed data. Data size
* per color channel is detected from format of passed data array.
* @param dimensions %Image dimensions
* @param components Color components. Data type is detected
* from passed data array.
* @param data %Image data with proper size
*
* Note that the image data are not copied on construction, but they
* are deleted on class destruction.
*/
template<class T> inline Image(ColorFormat colorFormat, const Math::Vector<GLsizei, Dimensions>& dimensions, T* data): AbstractImage(colorFormat, TypeTraits<T>::imageType()), _dimensions(dimensions), _data(data) {}
template<class T> inline Image(const Math::Vector<GLsizei, Dimensions>& dimensions, Components components, T* data): AbstractImage(components, TypeTraits<T>::imageType()), _dimensions(dimensions), _data(data) {}
/**
* @brief Constructor
* @param colorFormat Color format of passed data
* @param type Data type per color channel
* @param dimensions %Image dimensions
* @param components Color components
* @param type Data type
* @param data %Image data
*
* Note that the image data are not copied on construction, but they
* are deleted on class destruction.
*/
inline Image(const Math::Vector<GLsizei, Dimensions>& dimensions, Components components, ComponentType type, GLvoid* data): AbstractImage(components, type), _dimensions(dimensions), _data(reinterpret_cast<char*>(data)) {}
/**
* @brief Constructor
* @param components Color components
* @param type Data type
*
* Dimensions and data pointer are set to zero, call
* setDimensions() and setData() to fill the image with data.
* Dimensions and data pointer are set to zero, call setData() to fill
* the image with data.
*/
inline Image(ColorFormat colorFormat, Type type): AbstractImage(colorFormat, type), _data(nullptr) {}
inline Image(Components components, ComponentType type): AbstractImage(components, type), _data(nullptr) {}
/** @brief Destructor */
inline ~Image() { delete[] _data; }
@ -63,38 +75,39 @@ template<size_t imageDimensions> class Image: public AbstractImage {
/** @brief %Image dimensions */
inline const Math::Vector<GLsizei, Dimensions>& dimensions() const { return _dimensions; }
/** @brief Pointer to raw data */
inline const void* data() const { return _data; }
/**
* @brief Set image dimensions
* @param dimensions %Image dimensions
* @brief Set image data
* @param dimensions %Image dimensions
* @param components Color components. Data type is detected
* from passed data array.
* @param data %Image data
*
* Saves the dimensions and deletes the internal data array.
* Deletes previous data and replaces them with new. Note that the
* data are not copied, but they are deleted on destruction.
*/
inline void setDimensions(const Math::Vector2<GLsizei>& dimensions) {
_dimensions = dimensions;
delete _data;
_data = 0;
template<class T> inline void setData(const Math::Vector<GLsizei, Dimensions>& dimensions, Components components, T* data) {
setData(dimensions, components, TypeTraits<T>::imageType(), data);
}
/** @brief Pointer to raw data */
inline const void* data() const { return _data; }
/**
* @brief Set image data
* @param dimensions %Image dimensions
* @param components Color components
* @param type Data type
* @param data %Image data
*
* Deletes previous data and replaces them with new. Note that the
* data are not copied, but they are deleted on destruction. Also the
* type of passed data must be the same as data type passed in
* constructor.
* data are not copied, but they are deleted on destruction.
*/
template<class T> void setData(const T* data) {
if(TypeTraits<T>::imageType() != _type) {
Corrade::Utility::Error() << "Image: Passed data have wrong type";
return;
}
void setData(const Math::Vector<GLsizei, Dimensions>& dimensions, Components components, ComponentType type, GLvoid* data) {
delete _data;
_data = reinterpret_cast<const char*>(data);
_components = components;
_type = type;
_dimensions = dimensions;
_data = reinterpret_cast<char*>(data);
}
protected:
@ -106,27 +119,7 @@ template<size_t imageDimensions> class Image: public AbstractImage {
typedef Image<1> Image1D;
/** @brief Two-dimensional image */
class MAGNUM_EXPORT Image2D: public Image<2> {
public:
/**
* @brief Constructor
* @param colorFormat Color format of passed data
* @param type Data type per color channel
*
* Dimensions and data pointer are are set to zero, call
* setDimensions() and setData() to fill the image with data.
*/
/* doxygen: @copydoc Image::Image doesn't work */
inline Image2D(ColorFormat colorFormat, Type type): Image(colorFormat, type) {}
/**
* @brief Set image data from current framebuffer
* @param offset Offset of the pixamp to read
*
* Reads pixmap from given offset with already set dimensions.
*/
void setDataFromFramebuffer(const Math::Vector2<GLint>& offset);
};
typedef Image<2> Image2D;
/** @brief Three-dimensional image */
typedef Image<3> Image3D;

25
src/Trade/ImageData.h

@ -20,6 +20,7 @@
*/
#include "AbstractImage.h"
#include "TypeTraits.h"
namespace Magnum { namespace Trade {
@ -35,15 +36,27 @@ template<size_t imageDimensions> class ImageData: public AbstractImage {
/**
* @brief Constructor
* @param colorFormat Color format of passed data. Data size
* per color channel is detected from format of passed data array.
* @param dimensions %Image dimensions
* @param components Color components. Data type is detected
* from passed data array.
* @param data %Image data
*
* @attention Note that the image data are not copied on construction,
* but they are deleted on class destruction.
* Note that the image data are not copied on construction, but they
* are deleted on class destruction.
*/
template<class T> inline ImageData(ColorFormat colorFormat, const Math::Vector<GLsizei, Dimensions>& dimensions, const T* data): AbstractImage(colorFormat, TypeTraits<T>::imageType()), _dimensions(dimensions), _data(reinterpret_cast<const char*>(data)) {}
template<class T> inline ImageData(const Math::Vector<GLsizei, Dimensions>& dimensions, Components components, T* data): AbstractImage(components, TypeTraits<T>::imageType()), _dimensions(dimensions), _data(reinterpret_cast<char*>(data)) {}
/**
* @brief Constructor
* @param dimensions %Image dimensions
* @param components Color components
* @param type Data type
* @param data %Image data
*
* Note that the image data are not copied on construction, but they
* are deleted on class destruction.
*/
inline ImageData(const Math::Vector<GLsizei, Dimensions>& dimensions, Components components, ComponentType type, GLvoid* data): AbstractImage(components, type), _dimensions(dimensions), _data(reinterpret_cast<char*>(data)) {}
/** @brief Destructor */
inline virtual ~ImageData() { delete[] _data; }
@ -56,7 +69,7 @@ template<size_t imageDimensions> class ImageData: public AbstractImage {
private:
Math::Vector<GLsizei, Dimensions> _dimensions;
const char* _data;
char* _data;
};
/** @brief One-dimensional image */

18
src/TypeTraits.h

@ -19,7 +19,7 @@
* @brief Enum Magnum::Type, class Magnum::TypeOf, Magnum::TypeInfo, Magnum::TypeTraits
*/
#include "Magnum.h"
#include "AbstractImage.h"
namespace Magnum {
@ -56,7 +56,7 @@ template<class T> struct TypeTraits: public Math::TypeTraits<T> {
* GLubyte. This function is not present for types unusable for image data,
* like GLdouble and Matrix3.
*/
constexpr inline static Type imageType();
constexpr inline static AbstractImage::ComponentType imageType();
/**
* @brief Size of plain OpenGL type
@ -149,7 +149,7 @@ template<> struct TypeOf<Type::Double> { typedef GLdouble Type; };
template<> struct TypeTraits<GLubyte>: public Math::TypeTraits<unsigned char> {
inline constexpr static Type type() { return Type::UnsignedByte; }
inline constexpr static Type indexType() { return Type::UnsignedByte; }
inline constexpr static Type imageType() { return Type::UnsignedByte; }
inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::UnsignedByte; }
inline constexpr static size_t size() { return sizeof(GLubyte); }
inline constexpr static size_t count() { return 1; }
};
@ -157,7 +157,7 @@ template<> struct TypeTraits<GLubyte>: public Math::TypeTraits<unsigned char> {
template<> struct TypeTraits<GLbyte>: public Math::TypeTraits<char> {
inline constexpr static Type type() { return Type::Byte; }
/* Can not be used for indices */
inline constexpr static Type imageType() { return Type::Byte; }
inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::Byte; }
inline constexpr static size_t size() { return sizeof(GLbyte); }
inline constexpr static size_t count() { return 1; }
};
@ -165,7 +165,7 @@ template<> struct TypeTraits<GLbyte>: public Math::TypeTraits<char> {
template<> struct TypeTraits<GLushort>: public Math::TypeTraits<unsigned short> {
inline constexpr static Type type() { return Type::UnsignedShort; }
inline constexpr static Type indexType() { return Type::UnsignedShort; }
inline constexpr static Type imageType() { return Type::UnsignedShort; }
inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::UnsignedShort; }
inline constexpr static size_t size() { return sizeof(GLushort); }
inline constexpr static size_t count() { return 1; }
};
@ -173,7 +173,7 @@ template<> struct TypeTraits<GLushort>: public Math::TypeTraits<unsigned short>
template<> struct TypeTraits<GLshort>: public Math::TypeTraits<short> {
inline constexpr static Type type() { return Type::Short; }
/* Can not be used for indices */
inline constexpr static Type imageType() { return Type::Short; }
inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::Short; }
inline constexpr static size_t size() { return sizeof(GLshort); }
inline constexpr static size_t count() { return 1; }
};
@ -181,7 +181,7 @@ template<> struct TypeTraits<GLshort>: public Math::TypeTraits<short> {
template<> struct TypeTraits<GLuint>: public Math::TypeTraits<unsigned int> {
inline constexpr static Type type() { return Type::UnsignedInt; }
inline constexpr static Type indexType() { return Type::UnsignedInt; }
inline constexpr static Type imageType() { return Type::UnsignedInt; }
inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::UnsignedInt; }
inline constexpr static size_t size() { return sizeof(GLuint); }
inline constexpr static size_t count() { return 1; }
};
@ -189,7 +189,7 @@ template<> struct TypeTraits<GLuint>: public Math::TypeTraits<unsigned int> {
template<> struct TypeTraits<GLint>: public Math::TypeTraits<int> {
inline constexpr static Type type() { return Type::Int; }
/* Can not be used for indices */
inline constexpr static Type imageType() { return Type::Int; }
inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::Int; }
inline constexpr static size_t size() { return sizeof(GLint); }
inline constexpr static size_t count() { return 1; }
};
@ -197,7 +197,7 @@ template<> struct TypeTraits<GLint>: public Math::TypeTraits<int> {
template<> struct TypeTraits<GLfloat>: public Math::TypeTraits<float> {
inline constexpr static Type type() { return Type::Float; }
/* Can not be used for indices */
inline constexpr static Type imageType() { return Type::Float; }
inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::Float; }
inline constexpr static size_t size() { return sizeof(GLfloat); }
inline constexpr static size_t count() { return 1; }
};

Loading…
Cancel
Save