diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index 60f048b147..770917eda7 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -279,14 +279,7 @@ void VDSMCameraCullCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) } #endif // bin has to go inside camera cull or the rendertexture stage will override it - static osg::ref_ptr ss; - if (!ss) - { - ShadowsBin::addPrototype("ShadowsBin", _vdsm->getCastingPrograms()); - ss = new osg::StateSet; - ss->setRenderBinDetails(osg::StateSet::OPAQUE_BIN, "ShadowsBin", osg::StateSet::OVERRIDE_PROTECTED_RENDERBIN_DETAILS); - } - cv->pushStateSet(ss); + cv->pushStateSet(_vdsm->getOrCreateShadowsBinStateSet()); if (_vdsm->getShadowedScene()) { _vdsm->getShadowedScene()->osg::Group::traverse(*nv); @@ -811,6 +804,8 @@ MWShadowTechnique::MWShadowTechnique(const MWShadowTechnique& vdsm, const osg::C MWShadowTechnique::~MWShadowTechnique() { + if (_shadowsBin != nullptr) + osgUtil::RenderBin::removeRenderBinPrototype(_shadowsBin); } @@ -3282,3 +3277,18 @@ void SceneUtil::MWShadowTechnique::DebugHUD::addAnotherShadowMap() for(auto& uniformVector : mFrustumUniforms) uniformVector.push_back(new osg::Uniform(osg::Uniform::FLOAT_MAT4, "transform")); } + +osg::ref_ptr SceneUtil::MWShadowTechnique::getOrCreateShadowsBinStateSet() +{ + if (_shadowsBinStateSet == nullptr) + { + if (_shadowsBin == nullptr) + { + _shadowsBin = new ShadowsBin(_castingPrograms); + osgUtil::RenderBin::addRenderBinPrototype(_shadowsBinName, _shadowsBin); + } + _shadowsBinStateSet = new osg::StateSet; + _shadowsBinStateSet->setRenderBinDetails(osg::StateSet::OPAQUE_BIN, _shadowsBinName, osg::StateSet::OVERRIDE_PROTECTED_RENDERBIN_DETAILS); + } + return _shadowsBinStateSet; +} diff --git a/components/sceneutil/mwshadowtechnique.hpp b/components/sceneutil/mwshadowtechnique.hpp index 3f6c0fb765..574d054204 100644 --- a/components/sceneutil/mwshadowtechnique.hpp +++ b/components/sceneutil/mwshadowtechnique.hpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -215,8 +216,6 @@ namespace SceneUtil { virtual void createShaders(); - virtual std::array, GL_ALWAYS - GL_NEVER + 1> getCastingPrograms() const { return _castingPrograms; } - virtual bool selectActiveLights(osgUtil::CullVisitor* cv, ViewDependentData* vdd) const; virtual osg::Polytope computeLightViewFrustumPolytope(Frustum& frustum, LightData& positionedLight); @@ -237,6 +236,8 @@ namespace SceneUtil { void setWorldMask(unsigned int worldMask) { _worldMask = worldMask; } + osg::ref_ptr getOrCreateShadowsBinStateSet(); + protected: virtual ~MWShadowTechnique(); @@ -297,6 +298,9 @@ namespace SceneUtil { osg::ref_ptr _debugHud; std::array, GL_ALWAYS - GL_NEVER + 1> _castingPrograms; + const std::string _shadowsBinName = "ShadowsBin_" + std::to_string(reinterpret_cast(this)); + osg::ref_ptr _shadowsBin; + osg::ref_ptr _shadowsBinStateSet; }; } diff --git a/components/sceneutil/shadowsbin.cpp b/components/sceneutil/shadowsbin.cpp index 21f25dc4ad..3e933cbb98 100644 --- a/components/sceneutil/shadowsbin.cpp +++ b/components/sceneutil/shadowsbin.cpp @@ -146,12 +146,6 @@ StateGraph* ShadowsBin::cullStateGraph(StateGraph* sg, StateGraph* root, std::un return sg; } -void ShadowsBin::addPrototype(const std::string & name, const CastingPrograms& castingPrograms) -{ - osg::ref_ptr bin(new ShadowsBin(castingPrograms)); - osgUtil::RenderBin::addRenderBinPrototype(name, bin); -} - inline bool ShadowsBin::State::needTexture() const { return mAlphaBlend || (mAlphaFunc && mAlphaFunc->getFunction() != GL_ALWAYS); diff --git a/components/sceneutil/shadowsbin.hpp b/components/sceneutil/shadowsbin.hpp index 4b0d8cc544..2c838d509e 100644 --- a/components/sceneutil/shadowsbin.hpp +++ b/components/sceneutil/shadowsbin.hpp @@ -62,8 +62,6 @@ namespace SceneUtil osgUtil::StateGraph* cullStateGraph(osgUtil::StateGraph* sg, osgUtil::StateGraph* root, std::unordered_set& uninteresting, bool cullFaceOverridden); - static void addPrototype(const std::string& name, const CastingPrograms& castingPrograms); - private: ShadowsBin() {}