From e4a73d121edb9558266a0526a13ca610e3e39086 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 9 Aug 2011 06:54:44 +0000 Subject: [PATCH] Added replacement of the placeholder StateSet in the StateGraph with custom StateSet implemented just for the needs of that particular frame. --- include/osgShadow/ViewDependentShadowMap | 5 +- include/osgUtil/StateGraph | 4 +- src/osgShadow/ViewDependentShadowMap.cpp | 77 +++++++++++++----------- 3 files changed, 50 insertions(+), 36 deletions(-) diff --git a/include/osgShadow/ViewDependentShadowMap b/include/osgShadow/ViewDependentShadowMap index 3b7e936cb..7ee1d7225 100644 --- a/include/osgShadow/ViewDependentShadowMap +++ b/include/osgShadow/ViewDependentShadowMap @@ -125,10 +125,11 @@ class OSGSHADOW_EXPORT ViewDependentShadowMap : public ShadowTechnique virtual bool assignTexGenSettings(osgUtil::CullVisitor* cv, osg::Camera* camera, unsigned int textureUnit, osg::TexGen* texgen); - virtual void cullShadowReceivingScene(osgUtil::CullVisitor* cv, osg::StateSet* stateset) const; + virtual void cullShadowReceivingScene(osgUtil::CullVisitor* cv) const; virtual void cullShadowCastingScene(osgUtil::CullVisitor* cv, osg::Camera* camera) const; + virtual osg::StateSet* selectStateSetForRenderingShadow(PositionedLightList& pll) const; protected: virtual ~ViewDependentShadowMap(); @@ -136,6 +137,8 @@ protected: typedef std::map< osgUtil::CullVisitor*, osg::ref_ptr > ViewDependentDataMap; OpenThreads::Mutex _viewDependentDataMapMutex; ViewDependentDataMap _viewDependentDataMap; + + osg::ref_ptr _shadowRecievingPlaceholderStateSet; }; diff --git a/include/osgUtil/StateGraph b/include/osgUtil/StateGraph index 1e10e771a..df9454f73 100644 --- a/include/osgUtil/StateGraph +++ b/include/osgUtil/StateGraph @@ -100,7 +100,9 @@ class OSGUTIL_EXPORT StateGraph : public osg::Referenced void setUserData(osg::Referenced* obj) { _userData = obj; } osg::Referenced* getUserData() { return _userData.get(); } const osg::Referenced* getUserData() const { return _userData.get(); } - + + void setStateSet(const osg::StateSet* stateset) { _stateset = stateset; } + #ifdef OSGUTIL_RENDERBACKEND_USE_REF_PTR const osg::StateSet* getStateSet() const { return _stateset.get(); } #else diff --git a/src/osgShadow/ViewDependentShadowMap.cpp b/src/osgShadow/ViewDependentShadowMap.cpp index b3fc7543b..36cdba58d 100644 --- a/src/osgShadow/ViewDependentShadowMap.cpp +++ b/src/osgShadow/ViewDependentShadowMap.cpp @@ -115,11 +115,13 @@ void VDSMCameraCullCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) ViewDependentShadowMap::ViewDependentShadowMap(): ShadowTechnique() { + _shadowRecievingPlaceholderStateSet = new osg::StateSet; } ViewDependentShadowMap::ViewDependentShadowMap(const ViewDependentShadowMap& vdsm, const osg::CopyOp& copyop): ShadowTechnique(vdsm,copyop) { + _shadowRecievingPlaceholderStateSet = new osg::StateSet; } ViewDependentShadowMap::~ViewDependentShadowMap() @@ -165,13 +167,18 @@ void ViewDependentShadowMap::update(osg::NodeVisitor& nv) void ViewDependentShadowMap::cull(osgUtil::CullVisitor& cv) { - OSG_NOTICE<<"ViewDependentShadowMap::cull(osg::CullVisitor&"<<&cv<<")"< stateset = new osg::StateSet; - // 1. Traverse main scene graph - cullShadowReceivingScene(&cv, stateset.get()); + cv.pushStateSet( _shadowRecievingPlaceholderStateSet.get() ); + osg::ref_ptr decoratorStateGraph = cv.getCurrentStateGraph(); + + cullShadowReceivingScene(&cv); + + cv.popStateSet(); + + // 2. select active light sources // create a list of light sources + their matrices to place them PositionedLightList pll; @@ -283,32 +290,9 @@ void ViewDependentShadowMap::cull(osgUtil::CullVisitor& cv) { OSG_NOTICE<<"Need to assign "<setStateSet(selectStateSetForRenderingShadow(pll)); } - else - { - stateset->clear(); - } } @@ -797,7 +781,7 @@ bool ViewDependentShadowMap::assignTexGenSettings(osgUtil::CullVisitor* cv, osg: return true; } -void ViewDependentShadowMap::cullShadowReceivingScene(osgUtil::CullVisitor* cv, osg::StateSet* stateset) const +void ViewDependentShadowMap::cullShadowReceivingScene(osgUtil::CullVisitor* cv) const { OSG_NOTICE<<"cullShadowReceivingScene()"<setTraversalMask( traversalMask & _shadowedScene->getReceivesShadowTraversalMask() ); - if (stateset) cv->pushStateSet( stateset ); - - _shadowedScene->osg::Group::traverse(*cv); - - if (stateset) cv->popStateSet(); + _shadowedScene->osg::Group::traverse(*cv); cv->setTraversalMask( traversalMask ); @@ -833,6 +813,35 @@ void ViewDependentShadowMap::cullShadowCastingScene(osgUtil::CullVisitor* cv, os return; } +osg::StateSet* ViewDependentShadowMap::selectStateSetForRenderingShadow(PositionedLightList& pll) const +{ + osg::ref_ptr newStateSet = new osg::StateSet; + + newStateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); + + for(PositionedLightList::iterator itr = pll.begin(); + itr != pll.end(); + ++itr) + { + // 3. create per light/per shadow map division of lightspace/frustum + // create a list of light/shadow map data structures + + PositionedLight& pl = *itr; + + // if no texture units have been activated for this light then no shadow state required. + if (pl.textureUnits.empty()) continue; + + for(PositionedLight::ActiveTextureUnits::iterator atu_itr = pl.textureUnits.begin(); + atu_itr != pl.textureUnits.end(); + ++atu_itr) + { + OSG_NOTICE<<" Need to assign state for "<<*atu_itr<