diff --git a/include/osgVolume/VolumeScene b/include/osgVolume/VolumeScene index 63ad7f26a..117c0bb80 100644 --- a/include/osgVolume/VolumeScene +++ b/include/osgVolume/VolumeScene @@ -17,7 +17,8 @@ #include #include #include -#include + +#include namespace osgVolume { @@ -35,6 +36,8 @@ class OSGVOLUME_EXPORT VolumeScene : public osg::Group virtual void traverse(osg::NodeVisitor& nv); + void tileVisited(osg::NodeVisitor* nv, osgVolume::VolumeTile* tile); + protected: virtual ~VolumeScene(); @@ -48,6 +51,9 @@ class OSGVOLUME_EXPORT VolumeScene : public osg::Group osg::ref_ptr _rttCamera; osg::ref_ptr _postCamera; osg::ref_ptr _parentRenderStage; + + typedef std::list< osg::NodePath > Tiles; + Tiles _tiles; protected: virtual ~ViewData() {} }; diff --git a/src/osgVolume/MultipassTechnique.cpp b/src/osgVolume/MultipassTechnique.cpp index 144932a64..78933b9cf 100644 --- a/src/osgVolume/MultipassTechnique.cpp +++ b/src/osgVolume/MultipassTechnique.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -77,6 +78,20 @@ void MultipassTechnique::update(osgUtil::UpdateVisitor* /*uv*/) void MultipassTechnique::cull(osgUtil::CullVisitor* cv) { OSG_NOTICE<<"MultipassTechnique::cull() Need to set up"<getNodePath(); + for(osg::NodePath::reverse_iterator itr = nodePath.rbegin(); + itr != nodePath.rend(); + ++itr) + { + OSG_NOTICE<<" parent path node "<<*itr<<" "<<(*itr)->className()<(*itr); + if (vs) + { + OSG_NOTICE<<" HAVE VolumeScene"<tileVisited(cv, getVolumeTile()); + break; + } + } } void MultipassTechnique::cleanSceneGraph() diff --git a/src/osgVolume/VolumeScene.cpp b/src/osgVolume/VolumeScene.cpp index bfc9d7377..32054471a 100644 --- a/src/osgVolume/VolumeScene.cpp +++ b/src/osgVolume/VolumeScene.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include using namespace osgVolume; @@ -28,7 +30,21 @@ class RTTCameraCullCallback : public osg::NodeCallback virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) { #if 1 + osgUtil::CullVisitor* cv = dynamic_cast(nv); + if (cv) + { + osg::Camera* camera = cv->getCurrentCamera(); + OSG_NOTICE<<"Current camera="<_tiles.push_back(nv->getNodePath()); + } + } +} void VolumeScene::traverse(osg::NodeVisitor& nv) @@ -77,9 +112,20 @@ void VolumeScene::traverse(osg::NodeVisitor& nv) osgUtil::CullVisitor* cv = dynamic_cast(&nv); if (cv) { - OpenThreads::ScopedLock lock(_viewDataMapMutex); - osg::ref_ptr& viewData = _viewDataMap[cv]; - if (!viewData) + osg::ref_ptr viewData; + bool initializeViewData = false; + { + OpenThreads::ScopedLock lock(_viewDataMapMutex); + if (!_viewDataMap[cv]) + { + _viewDataMap[cv] = new ViewData; + initializeViewData = true; + } + + viewData = _viewDataMap[cv]; + } + + if (initializeViewData) { OSG_NOTICE<<"Creating ViewData"<getCurrentRenderStage()->getViewport(); + if (viewport) + { + textureWidth = viewport->width(); + textureHeight = viewport->height(); + } // set up depth texture viewData->_depthTexture = new osg::Texture2D; @@ -109,9 +160,8 @@ void VolumeScene::traverse(osg::NodeVisitor& nv) 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)); + viewData->_colorTexture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_EDGE); + viewData->_colorTexture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_EDGE); // set up the RTT Camera to capture the main scene to a color and depth texture that can be used in post processing @@ -127,8 +177,6 @@ void VolumeScene::traverse(osg::NodeVisitor& nv) // 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); @@ -140,10 +188,45 @@ void VolumeScene::traverse(osg::NodeVisitor& nv) // 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); + + osg::ref_ptr stateset = geode->getOrCreateStateSet(); + + stateset->setTextureAttributeAndModes(0, viewData->_colorTexture.get(), osg::StateAttribute::ON); + stateset->setTextureAttributeAndModes(1, viewData->_depthTexture.get(), osg::StateAttribute::ON); + stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); + stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + + osg::ref_ptr program = new osg::Program; + stateset->setAttribute(program); + + // get vertex shaders from source + osg::ref_ptr vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, "shaders/volume_color_depth.vert"); + if (vertexShader.valid()) + { + program->addShader(vertexShader.get()); + } +#if 0 + else + { + #include "Shaders/volume_color_depth_vert.cpp" + program->addShader(new osg::Shader(osg::Shader::VERTEX, volume_color_depth_vert)); + } +#endif + // get fragment shaders from source + osg::ref_ptr fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_color_depth.frag"); + if (fragmentShader.valid()) + { + program->addShader(fragmentShader.get()); + } +#if 0 + else + { + #include "Shaders/volume_color_depth_frag.cpp" + program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_color_depth_frag)); + } +#endif + stateset->addUniform(new osg::Uniform("colorTexture",0)); + stateset->addUniform(new osg::Uniform("depthTexture",1)); viewData->_postCamera = new osg::Camera; viewData->_postCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); @@ -156,11 +239,48 @@ void VolumeScene::traverse(osg::NodeVisitor& nv) } + // new frame so need to clear last frames log of VolumeTiles + viewData->_tiles.clear(); + + // record the parent render stage viewData->_parentRenderStage = cv->getCurrentRenderStage(); + osg::Viewport* viewport = cv->getCurrentRenderStage()->getViewport(); + if (viewport) + { + if (viewport->width() != viewData->_colorTexture->getTextureWidth() || + viewport->height() != viewData->_colorTexture->getTextureHeight()) + { + OSG_NOTICE<<"Need to change texture size to "<width()<<", "<< viewport->height()<_colorTexture->setTextureSize(viewport->width(), viewport->height()); + viewData->_colorTexture->dirtyTextureObject(); + viewData->_depthTexture->setTextureSize(viewport->width(), viewport->height()); + viewData->_depthTexture->dirtyTextureObject(); + viewData->_rttCamera->setViewport(0, 0, viewport->width(), viewport->height()); + viewData->_postCamera->setViewport(0, 0, viewport->width(), viewport->height()); + if (viewData->_rttCamera->getRenderingCache()) + { + viewData->_rttCamera->getRenderingCache()->releaseGLObjects(0); + } + } + } + + osg::Camera* parentCamera = cv->getCurrentCamera(); + viewData->_rttCamera->setClearColor(parentCamera->getClearColor()); + OSG_NOTICE<<"Ready to traverse RTT Camera"<_rttCamera->getProjectionMatrix()<_rttCamera->accept(nv); + OSG_NOTICE<<" RTT Camera ProjectionMatrix After "<_rttCamera->getProjectionMatrix()<getProjectionMatrix())<_tiles.size()<_postCamera->accept(nv); }