1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-30 21:45:33 +00:00

LightManager optimization

This commit is contained in:
scrawl 2015-04-12 19:44:48 +02:00
parent 61aaf0cf70
commit 987e923790

View file

@ -15,17 +15,32 @@
namespace SceneUtil namespace SceneUtil
{ {
class LightStateAttribute : public osg::Light // Resets the modelview matrix to just the view matrix before applying lights.
class LightStateAttribute : public osg::StateAttribute
{ {
public: public:
LightStateAttribute() {} LightStateAttribute() : mIndex(0) {}
LightStateAttribute(unsigned int index, const std::vector<osg::ref_ptr<osg::Light> >& lights) : mIndex(index), mLights(lights) {}
LightStateAttribute(const LightStateAttribute& light,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) LightStateAttribute(const LightStateAttribute& copy,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY)
: osg::Light(light,copyop) {} : osg::StateAttribute(copy,copyop), mIndex(copy.mIndex), mLights(copy.mLights) {}
LightStateAttribute(const osg::Light& light,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) unsigned int getMember() const
: osg::Light(light,copyop) {} {
return mIndex;
}
virtual bool getModeUsage(ModeUsage & usage) const
{
for (unsigned int i=0; i<mLights.size(); ++i)
usage.usesMode(GL_LIGHT0 + mIndex + i);
return true;
}
virtual int compare(const StateAttribute &sa) const
{
throw std::runtime_error("LightStateAttribute::compare: unimplemented");
}
META_StateAttribute(NifOsg, LightStateAttribute, osg::StateAttribute::LIGHT) META_StateAttribute(NifOsg, LightStateAttribute, osg::StateAttribute::LIGHT)
@ -33,16 +48,21 @@ namespace SceneUtil
{ {
osg::Matrix modelViewMatrix = state.getModelViewMatrix(); osg::Matrix modelViewMatrix = state.getModelViewMatrix();
// FIXME: we shouldn't have to apply the modelview matrix after every light
// this could be solvable by having the LightStateAttribute contain all lights instead of just one.
state.applyModelViewMatrix(state.getInitialViewMatrix()); state.applyModelViewMatrix(state.getInitialViewMatrix());
osg::Light::apply(state); for (unsigned int i=0; i<mLights.size(); ++i)
{
state.setGlobalDefaultAttribute(this); mLights[i]->setLightNum(i+mIndex);
mLights[i]->apply(state);
}
state.applyModelViewMatrix(modelViewMatrix); state.applyModelViewMatrix(modelViewMatrix);
} }
private:
unsigned int mIndex;
std::vector<osg::ref_ptr<osg::Light> > mLights;
}; };
// Set on a LightSource. Adds the light source to its light manager for the current frame. // Set on a LightSource. Adds the light source to its light manager for the current frame.
@ -133,6 +153,9 @@ namespace SceneUtil
LightSourceTransform l; LightSourceTransform l;
l.mLightSource = lightSource; l.mLightSource = lightSource;
l.mWorldMatrix = worldMat; l.mWorldMatrix = worldMat;
lightSource->getLight()->setPosition(osg::Vec4f(worldMat.getTrans().x(),
worldMat.getTrans().y(),
worldMat.getTrans().z(), 1.f));
mLights.push_back(l); mLights.push_back(l);
} }
@ -164,24 +187,22 @@ namespace SceneUtil
return found->second; return found->second;
else else
{ {
osg::ref_ptr<osg::StateSet> stateset (new osg::StateSet);
std::vector<osg::ref_ptr<osg::Light> > lights;
for (unsigned int i=0; i<lightList.size();++i) for (unsigned int i=0; i<lightList.size();++i)
{ {
int lightIndex = lightList[i]; const LightSourceTransform& l = mLights[lightList[i]];
osg::Light* light = mLights[lightIndex].mLightSource->getLight(); lights.push_back(l.mLightSource->getLight());
osg::ref_ptr<LightStateAttribute> clonedLight = new LightStateAttribute(*light, osg::CopyOp::DEEP_COPY_ALL);
clonedLight->setPosition(mLights[lightIndex].mWorldMatrix.preMult(light->getPosition()));
clonedLight->setLightNum(i+mStartLight);
// don't use setAttributeAndModes, that does not support light indices!
stateset->setAttribute(clonedLight, osg::StateAttribute::ON);
stateset->setAssociatedModes(clonedLight, osg::StateAttribute::ON);
//stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
} }
osg::ref_ptr<LightStateAttribute> attr = new LightStateAttribute(mStartLight, lights);
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
// don't use setAttributeAndModes, that does not support light indices!
stateset->setAttribute(attr, osg::StateAttribute::ON);
stateset->setAssociatedModes(attr, osg::StateAttribute::ON);
mStateSetCache.insert(std::make_pair(hash, stateset)); mStateSetCache.insert(std::make_pair(hash, stateset));
return stateset; return stateset;
} }