diff --git a/components/sceneutil/lightmanager.cpp b/components/sceneutil/lightmanager.cpp index bd8ef8af4..b421f87cf 100644 --- a/components/sceneutil/lightmanager.cpp +++ b/components/sceneutil/lightmanager.cpp @@ -381,21 +381,23 @@ namespace SceneUtil { osgUtil::CullVisitor* cv = static_cast(nv); + bool pushedState = pushLightState(node, cv); + traverse(node, nv); + if (pushedState) + cv->popStateSet(); + } + + bool LightListCallback::pushLightState(osg::Node *node, osgUtil::CullVisitor *cv) + { if (!mLightManager) { - mLightManager = findLightManager(nv->getNodePath()); + mLightManager = findLightManager(cv->getNodePath()); if (!mLightManager) - { - traverse(node, nv); - return; - } + return false; } if (!(cv->getCurrentCamera()->getCullMask() & mLightManager->getLightingMask())) - { - traverse(node, nv); - return; - } + return false; // Possible optimizations: // - cull list of lights by the camera frustum @@ -404,9 +406,9 @@ namespace SceneUtil // update light list if necessary // makes sure we don't update it more than once per frame when rendering with multiple cameras - if (mLastFrameNumber != nv->getTraversalNumber()) + if (mLastFrameNumber != cv->getTraversalNumber()) { - mLastFrameNumber = nv->getTraversalNumber(); + mLastFrameNumber = cv->getTraversalNumber(); // Don't use Camera::getViewMatrix, that one might be relative to another camera! const osg::RefMatrix* viewMatrix = cv->getCurrentRenderStage()->getInitialViewMatrix(); @@ -469,20 +471,16 @@ namespace SceneUtil while (lightList.size() > maxLights) lightList.pop_back(); } - stateset = mLightManager->getLightListStateSet(lightList, nv->getTraversalNumber()); + stateset = mLightManager->getLightListStateSet(lightList, cv->getTraversalNumber()); } else - stateset = mLightManager->getLightListStateSet(mLightList, nv->getTraversalNumber()); + stateset = mLightManager->getLightListStateSet(mLightList, cv->getTraversalNumber()); cv->pushStateSet(stateset); - - traverse(node, nv); - - cv->popStateSet(); + return true; } - else - traverse(node, nv); + return false; } } diff --git a/components/sceneutil/lightmanager.hpp b/components/sceneutil/lightmanager.hpp index 2c7a6a3d8..55d0c69cd 100644 --- a/components/sceneutil/lightmanager.hpp +++ b/components/sceneutil/lightmanager.hpp @@ -9,6 +9,11 @@ #include #include +namespace osgUtil +{ + class CullVisitor; +} + namespace SceneUtil { @@ -148,6 +153,7 @@ namespace SceneUtil /// rendering when the size of a light list exceeds the OpenGL limit on the number of concurrent lights (8). A good /// starting point is to attach a LightListCallback to each game object's base node. /// @note Not thread safe for CullThreadPerCamera threading mode. + /// @note Due to lack of OSG support, the callback does not work on Drawables. class LightListCallback : public osg::NodeCallback { public: @@ -166,6 +172,8 @@ namespace SceneUtil void operator()(osg::Node* node, osg::NodeVisitor* nv); + bool pushLightState(osg::Node* node, osgUtil::CullVisitor* nv); + std::set& getIgnoredLightSources() { return mIgnoredLightSources; } private: