Commit 5e424b90 authored by schultezub's avatar schultezub
Browse files

* ImageDataXYZ handles the number of channels

 * added ImageDataGL
 * extended WeaklyTypedPointer and TypeTraits

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@179 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 1088ad2a
......@@ -3,10 +3,12 @@
namespace TUMVis {
const std::string ImageDataDisk::loggerCat_ = "TUMVis.core.datastructures.ImageDataDisk";
ImageDataDisk::ImageDataDisk(const std::string& url, size_t dimensionality, const tgt::svec3& size, WeaklyTypedPointer::PointerType type, size_t offset /*= 0*/, EndianHelper::Endianness endianness /*= EndianHelper::LITTLE_ENDIAN*/, const tgt::svec3& stride /*= tgt::svec2::zero */)
ImageDataDisk::ImageDataDisk(const std::string& url, size_t dimensionality, const tgt::svec3& size, WeaklyTypedPointer::BaseType type, size_t numChannels, size_t offset /*= 0*/, EndianHelper::Endianness endianness /*= EndianHelper::LITTLE_ENDIAN*/, const tgt::svec3& stride /*= tgt::svec2::zero */)
: ImageData(dimensionality, size)
, _url(url)
, _offset(offset)
, _type(type)
, _numChannels(numChannels)
, _endianess(endianness)
, _stride(stride)
{
......@@ -25,15 +27,15 @@ namespace TUMVis {
return clone();
}
size_t newOffset = _offset + WeaklyTypedPointer::numBytes(_type) * llf.x;
size_t newOffset = _offset + WeaklyTypedPointer::numBytes(_type, _numChannels) * llf.x;
// the stride doesn't change!
tgt::svec3 newStride = (_stride == tgt::svec3::zero) ? getCanonicStride(_size) : _stride;
return new ImageDataDisk(_url, _dimensionality, newSize,_type, newOffset, _endianess, newStride);
return new ImageDataDisk(_url, _dimensionality, newSize, _type, _numChannels, newOffset, _endianess, newStride);
}
TUMVis::WeaklyTypedPointer ImageDataDisk::getImageData() const {
size_t numElements = tgt::hmul(_size);
size_t numBytesPerElement = WeaklyTypedPointer::numBytes(_type);
size_t numBytesPerElement = WeaklyTypedPointer::numBytes(_type, _numChannels);
size_t numBytes = numElements * numBytesPerElement;
// open file and prepare for read
......@@ -42,7 +44,7 @@ namespace TUMVis {
size_t fileSize = static_cast<size_t>(file.tellg());
if (fileSize < numBytes) {
LERROR("File is smaller than expected.");
return WeaklyTypedPointer(_type, 0);
return WeaklyTypedPointer(_type, _numChannels, 0);
}
file.seekg(_offset, std::ios::beg);
......@@ -162,11 +164,11 @@ namespace TUMVis {
}
return WeaklyTypedPointer(_type, static_cast<void*>(data));
return WeaklyTypedPointer(_type, _numChannels, static_cast<void*>(data));
}
else {
LERROR("Could not open file " << _url << " for reading.");
return WeaklyTypedPointer(_type, 0);
return WeaklyTypedPointer(_type, _numChannels, 0);
}
}
......@@ -176,6 +178,6 @@ namespace TUMVis {
}
ImageDataDisk* ImageDataDisk::clone() const {
return new ImageDataDisk(_url, _dimensionality, _size, _type, _offset, _endianess, _stride);
return new ImageDataDisk(_url, _dimensionality, _size, _type, _numChannels, _offset, _endianess, _stride);
}
}
\ No newline at end of file
......@@ -33,9 +33,10 @@ namespace TUMVis {
*/
ImageDataDisk(
const std::string& url,
size_t dimensionality,
size_t dimensionality,
const tgt::svec3& size,
WeaklyTypedPointer::PointerType type,
WeaklyTypedPointer::BaseType type,
size_t numChannels,
size_t offset = 0,
EndianHelper::Endianness endianness = EndianHelper::LITTLE_ENDIAN,
const tgt::svec3& stride = tgt::svec3::zero
......@@ -74,7 +75,8 @@ namespace TUMVis {
std::string _url; ///< path to file with raw data
size_t _offset; ///< offset of first data element in file (in bytes)
WeaklyTypedPointer::PointerType _type; ///< base type of data
WeaklyTypedPointer::BaseType _type; ///< base type of data
size_t _numChannels; ///< number of channels per element
EndianHelper::Endianness _endianess; ///< endianess of data
/**
......
#include "imagedatagl.h"
#include "tgt/assert.h"
#include "tgt/tgt_gl.h"
namespace TUMVis {
const std::string ImageDataGL::loggerCat_ = "TUMVis.core.datastructures.ImageDataGL";
ImageDataGL::ImageDataGL(size_t dimensionality, const tgt::svec3& size, const WeaklyTypedPointer& wtp)
: ImageData(dimensionality, size)
{
createTexture(wtp);
}
ImageDataGL::~ImageDataGL() {
delete _texture;
}
ImageDataGL* ImageDataGL::clone() const {
GLubyte* data = _texture->downloadTextureToBuffer();
WeaklyTypedPointer wtp(WeaklyTypedPointer::baseType(_texture->getDataType()), WeaklyTypedPointer::numChannels(_texture->getFormat()), data);
ImageDataGL* toReturn = new ImageDataGL(_dimensionality, _size, wtp);
delete data;
return toReturn;
}
ImageDataGL* ImageDataGL::getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const {
// TODO: implement
tgtAssert(false, "not yet implemented...");
return 0;
}
void ImageDataGL::createTexture(const WeaklyTypedPointer& wtp) {
tgtAssert(wtp._pointer != 0, "Pointer to image data must not be 0!");
_texture = new tgt::Texture(reinterpret_cast<GLubyte*>(wtp._pointer), _size, wtp.getGlFormat(), wtp.getGlInternalFormat(), wtp.getGlDataType(), tgt::Texture::LINEAR);
switch (_dimensionality) {
case 1:
_texture->setType(GL_TEXTURE_1D);
break;
case 2:
_texture->setType(GL_TEXTURE_2D);
break;
case 3:
_texture->setType(GL_TEXTURE_3D);
break;
default:
tgtAssert(false, "Unsupported dimensionality of image.");
break;
}
_texture->bind();
_texture->uploadTexture();
_texture->setWrapping(tgt::Texture::CLAMP);
// TODO: map signed types
// revoke ownership of local pixel data from the texture
_texture->setPixelData(0);
LGL_ERROR;
}
}
\ No newline at end of file
#ifndef IMAGEDATAGL_H__
#define IMAGEDATAGL_H__
#include "tgt/texture.h"
#include "tgt/vector.h"
#include "core/datastructures/imagedata.h"
#include "core/tools/weaklytypedpointer.h"
namespace TUMVis {
/**
* Stores image data as OpenGL texture.
* Can bei instantiated either by a WeaklyTypedPointer or strongly typed by an ImageDataRAM.
*/
class ImageDataGL : public ImageData {
public:
/**
* Creates a new ImageDataGL representation.
*
* \param dimensionality Dimensionality of data
* \param size Size of this image (number of elements per dimension)
* \param data Pointer to the image data, must not be 0, ImageDataGL does not take ownership of that pointer.
*/
ImageDataGL(size_t dimensionality, const tgt::svec3& size, const WeaklyTypedPointer& wtp);
/**
* Creates a new ImageDataGL representation from ImageDataRAM.
*
* \param dimensionality Dimensionality of data
* \param size Size of this image (number of elements per dimension)
* \param data Pointer to the ImageDataRAM instance, must not be 0, type has to match the template parameters.
* \tparam BASETYPE Base type of image data
* \tparam NUMCHANNELS Number of channels per element
*/
template<typename BASETYPE, size_t NUMCHANNELS>
ImageDataGL(size_t dimensionality, const tgt::svec3& size, typename TypeTraits<BASETYPE, NUMCHANNELS>::ImageRAMType* data);
/**
* Destructor
*/
virtual ~ImageDataGL();
/**
* \see AbstractData::clone()
**/
virtual ImageDataGL* clone() const;
/**
* \see ImageData::getSubImage
*/
virtual ImageDataGL* getSubImage(const tgt::svec3& llf, const tgt::svec3& urb) const;
protected:
/**
* Creates the OpenGL texture from the given pointer \a wtp.
* \param wtp WeaklyTypedPointer with source image data
*/
void createTexture(const WeaklyTypedPointer& wtp);
/**
* Creates the OpenGL texture from the given ImageDataRAM \a data.
* \param data Pointer to the ImageDataRAM instance, must not be 0, type has to match the template parameters.
* \tparam BASETYPE Base type of image data
* \tparam NUMCHANNELS Number of channels per element
*/
template<typename BASETYPE, size_t NUMCHANNELS>
void createTexture(typename TypeTraits<BASETYPE, NUMCHANNELS>::ImageRAMType* data);
tgt::Texture* _texture; //< OpenGL texture
static const std::string loggerCat_;
};
// = Template definition ==========================================================================
template<typename BASETYPE, size_t NUMCHANNELS>
TUMVis::ImageDataGL::ImageDataGL(size_t dimensionality, const tgt::svec3& size, typename TypeTraits<BASETYPE, NUMCHANNELS>::ImageRAMType* imageRAM)
: ImageData(dimensionality, size)
{
createTexture<BASETYPE, NUMCHANNELS>(data);
}
template<typename BASETYPE, size_t NUMCHANNELS>
void TUMVis::ImageDataGL::createTexture(typename TypeTraits<BASETYPE, NUMCHANNELS>::ImageRAMType* data) {
tgtAssert(data != 0, "Pointer to image must not be 0!");
_texture = new tgt::Texture(
reinterpret_cast<GLubyte*>(data->getImageData()),
_size,
TypeTraits<BASETYPE, NUMCHANNELS>::glFormat,
TypeTraits<BASETYPE, NUMCHANNELS>::glInternalFormat,
TypeTraits<BASETYPE, NUMCHANNELS>::glDataType,
tgt::Texture::LINEAR);
switch (_dimensionality) {
case 1:
_texture->setType(GL_TEXTURE_1D);
break;
case 2:
_texture->setType(GL_TEXTURE_2D);
break;
case 3:
_texture->setType(GL_TEXTURE_3D);
break;
default:
tgtAssert(false, "Unsupported dimensionality of image.");
break;
}
_texture->bind();
_texture->uploadTexture();
_texture->setWrapping(tgt::Texture::CLAMP);
// revoke ownership of local pixel data from the texture
_texture->setPixelData(0);
LGL_ERROR;
}
}
#endif // IMAGEDATAGL_H__
......@@ -5,7 +5,6 @@
#include "core/datastructures/imagedata.h"
#include "core/tools/endianhelper.h"
#include "core/tools/typetraits.h"
#include "core/tools/weaklytypedpointer.h"
#include <cstring>
......@@ -21,7 +20,7 @@ namespace TUMVis {
* encouraged to use ImageDataRAMTraits for a clearer approach and better support
* of the ImageData converters.
* \sa ImageDataRAMTraits
* \todo implement padding
* \todo implement padding, add some kind of cool iterators
* \tparam T base class of elements
*/
template<typename T>
......@@ -75,6 +74,12 @@ namespace TUMVis {
T* _data; ///< pointer to image data
static const std::string loggerCat_;
private:
// We don't want this data to be copied - clone() must be enough
// (read: We are too lazy to implement a correct copy constructor / assignment-operator)
ImageDataRAM(const ImageDataRAM<T>& rhs) {};
ImageDataRAM<T>& operator=(const ImageDataRAM& rhs) {};
};
// - Template implementation ----------------------------------------------------------------------
......@@ -152,6 +157,7 @@ namespace TUMVis {
*/
template<typename BASETYPE, size_t NUMCHANNELS>
struct ImageDataRAMTraits {
//typedef ImageDataRAM<BASETYPE> ImageType;
/**
* Returns the size of the element base type in bytes.
......@@ -206,7 +212,7 @@ namespace TUMVis {
* \tparam BASETYPE Base data type
*/
template<typename BASETYPE>
class ImageDataRAMTraits<BASETYPE, 4> {
struct ImageDataRAMTraits<BASETYPE, 4> {
typedef ImageDataRAM< tgt::Vector4<BASETYPE> > ImageType;
};
......
......@@ -21,7 +21,13 @@ namespace TUMVis {
}
void AbstractPipeline::setCanvas(tgt::GLCanvas* canvas) {
if (_canvas != 0 && _canvas->getEventHandler() != 0) {
_canvas->getEventHandler()->removeListener(this);
}
_canvas = canvas;
if (_canvas->getEventHandler() != 0) {
_canvas->getEventHandler()->addListenerToFront(this);
}
}
PropertyCollection& AbstractPipeline::getPropertyCollection() {
......
#ifndef typetraits_h__
#define typetraits_h__
#include "tgt/tgt_gl.h"
#include "core/datastructures/imagedataram.h"
#include <limits>
namespace TUMVis {
// = per-channel traits ===========================================================================
template<size_t NUMCHANNELS>
struct TypeTraitsNumChannels {
};
template<>
struct TypeTraitsNumChannels<1> {
static const GLint glFormat = GL_ALPHA;
};
template<>
struct TypeTraitsNumChannels<2> {
static const GLint glFormat = GL_LUMINANCE_ALPHA;
};
template<>
struct TypeTraitsNumChannels<3> {
static const GLint glFormat = GL_RGB;
};
template<>
struct TypeTraitsNumChannels<4> {
static const GLint glFormat = GL_RGBA;
};
// = per-channel traits ===========================================================================
template<typename BASETYPE>
struct TypeTraitsType {
};
template<>
struct TypeTraitsType<uint8_t> {
static const GLenum glDataType = GL_UNSIGNED_BYTE;
};
template<>
struct TypeTraitsType<int8_t> {
static const GLenum glDataType = GL_BYTE;
};
template<>
struct TypeTraitsType<uint16_t> {
static const GLenum glDataType = GL_UNSIGNED_SHORT;
};
template<>
struct TypeTraitsType<int16_t> {
static const GLenum glDataType = GL_SHORT;
};
template<>
struct TypeTraitsType<uint32_t> {
static const GLenum glDataType = GL_UNSIGNED_INT;
};
template<>
struct TypeTraitsType<int32_t> {
static const GLenum glDataType = GL_INT;
};
template<>
struct TypeTraitsType<float> {
static const GLenum glDataType = GL_FLOAT;
};
// = per-channel traits ===========================================================================
template<typename BASETYPE, size_t NUMCHANNELS>
struct TypeTraitsInternalFormat {
};
#define SPCIALIZE_TTIF(type,nc,internalFormat) \
template<> \
struct TypeTraitsInternalFormat<type, nc> { \
static const GLint glInteralFormat = internalFormat; \
}; \
SPCIALIZE_TTIF(uint8_t, 1, GL_ALPHA8)
SPCIALIZE_TTIF(int8_t, 1, GL_ALPHA8)
SPCIALIZE_TTIF(uint16_t,1, GL_ALPHA16)
SPCIALIZE_TTIF(int16_t, 1, GL_ALPHA16)
SPCIALIZE_TTIF(uint32_t,1, GL_ALPHA)
SPCIALIZE_TTIF(int32_t, 1, GL_ALPHA)
SPCIALIZE_TTIF(float, 1, GL_ALPHA32F_ARB)
SPCIALIZE_TTIF(uint8_t, 2, GL_LUMINANCE_ALPHA)
SPCIALIZE_TTIF(int8_t, 2, GL_LUMINANCE_ALPHA)
SPCIALIZE_TTIF(uint16_t,2, GL_LUMINANCE_ALPHA)
SPCIALIZE_TTIF(int16_t, 2, GL_LUMINANCE_ALPHA)
SPCIALIZE_TTIF(uint32_t,2, GL_LUMINANCE_ALPHA)
SPCIALIZE_TTIF(int32_t, 2, GL_LUMINANCE_ALPHA)
SPCIALIZE_TTIF(float, 2, GL_LUMINANCE_ALPHA)
SPCIALIZE_TTIF(uint8_t, 3, GL_RGB8)
SPCIALIZE_TTIF(int8_t, 3, GL_RGB8)
SPCIALIZE_TTIF(uint16_t,3, GL_RGB16)
SPCIALIZE_TTIF(int16_t, 3, GL_RGB16)
SPCIALIZE_TTIF(uint32_t,3, GL_RGB)
SPCIALIZE_TTIF(int32_t, 3, GL_RGB)
SPCIALIZE_TTIF(float, 3, GL_RGB32F_ARB)
SPCIALIZE_TTIF(uint8_t, 4, GL_RGBA8)
SPCIALIZE_TTIF(int8_t, 4, GL_RGBA8)
SPCIALIZE_TTIF(uint16_t,4, GL_RGBA16)
SPCIALIZE_TTIF(int16_t, 4, GL_RGBA16)
SPCIALIZE_TTIF(uint32_t,4, GL_RGBA)
SPCIALIZE_TTIF(int32_t, 4, GL_RGBA)
SPCIALIZE_TTIF(float, 4, GL_RGBA32F_ARB)
// = per-channel traits ===========================================================================
/**
* Struct offering various traits for handling and converting base types like char, int and float.
*
**/
template<typename T>
template<typename BASETYPE, size_t NUMCHANNELS>
struct TypeTraits {
/// Size of the data type in bytes
static const size_t numBytes;
typedef typename ImageDataRAMTraits<BASETYPE, NUMCHANNELS>::ImageType ImageRAMType;
/// flag whether the data type is signed
static const bool isSigned;
};
/**
* Returns the size of the element base type in bytes.
*/
static const size_t basetypeSize = sizeof(BASETYPE);
/**
* Returns the number of channels per image element.
*/
static const size_t numChannels = NUMCHANNELS;
// - Template implementation - let the evil template magic party begin ----------------------------
/**
* Returns the number of bytes required for one image element.
*/
static const size_t elementSize = sizeof(BASETYPE) * NUMCHANNELS;
static const GLint glFormat = TypeTraitsNumChannels<NUMCHANNELS>::glFormat;
static const GLenum glDataType = TypeTraitsType<BASETYPE>::glDataType;
static const GLint glInternalFormat = TypeTraitsInternalFormat<BASETYPE, NUMCHANNELS>::glInteralFormat;
};
template<typename T> const size_t TUMVis::TypeTraits<T>::numBytes = sizeof(T);
// - Template specializations ---------------------------------------------------------------------
template<typename T> const bool TUMVis::TypeTraits<T>::isSigned = std::numeric_limits<T>::is_signed;
}
......
#include "weaklytypedpointer.h"
namespace TUMVis {
const std::string WeaklyTypedPointer::loggerCat_ = "TUMVis.core.tools.WeaklyTypedPointer";
WeaklyTypedPointer::WeaklyTypedPointer(BaseType pt, size_t numChannels, void* ptr)
: _pointerType(pt)
, _numChannels(numChannels)
, _pointer(ptr)
{
tgtAssert(_numChannels > 0 && _numChannels <= 4, "Number of channels out of bounds!");
};
WeaklyTypedPointer::~WeaklyTypedPointer() {
// We do _not_ own the pointer, so we don't need to delete it.
}
size_t WeaklyTypedPointer::numBytes(BaseType pt, size_t numChannels) {
switch (pt) {
case WeaklyTypedPointer::UINT8:
case WeaklyTypedPointer::INT8:
return 1 * numChannels;
case WeaklyTypedPointer::UINT16:
case WeaklyTypedPointer::INT16:
return 2 * numChannels;
case WeaklyTypedPointer::UINT32:
case WeaklyTypedPointer::INT32:
return 4 * numChannels;
case WeaklyTypedPointer::FLOAT:
return sizeof(float) * numChannels;
case WeaklyTypedPointer::UINT64:
case WeaklyTypedPointer::INT64:
return 8 * numChannels;
case WeaklyTypedPointer::DOUBLE:
return sizeof(double) * numChannels;
default:
tgtAssert(false, "Should not reach this - called WeaklyTypedPointer::numBytes() with wrong argument!");
return 1;
}
};
size_t WeaklyTypedPointer::getNumBytesPerElement() const {
return WeaklyTypedPointer::numBytes(_pointerType, _numChannels);
}
GLint WeaklyTypedPointer::getGlFormat() const {
switch (_numChannels) {
case 1:
return GL_ALPHA;
case 2:
return GL_LUMINANCE_ALPHA;
case 3:
return GL_RGB;
case 4:
return GL_RGBA;
default:
tgtAssert(false, "Should not reach hier, wrong number of channels!");
return GL_ALPHA;
}
}
GLenum WeaklyTypedPointer::getGlDataType() const {
switch (_pointerType) {
case WeaklyTypedPointer::UINT8:
return GL_UNSIGNED_BYTE;
case WeaklyTypedPointer::INT8:
return GL_BYTE;
case WeaklyTypedPointer::UINT16:
return GL_UNSIGNED_SHORT;
case WeaklyTypedPointer::INT16:
return GL_SHORT;
case WeaklyTypedPointer::UINT32:
return GL_UNSIGNED_INT;
case WeaklyTypedPointer::INT32:
return GL_INT;
case WeaklyTypedPointer::FLOAT:
return GL_FLOAT;
case WeaklyTypedPointer::UINT64:
case WeaklyTypedPointer::INT64:
case WeaklyTypedPointer::DOUBLE:
tgtAssert(false, "Base data type unsupported by OpenGL!");
return GL_BYTE;
default:
tgtAssert(false, "Should not reach this - wrong base data type!");
return GL_BYTE;
}
}
GLint WeaklyTypedPointer::getGlInternalFormat() const{
switch (_numChannels) {
case 1:
switch (_pointerType) {
case WeaklyTypedPointer::UINT8:
case WeaklyTypedPointer::INT8:
return GL_ALPHA8;
case WeaklyTypedPointer::UINT16:
case WeaklyTypedPointer::INT16:
return GL_ALPHA16;
case WeaklyTypedPointer::UINT32:
case WeaklyTypedPointer::INT32:
return GL_ALPHA;
case WeaklyTypedPointer::FLOAT:
return GL_ALPHA32F_ARB;