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:
parent
9d4b44f956
commit
b176c3a223
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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 ||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user