- assert(dynamic_cast<osgUtil::CullVisitor*>(nv));
- osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(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<Mutex> 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.get(),
+ 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<std::string> 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<std::string> 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<std::string> 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;