X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fscene%2Ftgdb%2Fpt_lights.cxx;h=7e123a475da55583f31b65ba2dd59e28ae846fa8;hb=e4dacaf0d270fb70beb2821888945b5e837afb50;hp=bfe3c5ae963544aaab92c694afc79d79cdce94e3;hpb=795d481ca621613376517ab72db89d9fea1a516b;p=simgear.git diff --git a/simgear/scene/tgdb/pt_lights.cxx b/simgear/scene/tgdb/pt_lights.cxx index bfe3c5ae..7e123a47 100644 --- a/simgear/scene/tgdb/pt_lights.cxx +++ b/simgear/scene/tgdb/pt_lights.cxx @@ -60,6 +60,7 @@ #include #include #include +#include #include #include @@ -158,7 +159,7 @@ gen_standard_light_sprite(void) namespace { typedef boost::tuple PointParams; -typedef std::map > EffectMap; +typedef std::map > EffectMap; EffectMap effectMap; @@ -174,7 +175,11 @@ Effect* getLightEffect(float size, const Vec3& attenuation, ScopedLock lock(lightMutex); EffectMap::iterator eitr = effectMap.find(pointParams); if (eitr != effectMap.end()) - return eitr->second.get(); + { + ref_ptr effect; + if (eitr->second.lock(effect)) + return effect.release(); + } // Basic stuff; no sprite or attenuation support Pass *basicPass = new Pass; basicPass->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin"); @@ -194,7 +199,7 @@ Effect* getLightEffect(float size, const Vec3& attenuation, point->setDistanceAttenuation(attenuation); attenuationPass->setAttributeAndModes(point); Pass *spritePass = clone(basicPass, CopyOp::SHALLOW_COPY); - spritePass->setTextureAttributeAndModes(0, pointSprite, + spritePass->setTextureAttributeAndModes(0, pointSprite.get(), osg::StateAttribute::ON); Texture2D* texture = gen_standard_light_sprite(); spritePass->setTextureAttribute(0, texture); @@ -203,22 +208,27 @@ Effect* getLightEffect(float size, const Vec3& attenuation, 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); + ref_ptr effect = new Effect; std::vector parameterExtensions; - parameterExtensions.push_back(combinedExtensions.back()); + + if (SGSceneFeatures::instance()->getEnablePointSpriteLights()) + { + 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); + parameterExtensions.push_back(combinedExtensions.back()); + } + Technique* parameterTniq = new Technique; parameterTniq->passes.push_back(attenuationPass); parameterTniq->setGLExtensionsPred(1.4, parameterExtensions); @@ -226,8 +236,11 @@ Effect* getLightEffect(float size, const Vec3& attenuation, Technique* basicTniq = new Technique(true); basicTniq->passes.push_back(basicPass); effect->techniques.push_back(basicTniq); - effectMap.insert(std::make_pair(pointParams, effect)); - return effect; + if (eitr == effectMap.end()) + effectMap.insert(std::make_pair(pointParams, effect)); + else + eitr->second = effect; // update existing, but empty observer + return effect.release(); } @@ -402,8 +415,21 @@ buildVasi(const SGDirectionalLightBin& lights, const SGVec3f& up, drawable->addLight(lights.getLight(3).position, lights.getLight(3).normal, up, 2.5); return drawable; - } - else if (count == 12) { + + } else if (count == 6) { + SGVasiDrawable* drawable = new SGVasiDrawable(red, white); + + // probably vasi, first 3 are downwind bar (2.5 deg) + for (unsigned i = 0; i < 3; ++i) + drawable->addLight(lights.getLight(i).position, + lights.getLight(i).normal, up, 2.5); + // last 3 are upwind bar (3.0 deg) + for (unsigned i = 3; i < 6; ++i) + drawable->addLight(lights.getLight(i).position, + lights.getLight(i).normal, up, 3.0); + return drawable; + + } else if (count == 12) { SGVasiDrawable* drawable = new SGVasiDrawable(red, white); // probably vasi, first 6 are downwind bar (2.5 deg) @@ -414,8 +440,8 @@ buildVasi(const SGDirectionalLightBin& lights, const SGVec3f& up, for (unsigned i = 6; i < 12; ++i) drawable->addLight(lights.getLight(i).position, lights.getLight(i).normal, up, 3.0); - return drawable; + } else { // fail safe SG_LOG(SG_TERRAIN, SG_ALERT, @@ -514,3 +540,35 @@ SGLightFactory::getOdal(const SGLightBin& lights) return sequence; } + +// Blinking hold short line lights +osg::Node* +SGLightFactory::getHoldShort(const SGDirectionalLightBin& lights) +{ + if (lights.getNumLights() < 2) + return 0; + + sg_srandom(unsigned(lights.getLight(0).position[0])); + float flashTime = 2 + 0.1 * sg_random(); + osg::Sequence* sequence = new osg::Sequence; + + // start with lights off + sequence->addChild(new osg::Group, flashTime); + // ...and increase the lights in steps + for (int i = 2; i < 7; i+=2) { + Effect* effect = getLightEffect(i, osg::Vec3(1, 0.001, 0.000002), + 0, i, true); + EffectGeode* egeode = new EffectGeode; + for (unsigned int j = 0; j < lights.getNumLights(); ++j) { + egeode->addDrawable(getLightDrawable(lights.getLight(j))); + egeode->setEffect(effect); + } + sequence->addChild(egeode, (i==6) ? flashTime : 0.1); + } + + sequence->setInterval(osg::Sequence::SWING, 0, -1); + sequence->setDuration(1.0f, -1); + sequence->setMode(osg::Sequence::START); + + return sequence; +}