Show
Ignore:
Timestamp:
01/16/09 18:59:38 (6 years ago)
Author:
robert
Message:

Removed old volume rendering scene graph code from osgvolume example.

Moved createNormalMapTexture and applyTransferFunction functions from osgvolume example into include/osgVolume/Layer.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgvolume/osgvolume.cpp

    r9503 r9505  
    7777}; 
    7878 
    79 //  example ReadOperator 
    80 // struct ReadOperator 
    81 // { 
    82 //     inline void luminance(float l) const { rgba(l,l,l,1.0f); } 
    83 //     inline void alpha(float a) const { rgba(1.0f,1.0f,1.0f,a); } 
    84 //     inline void luminance_alpha(float l,float a) const { rgba(l,l,l,a); } 
    85 //     inline void rgb(float r,float g,float b) const { rgba(r,g,b,1.0f); } 
    86 //     inline void rgba(float r,float g,float b,float a) const { std::cout<<"pixel("<<r<<", "<<g<<", "<<b<<", "<<a<<")"<<std::endl; } 
    87 // }; 
    88  
    89  
    90  
    9179struct PassThroughTransformFunction 
    9280{ 
     
    469457} 
    470458 
    471  
    472 osg::Image* createNormalMapTexture(osg::Image* image_3d) 
    473 { 
    474     osg::notify(osg::NOTICE)<<"Computing NormalMapTexture"<<std::endl; 
    475  
    476     GLenum dataType = image_3d->getDataType(); 
    477  
    478     unsigned int sourcePixelIncrement = 1; 
    479     unsigned int alphaOffset = 0;  
    480     switch(image_3d->getPixelFormat()) 
    481     { 
    482     case(GL_ALPHA): 
    483     case(GL_LUMINANCE): 
    484         sourcePixelIncrement = 1; 
    485         alphaOffset = 0; 
    486         break; 
    487     case(GL_LUMINANCE_ALPHA): 
    488         sourcePixelIncrement = 2; 
    489         alphaOffset = 1; 
    490         break; 
    491     case(GL_RGB): 
    492         sourcePixelIncrement = 3; 
    493         alphaOffset = 0; 
    494         break; 
    495     case(GL_RGBA): 
    496         sourcePixelIncrement = 4; 
    497         alphaOffset = 3; 
    498         break; 
    499     default: 
    500         osg::notify(osg::NOTICE)<<"Source pixel format not support for normal map generation."<<std::endl; 
    501         return 0; 
    502     } 
    503  
    504  
    505     osg::ref_ptr<osg::Image> normalmap_3d = new osg::Image; 
    506     normalmap_3d->allocateImage(image_3d->s(),image_3d->t(),image_3d->r(), 
    507                             GL_RGBA,GL_UNSIGNED_BYTE); 
    508  
    509     if (osg::getCpuByteOrder()==osg::LittleEndian) alphaOffset = sourcePixelIncrement-alphaOffset-1; 
    510  
    511     for(int r=1;r<image_3d->r()-1;++r) 
    512     { 
    513         for(int t=1;t<image_3d->t()-1;++t) 
    514         { 
    515  
    516             if (dataType==GL_UNSIGNED_BYTE) 
    517             {         
    518                 unsigned char* ptr = image_3d->data(1,t,r)+alphaOffset; 
    519                 unsigned char* left = image_3d->data(0,t,r)+alphaOffset; 
    520                 unsigned char* right = image_3d->data(2,t,r)+alphaOffset; 
    521                 unsigned char* above = image_3d->data(1,t+1,r)+alphaOffset; 
    522                 unsigned char* below = image_3d->data(1,t-1,r)+alphaOffset; 
    523                 unsigned char* in = image_3d->data(1,t,r+1)+alphaOffset; 
    524                 unsigned char* out = image_3d->data(1,t,r-1)+alphaOffset; 
    525  
    526                 unsigned char* destination = (unsigned char*) normalmap_3d->data(1,t,r); 
    527  
    528                 for(int s=1;s<image_3d->s()-1;++s) 
    529                 { 
    530  
    531                     osg::Vec3 grad((float)(*left)-(float)(*right), 
    532                                    (float)(*below)-(float)(*above), 
    533                                    (float)(*out) -(float)(*in)); 
    534  
    535                     grad.normalize(); 
    536  
    537                     if (grad.x()==0.0f && grad.y()==0.0f && grad.z()==0.0f) 
    538                     { 
    539                         grad.set(128.0f,128.0f,128.0f); 
    540                     } 
    541                     else 
    542                     { 
    543                         grad.x() = osg::clampBetween((grad.x()+1.0f)*128.0f,0.0f,255.0f); 
    544                         grad.y() = osg::clampBetween((grad.y()+1.0f)*128.0f,0.0f,255.0f); 
    545                         grad.z() = osg::clampBetween((grad.z()+1.0f)*128.0f,0.0f,255.0f); 
    546                     } 
    547  
    548                     *(destination++) = (unsigned char)(grad.x()); // scale and bias X. 
    549                     *(destination++) = (unsigned char)(grad.y()); // scale and bias Y. 
    550                     *(destination++) = (unsigned char)(grad.z()); // scale and bias Z. 
    551  
    552                     *destination++ = *ptr; 
    553  
    554                     ptr += sourcePixelIncrement; 
    555                     left += sourcePixelIncrement; 
    556                     right += sourcePixelIncrement; 
    557                     above += sourcePixelIncrement; 
    558                     below += sourcePixelIncrement; 
    559                     in += sourcePixelIncrement; 
    560                     out += sourcePixelIncrement; 
    561                 } 
    562             } 
    563             else if (dataType==GL_SHORT) 
    564             { 
    565                 short* ptr = (short*)(image_3d->data(1,t,r)+alphaOffset); 
    566                 short* left = (short*)(image_3d->data(0,t,r)+alphaOffset); 
    567                 short* right = (short*)(image_3d->data(2,t,r)+alphaOffset); 
    568                 short* above = (short*)(image_3d->data(1,t+1,r)+alphaOffset); 
    569                 short* below = (short*)(image_3d->data(1,t-1,r)+alphaOffset); 
    570                 short* in = (short*)(image_3d->data(1,t,r+1)+alphaOffset); 
    571                 short* out = (short*)(image_3d->data(1,t,r-1)+alphaOffset); 
    572  
    573                 unsigned char* destination = (unsigned char*) normalmap_3d->data(1,t,r); 
    574  
    575                 for(int s=1;s<image_3d->s()-1;++s) 
    576                 { 
    577  
    578                     osg::Vec3 grad((float)(*left)-(float)(*right), 
    579                                    (float)(*below)-(float)(*above), 
    580                                    (float)(*out) -(float)(*in)); 
    581  
    582                     grad.normalize(); 
    583  
    584                     //osg::notify(osg::NOTICE)<<"normal "<<grad<<std::endl; 
    585  
    586                     if (grad.x()==0.0f && grad.y()==0.0f && grad.z()==0.0f) 
    587                     { 
    588                         grad.set(128.0f,128.0f,128.0f); 
    589                     } 
    590                     else 
    591                     { 
    592                         grad.x() = osg::clampBetween((grad.x()+1.0f)*128.0f,0.0f,255.0f); 
    593                         grad.y() = osg::clampBetween((grad.y()+1.0f)*128.0f,0.0f,255.0f); 
    594                         grad.z() = osg::clampBetween((grad.z()+1.0f)*128.0f,0.0f,255.0f); 
    595                     } 
    596                      
    597  
    598                     *(destination++) = (unsigned char)(grad.x()); // scale and bias X. 
    599                     *(destination++) = (unsigned char)(grad.y()); // scale and bias Y. 
    600                     *(destination++) = (unsigned char)(grad.z()); // scale and bias Z. 
    601  
    602                     *destination++ = *ptr/128; 
    603  
    604                     ptr += sourcePixelIncrement; 
    605                     left += sourcePixelIncrement; 
    606                     right += sourcePixelIncrement; 
    607                     above += sourcePixelIncrement; 
    608                     below += sourcePixelIncrement; 
    609                     in += sourcePixelIncrement; 
    610                     out += sourcePixelIncrement; 
    611                 } 
    612             } 
    613             else if (dataType==GL_UNSIGNED_SHORT) 
    614             { 
    615                 unsigned short* ptr = (unsigned short*)(image_3d->data(1,t,r)+alphaOffset); 
    616                 unsigned short* left = (unsigned short*)(image_3d->data(0,t,r)+alphaOffset); 
    617                 unsigned short* right = (unsigned short*)(image_3d->data(2,t,r)+alphaOffset); 
    618                 unsigned short* above = (unsigned short*)(image_3d->data(1,t+1,r)+alphaOffset); 
    619                 unsigned short* below = (unsigned short*)(image_3d->data(1,t-1,r)+alphaOffset); 
    620                 unsigned short* in = (unsigned short*)(image_3d->data(1,t,r+1)+alphaOffset); 
    621                 unsigned short* out = (unsigned short*)(image_3d->data(1,t,r-1)+alphaOffset); 
    622  
    623                 unsigned char* destination = (unsigned char*) normalmap_3d->data(1,t,r); 
    624  
    625                 for(int s=1;s<image_3d->s()-1;++s) 
    626                 { 
    627  
    628                     osg::Vec3 grad((float)(*left)-(float)(*right), 
    629                                    (float)(*below)-(float)(*above), 
    630                                    (float)(*out) -(float)(*in)); 
    631  
    632                     grad.normalize(); 
    633  
    634                     if (grad.x()==0.0f && grad.y()==0.0f && grad.z()==0.0f) 
    635                     { 
    636                         grad.set(128.0f,128.0f,128.0f); 
    637                     } 
    638                     else 
    639                     { 
    640                         grad.x() = osg::clampBetween((grad.x()+1.0f)*128.0f,0.0f,255.0f); 
    641                         grad.y() = osg::clampBetween((grad.y()+1.0f)*128.0f,0.0f,255.0f); 
    642                         grad.z() = osg::clampBetween((grad.z()+1.0f)*128.0f,0.0f,255.0f); 
    643                     } 
    644  
    645                     *(destination++) = (unsigned char)(grad.x()); // scale and bias X. 
    646                     *(destination++) = (unsigned char)(grad.y()); // scale and bias Y. 
    647                     *(destination++) = (unsigned char)(grad.z()); // scale and bias Z. 
    648  
    649                     *destination++ = *ptr/256; 
    650  
    651                     ptr += sourcePixelIncrement; 
    652                     left += sourcePixelIncrement; 
    653                     right += sourcePixelIncrement; 
    654                     above += sourcePixelIncrement; 
    655                     below += sourcePixelIncrement; 
    656                     in += sourcePixelIncrement; 
    657                     out += sourcePixelIncrement; 
    658                 } 
    659             } 
    660         } 
    661     } 
    662      
    663      
    664     osg::notify(osg::NOTICE)<<"Created NormalMapTexture"<<std::endl; 
    665      
    666     return normalmap_3d.release(); 
    667 } 
    668  
    669  
    670  
    671 osg::Node* createCube(float size,float alpha, unsigned int numSlices, float sliceEnd=1.0f) 
    672 { 
    673  
    674     // set up the Geometry. 
    675     osg::Geometry* geom = new osg::Geometry; 
    676  
    677     float halfSize = size*0.5f; 
    678     float y = halfSize; 
    679     float dy =-size/(float)(numSlices-1)*sliceEnd; 
    680  
    681     //y = -halfSize; 
    682     //dy *= 0.5; 
    683  
    684     osg::Vec3Array* coords = new osg::Vec3Array(4*numSlices); 
    685     geom->setVertexArray(coords); 
    686     for(unsigned int i=0;i<numSlices;++i, y+=dy) 
    687     { 
    688         (*coords)[i*4+0].set(-halfSize,y,halfSize); 
    689         (*coords)[i*4+1].set(-halfSize,y,-halfSize); 
    690         (*coords)[i*4+2].set(halfSize,y,-halfSize); 
    691         (*coords)[i*4+3].set(halfSize,y,halfSize); 
    692     } 
    693      
    694     osg::Vec3Array* normals = new osg::Vec3Array(1); 
    695     (*normals)[0].set(0.0f,-1.0f,0.0f); 
    696     geom->setNormalArray(normals); 
    697     geom->setNormalBinding(osg::Geometry::BIND_OVERALL); 
    698  
    699     osg::Vec4Array* colors = new osg::Vec4Array(1); 
    700     (*colors)[0].set(1.0f,1.0f,1.0f,alpha); 
    701     geom->setColorArray(colors); 
    702     geom->setColorBinding(osg::Geometry::BIND_OVERALL); 
    703  
    704     geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,coords->size())); 
    705  
    706     osg::Billboard* billboard = new osg::Billboard; 
    707     billboard->setMode(osg::Billboard::POINT_ROT_WORLD); 
    708     billboard->addDrawable(geom); 
    709     billboard->setPosition(0,osg::Vec3(0.0f,0.0f,0.0f)); 
    710      
    711     return billboard; 
    712 } 
    713459 
    714460class FollowMouseCallback : public osgGA::GUIEventHandler, public osg::StateSet::Callback 
     
    820566}; 
    821567 
    822 osg::Node* createShaderModel(ShadingModel shadingModel, 
    823                        osg::ref_ptr<osg::Image>& image_3d,  
    824                        osg::Image* normalmap_3d, 
    825                        osg::TransferFunction1D* tf, 
    826                        osg::Texture::InternalFormatMode internalFormatMode, 
    827                        float xSize, float ySize, float zSize, 
    828                        float /*xMultiplier*/, float /*yMultiplier*/, float /*zMultiplier*/, 
    829                        unsigned int /*numSlices*/=500, float /*sliceEnd*/=1.0f, float alphaFuncValue=0.02f) 
    830 { 
    831     osg::Texture::FilterMode minFilter = osg::Texture::LINEAR; 
    832     osg::Texture::FilterMode magFilter = osg::Texture::LINEAR; 
    833  
    834     osg::Group* root = new osg::Group; 
    835      
    836     osg::Geode* geode = new osg::Geode; 
    837     root->addChild(geode); 
    838      
    839     osg::StateSet* stateset = geode->getOrCreateStateSet(); 
    840      
    841     stateset->setEventCallback(new FollowMouseCallback(true)); 
    842      
    843     stateset->setMode(GL_ALPHA_TEST,osg::StateAttribute::ON); 
    844  
    845      
    846     osg::Program* program = new osg::Program; 
    847     stateset->setAttribute(program); 
    848  
    849     // get shaders from source 
    850      
    851     osg::Shader* vertexShader = osgDB::readShaderFile(osg::Shader::VERTEX, "volume.vert"); 
    852     if (vertexShader) 
    853     { 
    854         program->addShader(vertexShader); 
    855     } 
    856     else 
    857     { 
    858         #include "volume_vert.cpp" 
    859         program->addShader(new osg::Shader(osg::Shader::VERTEX, volume_vert)); 
    860     } 
    861  
    862     if (!(normalmap_3d && tf)) 
    863     { 
    864         // set up the 3d texture itself, 
    865         // note, well set the filtering up so that mip mapping is disabled, 
    866         // gluBuild3DMipsmaps doesn't do a very good job of handled the 
    867         // imbalanced dimensions of the 256x256x4 texture. 
    868         osg::Texture3D* texture3D = new osg::Texture3D; 
    869         texture3D->setResizeNonPowerOfTwoHint(false); 
    870         texture3D->setFilter(osg::Texture3D::MIN_FILTER,minFilter); 
    871         texture3D->setFilter(osg::Texture3D::MAG_FILTER, magFilter); 
    872         texture3D->setWrap(osg::Texture3D::WRAP_R,osg::Texture3D::CLAMP_TO_EDGE); 
    873         texture3D->setWrap(osg::Texture3D::WRAP_S,osg::Texture3D::CLAMP_TO_EDGE); 
    874         texture3D->setWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP_TO_EDGE); 
    875         if (image_3d->getPixelFormat()==GL_ALPHA ||  
    876             image_3d->getPixelFormat()==GL_LUMINANCE) 
    877         { 
    878             texture3D->setInternalFormatMode(osg::Texture3D::USE_USER_DEFINED_FORMAT); 
    879             texture3D->setInternalFormat(GL_INTENSITY); 
    880         } 
    881         else 
    882         { 
    883             texture3D->setInternalFormatMode(internalFormatMode); 
    884         } 
    885         texture3D->setImage(image_3d.get()); 
    886  
    887         stateset->setTextureAttributeAndModes(0,texture3D,osg::StateAttribute::ON); 
    888  
    889         osg::Uniform* baseTextureSampler = new osg::Uniform("baseTexture",0); 
    890         stateset->addUniform(baseTextureSampler); 
    891     } 
    892      
    893  
    894     if (shadingModel==MaximumIntensityProjection) 
    895     { 
    896         if (tf) 
    897         { 
    898             osg::Texture1D* texture1D = new osg::Texture1D; 
    899             texture1D->setImage(tf->getImage());     
    900             stateset->setTextureAttributeAndModes(1,texture1D,osg::StateAttribute::ON); 
    901  
    902             osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume_tf_mip.frag"); 
    903             if (fragmentShader) 
    904             { 
    905                 program->addShader(fragmentShader); 
    906             } 
    907             else 
    908             { 
    909                 #include "volume_tf_mip_frag.cpp" 
    910                 program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_tf_mip_frag)); 
    911             } 
    912  
    913             osg::Uniform* tfTextureSampler = new osg::Uniform("tfTexture",1); 
    914             stateset->addUniform(tfTextureSampler); 
    915  
    916         } 
    917         else 
    918         {     
    919             osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume_mip.frag"); 
    920             if (fragmentShader) 
    921             { 
    922                 program->addShader(fragmentShader); 
    923             } 
    924             else 
    925             { 
    926                 #include "volume_mip_frag.cpp" 
    927                 program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_mip_frag)); 
    928             } 
    929         } 
    930     } 
    931     else if (shadingModel==Isosurface) 
    932     { 
    933  
    934         if (tf) 
    935         { 
    936             osg::Texture1D* texture1D = new osg::Texture1D; 
    937             texture1D->setImage(tf->getImage());     
    938             texture1D->setResizeNonPowerOfTwoHint(false); 
    939             texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); 
    940             texture1D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); 
    941             texture1D->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE); 
    942             stateset->setTextureAttributeAndModes(1,texture1D,osg::StateAttribute::ON); 
    943  
    944             osg::Uniform* tfTextureSampler = new osg::Uniform("tfTexture",1); 
    945             stateset->addUniform(tfTextureSampler); 
    946  
    947             osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume_tf_iso.frag"); 
    948             if (fragmentShader) 
    949             { 
    950                 program->addShader(fragmentShader); 
    951             } 
    952             else 
    953             { 
    954                 #include "volume_tf_iso_frag.cpp" 
    955                 program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_tf_iso_frag)); 
    956             } 
    957         } 
    958         else 
    959         {     
    960             osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume_iso.frag"); 
    961             if (fragmentShader) 
    962             { 
    963                 program->addShader(fragmentShader); 
    964             } 
    965             else 
    966             { 
    967                 #include "volume_iso_frag.cpp" 
    968                 program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_iso_frag)); 
    969             } 
    970         } 
    971     } 
    972     else if (normalmap_3d) 
    973     { 
    974         osg::notify(osg::NOTICE)<<"Setting up normalmapping shader"<<std::endl; 
    975  
    976         osg::Uniform* normalMapSampler = new osg::Uniform("normalMap",1); 
    977         stateset->addUniform(normalMapSampler); 
    978  
    979         osg::Texture3D* normalMap = new osg::Texture3D; 
    980         normalMap->setImage(normalmap_3d);     
    981         normalMap->setResizeNonPowerOfTwoHint(false); 
    982         normalMap->setInternalFormatMode(internalFormatMode); 
    983         normalMap->setFilter(osg::Texture3D::MIN_FILTER, osg::Texture::LINEAR); 
    984         normalMap->setFilter(osg::Texture3D::MAG_FILTER, osg::Texture::LINEAR); 
    985         normalMap->setWrap(osg::Texture3D::WRAP_R,osg::Texture3D::CLAMP_TO_EDGE); 
    986         normalMap->setWrap(osg::Texture3D::WRAP_S,osg::Texture3D::CLAMP_TO_EDGE); 
    987         normalMap->setWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP_TO_EDGE); 
    988  
    989         stateset->setTextureAttributeAndModes(1,normalMap,osg::StateAttribute::ON); 
    990  
    991         if (tf) 
    992         { 
    993             osg::Texture1D* texture1D = new osg::Texture1D; 
    994             texture1D->setImage(tf->getImage());     
    995             texture1D->setResizeNonPowerOfTwoHint(false); 
    996             texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); 
    997             texture1D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); 
    998             texture1D->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE); 
    999             stateset->setTextureAttributeAndModes(0,texture1D,osg::StateAttribute::ON); 
    1000  
    1001             osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume-tf-n.frag"); 
    1002             if (fragmentShader) 
    1003             { 
    1004                 program->addShader(fragmentShader); 
    1005             } 
    1006             else 
    1007             { 
    1008                 #include "volume_tf_n_frag.cpp" 
    1009                 program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_tf_n_frag)); 
    1010             } 
    1011  
    1012             osg::Uniform* tfTextureSampler = new osg::Uniform("tfTexture",0); 
    1013             stateset->addUniform(tfTextureSampler); 
    1014         } 
    1015         else 
    1016         { 
    1017             osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume-n.frag"); 
    1018             if (fragmentShader) 
    1019             { 
    1020                 program->addShader(fragmentShader); 
    1021             } 
    1022             else 
    1023             { 
    1024                 #include "volume_n_frag.cpp" 
    1025                 program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_n_frag)); 
    1026             } 
    1027         } 
    1028     }  
    1029     else if (tf) 
    1030     { 
    1031         osg::Texture1D* texture1D = new osg::Texture1D; 
    1032         texture1D->setImage(tf->getImage());     
    1033         texture1D->setResizeNonPowerOfTwoHint(false); 
    1034         texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); 
    1035         texture1D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); 
    1036         texture1D->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE); 
    1037         stateset->setTextureAttributeAndModes(1,texture1D,osg::StateAttribute::ON); 
    1038  
    1039         osg::Uniform* tfTextureSampler = new osg::Uniform("tfTexture",1); 
    1040         stateset->addUniform(tfTextureSampler); 
    1041  
    1042         osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume-tf.frag"); 
    1043         if (fragmentShader) 
    1044         { 
    1045             program->addShader(fragmentShader); 
    1046         } 
    1047         else 
    1048         { 
    1049             #include "volume_tf_frag.cpp" 
    1050             program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_tf_frag)); 
    1051         } 
    1052  
    1053     } 
    1054     else 
    1055     {     
    1056  
    1057         osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume.frag"); 
    1058         if (fragmentShader) 
    1059         { 
    1060             program->addShader(fragmentShader); 
    1061         } 
    1062         else 
    1063         { 
    1064             #include "volume_frag.cpp" 
    1065             program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_frag)); 
    1066         } 
    1067     } 
    1068  
    1069     osg::Uniform* sampleDensity = new osg::Uniform("sampleDensity", 0.005f); 
    1070     stateset->addUniform(sampleDensity); 
    1071  
    1072     osg::Uniform* transpancy = new osg::Uniform("transparency",0.5f); 
    1073     stateset->addUniform(transpancy); 
    1074  
    1075     osg::Uniform* alphaCutOff = new osg::Uniform("alphaCutOff",alphaFuncValue); 
    1076     stateset->addUniform(alphaCutOff); 
    1077  
    1078     stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON); 
    1079  
    1080     osg::TexGen* texgen = new osg::TexGen; 
    1081     texgen->setMode(osg::TexGen::OBJECT_LINEAR); 
    1082     texgen->setPlane(osg::TexGen::S, osg::Plane(1.0f/xSize,0.0f,0.0f,0.0f)); 
    1083     texgen->setPlane(osg::TexGen::T, osg::Plane(0.0f,1.0f/ySize,0.0f,0.0f)); 
    1084     texgen->setPlane(osg::TexGen::R, osg::Plane(0.0f,0.0f,1.0f/zSize,0.0f)); 
    1085     texgen->setPlane(osg::TexGen::Q, osg::Plane(0.0f,0.0f,0.0f,1.0f)); 
    1086      
    1087     stateset->setTextureAttributeAndModes(0, texgen, osg::StateAttribute::ON); 
    1088  
    1089     { 
    1090         osg::Geometry* geom = new osg::Geometry; 
    1091  
    1092         osg::Vec3Array* coords = new osg::Vec3Array(8); 
    1093         (*coords)[0].set(0,0,0); 
    1094         (*coords)[1].set(xSize,0,0); 
    1095         (*coords)[2].set(xSize,ySize,0); 
    1096         (*coords)[3].set(0,ySize,0); 
    1097         (*coords)[4].set(0,0,zSize); 
    1098         (*coords)[5].set(xSize,0,zSize); 
    1099         (*coords)[6].set(ySize,ySize,zSize); 
    1100         (*coords)[7].set(0,ySize,zSize); 
    1101         geom->setVertexArray(coords); 
    1102  
    1103         osg::Vec4Array* colours = new osg::Vec4Array(1); 
    1104         (*colours)[0].set(1.0f,1.0f,1.0,1.0f); 
    1105         geom->setColorArray(colours); 
    1106         geom->setColorBinding(osg::Geometry::BIND_OVERALL); 
    1107  
    1108         osg::DrawElementsUShort* drawElements = new osg::DrawElementsUShort(GL_QUADS); 
    1109         // bottom 
    1110         drawElements->push_back(0); 
    1111         drawElements->push_back(1); 
    1112         drawElements->push_back(2); 
    1113         drawElements->push_back(3); 
    1114          
    1115         // bottom 
    1116         drawElements->push_back(3); 
    1117         drawElements->push_back(2); 
    1118         drawElements->push_back(6); 
    1119         drawElements->push_back(7); 
    1120  
    1121         // left 
    1122         drawElements->push_back(0); 
    1123         drawElements->push_back(3); 
    1124         drawElements->push_back(7); 
    1125         drawElements->push_back(4); 
    1126  
    1127         // right 
    1128         drawElements->push_back(5); 
    1129         drawElements->push_back(6); 
    1130         drawElements->push_back(2); 
    1131         drawElements->push_back(1); 
    1132  
    1133         // front 
    1134         drawElements->push_back(1); 
    1135         drawElements->push_back(0); 
    1136         drawElements->push_back(4); 
    1137         drawElements->push_back(5); 
    1138  
    1139         // top 
    1140         drawElements->push_back(7); 
    1141         drawElements->push_back(6); 
    1142         drawElements->push_back(5); 
    1143         drawElements->push_back(4); 
    1144  
    1145         geom->addPrimitiveSet(drawElements); 
    1146  
    1147         geode->addDrawable(geom); 
    1148  
    1149     }  
    1150     return root; 
    1151 } 
    1152  
    1153 osg::Node* createModel(ShadingModel shadeModel, 
    1154                        osg::ref_ptr<osg::Image>& image_3d,  
    1155                        osg::ref_ptr<osg::Image>& normalmap_3d, 
    1156                        osg::Texture::InternalFormatMode internalFormatMode, 
    1157                        float xSize, float ySize, float zSize, 
    1158                        float xMultiplier, float yMultiplier, float zMultiplier, 
    1159                        unsigned int numSlices=500, float sliceEnd=1.0f, float alphaFuncValue=0.02f, bool maximumIntensityProjection = false) 
    1160 { 
    1161     bool two_pass = normalmap_3d.valid() && (image_3d->getPixelFormat()==GL_RGB || image_3d->getPixelFormat()==GL_RGBA); 
    1162  
    1163     osg::BoundingBox bb(-xSize*0.5f,-ySize*0.5f,-zSize*0.5f,xSize*0.5f,ySize*0.5f,zSize*0.5f); 
    1164  
    1165  
    1166     osg::Texture::FilterMode minFilter = osg::Texture::NEAREST; 
    1167     osg::Texture::FilterMode magFilter = osg::Texture::NEAREST; 
    1168  
    1169     float maxAxis = xSize; 
    1170     if (ySize > maxAxis) maxAxis = ySize; 
    1171     if (zSize > maxAxis) maxAxis = zSize; 
    1172  
    1173     osg::Group* group = new osg::Group; 
    1174      
    1175     osg::TexGenNode* texgenNode_0 = new osg::TexGenNode; 
    1176     texgenNode_0->setTextureUnit(0); 
    1177     texgenNode_0->getTexGen()->setMode(osg::TexGen::EYE_LINEAR); 
    1178     texgenNode_0->getTexGen()->setPlane(osg::TexGen::S, osg::Plane(xMultiplier/xSize,0.0f,0.0f,0.5f)); 
    1179     texgenNode_0->getTexGen()->setPlane(osg::TexGen::T, osg::Plane(0.0f,yMultiplier/ySize,0.0f,0.5f)); 
    1180     texgenNode_0->getTexGen()->setPlane(osg::TexGen::R, osg::Plane(0.0f,0.0f,zMultiplier/zSize,0.5f)); 
    1181      
    1182     if (two_pass) 
    1183     { 
    1184         osg::TexGenNode* texgenNode_1 = new osg::TexGenNode; 
    1185         texgenNode_1->setTextureUnit(1); 
    1186         texgenNode_1->getTexGen()->setMode(osg::TexGen::EYE_LINEAR); 
    1187         texgenNode_1->getTexGen()->setPlane(osg::TexGen::S, texgenNode_0->getTexGen()->getPlane(osg::TexGen::S)); 
    1188         texgenNode_1->getTexGen()->setPlane(osg::TexGen::T, texgenNode_0->getTexGen()->getPlane(osg::TexGen::T)); 
    1189         texgenNode_1->getTexGen()->setPlane(osg::TexGen::R, texgenNode_0->getTexGen()->getPlane(osg::TexGen::R)); 
    1190  
    1191         texgenNode_1->addChild(texgenNode_0); 
    1192  
    1193         group->addChild(texgenNode_1); 
    1194     } 
    1195     else 
    1196     {   
    1197         group->addChild(texgenNode_0); 
    1198     } 
    1199  
    1200     float cubeSize = sqrtf(xSize*xSize+ySize*ySize+zSize*zSize); 
    1201  
    1202     osg::ClipNode* clipnode = new osg::ClipNode; 
    1203     clipnode->addChild(createCube(cubeSize,1.0f, numSlices,sliceEnd)); 
    1204     clipnode->createClipBox(bb); 
    1205  
    1206     { 
    1207         // set up the Geometry to enclose the clip volume to prevent near/far clipping from affecting billboard 
    1208         osg::Geometry* geom = new osg::Geometry; 
    1209  
    1210         osg::Vec3Array* coords = new osg::Vec3Array(); 
    1211         coords->push_back(bb.corner(0)); 
    1212         coords->push_back(bb.corner(1)); 
    1213         coords->push_back(bb.corner(2)); 
    1214         coords->push_back(bb.corner(3)); 
    1215         coords->push_back(bb.corner(4)); 
    1216         coords->push_back(bb.corner(5)); 
    1217         coords->push_back(bb.corner(6)); 
    1218         coords->push_back(bb.corner(7)); 
    1219  
    1220         geom->setVertexArray(coords); 
    1221  
    1222         osg::Vec4Array* colors = new osg::Vec4Array(1); 
    1223         (*colors)[0].set(1.0f,1.0f,1.0f,1.0f); 
    1224         geom->setColorArray(colors); 
    1225         geom->setColorBinding(osg::Geometry::BIND_OVERALL); 
    1226  
    1227         geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS,0,coords->size())); 
    1228  
    1229         osg::Geode* geode = new osg::Geode; 
    1230         geode->addDrawable(geom); 
    1231          
    1232         clipnode->addChild(geode); 
    1233          
    1234     } 
    1235  
    1236     texgenNode_0->addChild(clipnode); 
    1237  
    1238     osg::StateSet* stateset = texgenNode_0->getOrCreateStateSet(); 
    1239  
    1240     stateset->setEventCallback(new FollowMouseCallback(false)); 
    1241   
    1242     stateset->setMode(GL_LIGHTING,osg::StateAttribute::ON); 
    1243     stateset->setMode(GL_BLEND,osg::StateAttribute::ON); 
    1244     stateset->setAttributeAndModes(new osg::AlphaFunc(osg::AlphaFunc::GREATER,alphaFuncValue), osg::StateAttribute::ON); 
    1245      
    1246     osg::Material* material = new osg::Material; 
    1247     material->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(1.0f,1.0f,1.0f,1.0f)); 
    1248     stateset->setAttributeAndModes(material); 
    1249      
    1250     if (shadeModel==MaximumIntensityProjection) 
    1251     { 
    1252         stateset->setAttribute(new osg::BlendFunc(osg::BlendFunc::ONE, osg::BlendFunc::ONE)); 
    1253         stateset->setAttribute(new osg::BlendEquation(osg::BlendEquation::RGBA_MAX)); 
    1254     } 
    1255      
    1256     osg::Vec3 lightDirection(1.0f,-1.0f,1.0f); 
    1257     lightDirection.normalize(); 
    1258  
    1259     if (normalmap_3d.valid()) 
    1260     { 
    1261         if (two_pass) 
    1262         { 
    1263  
    1264             // set up normal texture 
    1265             osg::Texture3D* bump_texture3D = new osg::Texture3D; 
    1266             bump_texture3D->setFilter(osg::Texture3D::MIN_FILTER,minFilter); 
    1267             bump_texture3D->setFilter(osg::Texture3D::MAG_FILTER, magFilter); 
    1268             bump_texture3D->setWrap(osg::Texture3D::WRAP_R,osg::Texture3D::CLAMP_TO_EDGE); 
    1269             bump_texture3D->setWrap(osg::Texture3D::WRAP_S,osg::Texture3D::CLAMP_TO_EDGE); 
    1270             bump_texture3D->setWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP_TO_EDGE); 
    1271             bump_texture3D->setImage(normalmap_3d.get()); 
    1272  
    1273             bump_texture3D->setInternalFormatMode(internalFormatMode); 
    1274  
    1275             stateset->setTextureAttributeAndModes(0,bump_texture3D,osg::StateAttribute::ON); 
    1276  
    1277             osg::TexEnvCombine* tec = new osg::TexEnvCombine; 
    1278             tec->setConstantColorAsLightDirection(lightDirection); 
    1279  
    1280             tec->setCombine_RGB(osg::TexEnvCombine::DOT3_RGB); 
    1281             tec->setSource0_RGB(osg::TexEnvCombine::CONSTANT); 
    1282             tec->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); 
    1283             tec->setSource1_RGB(osg::TexEnvCombine::TEXTURE); 
    1284  
    1285             tec->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); 
    1286  
    1287             tec->setCombine_Alpha(osg::TexEnvCombine::REPLACE); 
    1288             tec->setSource0_Alpha(osg::TexEnvCombine::PRIMARY_COLOR); 
    1289             tec->setOperand0_Alpha(osg::TexEnvCombine::SRC_ALPHA); 
    1290             tec->setSource1_Alpha(osg::TexEnvCombine::TEXTURE); 
    1291             tec->setOperand1_Alpha(osg::TexEnvCombine::SRC_ALPHA); 
    1292  
    1293             stateset->setTextureAttributeAndModes(0, tec, osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON); 
    1294  
    1295             stateset->setTextureMode(0,GL_TEXTURE_GEN_S,osg::StateAttribute::ON); 
    1296             stateset->setTextureMode(0,GL_TEXTURE_GEN_T,osg::StateAttribute::ON); 
    1297             stateset->setTextureMode(0,GL_TEXTURE_GEN_R,osg::StateAttribute::ON); 
    1298  
    1299  
    1300             // set up color texture 
    1301             osg::Texture3D* texture3D = new osg::Texture3D; 
    1302             texture3D->setResizeNonPowerOfTwoHint(false); 
    1303             texture3D->setFilter(osg::Texture3D::MIN_FILTER,minFilter); 
    1304             texture3D->setFilter(osg::Texture3D::MAG_FILTER, magFilter); 
    1305             texture3D->setWrap(osg::Texture3D::WRAP_R,osg::Texture3D::CLAMP_TO_EDGE); 
    1306             texture3D->setWrap(osg::Texture3D::WRAP_S,osg::Texture3D::CLAMP_TO_EDGE); 
    1307             texture3D->setWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP_TO_EDGE); 
    1308             if (image_3d->getPixelFormat()==GL_ALPHA ||  
    1309                 image_3d->getPixelFormat()==GL_LUMINANCE) 
    1310             { 
    1311                 texture3D->setInternalFormatMode(osg::Texture3D::USE_USER_DEFINED_FORMAT); 
    1312                 texture3D->setInternalFormat(GL_INTENSITY); 
    1313             } 
    1314             else 
    1315             { 
    1316                 texture3D->setInternalFormatMode(internalFormatMode); 
    1317             } 
    1318             texture3D->setImage(image_3d.get()); 
    1319  
    1320             stateset->setTextureAttributeAndModes(1,texture3D,osg::StateAttribute::ON); 
    1321  
    1322             stateset->setTextureMode(1,GL_TEXTURE_GEN_S,osg::StateAttribute::ON); 
    1323             stateset->setTextureMode(1,GL_TEXTURE_GEN_T,osg::StateAttribute::ON); 
    1324             stateset->setTextureMode(1,GL_TEXTURE_GEN_R,osg::StateAttribute::ON); 
    1325  
    1326             stateset->setTextureAttributeAndModes(1,new osg::TexEnv(),osg::StateAttribute::ON); 
    1327  
    1328         } 
    1329         else 
    1330         { 
    1331             osg::Texture3D* bump_texture3D = new osg::Texture3D; 
    1332             bump_texture3D->setResizeNonPowerOfTwoHint(false); 
    1333             bump_texture3D->setFilter(osg::Texture3D::MIN_FILTER,minFilter); 
    1334             bump_texture3D->setFilter(osg::Texture3D::MAG_FILTER, magFilter); 
    1335             bump_texture3D->setWrap(osg::Texture3D::WRAP_R,osg::Texture3D::CLAMP_TO_EDGE); 
    1336             bump_texture3D->setWrap(osg::Texture3D::WRAP_S,osg::Texture3D::CLAMP_TO_EDGE); 
    1337             bump_texture3D->setWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP_TO_EDGE); 
    1338             bump_texture3D->setImage(normalmap_3d.get()); 
    1339  
    1340             bump_texture3D->setInternalFormatMode(internalFormatMode); 
    1341  
    1342             stateset->setTextureAttributeAndModes(0,bump_texture3D,osg::StateAttribute::ON); 
    1343  
    1344             osg::TexEnvCombine* tec = new osg::TexEnvCombine; 
    1345             tec->setConstantColorAsLightDirection(lightDirection); 
    1346  
    1347             tec->setCombine_RGB(osg::TexEnvCombine::DOT3_RGB); 
    1348             tec->setSource0_RGB(osg::TexEnvCombine::CONSTANT); 
    1349             tec->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); 
    1350             tec->setSource1_RGB(osg::TexEnvCombine::TEXTURE); 
    1351             tec->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); 
    1352  
    1353             tec->setCombine_Alpha(osg::TexEnvCombine::MODULATE); 
    1354             tec->setSource0_Alpha(osg::TexEnvCombine::PRIMARY_COLOR); 
    1355             tec->setOperand0_Alpha(osg::TexEnvCombine::SRC_ALPHA); 
    1356             tec->setSource1_Alpha(osg::TexEnvCombine::TEXTURE); 
    1357             tec->setOperand1_Alpha(osg::TexEnvCombine::SRC_ALPHA); 
    1358  
    1359             stateset->setTextureAttributeAndModes(0, tec, osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON); 
    1360  
    1361             stateset->setTextureMode(0,GL_TEXTURE_GEN_S,osg::StateAttribute::ON); 
    1362             stateset->setTextureMode(0,GL_TEXTURE_GEN_T,osg::StateAttribute::ON); 
    1363             stateset->setTextureMode(0,GL_TEXTURE_GEN_R,osg::StateAttribute::ON); 
    1364  
    1365             image_3d = normalmap_3d; 
    1366         } 
    1367     } 
    1368     else 
    1369     {      
    1370         // set up the 3d texture itself, 
    1371         // note, well set the filtering up so that mip mapping is disabled, 
    1372         // gluBuild3DMipsmaps doesn't do a very good job of handled the 
    1373         // imbalanced dimensions of the 256x256x4 texture. 
    1374         osg::Texture3D* texture3D = new osg::Texture3D; 
    1375         texture3D->setResizeNonPowerOfTwoHint(false); 
    1376         texture3D->setFilter(osg::Texture3D::MIN_FILTER,minFilter); 
    1377         texture3D->setFilter(osg::Texture3D::MAG_FILTER, magFilter); 
    1378         texture3D->setWrap(osg::Texture3D::WRAP_R,osg::Texture3D::CLAMP_TO_EDGE); 
    1379         texture3D->setWrap(osg::Texture3D::WRAP_S,osg::Texture3D::CLAMP_TO_EDGE); 
    1380         texture3D->setWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP_TO_EDGE); 
    1381         if (image_3d->getPixelFormat()==GL_ALPHA ||  
    1382             image_3d->getPixelFormat()==GL_LUMINANCE) 
    1383         { 
    1384             texture3D->setInternalFormatMode(osg::Texture3D::USE_USER_DEFINED_FORMAT); 
    1385             texture3D->setInternalFormat(GL_INTENSITY); 
    1386         } 
    1387         else 
    1388         { 
    1389             texture3D->setInternalFormatMode(internalFormatMode); 
    1390         } 
    1391  
    1392         texture3D->setImage(image_3d.get()); 
    1393  
    1394         stateset->setTextureAttributeAndModes(0,texture3D,osg::StateAttribute::ON); 
    1395  
    1396         stateset->setTextureMode(0,GL_TEXTURE_GEN_S,osg::StateAttribute::ON); 
    1397         stateset->setTextureMode(0,GL_TEXTURE_GEN_T,osg::StateAttribute::ON); 
    1398         stateset->setTextureMode(0,GL_TEXTURE_GEN_R,osg::StateAttribute::ON); 
    1399  
    1400         stateset->setTextureAttributeAndModes(0,new osg::TexEnv(),osg::StateAttribute::ON); 
    1401     } 
    1402   
    1403     return group; 
    1404 } 
    1405  
    1406568struct ScaleOperator 
    1407569{ 
     
    1652814 
    1653815 
    1654 struct ApplyTransferFunctionOperator 
    1655 { 
    1656     ApplyTransferFunctionOperator(osg::TransferFunction1D* tf, unsigned char* data): 
    1657         _tf(tf), 
    1658         _data(data) {} 
    1659          
    1660     inline void luminance(float l) const 
    1661     { 
    1662         osg::Vec4 c = _tf->getInterpolatedValue(l); 
    1663         //std::cout<<"l = "<<l<<" c="<<c<<std::endl; 
    1664         *(_data++) = (unsigned char)(c[0]*255.0f + 0.5f); 
    1665         *(_data++) = (unsigned char)(c[1]*255.0f + 0.5f); 
    1666         *(_data++) = (unsigned char)(c[2]*255.0f + 0.5f); 
    1667         *(_data++) = (unsigned char)(c[3]*255.0f + 0.5f); 
    1668     } 
    1669       
    1670     inline void alpha(float a) const 
    1671     { 
    1672         luminance(a); 
    1673     }  
    1674      
    1675     inline void luminance_alpha(float l,float a) const 
    1676     {  
    1677         luminance(l); 
    1678     } 
    1679       
    1680     inline void rgb(float r,float g,float b) const 
    1681     { 
    1682         luminance((r+g+b)*0.3333333); 
    1683     } 
    1684      
    1685     inline void rgba(float r,float g,float b,float a) const 
    1686     { 
    1687         luminance(a); 
    1688     } 
    1689      
    1690     mutable osg::ref_ptr<osg::TransferFunction1D> _tf; 
    1691     mutable unsigned char* _data; 
    1692 }; 
    1693  
    1694 osg::Image* applyTransferFunction(osg::Image* image, osg::TransferFunction1D* transferFunction) 
    1695 { 
    1696     std::cout<<"Applying transfer function"<<std::endl; 
    1697     osg::Image* output_image = new osg::Image; 
    1698     output_image->allocateImage(image->s(),image->t(), image->r(), GL_RGBA, GL_UNSIGNED_BYTE); 
    1699      
    1700     ApplyTransferFunctionOperator op(transferFunction, output_image->data()); 
    1701     osg::readImage(image,op);  
    1702      
    1703     return output_image; 
    1704 } 
    1705  
    1706816osg::TransferFunction1D* readTransferFunctionFile(const std::string& filename) 
    1707817{ 
     
    1777887    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); 
    1778888    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); 
    1779     arguments.getApplicationUsage()->addCommandLineOption("-n","Create normal map for per voxel lighting."); 
    1780889    arguments.getApplicationUsage()->addCommandLineOption("-s <numSlices>","Number of slices to create."); 
    1781890    arguments.getApplicationUsage()->addCommandLineOption("--images [filenames]","Specify a stack of 2d images to build the 3d volume from."); 
     
    1867976    while(arguments.read("--mip")) shadingModel =  MaximumIntensityProjection; 
    1868977 
    1869     bool createNormalMap = false; 
    1870     while (arguments.read("-n"))  
    1871     { 
    1872         shadingModel = Light; 
    1873         createNormalMap=true; 
    1874     } 
    1875  
    1876978    while (arguments.read("--isosurface"))  
    1877979    { 
     
    21301232 
    21311233    osg::RefMatrix* matrix = dynamic_cast<osg::RefMatrix*>(images.front()->getUserData()); 
    2132 #if 0 
    2133     if (matrix) 
    2134     { 
    2135         osg::notify(osg::NOTICE)<<"Image has Matrix = "<<*matrix<<std::endl; 
    2136         xSize = xSize * (*matrix)(0,0); 
    2137         ySize = ySize * (*matrix)(1,1); 
    2138         zSize = zSize * (*matrix)(2,2); 
    2139     } 
    2140 #endif 
    21411234 
    21421235    osg::Vec4 minValue(FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX); 
     
    22371330            ++itr) 
    22381331        {         
    2239             *itr = applyTransferFunction(itr->get(), transferFunction.get()); 
     1332            *itr = osgVolume::applyTransferFunction(itr->get(), transferFunction.get()); 
    22401333        } 
    22411334    } 
     
    22641357    } 
    22651358     
    2266     osg::ref_ptr<osg::Image> normalmap_3d = 0; 
    2267     if (createNormalMap) 
    2268     { 
    2269         if (images.size()==1) 
    2270         { 
    2271             normalmap_3d = createNormalMapTexture(images.front().get()); 
    2272         } 
    2273         else 
    2274         { 
    2275             osg::ref_ptr<osg::ImageSequence> normalmapSequence = new osg::ImageSequence; 
    2276             normalmap_3d = normalmapSequence.get(); 
    2277             for(Images::iterator itr = images.begin(); 
    2278                 itr != images.end(); 
    2279                 ++itr) 
    2280             {         
    2281                 normalmapSequence->addImage(createNormalMapTexture(itr->get())); 
    2282             } 
    2283             normalmapSequence->play(); 
    2284         } 
    2285     } 
    2286  
    22871359    // create a model from the images. 
    22881360    osg::ref_ptr<osg::Node> rootNode = 0; 
    22891361     
    2290     if (useOsgVolume) 
    22911362    { 
    22921363 
     
    23351406         
    23361407        rootNode = volume.get();         
    2337  
    2338     } 
    2339     else 
    2340     { 
    2341         if (useShader) 
    2342         { 
    2343             rootNode = createShaderModel(shadingModel,  
    2344                                    image_3d, normalmap_3d.get(),  
    2345                                    (gpuTransferFunction ? transferFunction.get() : 0), 
    2346                                    internalFormatMode, 
    2347                                    xSize, ySize, zSize, 
    2348                                    xMultiplier, yMultiplier, zMultiplier, 
    2349                                    numSlices, sliceEnd, alphaFunc); 
    2350         } 
    2351         else 
    2352         { 
    2353             rootNode = createModel(shadingModel, 
    2354                                    image_3d, normalmap_3d,  
    2355                                    internalFormatMode, 
    2356                                    xSize, ySize, zSize, 
    2357                                    xMultiplier, yMultiplier, zMultiplier, 
    2358                                    numSlices, sliceEnd, alphaFunc); 
    2359         } 
    2360          
    2361         if (matrix && rootNode) 
    2362         { 
    2363             osg::MatrixTransform* mt = new osg::MatrixTransform; 
    2364             mt->setMatrix(*matrix); 
    2365             mt->addChild(rootNode); 
    2366  
    2367             rootNode = mt; 
    2368         } 
    23691408    } 
    23701409         
     
    23801419                osgDB::writeImageFile(*image_3d, image_3d->getFileName()); 
    23811420            } 
    2382             if (normalmap_3d.valid()) 
    2383             { 
    2384                 normalmap_3d->setFileName(name_no_ext + "_normalmap.dds");             
    2385                 osgDB::writeImageFile(*normalmap_3d, normalmap_3d->getFileName()); 
    2386             } 
    2387              
    23881421            osgDB::writeNodeFile(*rootNode, outputFile); 
    23891422        }