mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 06:23:53 +00:00
Cache the light list in LightListCallback
When multiple cameras are rendering, the later cameras can reuse the light lists from the first camera.
This commit is contained in:
parent
1cf1c944b7
commit
c23609e22b
2 changed files with 25 additions and 16 deletions
|
@ -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())
|
if (mLightList.size())
|
||||||
{
|
{
|
||||||
traverse(node, nv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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…
Reference in a new issue