From: timoore Date: Wed, 15 Jul 2009 23:10:21 +0000 (+0000) Subject: Use Effect to implement point lights X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=40fe078021ebad743c5c19b8d8e287185395baf3;p=simgear.git Use Effect to implement point lights This allows different OpenGL features (point sprites, point attenuation) to be used depending on hardware support. --- diff --git a/simgear/scene/material/EffectCullVisitor.cxx b/simgear/scene/material/EffectCullVisitor.cxx index 8d86d8e0..dec2b1bd 100644 --- a/simgear/scene/material/EffectCullVisitor.cxx +++ b/simgear/scene/material/EffectCullVisitor.cxx @@ -14,6 +14,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +#include + #include "EffectCullVisitor.hxx" #include "EffectGeode.hxx" @@ -53,11 +55,19 @@ void EffectCullVisitor::apply(osg::Geode& node) CullVisitor::apply(node); return; } + // push the node's state. + osg::StateSet* node_state = node.getStateSet(); + if (node_state) + pushStateSet(node_state); for (EffectGeode::DrawablesIterator beginItr = eg->drawablesBegin(), e = eg->drawablesEnd(); beginItr != e; beginItr = technique->processDrawables(beginItr, e, this, eg->isCullingActive())) ; + // pop the node's state off the geostate stack. + if (node_state) + popStateSet(); + } } diff --git a/simgear/scene/material/mat.cxx b/simgear/scene/material/mat.cxx index 2c97551a..dddec02d 100644 --- a/simgear/scene/material/mat.cxx +++ b/simgear/scene/material/mat.cxx @@ -314,8 +314,7 @@ SGMaterial::build_state( bool defer_tex_load ) } _status[i].state = pass; - Technique* tniq = new Technique(); - tniq->setGLExtensionsPred(1.1, std::vector()); + Technique* tniq = new Technique(true); tniq->passes.push_back(pass); Effect* effect = new Effect; effect->techniques.push_back(tniq); diff --git a/simgear/scene/tgdb/obj.cxx b/simgear/scene/tgdb/obj.cxx index 2efad952..3869c521 100644 --- a/simgear/scene/tgdb/obj.cxx +++ b/simgear/scene/tgdb/obj.cxx @@ -683,7 +683,10 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool } if (!tileGeometryBin.vasiLights.empty()) { - osg::Geode* vasiGeode = new osg::Geode; + EffectGeode* vasiGeode = new EffectGeode; + Effect* vasiEffect + = getLightEffect(6, osg::Vec3(1, 0.0001, 0.000001), 1, 6, true); + vasiGeode->setEffect(vasiEffect); SGVec4f red(1, 0, 0, 1); SGMaterial* mat = 0; if (matlib) @@ -696,27 +699,31 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool mat = matlib->find("RWY_WHITE_LIGHTS"); if (mat) white = mat->get_light_color(); - SGDirectionalLightListBin::const_iterator i; for (i = tileGeometryBin.vasiLights.begin(); i != tileGeometryBin.vasiLights.end(); ++i) { vasiGeode->addDrawable(SGLightFactory::getVasi(up, *i, red, white)); } - vasiGeode->setCullCallback(new SGPointSpriteLightCullCallback(osg::Vec3(1, 0.0001, 0.000001), 6)); vasiGeode->setStateSet(lightManager->getRunwayLightStateSet()); lightGroup->addChild(vasiGeode); } - + Effect* runwayEffect = 0; + if (tileGeometryBin.runwayLights.getNumLights() > 0 + || !tileGeometryBin.rabitLights.empty() + || !tileGeometryBin.reilLights.empty() + || !tileGeometryBin.odalLights.empty() + || tileGeometryBin.taxiLights.getNumLights() > 0) + runwayEffect = getLightEffect(4, osg::Vec3(1, 0.001, 0.0002), 1, 4, true); if (tileGeometryBin.runwayLights.getNumLights() > 0 || !tileGeometryBin.rabitLights.empty() || !tileGeometryBin.reilLights.empty() || !tileGeometryBin.odalLights.empty()) { osg::Group* rwyLights = new osg::Group; - rwyLights->setCullCallback(new SGPointSpriteLightCullCallback); rwyLights->setStateSet(lightManager->getRunwayLightStateSet()); rwyLights->setNodeMask(RUNWAYLIGHTS_BIT); if (tileGeometryBin.runwayLights.getNumLights() != 0) { - osg::Geode* geode = new osg::Geode; + EffectGeode* geode = new EffectGeode; + geode->setEffect(runwayEffect); geode->addDrawable(SGLightFactory::getLights(tileGeometryBin .runwayLights)); rwyLights->addChild(geode); @@ -740,10 +747,10 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool if (tileGeometryBin.taxiLights.getNumLights() > 0) { osg::Group* taxiLights = new osg::Group; - taxiLights->setCullCallback(new SGPointSpriteLightCullCallback); taxiLights->setStateSet(lightManager->getTaxiLightStateSet()); taxiLights->setNodeMask(RUNWAYLIGHTS_BIT); - osg::Geode* geode = new osg::Geode; + EffectGeode* geode = new EffectGeode; + geode->setEffect(runwayEffect); geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.taxiLights)); taxiLights->addChild(geode); lightGroup->addChild(taxiLights); diff --git a/simgear/scene/tgdb/pt_lights.cxx b/simgear/scene/tgdb/pt_lights.cxx index 274a4e18..e15b7bea 100644 --- a/simgear/scene/tgdb/pt_lights.cxx +++ b/simgear/scene/tgdb/pt_lights.cxx @@ -26,6 +26,9 @@ #include "pt_lights.hxx" +#include +#include + #include #include #include @@ -57,12 +60,19 @@ #include #include #include +#include + +#include +#include +#include +#include #include "SGVasiDrawable.hxx" using OpenThreads::Mutex; using OpenThreads::ScopedLock; +using namespace osg; using namespace simgear; static void @@ -132,15 +142,11 @@ static Mutex lightMutex; static osg::Texture2D* gen_standard_light_sprite(void) { - // double checked locking ... + // Always called from when the lightMutex is already taken static osg::ref_ptr texture; if (texture.valid()) return texture.get(); - ScopedLock lock(lightMutex); - if (texture.valid()) - return texture.get(); - texture = new osg::Texture2D; texture->setImage(getPointSpriteImage(6)); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP); @@ -149,80 +155,84 @@ gen_standard_light_sprite(void) return texture.get(); } -SGPointSpriteLightCullCallback::SGPointSpriteLightCullCallback(const osg::Vec3& da, - float sz) : - _pointSpriteStateSet(new osg::StateSet), - _distanceAttenuationStateSet(new osg::StateSet) +namespace { - osg::PointSprite* pointSprite = new osg::PointSprite; - _pointSpriteStateSet->setTextureAttributeAndModes(0, pointSprite, - osg::StateAttribute::ON); - osg::Texture2D* texture = gen_standard_light_sprite(); - _pointSpriteStateSet->setTextureAttribute(0, texture); - _pointSpriteStateSet->setTextureMode(0, GL_TEXTURE_2D, - osg::StateAttribute::ON); - osg::TexEnv* texEnv = new osg::TexEnv; - texEnv->setMode(osg::TexEnv::MODULATE); - _pointSpriteStateSet->setTextureAttribute(0, texEnv); - - osg::Point* point = new osg::Point; - point->setFadeThresholdSize(1); - point->setMinSize(1); - point->setMaxSize(sz); - point->setSize(sz); - point->setDistanceAttenuation(da); - _distanceAttenuationStateSet->setAttributeAndModes(point); -} +typedef boost::tuple PointParams; +typedef std::map > EffectMap; -// FIXME make state sets static -SGPointSpriteLightCullCallback::SGPointSpriteLightCullCallback(osg::Point* point) : - _pointSpriteStateSet(new osg::StateSet), - _distanceAttenuationStateSet(new osg::StateSet) -{ - osg::PointSprite* pointSprite = new osg::PointSprite; - _pointSpriteStateSet->setTextureAttributeAndModes(0, pointSprite, - osg::StateAttribute::ON); - osg::Texture2D* texture = gen_standard_light_sprite(); - _pointSpriteStateSet->setTextureAttribute(0, texture); - _pointSpriteStateSet->setTextureMode(0, GL_TEXTURE_2D, - osg::StateAttribute::ON); - osg::TexEnv* texEnv = new osg::TexEnv; - texEnv->setMode(osg::TexEnv::MODULATE); - _pointSpriteStateSet->setTextureAttribute(0, texEnv); - - _distanceAttenuationStateSet->setAttributeAndModes(point); +EffectMap effectMap; + +ref_ptr polyMode = new PolygonMode(PolygonMode::FRONT, + PolygonMode::POINT); +ref_ptr pointSprite = new PointSprite; } -void -SGPointSpriteLightCullCallback::operator()(osg::Node* node, - osg::NodeVisitor* nv) +Effect* getLightEffect(float size, const Vec3& attenuation, + float minSize, float maxSize, bool directional) { - assert(dynamic_cast(nv)); - osgUtil::CullVisitor* cv = static_cast(nv); - - // Test for point sprites and point parameters availibility - unsigned contextId = cv->getRenderInfo().getContextID(); - SGSceneFeatures* features = SGSceneFeatures::instance(); - bool usePointSprite = features->getEnablePointSpriteLights(contextId); - bool usePointParameters = features->getEnableDistanceAttenuationLights(contextId); - - if (usePointSprite) - cv->pushStateSet(_pointSpriteStateSet.get()); - - if (usePointParameters) - cv->pushStateSet(_distanceAttenuationStateSet.get()); - - traverse(node, nv); - - if (usePointParameters) - cv->popStateSet(); - - if (usePointSprite) - cv->popStateSet(); + PointParams pointParams(size, attenuation, minSize, maxSize, directional); + ScopedLock lock(lightMutex); + EffectMap::iterator eitr = effectMap.find(pointParams); + if (eitr != effectMap.end()) + return eitr->second.get(); + // Basic stuff; no sprite or attenuation support + Pass *basicPass = new Pass; + basicPass->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin"); + basicPass->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + StateAttributeFactory *attrFact = StateAttributeFactory::instance(); + basicPass->setAttributeAndModes(attrFact->getStandardBlendFunc()); + basicPass->setAttributeAndModes(attrFact->getStandardAlphaFunc()); + if (directional) { + basicPass->setAttributeAndModes(attrFact->getCullFaceBack()); + basicPass->setAttribute(polyMode.get()); + } + Pass *attenuationPass = clone(basicPass, CopyOp::SHALLOW_COPY); + osg::Point* point = new osg::Point; + point->setMinSize(minSize); + point->setMaxSize(maxSize); + point->setSize(size); + point->setDistanceAttenuation(attenuation); + attenuationPass->setAttributeAndModes(point); + Pass *spritePass = clone(basicPass, CopyOp::SHALLOW_COPY); + spritePass->setTextureAttributeAndModes(0, pointSprite, + osg::StateAttribute::ON); + Texture2D* texture = gen_standard_light_sprite(); + spritePass->setTextureAttribute(0, texture); + spritePass->setTextureMode(0, GL_TEXTURE_2D, + osg::StateAttribute::ON); + spritePass->setTextureAttribute(0, attrFact->getStandardTexEnv()); + Pass *combinedPass = clone(spritePass, CopyOp::SHALLOW_COPY); + combinedPass->setAttributeAndModes(point); + Effect* effect = new Effect; + std::vector combinedExtensions; + combinedExtensions.push_back("GL_ARB_point_sprite"); + combinedExtensions.push_back("GL_ARB_point_parameters"); + Technique* combinedTniq = new Technique; + combinedTniq->passes.push_back(combinedPass); + combinedTniq->setGLExtensionsPred(2.0, combinedExtensions); + effect->techniques.push_back(combinedTniq); + std::vector spriteExtensions; + spriteExtensions.push_back(combinedExtensions.front()); + Technique* spriteTniq = new Technique; + spriteTniq->passes.push_back(spritePass); + spriteTniq->setGLExtensionsPred(2.0, spriteExtensions); + effect->techniques.push_back(spriteTniq); + std::vector parameterExtensions; + parameterExtensions.push_back(combinedExtensions.back()); + Technique* parameterTniq = new Technique; + parameterTniq->passes.push_back(attenuationPass); + parameterTniq->setGLExtensionsPred(1.4, parameterExtensions); + effect->techniques.push_back(parameterTniq); + Technique* basicTniq = new Technique(true); + basicTniq->passes.push_back(basicPass); + effect->techniques.push_back(basicTniq); + effectMap.insert(std::make_pair(pointParams, effect)); + return effect; } -osg::Node* -SGLightFactory::getLight(const SGLightBin::Light& light) + +osg::Drawable* +SGLightFactory::getLightDrawable(const SGLightBin::Light& light) { osg::Vec3Array* vertices = new osg::Vec3Array; osg::Vec4Array* colors = new osg::Vec4Array; @@ -244,28 +254,11 @@ SGLightFactory::getLight(const SGLightBin::Light& light) drawArrays = new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, vertices->size()); geometry->addPrimitiveSet(drawArrays); - - osg::StateSet* stateSet = geometry->getOrCreateStateSet(); - stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin"); - stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - - osg::BlendFunc* blendFunc = new osg::BlendFunc; - stateSet->setAttribute(blendFunc); - stateSet->setMode(GL_BLEND, osg::StateAttribute::ON); - - osg::AlphaFunc* alphaFunc; - alphaFunc = new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01); - stateSet->setAttribute(alphaFunc); - stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON); - - osg::Geode* geode = new osg::Geode; - geode->addDrawable(geometry); - - return geode; + return geometry; } -osg::Node* -SGLightFactory::getLight(const SGDirectionalLightBin::Light& light) +osg::Drawable* +SGLightFactory::getLightDrawable(const SGDirectionalLightBin::Light& light) { osg::Vec3Array* vertices = new osg::Vec3Array; osg::Vec4Array* colors = new osg::Vec4Array; @@ -297,40 +290,13 @@ SGLightFactory::getLight(const SGDirectionalLightBin::Light& light) drawArrays = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertices->size()); geometry->addPrimitiveSet(drawArrays); - - osg::StateSet* stateSet = geometry->getOrCreateStateSet(); - stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin"); - - osg::Material* material = new osg::Material; - material->setColorMode(osg::Material::OFF); - stateSet->setAttribute(material); - - osg::CullFace* cullFace = new osg::CullFace; - cullFace->setMode(osg::CullFace::BACK); - stateSet->setAttribute(cullFace, osg::StateAttribute::ON); - stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::ON); - - osg::PolygonMode* polygonMode = new osg::PolygonMode; - polygonMode->setMode(osg::PolygonMode::FRONT, osg::PolygonMode::POINT); - stateSet->setAttribute(polygonMode); - - stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - - osg::BlendFunc* blendFunc = new osg::BlendFunc; - stateSet->setAttribute(blendFunc); - stateSet->setMode(GL_BLEND, osg::StateAttribute::ON); - - osg::AlphaFunc* alphaFunc; - alphaFunc = new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01); - stateSet->setAttribute(alphaFunc); - stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON); - - osg::Geode* geode = new osg::Geode; - geode->addDrawable(geometry); - - return geode; + return geometry; } +namespace +{ + ref_ptr simpleLightSS; +} osg::Drawable* SGLightFactory::getLights(const SGLightBin& lights, unsigned inc, float alphaOff) { @@ -358,21 +324,19 @@ SGLightFactory::getLights(const SGLightBin& lights, unsigned inc, float alphaOff drawArrays = new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, vertices->size()); geometry->addPrimitiveSet(drawArrays); - - osg::StateSet* stateSet = geometry->getOrCreateStateSet(); - stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin"); - stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - - osg::BlendFunc* blendFunc = new osg::BlendFunc; - stateSet->setAttribute(blendFunc); - stateSet->setMode(GL_BLEND, osg::StateAttribute::ON); - - osg::AlphaFunc* alphaFunc; - alphaFunc = new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01); - stateSet->setAttribute(alphaFunc); - stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON); - + { + ScopedLock lock(lightMutex); + if (!simpleLightSS.valid()) { + StateAttributeFactory *attrFact = StateAttributeFactory::instance(); + simpleLightSS = new StateSet; + simpleLightSS->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin"); + simpleLightSS->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + simpleLightSS->setAttributeAndModes(attrFact->getStandardBlendFunc()); + simpleLightSS->setAttributeAndModes(attrFact->getStandardAlphaFunc()); + } + } + geometry->setStateSet(simpleLightSS.get()); return geometry; } @@ -413,34 +377,6 @@ SGLightFactory::getLights(const SGDirectionalLightBin& lights) drawArrays = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertices->size()); geometry->addPrimitiveSet(drawArrays); - - osg::StateSet* stateSet = geometry->getOrCreateStateSet(); - stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin"); - - osg::Material* material = new osg::Material; - material->setColorMode(osg::Material::OFF); - stateSet->setAttribute(material); - - osg::CullFace* cullFace = new osg::CullFace; - cullFace->setMode(osg::CullFace::BACK); - stateSet->setAttribute(cullFace, osg::StateAttribute::ON); - stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::ON); - - osg::PolygonMode* polygonMode = new osg::PolygonMode; - polygonMode->setMode(osg::PolygonMode::FRONT, osg::PolygonMode::POINT); - stateSet->setAttribute(polygonMode); - - stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - - osg::BlendFunc* blendFunc = new osg::BlendFunc; - stateSet->setAttribute(blendFunc); - stateSet->setMode(GL_BLEND, osg::StateAttribute::ON); - - osg::AlphaFunc* alphaFunc; - alphaFunc = new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01); - stateSet->setAttribute(alphaFunc); - stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON); - return geometry; } @@ -523,35 +459,19 @@ SGLightFactory::getSequenced(const SGDirectionalLightBin& lights) float flashTime = 2e-2 + 5e-3*sg_random(); osg::Sequence* sequence = new osg::Sequence; sequence->setDefaultTime(flashTime); - - for (int i = lights.getNumLights() - 1; 0 <= i; --i) - sequence->addChild(getLight(lights.getLight(i)), flashTime); + Effect* effect = getLightEffect(10.0f, osg::Vec3(1.0, 0.0001, 0.00000001), + 6.0f, 10.0f, true); + for (int i = lights.getNumLights() - 1; 0 <= i; --i) { + EffectGeode* egeode = new EffectGeode; + egeode->setEffect(effect); + egeode->addDrawable(getLightDrawable(lights.getLight(i))); + sequence->addChild(egeode, flashTime); + } sequence->addChild(new osg::Group, 1 + 1e-1*sg_random()); sequence->setInterval(osg::Sequence::LOOP, 0, -1); sequence->setDuration(1.0f, -1); sequence->setMode(osg::Sequence::START); sequence->setSync(true); - - osg::StateSet* stateSet = sequence->getOrCreateStateSet(); - stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin"); - stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - - osg::BlendFunc* blendFunc = new osg::BlendFunc; - stateSet->setAttribute(blendFunc); - stateSet->setMode(GL_BLEND, osg::StateAttribute::ON); - - osg::AlphaFunc* alphaFunc; - alphaFunc = new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01); - stateSet->setAttribute(alphaFunc); - stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON); - - osg::Point* point = new osg::Point; - point->setMinSize(6); - point->setMaxSize(10); - point->setSize(10); - point->setDistanceAttenuation(osg::Vec3(1.0, 0.0001, 0.00000001)); - sequence->setCullCallback(new SGPointSpriteLightCullCallback(point)); - return sequence; } @@ -566,15 +486,23 @@ SGLightFactory::getOdal(const SGLightBin& lights) float flashTime = 2e-2 + 5e-3*sg_random(); osg::Sequence* sequence = new osg::Sequence; sequence->setDefaultTime(flashTime); - + Effect* effect = getLightEffect(10.0f, osg::Vec3(1.0, 0.0001, 0.00000001), + 6.0, 10.0, false); // centerline lights - for (int i = lights.getNumLights() - 1; 2 <= i; --i) - sequence->addChild(getLight(lights.getLight(i)), flashTime); - + for (int i = lights.getNumLights() - 1; 2 <= i; --i) { + EffectGeode* egeode = new EffectGeode; + egeode->setEffect(effect); + egeode->addDrawable(getLightDrawable(lights.getLight(i))); + sequence->addChild(egeode, flashTime); + } // runway end lights osg::Group* group = new osg::Group; - for (unsigned i = 0; i < 2; ++i) - group->addChild(getLight(lights.getLight(i))); + for (unsigned i = 0; i < 2; ++i) { + EffectGeode* egeode = new EffectGeode; + egeode->setEffect(effect); + egeode->addDrawable(getLightDrawable(lights.getLight(i))); + group->addChild(egeode); + } sequence->addChild(group, flashTime); // add an extra empty group for a break @@ -584,25 +512,5 @@ SGLightFactory::getOdal(const SGLightBin& lights) sequence->setMode(osg::Sequence::START); sequence->setSync(true); - osg::StateSet* stateSet = sequence->getOrCreateStateSet(); - stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin"); - stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - - osg::BlendFunc* blendFunc = new osg::BlendFunc; - stateSet->setAttribute(blendFunc); - stateSet->setMode(GL_BLEND, osg::StateAttribute::ON); - - osg::AlphaFunc* alphaFunc; - alphaFunc = new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01); - stateSet->setAttribute(alphaFunc); - stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON); - - osg::Point* point = new osg::Point; - point->setMinSize(6); - point->setMaxSize(10); - point->setSize(10); - point->setDistanceAttenuation(osg::Vec3(1.0, 0.0001, 0.00000001)); - sequence->setCullCallback(new SGPointSpriteLightCullCallback(point)); - return sequence; } diff --git a/simgear/scene/tgdb/pt_lights.hxx b/simgear/scene/tgdb/pt_lights.hxx index 5f831cbf..6357c14c 100644 --- a/simgear/scene/tgdb/pt_lights.hxx +++ b/simgear/scene/tgdb/pt_lights.hxx @@ -45,8 +45,10 @@ #include "SGLightBin.hxx" #include "SGDirectionalLightBin.hxx" -using std::string; -using std::vector; +namespace simgear +{ +class Effect; +} // Specify the way we want to draw directional point lights (assuming the // appropriate extensions are available.) @@ -59,28 +61,19 @@ inline void SGConfigureDirectionalLights( bool use_point_sprites, sceneFeatures->setEnableDistanceAttenuationLights(distance_attenuation); } -class SGPointSpriteLightCullCallback : public osg::NodeCallback { -public: - SGPointSpriteLightCullCallback(const osg::Vec3& da = osg::Vec3(1, 0.001, 0.0002), - float sz = 4); - SGPointSpriteLightCullCallback(osg::Point* point); - - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv); - -private: - osg::ref_ptr _pointSpriteStateSet; - osg::ref_ptr _distanceAttenuationStateSet; -}; - class SGLightFactory { public: - static osg::Node* - getLight(const SGLightBin::Light& light); + static osg::Drawable* + getLightDrawable(const SGLightBin::Light& light); - static osg::Node* - getLight(const SGDirectionalLightBin::Light& light); + static osg::Drawable* + getLightDrawable(const SGDirectionalLightBin::Light& light); + /** + * Return a drawable for a very simple point light that isn't + * distance scaled. + */ static osg::Drawable* getLights(const SGLightBin& lights, unsigned inc = 1, float alphaOff = 0); @@ -98,4 +91,6 @@ public: getOdal(const SGLightBin& lights); }; +simgear::Effect* getLightEffect(float size, const osg::Vec3& attenuation, + float minSize, float maxSize, bool directional); #endif // _SG_PT_LIGHTS_HXX