Removed old volume rendering scene graph code from osgvolume example.

Moved createNormalMapTexture and applyTransferFunction functions from osgvolume example into include/osgVolume/Layer.
This commit is contained in:
Robert Osfield 2009-01-16 17:59:38 +00:00
parent 9d4b44f956
commit b176c3a223
5 changed files with 275 additions and 979 deletions

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@
#define OSGVOLUME_LAYER 1
#include <osg/Image>
#include <osg/TransferFunction>
#include <osgVolume/Locator>
#include <osgVolume/Property>
@ -208,6 +209,12 @@ class OSGVOLUME_EXPORT CompositeLayer : public Layer
Layers _layers;
};
/** Compute a 3d image that represent the normal map of the specified 3d image.*/
extern OSGVOLUME_EXPORT osg::Image* createNormalMapTexture(osg::Image* image_3d);
/** Create an image that has a transfer function applied specified Image.*/
extern OSGVOLUME_EXPORT osg::Image* applyTransferFunction(osg::Image* image, osg::TransferFunction1D* transferFunction);
}
#endif

View File

@ -134,12 +134,6 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
if (matrix)
{
// scale up to provide scale of complete tile
osg::Vec3d scale(osg::Vec3(result.getImage()->s(),result.getImage()->t(), result.getImage()->r()));
matrix->postMultScale(scale);
osgVolume::Locator* locator = new osgVolume::Locator(*matrix);
tile->setLocator(locator);
@ -241,6 +235,8 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
image->setUserData(matrix);
matrix.preMult(osg::Matrix::scale(double(image->s()), double(image->t()), double(image->r())));
return image;
}
#endif
@ -622,6 +618,8 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
(*matrix)(1,2) = fileInfo.matrix(1,2) * averageThickness;
(*matrix)(2,2) = fileInfo.matrix(2,2) * averageThickness;
image = new osg::Image;
image->setUserData(matrix.get());
image->setFileName(fileName.c_str());
@ -629,6 +627,8 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
pixelFormat, dataType);
matrix->preMult(osg::Matrix::scale(double(image->s()), double(image->t()), double(image->r())));
notice()<<"Image dimensions = "<<image->s()<<", "<<image->t()<<", "<<image->r()<<" pixelFormat=0x"<<std::hex<<pixelFormat<<" dataType=0x"<<std::hex<<dataType<<std::endl;
}
else if (pixelData->getPlanes()>numPlanes ||

View File

@ -14,6 +14,7 @@
#include <osgVolume/Layer>
#include <osg/ImageUtils>
#include <osg/Endian>
#include <osg/Notify>
#include <osg/io_utils>
@ -182,3 +183,261 @@ void CompositeLayer::clear()
{
_layers.clear();
}
/////////////////////////////////////////////////////////////////////////////
//
// createNormalMapTexture
//
osg::Image* osgVolume::createNormalMapTexture(osg::Image* image_3d)
{
osg::notify(osg::INFO)<<"Computing NormalMapTexture"<<std::endl;
GLenum dataType = image_3d->getDataType();
unsigned int sourcePixelIncrement = 1;
unsigned int alphaOffset = 0;
switch(image_3d->getPixelFormat())
{
case(GL_ALPHA):
case(GL_LUMINANCE):
sourcePixelIncrement = 1;
alphaOffset = 0;
break;
case(GL_LUMINANCE_ALPHA):
sourcePixelIncrement = 2;
alphaOffset = 1;
break;
case(GL_RGB):
sourcePixelIncrement = 3;
alphaOffset = 0;
break;
case(GL_RGBA):
sourcePixelIncrement = 4;
alphaOffset = 3;
break;
default:
osg::notify(osg::NOTICE)<<"Source pixel format not support for normal map generation."<<std::endl;
return 0;
}
osg::ref_ptr<osg::Image> normalmap_3d = new osg::Image;
normalmap_3d->allocateImage(image_3d->s(),image_3d->t(),image_3d->r(),
GL_RGBA,GL_UNSIGNED_BYTE);
if (osg::getCpuByteOrder()==osg::LittleEndian) alphaOffset = sourcePixelIncrement-alphaOffset-1;
for(int r=1;r<image_3d->r()-1;++r)
{
for(int t=1;t<image_3d->t()-1;++t)
{
if (dataType==GL_UNSIGNED_BYTE)
{
unsigned char* ptr = image_3d->data(1,t,r)+alphaOffset;
unsigned char* left = image_3d->data(0,t,r)+alphaOffset;
unsigned char* right = image_3d->data(2,t,r)+alphaOffset;
unsigned char* above = image_3d->data(1,t+1,r)+alphaOffset;
unsigned char* below = image_3d->data(1,t-1,r)+alphaOffset;
unsigned char* in = image_3d->data(1,t,r+1)+alphaOffset;
unsigned char* out = image_3d->data(1,t,r-1)+alphaOffset;
unsigned char* destination = (unsigned char*) normalmap_3d->data(1,t,r);
for(int s=1;s<image_3d->s()-1;++s)
{
osg::Vec3 grad((float)(*left)-(float)(*right),
(float)(*below)-(float)(*above),
(float)(*out) -(float)(*in));
grad.normalize();
if (grad.x()==0.0f && grad.y()==0.0f && grad.z()==0.0f)
{
grad.set(128.0f,128.0f,128.0f);
}
else
{
grad.x() = osg::clampBetween((grad.x()+1.0f)*128.0f,0.0f,255.0f);
grad.y() = osg::clampBetween((grad.y()+1.0f)*128.0f,0.0f,255.0f);
grad.z() = osg::clampBetween((grad.z()+1.0f)*128.0f,0.0f,255.0f);
}
*(destination++) = (unsigned char)(grad.x()); // scale and bias X.
*(destination++) = (unsigned char)(grad.y()); // scale and bias Y.
*(destination++) = (unsigned char)(grad.z()); // scale and bias Z.
*destination++ = *ptr;
ptr += sourcePixelIncrement;
left += sourcePixelIncrement;
right += sourcePixelIncrement;
above += sourcePixelIncrement;
below += sourcePixelIncrement;
in += sourcePixelIncrement;
out += sourcePixelIncrement;
}
}
else if (dataType==GL_SHORT)
{
short* ptr = (short*)(image_3d->data(1,t,r)+alphaOffset);
short* left = (short*)(image_3d->data(0,t,r)+alphaOffset);
short* right = (short*)(image_3d->data(2,t,r)+alphaOffset);
short* above = (short*)(image_3d->data(1,t+1,r)+alphaOffset);
short* below = (short*)(image_3d->data(1,t-1,r)+alphaOffset);
short* in = (short*)(image_3d->data(1,t,r+1)+alphaOffset);
short* out = (short*)(image_3d->data(1,t,r-1)+alphaOffset);
unsigned char* destination = (unsigned char*) normalmap_3d->data(1,t,r);
for(int s=1;s<image_3d->s()-1;++s)
{
osg::Vec3 grad((float)(*left)-(float)(*right),
(float)(*below)-(float)(*above),
(float)(*out) -(float)(*in));
grad.normalize();
//osg::notify(osg::NOTICE)<<"normal "<<grad<<std::endl;
if (grad.x()==0.0f && grad.y()==0.0f && grad.z()==0.0f)
{
grad.set(128.0f,128.0f,128.0f);
}
else
{
grad.x() = osg::clampBetween((grad.x()+1.0f)*128.0f,0.0f,255.0f);
grad.y() = osg::clampBetween((grad.y()+1.0f)*128.0f,0.0f,255.0f);
grad.z() = osg::clampBetween((grad.z()+1.0f)*128.0f,0.0f,255.0f);
}
*(destination++) = (unsigned char)(grad.x()); // scale and bias X.
*(destination++) = (unsigned char)(grad.y()); // scale and bias Y.
*(destination++) = (unsigned char)(grad.z()); // scale and bias Z.
*destination++ = *ptr/128;
ptr += sourcePixelIncrement;
left += sourcePixelIncrement;
right += sourcePixelIncrement;
above += sourcePixelIncrement;
below += sourcePixelIncrement;
in += sourcePixelIncrement;
out += sourcePixelIncrement;
}
}
else if (dataType==GL_UNSIGNED_SHORT)
{
unsigned short* ptr = (unsigned short*)(image_3d->data(1,t,r)+alphaOffset);
unsigned short* left = (unsigned short*)(image_3d->data(0,t,r)+alphaOffset);
unsigned short* right = (unsigned short*)(image_3d->data(2,t,r)+alphaOffset);
unsigned short* above = (unsigned short*)(image_3d->data(1,t+1,r)+alphaOffset);
unsigned short* below = (unsigned short*)(image_3d->data(1,t-1,r)+alphaOffset);
unsigned short* in = (unsigned short*)(image_3d->data(1,t,r+1)+alphaOffset);
unsigned short* out = (unsigned short*)(image_3d->data(1,t,r-1)+alphaOffset);
unsigned char* destination = (unsigned char*) normalmap_3d->data(1,t,r);
for(int s=1;s<image_3d->s()-1;++s)
{
osg::Vec3 grad((float)(*left)-(float)(*right),
(float)(*below)-(float)(*above),
(float)(*out) -(float)(*in));
grad.normalize();
if (grad.x()==0.0f && grad.y()==0.0f && grad.z()==0.0f)
{
grad.set(128.0f,128.0f,128.0f);
}
else
{
grad.x() = osg::clampBetween((grad.x()+1.0f)*128.0f,0.0f,255.0f);
grad.y() = osg::clampBetween((grad.y()+1.0f)*128.0f,0.0f,255.0f);
grad.z() = osg::clampBetween((grad.z()+1.0f)*128.0f,0.0f,255.0f);
}
*(destination++) = (unsigned char)(grad.x()); // scale and bias X.
*(destination++) = (unsigned char)(grad.y()); // scale and bias Y.
*(destination++) = (unsigned char)(grad.z()); // scale and bias Z.
*destination++ = *ptr/256;
ptr += sourcePixelIncrement;
left += sourcePixelIncrement;
right += sourcePixelIncrement;
above += sourcePixelIncrement;
below += sourcePixelIncrement;
in += sourcePixelIncrement;
out += sourcePixelIncrement;
}
}
}
}
osg::notify(osg::INFO)<<"Created NormalMapTexture"<<std::endl;
return normalmap_3d.release();
}
/////////////////////////////////////////////////////////////////////////////
//
// applyTransferFunction
//
struct ApplyTransferFunctionOperator
{
ApplyTransferFunctionOperator(osg::TransferFunction1D* tf, unsigned char* data):
_tf(tf),
_data(data) {}
inline void luminance(float l) const
{
osg::Vec4 c = _tf->getInterpolatedValue(l);
//std::cout<<"l = "<<l<<" c="<<c<<std::endl;
*(_data++) = (unsigned char)(c[0]*255.0f + 0.5f);
*(_data++) = (unsigned char)(c[1]*255.0f + 0.5f);
*(_data++) = (unsigned char)(c[2]*255.0f + 0.5f);
*(_data++) = (unsigned char)(c[3]*255.0f + 0.5f);
}
inline void alpha(float a) const
{
luminance(a);
}
inline void luminance_alpha(float l,float a) const
{
luminance(l);
}
inline void rgb(float r,float g,float b) const
{
luminance((r+g+b)*0.3333333);
}
inline void rgba(float r,float g,float b,float a) const
{
luminance(a);
}
mutable osg::ref_ptr<osg::TransferFunction1D> _tf;
mutable unsigned char* _data;
};
osg::Image* osgVolume::applyTransferFunction(osg::Image* image, osg::TransferFunction1D* transferFunction)
{
osg::notify(osg::INFO)<<"Applying transfer function"<<std::endl;
osg::Image* output_image = new osg::Image;
output_image->allocateImage(image->s(),image->t(), image->r(), GL_RGBA, GL_UNSIGNED_BYTE);
ApplyTransferFunctionOperator op(transferFunction, output_image->data());
osg::readImage(image,op);
return output_image;
}

View File

@ -113,14 +113,11 @@ void ShaderTechnique::init()
matrix = masterLocator->getTransform();
}
osg::notify(osg::NOTICE)<<"Matrix = "<<matrix<<std::endl;
osg::Texture::InternalFormatMode internalFormatMode = osg::Texture::USE_IMAGE_DATA_FORMAT;
float xSize = (matrix)(0,0);
float ySize = (matrix)(1,1);
float zSize = (matrix)(2,2);
{
osg::Texture::FilterMode minFilter = osg::Texture::LINEAR;