Added replacement of the placeholder StateSet in the StateGraph with custom StateSet implemented just for the

needs of that particular frame.
This commit is contained in:
Robert Osfield
2011-08-09 06:54:44 +00:00
parent 4238629ebf
commit e4a73d121e
3 changed files with 50 additions and 36 deletions

View File

@@ -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<ViewDependentData> > ViewDependentDataMap;
OpenThreads::Mutex _viewDependentDataMapMutex;
ViewDependentDataMap _viewDependentDataMap;
osg::ref_ptr<osg::StateSet> _shadowRecievingPlaceholderStateSet;
};

View File

@@ -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

View File

@@ -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<<")"<<std::endl;
OSG_NOTICE<<std::endl<<std::endl<<"ViewDependentShadowMap::cull(osg::CullVisitor&"<<&cv<<")"<<std::endl;
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
// 1. Traverse main scene graph
cullShadowReceivingScene(&cv, stateset.get());
cv.pushStateSet( _shadowRecievingPlaceholderStateSet.get() );
osg::ref_ptr<osgUtil::StateGraph> 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 "<<numValidShadows<<" shadows"<<std::endl;
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<<std::endl;
}
}
decoratorStateGraph->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()"<<std::endl;
@@ -806,11 +790,7 @@ void ViewDependentShadowMap::cullShadowReceivingScene(osgUtil::CullVisitor* cv,
cv->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<osg::StateSet> 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<<std::endl;
}
}
return newStateSet.release();
}
///////////////////////////////////////////////////////////////////////////////////////////////
//