From 3858acf70f4a1980b7061282f900dc477500d60d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 6 Dec 2013 19:31:12 +0000 Subject: [PATCH] Further work on new MultipassTechnique/VolumeScene. --- examples/osgvolume/osgvolume.cpp | 2 +- include/osgUtil/CullVisitor | 10 +- include/osgVolume/Locator | 33 +++ include/osgVolume/VolumeScene | 25 +- src/osgVolume/Locator.cpp | 32 +++ src/osgVolume/MultipassTechnique.cpp | 326 ++++++++++++++++++++++++++- src/osgVolume/RayTracedTechnique.cpp | 43 ---- src/osgVolume/VolumeScene.cpp | 222 +++++++++++++----- 8 files changed, 574 insertions(+), 119 deletions(-) diff --git a/examples/osgvolume/osgvolume.cpp b/examples/osgvolume/osgvolume.cpp index 85cc74b53..584774ad2 100644 --- a/examples/osgvolume/osgvolume.cpp +++ b/examples/osgvolume/osgvolume.cpp @@ -1225,12 +1225,12 @@ int main( int argc, char **argv ) { osg::ref_ptr volumeScene = new osgVolume::VolumeScene; volumeScene->addChild(loadedModel.get()); + loadedModel->getOrCreateStateSet(); loadedModel = volumeScene.get(); } - // set the scene to render viewer.setSceneData(loadedModel.get()); diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index f75e1cf11..4530d37d3 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -320,12 +320,12 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac else acceptNode->accept(*this); } - osg::ref_ptr _rootStateGraph; - StateGraph* _currentStateGraph; + osg::ref_ptr _rootStateGraph; + StateGraph* _currentStateGraph; - osg::ref_ptr _rootRenderStage; - RenderBin* _currentRenderBin; - std::vector _renderBinStack; + osg::ref_ptr _rootRenderStage; + RenderBin* _currentRenderBin; + std::vector _renderBinStack; unsigned int _traversalNumber; diff --git a/include/osgVolume/Locator b/include/osgVolume/Locator index 338fe7178..e57135983 100644 --- a/include/osgVolume/Locator +++ b/include/osgVolume/Locator @@ -17,7 +17,10 @@ #include #include +#include #include +#include +#include #include @@ -95,6 +98,36 @@ class OSGVOLUME_EXPORT Locator : public osg::Object LocatorCallbacks _locatorCallbacks; }; +class OSGVOLUME_EXPORT TransformLocatorCallback : public Locator::LocatorCallback +{ + public: + + TransformLocatorCallback(osg::MatrixTransform* transform); + + void locatorModified(Locator* locator); + + protected: + + osg::observer_ptr _transform; +}; + + +class OSGVOLUME_EXPORT TexGenLocatorCallback : public Locator::LocatorCallback +{ + public: + + TexGenLocatorCallback(osg::TexGen* texgen, Locator* geometryLocator, Locator* imageLocator); + + void locatorModified(Locator*); + + protected: + + osg::observer_ptr _texgen; + osg::observer_ptr _geometryLocator; + osg::observer_ptr _imageLocator; +}; + + } #endif diff --git a/include/osgVolume/VolumeScene b/include/osgVolume/VolumeScene index 117c0bb80..0676f06ba 100644 --- a/include/osgVolume/VolumeScene +++ b/include/osgVolume/VolumeScene @@ -42,18 +42,29 @@ class OSGVOLUME_EXPORT VolumeScene : public osg::Group virtual ~VolumeScene(); + struct TileData : public osg::Referenced + { + osg::NodePath nodePath; + osg::ref_ptr projectionMatrix; + osg::ref_ptr modelviewMatrix; + }; + typedef std::list< osg::ref_ptr > Tiles; + 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; + osg::ref_ptr _depthTexture; + osg::ref_ptr _colorTexture; + osg::ref_ptr _rttCamera; + osg::ref_ptr _backdropSubgraph; + osg::ref_ptr _geometry; + osg::ref_ptr _vertices; + osg::ref_ptr _stateset; + osg::ref_ptr _viewportSizeUniform; + + Tiles _tiles; - typedef std::list< osg::NodePath > Tiles; - Tiles _tiles; protected: virtual ~ViewData() {} }; diff --git a/src/osgVolume/Locator.cpp b/src/osgVolume/Locator.cpp index 1a949f628..d6061d9a1 100644 --- a/src/osgVolume/Locator.cpp +++ b/src/osgVolume/Locator.cpp @@ -222,3 +222,35 @@ void Locator::locatorModified() } } + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TransformLocatorCallback +// +TransformLocatorCallback::TransformLocatorCallback(osg::MatrixTransform* transform): + _transform(transform) +{} + +void TransformLocatorCallback::locatorModified(Locator* locator) +{ + if (_transform.valid()) _transform->setMatrix(locator->getTransform()); +} + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TexGenLocatorCallback +// +TexGenLocatorCallback::TexGenLocatorCallback(osg::TexGen* texgen, Locator* geometryLocator, Locator* imageLocator): + _texgen(texgen), + _geometryLocator(geometryLocator), + _imageLocator(imageLocator) {} + +void TexGenLocatorCallback::locatorModified(Locator*) +{ + if (!_texgen || !_geometryLocator || !_imageLocator) return; + + _texgen->setPlanesFromMatrix( + _geometryLocator->getTransform() * + osg::Matrix::inverse(_imageLocator->getTransform())); +} diff --git a/src/osgVolume/MultipassTechnique.cpp b/src/osgVolume/MultipassTechnique.cpp index 78933b9cf..d30cd2d97 100644 --- a/src/osgVolume/MultipassTechnique.cpp +++ b/src/osgVolume/MultipassTechnique.cpp @@ -16,9 +16,12 @@ #include #include +#include #include #include +#include +#include #include #include #include @@ -68,6 +71,297 @@ void MultipassTechnique::init() } OSG_NOTICE<<"MultipassTechnique::init() Need to set up"<getLayer()->getProperty()) + { + _volumeTile->getLayer()->getProperty()->accept(cpv); + } + + osg::ref_ptr geode = new osg::Geode; + + { + osg::Geometry* geom = new osg::Geometry; + + osg::Vec3Array* coords = new osg::Vec3Array(8); + (*coords)[0] = osg::Vec3d(0.0,0.0,0.0); + (*coords)[1] = osg::Vec3d(1.0,0.0,0.0); + (*coords)[2] = osg::Vec3d(1.0,1.0,0.0); + (*coords)[3] = osg::Vec3d(0.0,1.0,0.0); + (*coords)[4] = osg::Vec3d(0.0,0.0,1.0); + (*coords)[5] = osg::Vec3d(1.0,0.0,1.0); + (*coords)[6] = osg::Vec3d(1.0,1.0,1.0); + (*coords)[7] = osg::Vec3d(0.0,1.0,1.0); + geom->setVertexArray(coords); + + osg::Vec4Array* colours = new osg::Vec4Array(1); + (*colours)[0].set(1.0f,1.0f,1.0,1.0f); + geom->setColorArray(colours, osg::Array::BIND_OVERALL); + + osg::DrawElementsUShort* drawElements = new osg::DrawElementsUShort(GL_QUADS); + // bottom + drawElements->push_back(3); + drawElements->push_back(2); + drawElements->push_back(1); + drawElements->push_back(0); + + // bottom + drawElements->push_back(7);//7623 + drawElements->push_back(6); + drawElements->push_back(2); + drawElements->push_back(3); + + // left + drawElements->push_back(4);//4730 + drawElements->push_back(7); + drawElements->push_back(3); + drawElements->push_back(0); + + // right + drawElements->push_back(1);//1265 + drawElements->push_back(2); + drawElements->push_back(6); + drawElements->push_back(5); + + // front + drawElements->push_back(5);//5401 + drawElements->push_back(4); + drawElements->push_back(0); + drawElements->push_back(1); + + // top + drawElements->push_back(4);//4567 + drawElements->push_back(5); + drawElements->push_back(6); + drawElements->push_back(7); + + geom->addPrimitiveSet(drawElements); + + geode->addDrawable(geom); + + } + + _transform = new osg::MatrixTransform; + + // handle locators + Locator* masterLocator = _volumeTile->getLocator(); + Locator* layerLocator = _volumeTile->getLayer()->getLocator(); + + if (!masterLocator && layerLocator) masterLocator = layerLocator; + if (!layerLocator && masterLocator) layerLocator = masterLocator; + + osg::Matrix geometryMatrix; + if (masterLocator) + { + geometryMatrix = masterLocator->getTransform(); + _transform->setMatrix(geometryMatrix); + masterLocator->addCallback(new TransformLocatorCallback(_transform.get())); + } + + osg::Matrix imageMatrix; + if (layerLocator) + { + imageMatrix = layerLocator->getTransform(); + } + + OSG_NOTICE<<"MultipassTechnique::init() : geometryMatrix = "<addUniform(new osg::Uniform("depthTexture",1)); + + stateset->setMode(GL_ALPHA_TEST,osg::StateAttribute::ON); + + float alphaFuncValue = 0.1; + if (cpv._isoProperty.valid()) + { + alphaFuncValue = cpv._isoProperty->getValue(); + } + + if (cpv._sampleDensityProperty.valid()) + stateset->addUniform(cpv._sampleDensityProperty->getUniform()); + else + stateset->addUniform(new osg::Uniform("SampleDensityValue",0.0005f)); + + + if (cpv._transparencyProperty.valid()) + stateset->addUniform(cpv._transparencyProperty->getUniform()); + else + stateset->addUniform(new osg::Uniform("TransparencyValue",1.0f)); + + + if (cpv._afProperty.valid()) + stateset->addUniform(cpv._afProperty->getUniform()); + else + stateset->addUniform(new osg::Uniform("AlphaFuncValue",alphaFuncValue)); + +#if 1 + osg::ref_ptr texgen = new osg::TexGen; + texgen->setMode(osg::TexGen::OBJECT_LINEAR); + texgen->setPlanesFromMatrix( geometryMatrix * osg::Matrix::inverse(imageMatrix)); + + if (masterLocator) + { + osg::ref_ptr locatorCallback = new TexGenLocatorCallback(texgen, masterLocator, layerLocator); + masterLocator->addCallback(locatorCallback.get()); + if (masterLocator != layerLocator) + { + if (layerLocator) layerLocator->addCallback(locatorCallback.get()); + } + } + + stateset->setTextureAttributeAndModes(texgenTextureUnit, texgen.get(), osg::StateAttribute::ON); +#endif + } + + + // set up 3D texture + osg::ref_ptr image_3d = _volumeTile->getLayer()->getImage(); + osg::ref_ptr texture3D = new osg::Texture3D; + { + osg::Texture::InternalFormatMode internalFormatMode = osg::Texture::USE_IMAGE_DATA_FORMAT; + osg::Texture::FilterMode minFilter = osg::Texture::LINEAR; + osg::Texture::FilterMode magFilter = osg::Texture::LINEAR; + + // 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. + 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_BORDER); + texture3D->setWrap(osg::Texture3D::WRAP_S,osg::Texture3D::CLAMP_TO_BORDER); + texture3D->setWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP_TO_BORDER); + texture3D->setBorderColor(osg::Vec4(0.0,0.0,0.0,0.0)); + 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(volumeTextureUnit, texture3D, osg::StateAttribute::ON); + + osg::Uniform* baseTextureSampler = new osg::Uniform("volumeTexture", int(volumeTextureUnit)); + stateset->addUniform(baseTextureSampler); + } + + + + osg::ref_ptr computeRayColorShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_compute_ray_color.frag"); +#if 0 + if (!computeRayColorShader) + { + #include "Shaders/volume_compute_ray_color_frag.cpp"; + computeRayColorShader = new osg::Shader(osg::Shader::FRAGMENT, volume_compute_ray_color_frag); + } +#endif + + // set up the renderin of the front faces + { + osg::ref_ptr front_face_group = new osg::Group; + front_face_group->addChild(geode.get()); + _transform->addChild(front_face_group.get()); + + osg::ref_ptr front_face_stateset = front_face_group->getOrCreateStateSet(); + front_face_stateset->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON); + + osg::ref_ptr program = new osg::Program; + front_face_stateset->setAttribute(program); + + // get vertex shaders from source + osg::ref_ptr vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, "shaders/volume_multipass_front.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_multipass_front.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 + + if (computeRayColorShader.valid()) + { + program->addShader(computeRayColorShader.get()); + } + } + + + // set up the rendering of the back faces + { + osg::ref_ptr back_face_group = new osg::Group; + back_face_group->addChild(geode.get()); + _transform->addChild(back_face_group.get()); + + osg::ref_ptr back_face_stateset = back_face_group->getOrCreateStateSet(); + back_face_stateset->setAttributeAndModes(new osg::CullFace(osg::CullFace::FRONT), osg::StateAttribute::ON); + + osg::ref_ptr program = new osg::Program; + back_face_stateset->setAttribute(program); + + // get vertex shaders from source + osg::ref_ptr vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, "shaders/volume_multipass_back.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_multipass_back.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 + if (computeRayColorShader.valid()) + { + program->addShader(computeRayColorShader.get()); + } + + } + + } void MultipassTechnique::update(osgUtil::UpdateVisitor* /*uv*/) @@ -77,19 +371,29 @@ 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) + std::string traversalPass; + bool postTraversal = cv->getUserValue("VolumeSceneTraversal", traversalPass) && traversalPass=="Post"; + + // OSG_NOTICE<<"MultipassTechnique::cull() traversalPass="<className()<(*itr); - if (vs) + // OSG_NOTICE<<" OK need to handle postTraversal"<accept(*cv); + } + else + { + osg::NodePath& nodePath = cv->getNodePath(); + for(osg::NodePath::reverse_iterator itr = nodePath.rbegin(); + itr != nodePath.rend(); + ++itr) { - OSG_NOTICE<<" HAVE VolumeScene"<tileVisited(cv, getVolumeTile()); - break; + osgVolume::VolumeScene* vs = dynamic_cast(*itr); + if (vs) + { + vs->tileVisited(cv, getVolumeTile()); + break; + } } } } diff --git a/src/osgVolume/RayTracedTechnique.cpp b/src/osgVolume/RayTracedTechnique.cpp index 4ef618f7d..167015ab6 100644 --- a/src/osgVolume/RayTracedTechnique.cpp +++ b/src/osgVolume/RayTracedTechnique.cpp @@ -30,49 +30,6 @@ namespace osgVolume { -class TransformLocatorCallback : public Locator::LocatorCallback -{ - public: - - TransformLocatorCallback(osg::MatrixTransform* transform): _transform(transform) {} - - void locatorModified(Locator* locator) - { - if (_transform.valid()) _transform->setMatrix(locator->getTransform()); - } - - protected: - - osg::observer_ptr _transform; -}; - - -class TexGenLocatorCallback : public Locator::LocatorCallback -{ - public: - - TexGenLocatorCallback(osg::TexGen* texgen, Locator* geometryLocator, Locator* imageLocator): - _texgen(texgen), - _geometryLocator(geometryLocator), - _imageLocator(imageLocator) {} - - void locatorModified(Locator*) - { - if (!_texgen || !_geometryLocator || !_imageLocator) return; - - _texgen->setPlanesFromMatrix( - _geometryLocator->getTransform() * - osg::Matrix::inverse(_imageLocator->getTransform())); - } - - protected: - - osg::observer_ptr _texgen; - osg::observer_ptr _geometryLocator; - osg::observer_ptr _imageLocator; -}; - - RayTracedTechnique::RayTracedTechnique() { } diff --git a/src/osgVolume/VolumeScene.cpp b/src/osgVolume/VolumeScene.cpp index 32054471a..c65f6b3f7 100644 --- a/src/osgVolume/VolumeScene.cpp +++ b/src/osgVolume/VolumeScene.cpp @@ -13,7 +13,9 @@ #include #include +#include #include +#include #include #include #include @@ -29,34 +31,12 @@ 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="<className()<<", "<className()<osg::Group::traverse(*nv); - } - else - { - OSG_NOTICE<<"Can't traverse RTT subgraph"<setUserValue("CalculatedNearPlane",double(cv->getCalculatedNearPlane())); + node->setUserValue("CalculatedFarPlane",double(cv->getCalculatedFarPlane())); } protected: @@ -64,6 +44,7 @@ class RTTCameraCullCallback : public osg::NodeCallback virtual ~RTTCameraCullCallback() {} osgVolume::VolumeScene* _volumeScene; + }; @@ -100,8 +81,11 @@ void VolumeScene::tileVisited(osg::NodeVisitor* nv, osgVolume::VolumeTile* tile) if (viewData.valid()) { - OSG_NOTICE<<"tileVisited("<_tiles.push_back(nv->getNodePath()); + osg::ref_ptr tileData = new TileData; + tileData->nodePath = cv->getNodePath(); + tileData->projectionMatrix = cv->getProjectionMatrix(); + tileData->modelviewMatrix = cv->getModelViewMatrix(); + viewData->_tiles.push_back(tileData.get()); } } } @@ -129,7 +113,6 @@ void VolumeScene::traverse(osg::NodeVisitor& nv) { OSG_NOTICE<<"Creating ViewData"< 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->setCullingActive(false); - osg::ref_ptr stateset = geode->getOrCreateStateSet(); + viewData->_backdropSubgraph = 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))); - 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); + viewData->_geometry = new osg::Geometry; + geode->addDrawable(viewData->_geometry.get()); + + viewData->_geometry->setUseDisplayList(false); + viewData->_geometry->setUseVertexBufferObjects(false); + + viewData->_vertices = new osg::Vec3Array(4); + viewData->_geometry->setVertexArray(viewData->_vertices.get()); + + osg::ref_ptr colors = new osg::Vec4Array(1); + (*colors)[0].set(1.0f,1.0f,1.0f,1.0f); + viewData->_geometry->setColorArray(colors.get(), osg::Array::BIND_OVERALL); + + osg::ref_ptr texcoords = new osg::Vec2Array(4); + (*texcoords)[0].set(0.0f,1.0f); + (*texcoords)[1].set(0.0f,0.0f); + (*texcoords)[2].set(1.0f,1.0f); + (*texcoords)[3].set(1.0f,0.0f); + viewData->_geometry->setTexCoordArray(0, texcoords.get(), osg::Array::BIND_PER_VERTEX); + + viewData->_geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP,0,4)); + + + osg::ref_ptr stateset = viewData->_geometry->getOrCreateStateSet(); + + stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + stateset->setMode(GL_BLEND, osg::StateAttribute::ON); + stateset->setRenderBinDetails(10,"DepthSortedBin"); osg::ref_ptr program = new osg::Program; stateset->setAttribute(program); @@ -225,29 +234,37 @@ void VolumeScene::traverse(osg::NodeVisitor& nv) 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->_stateset = new osg::StateSet; + viewData->_stateset->addUniform(new osg::Uniform("colorTexture",0)); + viewData->_stateset->addUniform(new osg::Uniform("depthTexture",1)); - viewData->_postCamera = new osg::Camera; - viewData->_postCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); - viewData->_postCamera->addChild(geode); + viewData->_stateset->setTextureAttributeAndModes(0, viewData->_colorTexture.get(), osg::StateAttribute::ON); + viewData->_stateset->setTextureAttributeAndModes(1, viewData->_depthTexture.get(), osg::StateAttribute::ON); + + viewData->_viewportSizeUniform = new osg::Uniform("viewportSize",osg::Vec2(1280.0,1024.0)); + viewData->_stateset->addUniform(viewData->_viewportSizeUniform.get()); + + geode->setStateSet(viewData->_stateset.get()); } else { - OSG_NOTICE<<"Reusing ViewData"<getProjectionMatrix()); + osg::Matrix modelviewMatrix = *(cv->getModelViewMatrix()); + + // 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) { + viewData->_viewportSizeUniform->set(osg::Vec2(viewport->width(),viewport->height())); + if (viewport->width() != viewData->_colorTexture->getTextureWidth() || viewport->height() != viewData->_colorTexture->getTextureHeight()) { @@ -257,7 +274,6 @@ void VolumeScene::traverse(osg::NodeVisitor& nv) 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); @@ -265,24 +281,126 @@ void VolumeScene::traverse(osg::NodeVisitor& nv) } } + cv->setUserValue("VolumeSceneTraversal",std::string("RenderToTexture")); + osg::Camera* parentCamera = cv->getCurrentCamera(); viewData->_rttCamera->setClearColor(parentCamera->getClearColor()); - OSG_NOTICE<<"Ready to traverse RTT Camera"<_rttCamera->getProjectionMatrix()<_rttCamera->getProjectionMatrix()<_rttCamera->accept(nv); - OSG_NOTICE<<" RTT Camera ProjectionMatrix After "<_rttCamera->getProjectionMatrix()<getProjectionMatrix())<_rttCamera->getProjectionMatrix()<getProjectionMatrix())<_tiles.size()<_tiles.size()<_postCamera->accept(nv); + double calculatedNearPlane = DBL_MAX; + double calculatedFarPlane = -DBL_MAX; + if (viewData->_rttCamera->getUserValue("CalculatedNearPlane",calculatedNearPlane) && + viewData->_rttCamera->getUserValue("CalculatedFarPlane",calculatedFarPlane)) + { + calculatedNearPlane *= 0.5; + calculatedFarPlane *= 2.0; + + //OSG_NOTICE<<"Got from RTTCamera CalculatedNearPlane="<_tiles; + for(Tiles::iterator itr = tiles.begin(); + itr != tiles.end(); + ++itr) + { + TileData* tileData = itr->get(); + unsigned int numStateSetPushed = 0; + + // OSG_NOTICE<<"VolumeTile to add "<projectionMatrix.get()<<", "<modelviewMatrix.get()<nodePath; + + cv->getNodePath() = nodePath; + cv->pushProjectionMatrix(tileData->projectionMatrix.get()); + cv->pushModelViewMatrix(tileData->modelviewMatrix.get(), osg::Transform::ABSOLUTE_RF_INHERIT_VIEWPOINT); + + + cv->pushStateSet(viewData->_stateset.get()); + ++numStateSetPushed; + + + osg::NodePath::iterator np_itr = nodePath.begin(); + + // skip over all nodes above VolumeScene as this will have already been traverse by CullVisitor + while(np_itr!=nodePath.end() && (*np_itr)!=viewData->_rttCamera.get()) { ++np_itr; } + if (np_itr!=nodePath.end()) ++np_itr; + + // push the stateset on the nodes between this VolumeScene and the VolumeTile + for(osg::NodePath::iterator ss_itr = np_itr; + ss_itr != nodePath.end(); + ++ss_itr) + { + if ((*ss_itr)->getStateSet()) + { + numStateSetPushed++; + cv->pushStateSet((*ss_itr)->getStateSet()); + // OSG_NOTICE<<" pushing StateSet"<traverse(*(tileData->nodePath.back())); + + // pop the StateSet's + for(unsigned int i=0; ipopStateSet(); + // OSG_NOTICE<<" popping StateSet"<popModelViewMatrix(); + cv->popProjectionMatrix(); + } + + cv->getNodePath() = nodePathPriorToTraversingSubgraph; } else {