diff --git a/examples/osgvolume/osgvolume.cpp b/examples/osgvolume/osgvolume.cpp index 1c899687b..a7449dfa5 100644 --- a/examples/osgvolume/osgvolume.cpp +++ b/examples/osgvolume/osgvolume.cpp @@ -69,6 +69,8 @@ #include #include #include +#include +#include enum ShadingModel { @@ -437,6 +439,9 @@ int main( int argc, char **argv ) arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); arguments.getApplicationUsage()->addCommandLineOption("--images [filenames]","Specify a stack of 2d images to build the 3d volume from."); arguments.getApplicationUsage()->addCommandLineOption("--shader","Use OpenGL Shading Language. (default)"); + arguments.getApplicationUsage()->addCommandLineOption("--multi-pass","Use MultipassTechnique to render volumes."); + arguments.getApplicationUsage()->addCommandLineOption("--model","load 3D model and insert into the scene along with the volume."); + arguments.getApplicationUsage()->addCommandLineOption("--hull","load 3D hull that defines the extents of the region to volume render."); arguments.getApplicationUsage()->addCommandLineOption("--no-shader","Disable use of OpenGL Shading Language."); arguments.getApplicationUsage()->addCommandLineOption("--gpu-tf","Aply the transfer function on the GPU. (default)"); arguments.getApplicationUsage()->addCommandLineOption("--cpu-tf","Apply the transfer function on the CPU."); @@ -618,11 +623,36 @@ int main( int argc, char **argv ) bool useManipulator = false; while(arguments.read("--manipulator") || arguments.read("-m")) { useManipulator = true; } - bool useShader = true; while(arguments.read("--shader")) { useShader = true; } while(arguments.read("--no-shader")) { useShader = false; } + bool useMultipass = false; + while(arguments.read("--multi-pass")) useMultipass = true; + + std::string filename; + osg::ref_ptr models; + while(arguments.read("--model",filename)) + { + osg::ref_ptr model = osgDB::readNodeFile(filename); + if (model.valid()) + { + if (!models) models = new osg::Group; + models->addChild(model.get()); + } + } + + osg::ref_ptr hulls; + while(arguments.read("--hull",filename)) + { + osg::ref_ptr hull = osgDB::readNodeFile(filename); + if (hull.valid()) + { + if (!hulls) hulls = new osg::Group; + hulls->addChild(hull.get()); + } + } + bool gpuTransferFunction = true; while(arguments.read("--gpu-tf")) { gpuTransferFunction = true; } while(arguments.read("--cpu-tf")) { gpuTransferFunction = false; } @@ -1098,7 +1128,14 @@ int main( int argc, char **argv ) layer->addProperty(sp); - tile->setVolumeTechnique(new osgVolume::RayTracedTechnique); + if (useMultipass) + { + tile->setVolumeTechnique(new osgVolume::MultipassTechnique); + } + else + { + tile->setVolumeTechnique(new osgVolume::RayTracedTechnique); + } } else { @@ -1165,6 +1202,28 @@ int main( int argc, char **argv ) loadedModel = group; } + if (hulls.get()) + { + tile->addChild(hulls.get()); + } + + // add add models into the scene alongside the volume + if (models.get()) + { + osg::ref_ptr group = new osg::Group; + group->addChild(models.get()); + group->addChild(loadedModel.get()); + loadedModel = group.get(); + } + + // if we want to do multi-pass volume rendering we need decorate the whole scene with a VolumeScene node. + if (useMultipass) + { + osg::ref_ptr volumeScene = new osgVolume::VolumeScene; + volumeScene->addChild(loadedModel.get()); + loadedModel = volumeScene.get(); + } + // set the scene to render viewer.setSceneData(loadedModel.get()); diff --git a/include/osgVolume/MultipassTechnique b/include/osgVolume/MultipassTechnique new file mode 100644 index 000000000..beb2ac6db --- /dev/null +++ b/include/osgVolume/MultipassTechnique @@ -0,0 +1,60 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGVOLUME_MULTIPASSTECHNIQUE +#define OSGVOLUME_MULTIPASSTECHNIQUE 1 + +#include +#include + +namespace osgVolume { + +class OSGVOLUME_EXPORT MultipassTechnique : public VolumeTechnique +{ + public: + + MultipassTechnique(); + + MultipassTechnique(const MultipassTechnique&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Object(osgVolume, MultipassTechnique); + + virtual void init(); + + virtual void update(osgUtil::UpdateVisitor* nv); + + virtual void cull(osgUtil::CullVisitor* nv); + + /** Clean scene graph from any terrain technique specific nodes.*/ + virtual void cleanSceneGraph(); + + /** Traverse the terrain subgraph.*/ + virtual void traverse(osg::NodeVisitor& nv); + + protected: + + virtual ~MultipassTechnique(); + + osg::ref_ptr _transform; + + typedef std::map ModelViewMatrixMap; + + OpenThreads::Mutex _mutex; + ModelViewMatrixMap _modelViewMatrixMap; + + osg::ref_ptr _whenMovingStateSet; +}; + +} + +#endif diff --git a/include/osgVolume/VolumeScene b/include/osgVolume/VolumeScene new file mode 100644 index 000000000..ad2edd72c --- /dev/null +++ b/include/osgVolume/VolumeScene @@ -0,0 +1,44 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGVOLUMESCENE +#define OSGVOLUMESCENE 1 + +#include +#include + +namespace osgVolume { + +/** VolumeScene provides high level support for doing multi-pass rendering of volumes where the main scene to rendered to color and depth textures and then re-rendered for the purposes of volume rendering.*/ +class OSGVOLUME_EXPORT VolumeScene : public osg::Group +{ + public: + + VolumeScene(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + VolumeScene(const VolumeScene&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Node(osgVolume, VolumeScene); + + virtual void traverse(osg::NodeVisitor& nv); + + protected: + + virtual ~VolumeScene(); + +}; + +} + +#endif diff --git a/src/osgVolume/CMakeLists.txt b/src/osgVolume/CMakeLists.txt index ad3a89201..6f530a2d9 100644 --- a/src/osgVolume/CMakeLists.txt +++ b/src/osgVolume/CMakeLists.txt @@ -12,10 +12,12 @@ SET(TARGET_H ${HEADER_PATH}/FixedFunctionTechnique ${HEADER_PATH}/Layer ${HEADER_PATH}/Locator + ${HEADER_PATH}/MultipassTechnique ${HEADER_PATH}/Property ${HEADER_PATH}/RayTracedTechnique ${HEADER_PATH}/Version ${HEADER_PATH}/Volume + ${HEADER_PATH}/VolumeScene ${HEADER_PATH}/VolumeTechnique ${HEADER_PATH}/VolumeTile ) @@ -25,17 +27,19 @@ SET(TARGET_SRC FixedFunctionTechnique.cpp Layer.cpp Locator.cpp + MultipassTechnique.cpp Property.cpp RayTracedTechnique.cpp Version.cpp Volume.cpp + VolumeScene.cpp VolumeTechnique.cpp VolumeTile.cpp ${OPENSCENEGRAPH_VERSIONINFO_RC} ) -SET(TARGET_LIBRARIES +SET(TARGET_LIBRARIES osgUtil osgDB osgGA diff --git a/src/osgVolume/MultipassTechnique.cpp b/src/osgVolume/MultipassTechnique.cpp new file mode 100644 index 000000000..144932a64 --- /dev/null +++ b/src/osgVolume/MultipassTechnique.cpp @@ -0,0 +1,124 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace osgVolume +{ + + +MultipassTechnique::MultipassTechnique() +{ +} + +MultipassTechnique::MultipassTechnique(const MultipassTechnique& fft,const osg::CopyOp& copyop): + VolumeTechnique(fft,copyop) +{ +} + +MultipassTechnique::~MultipassTechnique() +{ +} + +void MultipassTechnique::init() +{ + OSG_INFO<<"MultipassTechnique::init()"<getLayer()==0) + { + OSG_NOTICE<<"MultipassTechnique::init(), error no layer assigend to volume tile."<getLayer()->getImage()==0) + { + OSG_NOTICE<<"MultipassTechnique::init(), error no image assigned to layer."<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_INFO<<"******* Doing init ***********"<init(); + } +} + + +} // end of osgVolume namespace diff --git a/src/osgVolume/VolumeScene.cpp b/src/osgVolume/VolumeScene.cpp new file mode 100644 index 000000000..40f230f09 --- /dev/null +++ b/src/osgVolume/VolumeScene.cpp @@ -0,0 +1,36 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include +#include + +using namespace osgVolume; + +VolumeScene::VolumeScene() +{ +} + +VolumeScene::VolumeScene(const VolumeScene& vs, const osg::CopyOp& copyop): + osg::Group(vs,copyop) +{ +} + + +VolumeScene::~VolumeScene() +{ +} + +void VolumeScene::traverse(osg::NodeVisitor& nv) +{ + Group::traverse(nv); +}