diff --git a/include/osg/ImpostorSprite b/include/osg/ImpostorSprite index 70fc9f455..a7d7bebbb 100644 --- a/include/osg/ImpostorSprite +++ b/include/osg/ImpostorSprite @@ -198,7 +198,10 @@ class SG_EXPORT ImpostorSpriteManager : public Referenced void remove(ImpostorSprite* is); ImpostorSprite* createOrReuseImpostorSprite(int s,int t,int frameNumber); - + + StateSet* createOrReuseStateSet(); + + void reset(); protected: @@ -210,6 +213,10 @@ class SG_EXPORT ImpostorSpriteManager : public Referenced ImpostorSprite* _first; ImpostorSprite* _last; + + typedef std::vector< ref_ptr > StateSetList; + StateSetList _stateSetList; + unsigned int _reuseStateSetIndex; }; diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index 8f8addedd..76f45c4ad 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -244,8 +244,6 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac osg::ref_ptr _rootRenderStage; RenderBin* _currentRenderBin; - osg::ref_ptr _localPreRenderState; - ComputeNearFarMode _computeNearFar; float _computed_znear; float _computed_zfar; diff --git a/src/osg/ImpostorSprite.cpp b/src/osg/ImpostorSprite.cpp index 7a2c41008..7b6b9eb67 100644 --- a/src/osg/ImpostorSprite.cpp +++ b/src/osg/ImpostorSprite.cpp @@ -163,6 +163,8 @@ ImpostorSpriteManager::ImpostorSpriteManager(): _alphafunc = new osg::AlphaFunc; _alphafunc->setFunction( AlphaFunc::GREATER, 0.000f ); + + _reuseStateSetIndex = 0; } @@ -305,3 +307,18 @@ ImpostorSprite* ImpostorSpriteManager::createOrReuseImpostorSprite(int s,int t,i } +StateSet* ImpostorSpriteManager::createOrReuseStateSet() +{ + if (_reuseStateSetIndex<_stateSetList.size()) + { + return _stateSetList[_reuseStateSetIndex++].get(); + } + _stateSetList.push_back(new StateSet); + _reuseStateSetIndex=_stateSetList.size(); + return _stateSetList.back().get(); +} + +void ImpostorSpriteManager::reset() +{ + _reuseStateSetIndex = 0; +} diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index ce7039c84..e6009d39a 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -142,6 +142,8 @@ void CullVisitor::reset() (*itr)->reset(); } + if (_impostorSpriteManager.valid()) _impostorSpriteManager->reset(); + } float CullVisitor::getDistanceToEyePoint(const Vec3& pos, bool withLODScale) const @@ -802,9 +804,9 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node) // into account the new camera orientation. pushModelViewMatrix(rotate_matrix); - if (!_localPreRenderState) _localPreRenderState = new StateSet; + StateSet* localPreRenderState = _impostorSpriteManager->createOrReuseStateSet(); - pushStateSet(_localPreRenderState.get()); + pushStateSet(localPreRenderState); { @@ -888,7 +890,7 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node) new_viewport->setViewport(center_x-new_s/2,center_y-new_t/2,new_s,new_t); rtts->setViewport(new_viewport); - _localPreRenderState->setAttribute(new_viewport); + localPreRenderState->setAttribute(new_viewport); // create the impostor sprite. ImpostorSprite* impostorSprite = @@ -912,7 +914,7 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node) // the depth sort bin should probably be user definable, // will look into this later. RO July 2001. StateSet* stateset = impostorSprite->getStateSet(); - stateset->setRenderBinDetails(1,"DepthSortedBin"); + stateset->setRenderBinDetails(10,"DepthSortedBin"); } Texture2D* texture = impostorSprite->getTexture();