From 4d4dc1b9c1e08c4a5b258d605118de0b5b15074f Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 Feb 2017 23:01:36 +0100 Subject: [PATCH] Add specialized DisableLight state attribute for more efficient undoing of light state Seems to reduce # of GL calls by 10-15% in a typical scene. --- components/sceneutil/lightmanager.cpp | 48 ++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/components/sceneutil/lightmanager.cpp b/components/sceneutil/lightmanager.cpp index 28f9a3a62..521939170 100644 --- a/components/sceneutil/lightmanager.cpp +++ b/components/sceneutil/lightmanager.cpp @@ -262,18 +262,56 @@ namespace SceneUtil return it->second; } + class DisableLight : public osg::StateAttribute + { + public: + DisableLight() : mIndex(0) {} + DisableLight(int index) : mIndex(index) {} + + DisableLight(const DisableLight& copy,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) + : osg::StateAttribute(copy,copyop), mIndex(copy.mIndex) {} + + unsigned int getMember() const + { + return mIndex; + } + + virtual bool getModeUsage(ModeUsage & usage) const + { + usage.usesMode(GL_LIGHT0 + mIndex); + return true; + } + + virtual int compare(const StateAttribute &sa) const + { + throw std::runtime_error("DisableLight::compare: unimplemented"); + } + + META_StateAttribute(SceneUtil, DisableLight, osg::StateAttribute::LIGHT) + + virtual void apply(osg::State&) const + { + int lightNum = GL_LIGHT0 + mIndex; + glLightfv( lightNum, GL_AMBIENT, mNull.ptr() ); + glLightfv( lightNum, GL_DIFFUSE, mNull.ptr() ); + glLightfv( lightNum, GL_SPECULAR, mNull.ptr() ); + } + + private: + unsigned int mIndex; + osg::Vec4f mNull; + }; + void LightManager::setStartLight(int start) { mStartLight = start; // Set default light state to zero + // This is necessary because shaders don't respect glDisable(GL_LIGHTX) so in addition to disabling + // we'll have to set a light state that has no visible effect for (int i=start; i<8; ++i) { - osg::ref_ptr defaultLight (new osg::Light(i)); - defaultLight->setAmbient(osg::Vec4()); - defaultLight->setDiffuse(osg::Vec4()); - defaultLight->setSpecular(osg::Vec4()); - defaultLight->setConstantAttenuation(0.f); + osg::ref_ptr defaultLight (new DisableLight(i)); getOrCreateStateSet()->setAttributeAndModes(defaultLight, osg::StateAttribute::OFF); } }