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.
pull/279/head
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 "AbstractImage.h"
#include "TypeTraits.h"
namespace Magnum { namespace Magnum {
size_t AbstractImage::pixelSize(ColorFormat format, Type type) { size_t AbstractImage::pixelSize(Components format, ComponentType type) {
size_t size = TypeInfo::sizeOf(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) { switch(format) {
case ColorFormat::Red: case Components::Red:
return 1*size; return 1*size;
case ColorFormat::RedGreen: case Components::RedGreen:
return 2*size; return 2*size;
case ColorFormat::RGB: case Components::RGB:
case ColorFormat::BGR: case Components::BGR:
return 3*size; return 3*size;
case ColorFormat::RGBA: case Components::RGBA:
case ColorFormat::BGRA: case Components::BGRA:
return 4*size; return 4*size;
default: default:
return 0; return 0;

177
src/AbstractImage.h

@ -20,7 +20,6 @@
*/ */
#include "Magnum.h" #include "Magnum.h"
#include "TypeTraits.h"
namespace Magnum { namespace Magnum {
@ -36,42 +35,182 @@ class AbstractImage {
AbstractImage& operator=(AbstractImage&& other) = delete; AbstractImage& operator=(AbstractImage&& other) = delete;
public: public:
/** @brief Color format */ /**
enum class ColorFormat: GLenum { * @{ @name Image formats
Red = GL_RED, /**< One-component (red channel) */ *
RedGreen = GL_RG, /**< Two-component (red and green channel) */ * Note that some formats can be used only for framebuffer reading
RGB = GL_RGB, /**< Three-component (RGB) */ * (using Framebuffer::read()) and some only for texture data (using
RGBA = GL_RGBA, /**< Four-component (RGBA) */ * Texture::setData() and others).
BGR = GL_BGR, /**< Three-component (BGR) */ */
BGRA = GL_BGRA /**< Four-component (BGRA) */
/** @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) * @brief Pixel size (in bytes)
* @param format Color format * @param components Color components
* @param type Data type per color channel * @param type Data type
*/ */
static size_t pixelSize(ColorFormat format, Type type); static size_t pixelSize(Components components, ComponentType type);
/** /**
* @brief Constructor * @brief Constructor
* @param colorFormat Color format of passed data * @param components Color components of passed data
* @param type %Image data type * @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 */ /** @brief Destructor */
inline virtual ~AbstractImage() {} inline virtual ~AbstractImage() {}
/** @brief Color format */ /** @brief Color components */
inline ColorFormat colorFormat() const { return _colorFormat; } inline Components components() const { return _components; }
/** @brief Data type */ /** @brief Data type */
inline Type type() const { return _type; } inline ComponentType type() const { return _type; }
protected: protected:
ColorFormat _colorFormat; /**< @brief Color format */ Components _components; /**< @brief Color components */
Type _type; /**< @brief Data type per color channel */ ComponentType _type; /**< @brief Data type */
}; };
} }

14
src/AbstractTexture.h

@ -94,7 +94,7 @@ class MAGNUM_EXPORT AbstractTexture {
/** @{ @name Internal texture formats */ /** @{ @name Internal texture formats */
/** @brief Number of components for each value */ /** @brief Color components */
enum class Components { enum class Components {
/** /**
* Red component only. Green and blue are set to `0`, alpha is set * 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) { 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) { 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> { 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) { 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) { 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> { 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) { 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) { 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 #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 "AbstractImage.h"
#include "Buffer.h" #include "Buffer.h"
#include "TypeTraits.h"
namespace Magnum { namespace Magnum {
@ -28,8 +29,7 @@ namespace Magnum {
@brief %Buffered image @brief %Buffered image
Class for storing image data in GPU memory. Can be replaced with Image, which 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 stores image data in client memory, or for example with Trade::ImageData.
also BufferedImage2D, which has additional data updating functions.
*/ */
template<size_t imageDimensions> class BufferedImage: public AbstractImage { template<size_t imageDimensions> class BufferedImage: public AbstractImage {
public: public:
@ -37,27 +37,17 @@ template<size_t imageDimensions> class BufferedImage: public AbstractImage {
/** /**
* @brief Constructor * @brief Constructor
* @param colorFormat Color format of the data. * @param components Color components
* @param type Data type per color channel * @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 */ /** @brief %Image dimensions */
inline Math::Vector<GLsizei, Dimensions> dimensions() const { return _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 * @brief Data
* *
@ -75,20 +65,35 @@ template<size_t imageDimensions> class BufferedImage: public AbstractImage {
/** /**
* @brief Set image data * @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 data %Image data
* @param usage %Image buffer usage
* *
* Updates the image buffer with given data. The data are not deleted * Updates the image buffer with given data. The data are not deleted
* after filling the buffer. Note that the data must have the right * after filling the buffer.
* size and type of passed data must be the same as data type passed
* in constructor.
*/ */
template<class T> void setData(const T* data) { template<class T> inline void setData(const Math::Vector<GLsizei, Dimensions>& dimensions, Components components, const T* data, Buffer::Usage usage) {
if(TypeTraits<T>::imageType() != _type) { setData(dimensions, components, TypeTraits<T>::imageType(), data, usage);
Corrade::Utility::Error() << "BufferedImage: Passed data have wrong type"; }
return;
}
_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: protected:
@ -100,24 +105,7 @@ template<size_t imageDimensions> class BufferedImage: public AbstractImage {
typedef BufferedImage<1> BufferedImage1D; typedef BufferedImage<1> BufferedImage1D;
/** @brief Two-dimensional buffered image */ /** @brief Two-dimensional buffered image */
class MAGNUM_EXPORT BufferedImage2D: public BufferedImage<2> { typedef BufferedImage<2> BufferedImage2D;
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);
};
/** @brief Three-dimensional buffered image */ /** @brief Three-dimensional buffered image */
typedef BufferedImage<3> BufferedImage3D; typedef BufferedImage<3> BufferedImage3D;

2
src/CMakeLists.txt

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

16
src/Framebuffer.cpp

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

25
src/Trade/ImageData.h

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

18
src/TypeTraits.h

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

Loading…
Cancel
Save