diff --git a/examples/osgvolume/osgvolume.cpp b/examples/osgvolume/osgvolume.cpp index f119fe239..e1b568287 100644 --- a/examples/osgvolume/osgvolume.cpp +++ b/examples/osgvolume/osgvolume.cpp @@ -1948,7 +1948,7 @@ int main( int argc, char **argv ) bool useShader = true; while(arguments.read("--shader")) { useShader = true; } - while(arguments.read("--no-shader")) { useShader = true; } + while(arguments.read("--no-shader")) { useShader = false; } bool gpuTransferFunction = true; while(arguments.read("--gpu-tf")) { gpuTransferFunction = true; } diff --git a/include/osgVolume/FixedFunctionTechnique b/include/osgVolume/FixedFunctionTechnique index a0e0019e0..c87bac703 100644 --- a/include/osgVolume/FixedFunctionTechnique +++ b/include/osgVolume/FixedFunctionTechnique @@ -44,6 +44,8 @@ class OSGVOLUME_EXPORT FixedFunctionTechnique : public VolumeTechnique protected: virtual ~FixedFunctionTechnique(); + + osg::ref_ptr _node; }; } diff --git a/include/osgVolume/Property b/include/osgVolume/Property index 9d9d5a275..3e0727bc3 100644 --- a/include/osgVolume/Property +++ b/include/osgVolume/Property @@ -48,6 +48,7 @@ class PropertyVisitor virtual void apply(LightingProperty&) {} }; + class OSGVOLUME_EXPORT Property : public osg::Object { public: @@ -238,6 +239,30 @@ class OSGVOLUME_EXPORT LightingProperty : public Property }; +class OSGVOLUME_EXPORT CollectPropertiesVisitor : public osgVolume::PropertyVisitor +{ + public: + + CollectPropertiesVisitor(); + + virtual void apply(Property&); + + virtual void apply(CompositeProperty& cp); + virtual void apply(TransferFunctionProperty& tf); + virtual void apply(ScalarProperty&); + virtual void apply(IsoSurfaceProperty& iso); + virtual void apply(AlphaFuncProperty& af); + virtual void apply(MaximumIntensityProjectionProperty& mip); + virtual void apply(LightingProperty& lp); + + osg::ref_ptr _tfProperty; + osg::ref_ptr _isoProperty; + osg::ref_ptr _afProperty; + osg::ref_ptr _mipProperty; + osg::ref_ptr _lightingProperty; + +}; + } #endif diff --git a/src/osgVolume/FixedFunctionTechnique.cpp b/src/osgVolume/FixedFunctionTechnique.cpp index 390278a48..af42e0085 100644 --- a/src/osgVolume/FixedFunctionTechnique.cpp +++ b/src/osgVolume/FixedFunctionTechnique.cpp @@ -12,6 +12,19 @@ */ #include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include using namespace osgVolume; @@ -28,19 +41,235 @@ FixedFunctionTechnique::~FixedFunctionTechnique() { } +osg::Node* createCube(float size,float alpha, unsigned int numSlices, float sliceEnd=1.0f) +{ + + // set up the Geometry. + osg::Geometry* geom = new osg::Geometry; + + float halfSize = size*0.5f; + float y = halfSize; + float dy =-size/(float)(numSlices-1)*sliceEnd; + + //y = -halfSize; + //dy *= 0.5; + + osg::Vec3Array* coords = new osg::Vec3Array(4*numSlices); + geom->setVertexArray(coords); + for(unsigned int i=0;isetNormalArray(normals); + geom->setNormalBinding(osg::Geometry::BIND_OVERALL); + + osg::Vec4Array* colors = new osg::Vec4Array(1); + (*colors)[0].set(1.0f,1.0f,1.0f,alpha); + geom->setColorArray(colors); + geom->setColorBinding(osg::Geometry::BIND_OVERALL); + + geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,coords->size())); + + osg::Billboard* billboard = new osg::Billboard; + billboard->setMode(osg::Billboard::POINT_ROT_WORLD); + billboard->addDrawable(geom); + billboard->setPosition(0,osg::Vec3(0.0f,0.0f,0.0f)); + + return billboard; +} + + void FixedFunctionTechnique::init() { osg::notify(osg::NOTICE)<<"FixedFunctionTechnique::init()"<getLocator(); + osg::Texture::InternalFormatMode internalFormatMode = osg::Texture::USE_IMAGE_DATA_FORMAT; + + image_3d = _volumeTile->getLayer()->getImage(); + + CollectPropertiesVisitor cpv; + if (_volumeTile->getLayer()->getProperty()) + { + _volumeTile->getLayer()->getProperty()->accept(cpv); + } + + if (cpv._isoProperty.valid()) + { + alphaFuncValue = cpv._isoProperty->getValue(); + } + + if (cpv._tfProperty.valid()) + { + tf = dynamic_cast(cpv._tfProperty->getTransferFunction()); + } + + if (cpv._afProperty.valid()) + { + alphaFuncValue = cpv._afProperty->getValue(); + } + + + if (_volumeTile->getLayer() && !masterLocator) + { + masterLocator = _volumeTile->getLayer()->getLocator(); + osg::notify(osg::NOTICE)<<"assigning locator = "<getTransform(); + } + + osg::notify(osg::NOTICE)<<"Matrix = "< maxAxis) maxAxis = ySize; + if (zSize > maxAxis) maxAxis = zSize; + + osg::Group* group = new osg::Group; + + osg::TexGenNode* texgenNode_0 = new osg::TexGenNode; + texgenNode_0->setTextureUnit(0); + texgenNode_0->getTexGen()->setMode(osg::TexGen::EYE_LINEAR); + texgenNode_0->getTexGen()->setPlane(osg::TexGen::S, osg::Plane(xMultiplier/xSize,0.0f,0.0f,0.5f)); + texgenNode_0->getTexGen()->setPlane(osg::TexGen::T, osg::Plane(0.0f,yMultiplier/ySize,0.0f,0.5f)); + texgenNode_0->getTexGen()->setPlane(osg::TexGen::R, osg::Plane(0.0f,0.0f,zMultiplier/zSize,0.5f)); + + group->addChild(texgenNode_0); + + float cubeSize = sqrtf(xSize*xSize+ySize*ySize+zSize*zSize); + + osg::ClipNode* clipnode = new osg::ClipNode; + clipnode->addChild(createCube(cubeSize,1.0f, numSlices,sliceEnd)); + clipnode->createClipBox(bb); + + { + // set up the Geometry to enclose the clip volume to prevent near/far clipping from affecting billboard + osg::Geometry* geom = new osg::Geometry; + + osg::Vec3Array* coords = new osg::Vec3Array(); + coords->push_back(bb.corner(0)); + coords->push_back(bb.corner(1)); + coords->push_back(bb.corner(2)); + coords->push_back(bb.corner(3)); + coords->push_back(bb.corner(4)); + coords->push_back(bb.corner(5)); + coords->push_back(bb.corner(6)); + coords->push_back(bb.corner(7)); + + geom->setVertexArray(coords); + + osg::Vec4Array* colors = new osg::Vec4Array(1); + (*colors)[0].set(1.0f,1.0f,1.0f,1.0f); + geom->setColorArray(colors); + geom->setColorBinding(osg::Geometry::BIND_OVERALL); + + geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS,0,coords->size())); + + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geom); + + clipnode->addChild(geode); + + } + + texgenNode_0->addChild(clipnode); + + osg::StateSet* stateset = texgenNode_0->getOrCreateStateSet(); + + stateset->setMode(GL_LIGHTING,osg::StateAttribute::ON); + stateset->setMode(GL_BLEND,osg::StateAttribute::ON); + stateset->setAttributeAndModes(new osg::AlphaFunc(osg::AlphaFunc::GREATER,alphaFuncValue), osg::StateAttribute::ON); + + osg::Material* material = new osg::Material; + material->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + stateset->setAttributeAndModes(material); + + if (cpv._mipProperty.valid()) + { + stateset->setAttribute(new osg::BlendFunc(osg::BlendFunc::ONE, osg::BlendFunc::ONE)); + stateset->setAttribute(new osg::BlendEquation(osg::BlendEquation::RGBA_MAX)); + } + + + // set up the 3d texture itself, + // note, well set the filtering up so that mip mapping is disabled, + // gluBuild3DMipsmaps doesn't do a very good job of handled the + // imbalanced dimensions of the 256x256x4 texture. + osg::Texture3D* texture3D = new osg::Texture3D; + texture3D->setResizeNonPowerOfTwoHint(false); + texture3D->setFilter(osg::Texture3D::MIN_FILTER,minFilter); + texture3D->setFilter(osg::Texture3D::MAG_FILTER, magFilter); + texture3D->setWrap(osg::Texture3D::WRAP_R,osg::Texture3D::CLAMP_TO_EDGE); + texture3D->setWrap(osg::Texture3D::WRAP_S,osg::Texture3D::CLAMP_TO_EDGE); + texture3D->setWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP_TO_EDGE); + if (image_3d->getPixelFormat()==GL_ALPHA || + image_3d->getPixelFormat()==GL_LUMINANCE) + { + texture3D->setInternalFormatMode(osg::Texture3D::USE_USER_DEFINED_FORMAT); + texture3D->setInternalFormat(GL_INTENSITY); + } + else + { + texture3D->setInternalFormatMode(internalFormatMode); + } + + texture3D->setImage(image_3d); + + stateset->setTextureAttributeAndModes(0,texture3D,osg::StateAttribute::ON); + + stateset->setTextureMode(0,GL_TEXTURE_GEN_S,osg::StateAttribute::ON); + stateset->setTextureMode(0,GL_TEXTURE_GEN_T,osg::StateAttribute::ON); + stateset->setTextureMode(0,GL_TEXTURE_GEN_R,osg::StateAttribute::ON); + + stateset->setTextureAttributeAndModes(0,new osg::TexEnv(),osg::StateAttribute::ON); + + + _node = group; } -void FixedFunctionTechnique::update(osgUtil::UpdateVisitor* nv) +void FixedFunctionTechnique::update(osgUtil::UpdateVisitor* uv) { - osg::notify(osg::NOTICE)<<"FixedFunctionTechnique:update(osgUtil::UpdateVisitor* nv):"<accept(*cv); + } } void FixedFunctionTechnique::cleanSceneGraph() @@ -50,6 +279,37 @@ void FixedFunctionTechnique::cleanSceneGraph() void FixedFunctionTechnique::traverse(osg::NodeVisitor& nv) { - osg::notify(osg::NOTICE)<<"FixedFunctionTechnique::traverse(osg::NodeVisitor& nv)"<getDirty()) _volumeTile->init(); + + osgUtil::UpdateVisitor* uv = dynamic_cast(&nv); + if (uv) + { + update(uv); + return; + } + + } + else if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR) + { + osgUtil::CullVisitor* cv = dynamic_cast(&nv); + if (cv) + { + cull(cv); + return; + } + } + + + if (_volumeTile->getDirty()) + { + osg::notify(osg::INFO)<<"******* Doing init ***********"<init(); + } } diff --git a/src/osgVolume/Property.cpp b/src/osgVolume/Property.cpp index 00e040449..ca0e45199 100644 --- a/src/osgVolume/Property.cpp +++ b/src/osgVolume/Property.cpp @@ -138,3 +138,26 @@ LightingProperty::LightingProperty(const LightingProperty& isp,const osg::CopyOp Property(isp, copyop) { } + +///////////////////////////////////////////////////////////////////////////// +// +// CollectPropertiesVisitor +// +CollectPropertiesVisitor::CollectPropertiesVisitor() {} + +void CollectPropertiesVisitor::apply(Property&) {} + +void CollectPropertiesVisitor::apply(CompositeProperty& cp) +{ + for(unsigned int i=0; iaccept(*this); + } +} + +void CollectPropertiesVisitor::apply(TransferFunctionProperty& tf) { _tfProperty = &tf; } +void CollectPropertiesVisitor::apply(ScalarProperty&) {} +void CollectPropertiesVisitor::apply(IsoSurfaceProperty& iso) { _isoProperty = &iso; } +void CollectPropertiesVisitor::apply(AlphaFuncProperty& af) { _afProperty = ⁡ } +void CollectPropertiesVisitor::apply(MaximumIntensityProjectionProperty& mip) { _mipProperty = &mip; } +void CollectPropertiesVisitor::apply(LightingProperty& lp) { _lightingProperty = &lp; }