Browse Source

Added classes Image and BufferedImage.

These classes are meant to be used in the same texture updating
functions as Trade::ImageData due to static polymorphism. In addition to
Trade::ImageData, which is read-only, these classes support updating the
dimensions and data. Image2D and ImageBuffer2D can update the data also
from framebuffer.
pull/279/head
Vladimír Vondruš 14 years ago
parent
commit
6504aecf0c
  1. 48
      src/AbstractTexture.h
  2. 25
      src/BufferedImage.cpp
  3. 136
      src/BufferedImage.h
  4. 2
      src/CMakeLists.txt
  5. 33
      src/CubeMapTexture.h
  6. 24
      src/Image.cpp
  7. 141
      src/Image.h
  8. 14
      src/Texture.h
  9. 8
      src/Trade/ImageData.h

48
src/AbstractTexture.h

@ -271,6 +271,18 @@ class MAGNUM_EXPORT AbstractTexture {
*/ */
inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector<GLsizei, textureDimensions>& dimensions, ColorFormat colorFormat, Type type, const void* data); inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector<GLsizei, textureDimensions>& dimensions, ColorFormat colorFormat, Type type, const void* data);
/**
* @brief Set texture data from image
* @param target %Target
* @param mipLevel Mip level
* @param internalFormat Internal texture format
* @param image Image, BufferedImage or for example
* Trade::ImageData of the same dimension count
*
* Calls set() with image data.
*/
template<class T> inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image);
/** /**
* @brief Set texture subdata * @brief Set texture subdata
* @param target %Target * @param target %Target
@ -285,6 +297,18 @@ class MAGNUM_EXPORT AbstractTexture {
* depending on dimension count. * depending on dimension count.
*/ */
inline static void setSub(SubTarget target, GLint mipLevel, const Math::Vector<GLint, textureDimensions>& offset, const Math::Vector<GLsizei, textureDimensions>& dimensions, ColorFormat colorFormat, Type type, const void* data); inline static void setSub(SubTarget target, GLint mipLevel, const Math::Vector<GLint, textureDimensions>& offset, const Math::Vector<GLsizei, textureDimensions>& dimensions, ColorFormat colorFormat, Type type, const void* data);
/**
* @brief Set texture subdata from image
* @param target %Target
* @param mipLevel Mip level
* @param offset Offset where to put data in the texture
* @param image Image, BufferedImage or for example
* Trade::ImageData of the same dimension count
*
* Calls setSub() with image data.
*/
template<class T> inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, textureDimensions>& offset, T* image);
#endif #endif
}; };
@ -310,9 +334,17 @@ template<> struct AbstractTexture::DataHelper<1> {
glTexImage1D(static_cast<GLenum>(target), mipLevel, static_cast<GLint>(internalFormat), dimensions.at(0), 0, static_cast<GLenum>(colorFormat), static_cast<GLenum>(type), data); glTexImage1D(static_cast<GLenum>(target), mipLevel, static_cast<GLint>(internalFormat), dimensions.at(0), 0, static_cast<GLenum>(colorFormat), static_cast<GLenum>(type), data);
} }
template<class T> inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) {
set(target, mipLevel, internalFormat, image->dimensions(), image->colorFormat(), image->type(), image->data());
}
inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 1>& offset, const Math::Vector<GLsizei, 1>& dimensions, ColorFormat colorFormat, Type type, const void* data) { inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 1>& offset, const Math::Vector<GLsizei, 1>& dimensions, ColorFormat colorFormat, Type type, const void* data) {
glTexSubImage1D(static_cast<GLenum>(target), mipLevel, offset.at(0), dimensions.at(0), static_cast<GLenum>(colorFormat), static_cast<GLenum>(type), data); glTexSubImage1D(static_cast<GLenum>(target), mipLevel, offset.at(0), dimensions.at(0), static_cast<GLenum>(colorFormat), static_cast<GLenum>(type), data);
} }
template<class T> inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 1>& offset, T* image) {
setSub(target, mipLevel, offset, image->dimensions(), image->colorFormat(), image->type(), image->data());
}
}; };
template<> struct AbstractTexture::DataHelper<2> { template<> struct AbstractTexture::DataHelper<2> {
enum class Target: GLenum { enum class Target: GLenum {
@ -339,9 +371,17 @@ template<> struct AbstractTexture::DataHelper<2> {
glTexImage2D(static_cast<GLenum>(target), mipLevel, static_cast<GLint>(internalFormat), dimensions.at(0), dimensions.at(1), 0, static_cast<GLenum>(colorFormat), static_cast<GLenum>(type), data); glTexImage2D(static_cast<GLenum>(target), mipLevel, static_cast<GLint>(internalFormat), dimensions.at(0), dimensions.at(1), 0, static_cast<GLenum>(colorFormat), static_cast<GLenum>(type), data);
} }
template<class T> inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) {
set(target, mipLevel, internalFormat, image->dimensions(), image->colorFormat(), image->type(), image->data());
}
inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 2>& offset, const Math::Vector<GLsizei, 2>& dimensions, ColorFormat colorFormat, Type type, const void* data) { inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 2>& offset, const Math::Vector<GLsizei, 2>& dimensions, ColorFormat colorFormat, Type type, const void* data) {
glTexSubImage2D(static_cast<GLenum>(target), mipLevel, offset.at(0), offset.at(1), dimensions.at(0), dimensions.at(1), static_cast<GLenum>(colorFormat), static_cast<GLenum>(type), data); glTexSubImage2D(static_cast<GLenum>(target), mipLevel, offset.at(0), offset.at(1), dimensions.at(0), dimensions.at(1), static_cast<GLenum>(colorFormat), static_cast<GLenum>(type), data);
} }
template<class T> inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 2>& offset, T* image) {
setSub(target, mipLevel, offset, image->dimensions(), image->colorFormat(), image->type(), image->data());
}
}; };
template<> struct AbstractTexture::DataHelper<3> { template<> struct AbstractTexture::DataHelper<3> {
enum class Target: GLenum { enum class Target: GLenum {
@ -361,9 +401,17 @@ template<> struct AbstractTexture::DataHelper<3> {
glTexImage3D(static_cast<GLenum>(target), mipLevel, static_cast<GLint>(internalFormat), dimensions.at(0), dimensions.at(1), dimensions.at(2), 0, static_cast<GLenum>(colorFormat), static_cast<GLenum>(type), data); glTexImage3D(static_cast<GLenum>(target), mipLevel, static_cast<GLint>(internalFormat), dimensions.at(0), dimensions.at(1), dimensions.at(2), 0, static_cast<GLenum>(colorFormat), static_cast<GLenum>(type), data);
} }
template<class T> inline static void set(Target target, GLint mipLevel, InternalFormat internalFormat, T* image) {
set(target, mipLevel, internalFormat, image->dimensions(), image->colorFormat(), image->type(), image->data());
}
inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 3>& offset, const Math::Vector<GLsizei, 3>& dimensions, ColorFormat colorFormat, Type type, const void* data) { inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 3>& offset, const Math::Vector<GLsizei, 3>& dimensions, ColorFormat colorFormat, Type type, const void* data) {
glTexSubImage3D(static_cast<GLenum>(target), mipLevel, offset.at(0), offset.at(1), offset.at(2), dimensions.at(0), dimensions.at(1), dimensions.at(2), static_cast<GLenum>(colorFormat), static_cast<GLenum>(type), data); glTexSubImage3D(static_cast<GLenum>(target), mipLevel, offset.at(0), offset.at(1), offset.at(2), dimensions.at(0), dimensions.at(1), dimensions.at(2), static_cast<GLenum>(colorFormat), static_cast<GLenum>(type), data);
} }
template<class T> inline static void setSub(Target target, GLint mipLevel, const Math::Vector<GLint, 3>& offset, T* image) {
setSub(target, mipLevel, offset, image->dimensions(), image->colorFormat(), image->type(), image->data());
}
}; };
#endif #endif

25
src/BufferedImage.cpp

@ -0,0 +1,25 @@
/*
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);
}
}

136
src/BufferedImage.h

@ -0,0 +1,136 @@
#ifndef Magnum_BufferedImage_h
#define Magnum_BufferedImage_h
/*
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.
*/
/** @file
* @brief Class Magnum::BufferedImage
*/
#include "AbstractTexture.h"
#include "Buffer.h"
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.
*/
template<size_t imageDimensions> class BufferedImage {
BufferedImage(const BufferedImage<imageDimensions>& other) = delete;
BufferedImage(BufferedImage<imageDimensions>&& other) = delete;
BufferedImage& operator=(const BufferedImage<imageDimensions>& other) = delete;
BufferedImage& operator=(BufferedImage<imageDimensions>&& other) = delete;
public:
const static size_t Dimensions = imageDimensions; /**< @brief Image dimension count */
/**
* @brief Constructor
* @param colorFormat Color format of the data.
* @param type Data type per color channel
*/
BufferedImage(AbstractTexture::ColorFormat colorFormat, Type type): _colorFormat(colorFormat), _type(type), _buffer(Buffer::Target::PixelPack) {}
inline virtual ~BufferedImage() {}
/** @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;
size_t textureSize = AbstractTexture::pixelSize(AbstractTexture::ColorFormat::RGB, Type::UnsignedByte)*dimensions.product();
_buffer.setData(Buffer::Target::PixelPack, textureSize, nullptr, usage);
}
/** @brief Color format */
inline AbstractTexture::ColorFormat colorFormat() const { return _colorFormat; }
/** @brief Data type */
inline Type type() const { return _type; }
/**
* @brief Data
*
* Binds the buffer to @ref Buffer::Target::PixelUnpack "pixel unpack
* target" and returns nullptr, so it can be used for texture updating
* functions the same way as Image::data().
*/
void* data() {
_buffer.bind(Buffer::Target::PixelUnpack);
return nullptr;
}
/**
* @brief Set image data
* @param data %Image data
*
* 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.
*/
template<class T> void setData(const T* data) {
if(TypeTraits<typename TypeTraits<T>::TextureType>::glType() != _type) {
Corrade::Utility::Error() << "BufferedImage: Passed data have type" << TypeTraits<typename TypeTraits<T>::TextureType>::glType() << "but it should be" << _type;
return;
}
size_t textureSize = AbstractTexture::pixelSize(AbstractTexture::ColorFormat::RGB, Type::UnsignedByte)*dimensions.product();
_buffer.setSubData(Buffer::Target::PixelPack, 0, textureSize, data);
}
protected:
AbstractTexture::ColorFormat _colorFormat; /**< @brief Color format */
Type _type; /**< @brief Data type per color channel */
Math::Vector<GLsizei, Dimensions> _dimensions; /**< @brief %Image dimensions */
Buffer _buffer; /**< @brief %Image buffer */
};
/** @brief One-dimensional buffered image */
typedef BufferedImage<1> BufferedImage1D;
/** @brief Two-dimensional buffered image */
class BufferedImage2D: public BufferedImage<2> {
public:
/** @copydoc BufferedImage::BufferedImage */
inline BufferedImage2D(AbstractTexture::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 */
typedef BufferedImage<3> BufferedImage3D;
}
#endif

2
src/CMakeLists.txt

@ -11,7 +11,9 @@ set(Magnum_SRCS
Object.cpp Object.cpp
AbstractTexture.cpp AbstractTexture.cpp
AbstractShaderProgram.cpp AbstractShaderProgram.cpp
BufferedImage.cpp
Camera.cpp Camera.cpp
Image.cpp
IndexedMesh.cpp IndexedMesh.cpp
Light.cpp Light.cpp
Mesh.cpp Mesh.cpp

33
src/CubeMapTexture.h

@ -65,24 +65,26 @@ class CubeMapTexture: public Texture2D {
inline CubeMapTexture(GLint layer = 0): Texture(layer, Target::CubeMap) {} inline CubeMapTexture(GLint layer = 0): Texture(layer, Target::CubeMap) {}
template<class T> inline void setData(GLint mipLevel, InternalFormat internalFormat, const Math::Vector<GLsizei, Dimensions>& _dimensions, ColorFormat colorFormat, const T* data) = delete; template<class T> inline void setData(GLint mipLevel, InternalFormat internalFormat, const Math::Vector<GLsizei, Dimensions>& _dimensions, ColorFormat colorFormat, const T* data) = delete;
void setData(GLint mipLevel, InternalFormat internalFormat, const Trade::ImageData<Dimensions>* image) = delete; template<class T> void setData(GLint mipLevel, InternalFormat internalFormat, T* image) = delete;
template<class T> inline void setSubData(GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, const Math::Vector<GLsizei, Dimensions>& _dimensions, ColorFormat colorFormat, const T* data) = delete; template<class T> inline void setSubData(GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, const Math::Vector<GLsizei, Dimensions>& _dimensions, ColorFormat colorFormat, const T* data) = delete;
void setSubData(GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, const Trade::ImageData<Dimensions>* image) = delete; template<class T> void setSubData(GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, T* image) = delete;
/** /**
* @copydoc Texture::setData(GLint, InternalFormat, const Math::Vector<GLsizei, Dimensions>&, ColorFormat, const T*) * @copydoc Texture::setData(GLint, InternalFormat, const Math::Vector<GLsizei, Dimensions>&, ColorFormat, const T*)
* @param coordinate Coordinate * @param coordinate Coordinate
*/ */
template<class T> inline void setData(Coordinate coordinate, GLint mipLevel, InternalFormat internalFormat, const Math::Vector<GLsizei, Dimensions>& _dimensions, ColorFormat colorFormat, const T* data) { template<class T> inline void setData(Coordinate coordinate, GLint mipLevel, InternalFormat internalFormat, const Math::Vector<GLsizei, Dimensions>& _dimensions, ColorFormat colorFormat, const T* data) {
setData(coordinate, mipLevel, internalFormat, _dimensions, colorFormat, TypeTraits<typename TypeTraits<T>::TextureType>::glType(), data); bind();
DataHelper<Dimensions>::set(static_cast<Target>(coordinate), mipLevel, internalFormat, _dimensions, colorFormat, TypeTraits<typename TypeTraits<T>::TextureType>::glType(), data);
} }
/** /**
* @copydetails Texture::setData(GLint, InternalFormat, const Trade::ImageData<Dimensions>*) * @copydetails Texture::setData(GLint, InternalFormat, T*)
* @param coordinate Coordinate * @param coordinate Coordinate
*/ */
inline void setData(Coordinate coordinate, GLint mipLevel, InternalFormat internalFormat, const Trade::ImageData<Dimensions>* image) { template<class T> inline void setData(Coordinate coordinate, GLint mipLevel, InternalFormat internalFormat, T* image) {
setData(coordinate, mipLevel, internalFormat, image->dimensions(), image->colorFormat(), image->type(), image->data()); bind();
DataHelper<Dimensions>::set(static_cast<Target>(coordinate), mipLevel, internalFormat, image);
} }
/** /**
@ -90,26 +92,17 @@ class CubeMapTexture: public Texture2D {
* @param coordinate Coordinate * @param coordinate Coordinate
*/ */
template<class T> inline void setSubData(Coordinate coordinate, GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, const Math::Vector<GLsizei, Dimensions>& _dimensions, ColorFormat colorFormat, const T* data) { template<class T> inline void setSubData(Coordinate coordinate, GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, const Math::Vector<GLsizei, Dimensions>& _dimensions, ColorFormat colorFormat, const T* data) {
setSubData(coordinate, mipLevel, offset, _dimensions, colorFormat, TypeTraits<typename TypeTraits<T>::TextureType>::glType(), data); bind();
DataHelper<Dimensions>::setSub(static_cast<Target>(coordinate), mipLevel, offset, _dimensions, colorFormat, TypeTraits<typename TypeTraits<T>::TextureType>::glType(), data);
} }
/** /**
* @copydoc Texture::setSubData(GLint, const Math::Vector<GLint, Dimensions>&, const Trade::ImageData<Dimensions>*) * @copydoc Texture::setSubData(GLint, const Math::Vector<GLint, Dimensions>&, T*)
* @param coordinate Coordinate * @param coordinate Coordinate
*/ */
inline void setSubData(Coordinate coordinate, GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, const Trade::ImageData<Dimensions>* image) { template<class T> inline void setSubData(Coordinate coordinate, GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, const T* image) {
setSubData(coordinate, mipLevel, offset, image->dimensions(), image->colorFormat(), image->type(), image->data());
}
private:
inline void setData(Coordinate coordinate, GLint mipLevel, InternalFormat internalFormat, const Math::Vector<GLsizei, Dimensions>& _dimensions, ColorFormat colorFormat, Type type, const void* data) {
bind();
DataHelper<Dimensions>::set(static_cast<Target>(coordinate), mipLevel, internalFormat, _dimensions, colorFormat, type, data);
}
inline void setSubData(Coordinate coordinate, GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, const Math::Vector<GLsizei, Dimensions>& dimensions, ColorFormat colorFormat, Type type, const void* data) {
bind(); bind();
DataHelper<Dimensions>::setSub(static_cast<Target>(coordinate), mipLevel, offset, dimensions, colorFormat, type, data); DataHelper<Dimensions>::setSub(static_cast<Target>(coordinate), mipLevel, offset, image);
} }
}; };

24
src/Image.cpp

@ -0,0 +1,24 @@
/*
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);
}
}

141
src/Image.h

@ -0,0 +1,141 @@
#ifndef Magnum_Image_h
#define Magnum_Image_h
/*
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.
*/
/** @file
* @brief Class Magnum::Image
*/
#include "AbstractTexture.h"
namespace Magnum {
/**
@brief %Image
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.
*/
template<size_t imageDimensions> class Image {
Image<imageDimensions>(const Image<imageDimensions>& other) = delete;
Image<imageDimensions>(Image<imageDimensions>&& other) = delete;
Image<imageDimensions>& operator=(const Image<imageDimensions>& other) = delete;
Image<imageDimensions>& operator=(Image<imageDimensions>&& other) = delete;
public:
const static size_t Dimensions = imageDimensions; /**< @brief Image dimension count */
/**
* @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 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(AbstractTexture::ColorFormat colorFormat, const Math::Vector<GLsizei, Dimensions>& dimensions, T* data): _colorFormat(colorFormat), _type(TypeTraits<typename TypeTraits<T>::TextureType>::glType()), _dimensions(dimensions), _data(data) {}
/**
* @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.
*/
inline Image(AbstractTexture::ColorFormat colorFormat, Type type): _colorFormat(colorFormat), _type(type), _data(nullptr) {}
/** @brief Destructor */
inline virtual ~Image() { delete[] _data; }
/** @brief %Image dimensions */
inline const Math::Vector<GLsizei, Dimensions>& dimensions() const { return _dimensions; }
/**
* @brief Set image dimensions
* @param dimensions %Image dimensions
*
* Saves the dimensions and deletes the internal data array.
*/
inline void setDimensions(const Math::Vector2<GLsizei>& dimensions) {
_dimensions = dimensions;
delete _data;
_data = 0;
}
/** @brief Color format */
inline AbstractTexture::ColorFormat colorFormat() const { return _colorFormat; }
/** @brief Data type */
inline Type type() const { return _type; }
/** @brief Pointer to raw data */
inline const void* data() const { return _data; }
/**
* @brief Set image data
* @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.
*/
template<class T> void setData(const T* data) {
if(TypeTraits<typename TypeTraits<T>::TextureType>::glType() != _type) {
Corrade::Utility::Error() << "Image: Passed data have type" << TypeTraits<typename TypeTraits<T>::TextureType>::glType() << "but it should be" << _type;
return;
}
delete _data;
_data = reinterpret_cast<const char*>(data);
}
protected:
AbstractTexture::ColorFormat _colorFormat; /**< @brief Color format */
Type _type; /**< @brief Data type per color channel */
Math::Vector<GLsizei, Dimensions> _dimensions; /**< @brief %Image dimensions */
char* _data; /**< @brief %Image data */
};
/** @brief One-dimensional image */
typedef Image<1> Image1D;
/** @brief Two-dimensional image */
class Image2D: public Image<2> {
public:
/** @copydoc Image::Image */
inline Image2D(AbstractTexture::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 */
typedef Image<3> Image3D;
}
#endif

14
src/Texture.h

@ -99,14 +99,15 @@ template<size_t dimensions> class Texture: public AbstractTexture {
* @brief Set texture data from image * @brief Set texture data from image
* @param mipLevel Mip level * @param mipLevel Mip level
* @param internalFormat Internal texture format * @param internalFormat Internal texture format
* @param image Image * @param image Image, BufferedImage or for example
* Trade::ImageData of the same dimension count
* *
* Sets texture data from given image. The image is not deleted * Sets texture data from given image. The image is not deleted
* afterwards. * afterwards.
*/ */
inline void setData(GLint mipLevel, InternalFormat internalFormat, const Trade::ImageData<Dimensions>* image) { template<class T> inline void setData(GLint mipLevel, InternalFormat internalFormat, T* image) {
bind(); bind();
DataHelper<Dimensions>::set(target, mipLevel, internalFormat, image->dimensions(), image->colorFormat(), image->type(), image->data()); DataHelper<Dimensions>::set(target, mipLevel, internalFormat, image);
} }
/** /**
@ -130,14 +131,15 @@ template<size_t dimensions> class Texture: public AbstractTexture {
* @brief Set texture subdata from image * @brief Set texture subdata from image
* @param mipLevel Mip level * @param mipLevel Mip level
* @param offset Offset where to put data in the texture * @param offset Offset where to put data in the texture
* @param image Image * @param image Image, BufferedImage or for example
* Trade::ImageData of the same dimension count
* *
* Sets texture subdata from given image. The image is not deleted * Sets texture subdata from given image. The image is not deleted
* afterwards. * afterwards.
*/ */
inline void setSubData(GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, const Trade::ImageData<Dimensions>* image) { template<class T> inline void setSubData(GLint mipLevel, const Math::Vector<GLint, Dimensions>& offset, T* image) {
bind(); bind();
DataHelper<Dimensions>::setSub(target, mipLevel, offset, image->dimensions(), image->colorFormat(), image->type(), image->data()); DataHelper<Dimensions>::setSub(target, mipLevel, offset, image);
} }
private: private:

8
src/Trade/ImageData.h

@ -27,7 +27,7 @@ namespace Magnum { namespace Trade {
@brief %Image @brief %Image
Provides access to image data and additional information about data type and Provides access to image data and additional information about data type and
dimensions. dimensions. Can be used in the same situations as Image and BufferedImage.
*/ */
template<size_t imageDimensions> class ImageData { template<size_t imageDimensions> class ImageData {
ImageData<imageDimensions>(const ImageData<imageDimensions>& other) = delete; ImageData<imageDimensions>(const ImageData<imageDimensions>& other) = delete;
@ -40,15 +40,15 @@ template<size_t imageDimensions> class ImageData {
/** /**
* @brief Constructor * @brief Constructor
* @param dimensions %Image dimensions
* @param colorFormat Color format of passed data. Data size * @param colorFormat Color format of passed data. Data size
* per color channel is detected from format of passed data array. * per color channel is detected from format of passed data array.
* @param dimensions %Image dimensions
* @param data %Image data * @param data %Image data
* *
* @attention Note that the image data are not copied on construction, * @attention Note that the image data are not copied on construction,
* but they are deleted on class destruction. * but they are deleted on class destruction.
*/ */
template<class T> inline ImageData(const Math::Vector<GLsizei, Dimensions>& dimensions, AbstractTexture::ColorFormat colorFormat, const T* data): _dimensions(dimensions), _colorFormat(colorFormat), _type(TypeTraits<typename TypeTraits<T>::TextureType>::glType()), _data(reinterpret_cast<const char*>(data)) {} template<class T> inline ImageData(AbstractTexture::ColorFormat colorFormat, const Math::Vector<GLsizei, Dimensions>& dimensions, const T* data): _colorFormat(colorFormat), _type(TypeTraits<typename TypeTraits<T>::TextureType>::glType()), _dimensions(dimensions), _data(reinterpret_cast<const char*>(data)) {}
/** @brief Destructor */ /** @brief Destructor */
inline virtual ~ImageData() { delete[] _data; } inline virtual ~ImageData() { delete[] _data; }
@ -66,9 +66,9 @@ template<size_t imageDimensions> class ImageData {
inline const void* data() const { return _data; } inline const void* data() const { return _data; }
private: private:
Math::Vector<GLsizei, Dimensions> _dimensions;
AbstractTexture::ColorFormat _colorFormat; AbstractTexture::ColorFormat _colorFormat;
Type _type; Type _type;
Math::Vector<GLsizei, Dimensions> _dimensions;
const char* _data; const char* _data;
}; };

Loading…
Cancel
Save