Cache the light list in LightListCallback

When multiple cameras are rendering, the later cameras can reuse the light lists from the first camera.
openmw-37
scrawl 9 years ago
parent 1cf1c944b7
commit c23609e22b

@ -280,37 +280,40 @@ namespace SceneUtil
// - cull list of lights by the camera frustum // - cull list of lights by the camera frustum
// - organize lights in a quad tree // - organize lights in a quad tree
// Don't use Camera::getViewMatrix, that one might be relative to another camera!
const osg::RefMatrix* viewMatrix = cv->getCurrentRenderStage()->getInitialViewMatrix();
const std::vector<LightManager::LightSourceViewBound>& lights = mLightManager->getLightsInViewSpace(cv->getCurrentCamera(), viewMatrix); // update light list if necessary
// makes sure we don't update it more than once per frame when rendering with multiple cameras
if (lights.size()) if (mLastFrameNumber != nv->getFrameStamp()->getFrameNumber())
{ {
mLastFrameNumber = nv->getFrameStamp()->getFrameNumber();
// Don't use Camera::getViewMatrix, that one might be relative to another camera!
const osg::RefMatrix* viewMatrix = cv->getCurrentRenderStage()->getInitialViewMatrix();
const std::vector<LightManager::LightSourceViewBound>& lights = mLightManager->getLightsInViewSpace(cv->getCurrentCamera(), viewMatrix);
// we do the intersections in view space // we do the intersections in view space
osg::BoundingSphere nodeBound = node->getBound(); osg::BoundingSphere nodeBound = node->getBound();
osg::Matrixf mat = *cv->getModelViewMatrix(); osg::Matrixf mat = *cv->getModelViewMatrix();
transformBoundingSphere(mat, nodeBound); transformBoundingSphere(mat, nodeBound);
LightManager::LightList lightList; mLightList.clear();
for (unsigned int i=0; i<lights.size(); ++i) for (unsigned int i=0; i<lights.size(); ++i)
{ {
const LightManager::LightSourceViewBound& l = lights[i]; const LightManager::LightSourceViewBound& l = lights[i];
if (l.mViewBound.intersects(nodeBound)) if (l.mViewBound.intersects(nodeBound))
lightList.push_back(&l); mLightList.push_back(&l);
}
if (lightList.empty())
{
traverse(node, nv);
return;
} }
}
if (mLightList.size())
{
unsigned int maxLights = static_cast<unsigned int> (8 - mLightManager->getStartLight()); unsigned int maxLights = static_cast<unsigned int> (8 - mLightManager->getStartLight());
if (lightList.size() > maxLights) osg::StateSet* stateset = NULL;
if (mLightList.size() > maxLights)
{ {
// remove lights culled by this camera // remove lights culled by this camera
LightManager::LightList lightList = mLightList;
for (LightManager::LightList::iterator it = lightList.begin(); it != lightList.end() && lightList.size() > maxLights; ) for (LightManager::LightList::iterator it = lightList.begin(); it != lightList.end() && lightList.size() > maxLights; )
{ {
osg::CullStack::CullingStack& stack = cv->getModelViewCullingStack(); osg::CullStack::CullingStack& stack = cv->getModelViewCullingStack();
@ -334,9 +337,11 @@ namespace SceneUtil
while (lightList.size() > maxLights) while (lightList.size() > maxLights)
lightList.pop_back(); lightList.pop_back();
} }
stateset = mLightManager->getLightListStateSet(lightList);
} }
else
stateset = mLightManager->getLightListStateSet(mLightList);
osg::StateSet* stateset = mLightManager->getLightListStateSet(lightList);
cv->pushStateSet(stateset); cv->pushStateSet(stateset);

@ -113,11 +113,13 @@ namespace SceneUtil
int mStartLight; int mStartLight;
}; };
/// @note Not thread safe for CullThreadPerCamera threading mode.
class LightListCallback : public osg::NodeCallback class LightListCallback : public osg::NodeCallback
{ {
public: public:
LightListCallback() LightListCallback()
: mLightManager(NULL) : mLightManager(NULL)
, mLastFrameNumber(0)
{} {}
LightListCallback(const LightListCallback& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) LightListCallback(const LightListCallback& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY)
: osg::Object(copy, copyop), osg::NodeCallback(copy, copyop), mLightManager(copy.mLightManager) : osg::Object(copy, copyop), osg::NodeCallback(copy, copyop), mLightManager(copy.mLightManager)
@ -129,6 +131,8 @@ namespace SceneUtil
private: private:
LightManager* mLightManager; LightManager* mLightManager;
unsigned int mLastFrameNumber;
LightManager::LightList mLightList;
}; };
/// @brief Configures a light's attenuation according to vanilla Morrowind attenuation settings. /// @brief Configures a light's attenuation according to vanilla Morrowind attenuation settings.

Loading…
Cancel
Save