diff --git a/examples/osgvolume/osgvolume.cpp b/examples/osgvolume/osgvolume.cpp index a7449dfa5..85cc74b53 100644 --- a/examples/osgvolume/osgvolume.cpp +++ b/examples/osgvolume/osgvolume.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -490,6 +491,9 @@ int main( int argc, char **argv ) // add the stats handler viewer.addEventHandler(new osgViewer::StatsHandler); + // add stateset manipulator + viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); + viewer.getCamera()->setClearColor(osg::Vec4(0.0f,0.0f,0.0f,0.0f)); // if user request help write it out to cout. @@ -1225,6 +1229,8 @@ int main( int argc, char **argv ) } + + // set the scene to render viewer.setSceneData(loadedModel.get()); diff --git a/include/osgVolume/VolumeScene b/include/osgVolume/VolumeScene index ad2edd72c..63ad7f26a 100644 --- a/include/osgVolume/VolumeScene +++ b/include/osgVolume/VolumeScene @@ -15,6 +15,8 @@ #define OSGVOLUMESCENE 1 #include +#include +#include #include namespace osgVolume { @@ -37,6 +39,22 @@ class OSGVOLUME_EXPORT VolumeScene : public osg::Group virtual ~VolumeScene(); + class ViewData : public osg::Referenced + { + public: + ViewData(); + osg::ref_ptr _depthTexture; + osg::ref_ptr _colorTexture; + osg::ref_ptr _rttCamera; + osg::ref_ptr _postCamera; + osg::ref_ptr _parentRenderStage; + protected: + virtual ~ViewData() {} + }; + + typedef std::map< osgUtil::CullVisitor*, osg::ref_ptr > ViewDataMap; + OpenThreads::Mutex _viewDataMapMutex; + ViewDataMap _viewDataMap; }; } diff --git a/src/osgVolume/VolumeScene.cpp b/src/osgVolume/VolumeScene.cpp index 40f230f09..bfc9d7377 100644 --- a/src/osgVolume/VolumeScene.cpp +++ b/src/osgVolume/VolumeScene.cpp @@ -12,10 +12,50 @@ */ #include +#include +#include #include using namespace osgVolume; +class RTTCameraCullCallback : public osg::NodeCallback +{ + public: + + RTTCameraCullCallback(VolumeScene* vs): + _volumeScene(vs) {} + + virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + { +#if 1 + _volumeScene->osg::Group::traverse(*nv); +#else + osg::Group* group = dynamic_cast(node); + if (group) + { + OSG_NOTICE<<"Traversing RTT subgraph, "<className()<<", "<className()<osg::Group::traverse(*nv); + } + else + { + OSG_NOTICE<<"Can't traverse RTT subgraph"<(&nv); + if (cv) + { + OpenThreads::ScopedLock lock(_viewDataMapMutex); + osg::ref_ptr& viewData = _viewDataMap[cv]; + if (!viewData) + { + OSG_NOTICE<<"Creating ViewData"<_depthTexture = new osg::Texture2D; + + viewData->_depthTexture->setTextureSize(textureWidth, textureHeight); + viewData->_depthTexture->setInternalFormat(GL_DEPTH_COMPONENT); + viewData->_depthTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); + viewData->_depthTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); + + viewData->_depthTexture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER); + viewData->_depthTexture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER); + viewData->_depthTexture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + + // set up color texture + viewData->_colorTexture = new osg::Texture2D; + + viewData->_colorTexture->setTextureSize(textureWidth, textureHeight); + viewData->_colorTexture->setInternalFormat(GL_RGBA); + viewData->_colorTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); + viewData->_colorTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); + + viewData->_colorTexture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER); + viewData->_colorTexture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER); + viewData->_colorTexture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + + + // set up the RTT Camera to capture the main scene to a color and depth texture that can be used in post processing + viewData->_rttCamera = new osg::Camera; + viewData->_rttCamera->attach(osg::Camera::DEPTH_BUFFER, viewData->_depthTexture.get()); + viewData->_rttCamera->attach(osg::Camera::COLOR_BUFFER, viewData->_colorTexture.get()); + viewData->_rttCamera->setCullCallback(new RTTCameraCullCallback(this)); + viewData->_rttCamera->setViewport(0,0,textureWidth,textureHeight); + + // clear the depth and colour bufferson each clear. + viewData->_rttCamera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + // set the camera to render before the main camera. + viewData->_rttCamera->setRenderOrder(osg::Camera::PRE_RENDER); + + viewData->_rttCamera->setClearColor(osg::Vec4(1.0,0.5,0.5,1.0)); + + // tell the camera to use OpenGL frame buffer object where supported. + viewData->_rttCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); + + + viewData->_rttCamera->setReferenceFrame(osg::Transform::RELATIVE_RF); + viewData->_rttCamera->setProjectionMatrix(osg::Matrixd::identity()); + viewData->_rttCamera->setViewMatrix(osg::Matrixd::identity()); + + // create mesh for rendering the RTT textures onto the screen + osg::ref_ptr geode = new osg::Geode; + geode->addDrawable(osg::createTexturedQuadGeometry(osg::Vec3(-1.0f,-1.0f,-1.0f),osg::Vec3(2.0f,0.0f,-1.0f),osg::Vec3(0.0f,2.0f,-1.0f))); + //geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, viewData->_colorTexture.get(), osg::StateAttribute::ON); + geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, viewData->_depthTexture.get(), osg::StateAttribute::ON); + geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); + geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + + viewData->_postCamera = new osg::Camera; + viewData->_postCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); + viewData->_postCamera->addChild(geode); + + } + else + { + OSG_NOTICE<<"Reusing ViewData"<_parentRenderStage = cv->getCurrentRenderStage(); + + OSG_NOTICE<<"Ready to traverse RTT Camera"<_rttCamera->accept(nv); + + OSG_NOTICE<<"Ready to traverse POST Camera"<_postCamera->accept(nv); + } + else + { + Group::traverse(nv); + } }