]> git.mxchange.org Git - simgear.git/commitdiff
OSG 3.2.0 compatibility and surface light effects.
authorStuart Buchanan <stuart_d_buchanan@yahoo.co.uk>
Tue, 18 Feb 2014 21:30:15 +0000 (21:30 +0000)
committerStuart Buchanan <stuart_d_buchanan@yahoo.co.uk>
Tue, 18 Feb 2014 21:30:15 +0000 (21:30 +0000)
12 files changed:
simgear/canvas/elements/CanvasImage.cxx
simgear/scene/material/Effect.cxx
simgear/scene/material/TextureBuilder.cxx
simgear/scene/sky/cloud.cxx
simgear/scene/sky/dome.cxx
simgear/scene/sky/oursun.cxx
simgear/scene/tgdb/SGBuildingBin.cxx
simgear/scene/tgdb/SGBuildingBin.hxx
simgear/scene/tgdb/TreeBin.cxx
simgear/scene/tgdb/obj.cxx
simgear/scene/tgdb/pt_lights.cxx
simgear/scene/tgdb/pt_lights.hxx

index d86c7115337350d62062104e5c4c7abda1c8ea42..2852638984c2e4d80d5d6e47e2f15f47f489cb03 100644 (file)
@@ -128,12 +128,11 @@ namespace canvas
 
     _texCoords = new osg::Vec2Array(4);
     _texCoords->setDataVariance(osg::Object::DYNAMIC);
-    _geom->setTexCoordArray(0, _texCoords);
+    _geom->setTexCoordArray(0, _texCoords, osg::Array::BIND_PER_VERTEX);
 
     _colors = new osg::Vec4Array(1);
     _colors->setDataVariance(osg::Object::DYNAMIC);
-    _geom->setColorArray(_colors);
-    _geom->setColorBinding(osg::Geometry::BIND_OVERALL);
+    _geom->setColorArray(_colors, osg::Array::BIND_OVERALL);
 
     _prim = new osg::DrawArrays(osg::PrimitiveSet::QUADS);
     _prim->set(osg::PrimitiveSet::QUADS, 0, 4);
index 17b02a65a8e878e6d0d1cbb788cae66d860cf34c..7d961af47f51d3ed14e2b3332fd902aa5b0f9c32 100644 (file)
@@ -48,6 +48,7 @@
 #include <osg/Math>
 #include <osg/PolygonMode>
 #include <osg/PolygonOffset>
+#include <osg/Point>
 #include <osg/Program>
 #include <osg/Referenced>
 #include <osg/RenderInfo>
@@ -265,8 +266,8 @@ struct CullFaceBuilder : PassAttributeBuilder
             pass->setMode(GL_CULL_FACE, StateAttribute::OFF);
         else
             SG_LOG(SG_INPUT, SG_ALERT,
-                   "invalid cull face property " << propVal);            
-    }    
+                   "invalid cull face property " << propVal);
+    }
 };
 
 InstallAttributeBuilder<CullFaceBuilder> installCullFace("cull-face");
@@ -284,7 +285,7 @@ struct ColorMaskBuilder : PassAttributeBuilder
         Vec4 m = getColor(realProp);
         mask->setMask(m.r() > 0.0, m.g() > 0.0, m.b() > 0.0, m.a() > 0.0);
         pass->setAttributeAndModes(mask);
-    }    
+    }
 };
 
 InstallAttributeBuilder<ColorMaskBuilder> installColorMask("color-mask");
@@ -309,7 +310,7 @@ struct HintBuilder : public PassAttributeBuilder
         StateSet::RenderingHint renderingHint = StateSet::DEFAULT_BIN;
         findAttr(renderingHints, realProp, renderingHint);
         pass->setRenderingHint(renderingHint);
-    }    
+    }
 };
 
 InstallAttributeBuilder<HintBuilder> installHint("rendering-hint");
@@ -387,9 +388,9 @@ void MaterialBuilder::buildAttribute(Effect* effect, Pass* pass,
     if ((color = getEffectPropertyChild(effect, prop, "emissive")))
         mat->setEmission(Material::FRONT_AND_BACK, getColor(color));
     if ((color = getEffectPropertyChild(effect, prop, "emissive-front")))
-        mat->setEmission(Material::FRONT, getColor(color));        
+        mat->setEmission(Material::FRONT, getColor(color));
     if ((color = getEffectPropertyChild(effect, prop, "emissive-back")))
-        mat->setEmission(Material::BACK, getColor(color));        
+        mat->setEmission(Material::BACK, getColor(color));
     const SGPropertyNode* shininess = 0;
     mat->setShininess(Material::FRONT_AND_BACK, 0.0f);
     if ((shininess = getEffectPropertyChild(effect, prop, "shininess")))
@@ -538,7 +539,7 @@ struct StencilBuilder : public PassAttributeBuilder
             findAttr(stencilFunction, pfunction, func);
         if (pvalue)
             ref = pvalue->getIntValue();
-        if (pmask) 
+        if (pmask)
             mask = pmask->getIntValue();
 
         if (psfail)
@@ -578,7 +579,7 @@ void AlphaToCoverageBuilder::buildAttribute(Effect* effect, Pass* pass,
     const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
     if (!realProp)
         return;
-    pass->setMode(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB, (realProp->getValue<bool>() ? 
+    pass->setMode(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB, (realProp->getValue<bool>() ?
                                     StateAttribute::ON : StateAttribute::OFF));
 }
 
@@ -1062,19 +1063,19 @@ struct PolygonOffsetBuilder : public PassAttributeBuilder
     {
         if (!isAttributeActive(effect, prop))
             return;
-        
+
         const SGPropertyNode* factor
            = getEffectPropertyChild(effect, prop, "factor");
         const SGPropertyNode* units
            = getEffectPropertyChild(effect, prop, "units");
-        
+
         ref_ptr<PolygonOffset> polyoffset = new PolygonOffset;
-        
+
         polyoffset->setFactor(factor->getFloatValue());
         polyoffset->setUnits(units->getFloatValue());
 
         SG_LOG(SG_INPUT, SG_BULK,
-                   "Set PolygonOffset to " << polyoffset->getFactor() << polyoffset->getUnits() );            
+                   "Set PolygonOffset to " << polyoffset->getFactor() << polyoffset->getUnits() );
 
         pass->setAttributeAndModes(polyoffset.get(),
                                    StateAttribute::OVERRIDE|StateAttribute::ON);
@@ -1117,6 +1118,52 @@ struct VertexProgramPointSizeBuilder : public PassAttributeBuilder
 InstallAttributeBuilder<VertexProgramPointSizeBuilder>
 installPointSize("vertex-program-point-size");
 
+struct PointBuilder : public PassAttributeBuilder
+{
+    void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
+                        const SGReaderWriterOptions* options)
+    {
+        float minsize = 1.0;
+        float maxsize = 1.0;
+        float size    = 1.0;
+        osg::Vec3f attenuation = osg::Vec3f(1.0, 1.0, 1.0);
+
+        const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
+        if (!realProp)
+            return;
+
+        const SGPropertyNode* pminsize
+            = getEffectPropertyChild(effect, prop, "min-size");
+        const SGPropertyNode* pmaxsize
+            = getEffectPropertyChild(effect, prop, "max-size");
+        const SGPropertyNode* psize
+            = getEffectPropertyChild(effect, prop, "size");
+        const SGPropertyNode* pattenuation
+            = getEffectPropertyChild(effect, prop, "attenuation");
+
+        if (pminsize)
+            minsize = pminsize->getFloatValue();
+        if (pmaxsize)
+            maxsize = pmaxsize->getFloatValue();
+        if (psize)
+            size = psize->getFloatValue();
+        if (pattenuation)
+            attenuation = osg::Vec3f(pattenuation->getChild("x")->getFloatValue(),
+                                     pattenuation->getChild("y")->getFloatValue(),
+                                     pattenuation->getChild("z")->getFloatValue());
+
+        osg::Point* point = new osg::Point;
+        point->setMinSize(minsize);
+        point->setMaxSize(maxsize);
+        point->setSize(size);
+        point->setDistanceAttenuation(attenuation);
+        pass->setAttributeAndModes(point);
+    }
+};
+
+InstallAttributeBuilder<PointBuilder>
+installPoint("point");
+
 EffectNameValue<Depth::Function> depthFunctionInit[] =
 {
     {"never", Depth::NEVER},
@@ -1359,17 +1406,17 @@ class PropertyExpression : public SGExpression<T>
 {
 public:
     PropertyExpression(SGPropertyNode* pnode) : _pnode(pnode), _listener(NULL) {}
-    
+
     ~PropertyExpression()
     {
         delete _listener;
     }
-    
+
     void eval(T& value, const expression::Binding*) const
     {
         value = _pnode->getValue<T>();
     }
-    
+
     void setListener(SGPropertyChangeListener* l)
     {
         _listener = l;
@@ -1383,15 +1430,15 @@ class EffectPropertyListener : public SGPropertyChangeListener
 {
 public:
     EffectPropertyListener(Technique* tniq) : _tniq(tniq) {}
-    
+
     void valueChanged(SGPropertyNode* node)
     {
         if (_tniq.valid())
             _tniq->refreshValidity();
     }
-    
+
     virtual ~EffectPropertyListener() { }
-    
+
 protected:
     osg::observer_ptr<Technique> _tniq;
 };
index ab5bbe0385864e444c9014e3cccd9409d5356756..0c0dfe48b3635419816d710527ec78f65c0840a7 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "Pass.hxx"
 
+#include <osg/PointSprite>
 #include <osg/TexEnv>
 #include <osg/TexEnvCombine>
 #include <osg/TexGen>
@@ -34,6 +35,9 @@
 #include <osgDB/FileUtils>
 #include <osgDB/ReadFile>
 
+#include <OpenThreads/Mutex>
+#include <OpenThreads/ScopedLock>
+
 #include <boost/lexical_cast.hpp>
 #include <boost/tuple/tuple.hpp>
 #include <boost/tuple/tuple_comparison.hpp>
 
 namespace simgear
 {
+
+using OpenThreads::Mutex;
+using OpenThreads::ScopedLock;
+
 using namespace std;
 using namespace osg;
 
@@ -138,7 +146,15 @@ void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass,
             << "using white for type '" << type << "' on '" << pass->getName() << "', in " << prop->getPath() );
         texture = StateAttributeFactory::instance()->getWhiteTexture();
     }
+
+    const SGPropertyNode* pPoint = getEffectPropertyChild(effect, prop, "point-sprite");
+    if (pPoint && pPoint->getBoolValue()) {
+        ref_ptr<PointSprite> pointSprite = new PointSprite;
+        pass->setTextureAttributeAndModes(unit, pointSprite.get(), osg::StateAttribute::ON);
+    }
+
     pass->setTextureAttributeAndModes(unit, texture);
+
     const SGPropertyNode* envProp = prop->getChild("environment");
     if (envProp) {
         TexEnv* env = buildTexEnv(effect, envProp);
@@ -225,7 +241,7 @@ TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props,
 
     const SGPropertyNode* pMipmapControl
         = getEffectPropertyChild(effect, props, "mipmap-control");
-    MipMapTuple mipmapFunctions( AUTOMATIC, AUTOMATIC, AUTOMATIC, AUTOMATIC ); 
+    MipMapTuple mipmapFunctions( AUTOMATIC, AUTOMATIC, AUTOMATIC, AUTOMATIC );
     if ( pMipmapControl )
         mipmapFunctions = makeMipMapTuple(effect, pMipmapControl, options);
 
@@ -237,9 +253,9 @@ bool setAttrs(const TexTuple& attrs, Texture* tex,
               const SGReaderWriterOptions* options)
 {
     const string& imageName = attrs.get<0>();
-    if (imageName.empty()) 
+    if (imageName.empty())
         return false;
-        
+
     osgDB::ReaderWriter::ReadResult result;
     result = osgDB::readImageFile(imageName, options);
     osg::ref_ptr<osg::Image> image;
@@ -305,7 +321,7 @@ Texture* TexBuilder<T>::build(Effect* effect, Pass* pass, const SGPropertyNode*
     tex = new T;
     if (!setAttrs(attrs, tex, options))
         return NULL;
-    
+
     if (itr == texMap.end())
         texMap.insert(make_pair(attrs, tex));
     else
@@ -385,7 +401,103 @@ namespace
 TextureBuilder::Registrar installNoise("noise", new NoiseBuilder);
 }
 
+class LightSpriteBuilder : public TextureBuilder
+{
+public:
+    Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
+                   const SGReaderWriterOptions* options);
+protected:
+    Mutex lightMutex;
+    void setPointSpriteImage(unsigned char* data, unsigned log2resolution,
+                    unsigned charsPerPixel);
+    osg::Image* getPointSpriteImage(int logResolution);
+};
+
+Texture* LightSpriteBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode* props,
+                             const SGReaderWriterOptions* options)
+{
+    ScopedLock<Mutex> lock(lightMutex);
+
+    // Always called from when the lightMutex is already taken
+    static osg::ref_ptr<osg::Texture2D> texture;
+
+    if (texture.valid())
+      return texture.get();
+
+    texture = new osg::Texture2D;
+    texture->setImage(getPointSpriteImage(6));
+    texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
+    texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP);
+
+    return texture.get();
+}
+
+void
+LightSpriteBuilder::setPointSpriteImage(unsigned char* data, unsigned log2resolution,
+                    unsigned charsPerPixel)
+{
+  int env_tex_res = (1 << log2resolution);
+  for (int i = 0; i < env_tex_res; ++i) {
+    for (int j = 0; j < env_tex_res; ++j) {
+      int xi = 2*i + 1 - env_tex_res;
+      int yi = 2*j + 1 - env_tex_res;
+      if (xi < 0)
+        xi = -xi;
+      if (yi < 0)
+        yi = -yi;
+
+      xi -= 1;
+      yi -= 1;
+
+      if (xi < 0)
+        xi = 0;
+      if (yi < 0)
+        yi = 0;
+
+      float x = 1.5*xi/(float)(env_tex_res);
+      float y = 1.5*yi/(float)(env_tex_res);
+      //       float x = 2*xi/(float)(env_tex_res);
+      //       float y = 2*yi/(float)(env_tex_res);
+      float dist = sqrt(x*x + y*y);
+      float bright = SGMiscf::clip(255*(1-dist), 0, 255);
+      for (unsigned l = 0; l < charsPerPixel; ++l)
+        data[charsPerPixel*(i*env_tex_res + j) + l] = (unsigned char)bright;
+    }
+  }
+}
+
+osg::Image*
+LightSpriteBuilder::getPointSpriteImage(int logResolution)
+{
+  osg::Image* image = new osg::Image;
+
+  osg::Image::MipmapDataType mipmapOffsets;
+  unsigned off = 0;
+  for (int i = logResolution; 0 <= i; --i) {
+    unsigned res = 1 << i;
+    off += res*res;
+    mipmapOffsets.push_back(off);
+  }
+
+  int env_tex_res = (1 << logResolution);
+
+  unsigned char* imageData = new unsigned char[off];
+  image->setImage(env_tex_res, env_tex_res, 1,
+                  GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, imageData,
+                  osg::Image::USE_NEW_DELETE);
+  image->setMipmapLevels(mipmapOffsets);
 
+  for (int k = logResolution; 0 <= k; --k) {
+    setPointSpriteImage(image->getMipmapData(logResolution - k), k, 1);
+  }
+
+  return image;
+}
+
+namespace
+{
+TextureBuilder::Registrar installLightSprite("light-sprite", new LightSpriteBuilder);
+}
 
 // Image names for all sides
 typedef boost::tuple<string, string, string, string, string, string> CubeMapTuple;
@@ -430,7 +542,7 @@ protected:
 
 // I use this until osg::CopyImage is fixed
 // This one assumes images are the same format and sizes are correct
-void copySubImage(const osg::Image* srcImage, int src_s, int src_t, int width, int height, 
+void copySubImage(const osg::Image* srcImage, int src_s, int src_t, int width, int height,
                  osg::Image* destImage, int dest_s, int dest_t)
 {
     for(int row = 0; row<height; ++row)
index 3558cac90a01c489d7db12c5e4594e06a81081f6..cdd851b47486dc0e2d2fa62f6d2dbff11ed6369e 100644 (file)
@@ -194,7 +194,7 @@ SGCloudLayer::SGCloudLayer( const string &tex_path ) :
                                        ->getWhiteTexture(),
                                        osg::StateAttribute::ON);
   rootSet->setDataVariance(osg::Object::DYNAMIC);
-  
+
   // Ensure repeatability of the random seed within 10 minutes,
   // to keep multi-computer systems in sync.
   sg_srandom_time_10();
@@ -319,7 +319,7 @@ SGCloudLayer::getCoverageString( Coverage coverage )
        }
 }
 
-SGCloudLayer::Coverage 
+SGCloudLayer::Coverage
 SGCloudLayer::getCoverageType( const std::string & coverage )
 {
        if( SG_CLOUD_OVERCAST_STRING == coverage ) {
@@ -374,14 +374,14 @@ void
 SGCloudLayer::rebuild()
 {
     // Initialize states and sizes if necessary.
-    if ( !state_initialized ) { 
+    if ( !state_initialized ) {
         state_initialized = true;
 
         SG_LOG(SG_ASTRO, SG_INFO, "initializing cloud layers");
 
-        // This bump mapping code was inspired by the tutorial available at 
+        // This bump mapping code was inspired by the tutorial available at
         // http://www.paulsprojects.net/tutorials/simplebump/simplebump.html
-        // and a NVidia white paper 
+        // and a NVidia white paper
         //  http://developer.nvidia.com/object/bumpmappingwithregistercombiners.html
         // The normal map textures were generated by the normal map Gimp plugin :
         //  http://nifelheim.dyndns.org/~cocidius/normalmap/
@@ -407,7 +407,7 @@ SGCloudLayer::rebuild()
                           -( i + offset - half_size ) );
             tmp.normalize();
             tmp = tmp*0.5 - zero_normal;
-            
+
             *ptr++ = (unsigned char)( tmp[ 0 ] * 255 );
             *ptr++ = (unsigned char)( tmp[ 1 ] * 255 );
             *ptr++ = (unsigned char)( tmp[ 2 ] * 255 );
@@ -424,7 +424,7 @@ SGCloudLayer::rebuild()
                           ( i + offset - half_size ) );
             tmp.normalize();
             tmp = tmp*0.5 - zero_normal;
-            
+
             *ptr++ = (unsigned char)( tmp[ 0 ] * 255 );
             *ptr++ = (unsigned char)( tmp[ 1 ] * 255 );
             *ptr++ = (unsigned char)( tmp[ 2 ] * 255 );
@@ -441,7 +441,7 @@ SGCloudLayer::rebuild()
                           ( j + offset - half_size ) );
             tmp.normalize();
             tmp = tmp*0.5 - zero_normal;
-            
+
             *ptr++ = (unsigned char)( tmp[ 0 ] * 255 );
             *ptr++ = (unsigned char)( tmp[ 1 ] * 255 );
             *ptr++ = (unsigned char)( tmp[ 2 ] * 255 );
@@ -475,7 +475,7 @@ SGCloudLayer::rebuild()
                           -( j + offset - half_size ), half_size );
             tmp.normalize();
             tmp = tmp*0.5 - zero_normal;
-            
+
             *ptr++ = (unsigned char)( tmp[ 0 ] * 255 );
             *ptr++ = (unsigned char)( tmp[ 1 ] * 255 );
             *ptr++ = (unsigned char)( tmp[ 2 ] * 255 );
@@ -504,23 +504,23 @@ SGCloudLayer::rebuild()
         layer_states[SG_CLOUD_OVERCAST] = state;
         state = SGMakeState(texture_path, "overcast_top.png", "overcast_top_n.png");
         layer_states2[SG_CLOUD_OVERCAST] = state;
-        
+
         state = SGMakeState(texture_path, "broken.png", "broken_n.png");
         layer_states[SG_CLOUD_BROKEN] = state;
         layer_states2[SG_CLOUD_BROKEN] = state;
-        
+
         state = SGMakeState(texture_path, "scattered.png", "scattered_n.png");
         layer_states[SG_CLOUD_SCATTERED] = state;
         layer_states2[SG_CLOUD_SCATTERED] = state;
-        
+
         state = SGMakeState(texture_path, "few.png", "few_n.png");
         layer_states[SG_CLOUD_FEW] = state;
         layer_states2[SG_CLOUD_FEW] = state;
-        
+
         state = SGMakeState(texture_path, "cirrus.png", "cirrus_n.png");
         layer_states[SG_CLOUD_CIRRUS] = state;
         layer_states2[SG_CLOUD_CIRRUS] = state;
-        
+
         layer_states[SG_CLOUD_CLEAR] = 0;
         layer_states2[SG_CLOUD_CLEAR] = 0;
 #if 1
@@ -545,8 +545,8 @@ SGCloudLayer::rebuild()
     // build the cloud layer
     const float layer_scale = layer_span / scale;
     const float mpi = SG_PI/4;
-    
-    // caclculate the difference between a flat-earth model and 
+
+    // caclculate the difference between a flat-earth model and
     // a round earth model given the span and altutude ASL of
     // the cloud layer. This is the difference in altitude between
     // the top of the inverted bowl and the edge of the bowl.
@@ -555,38 +555,38 @@ SGCloudLayer::rebuild()
     const float layer_angle = 0.5*layer_span / layer_to_core; // The angle is half the span
     const float border_to_core = layer_to_core * cos(layer_angle);
     const float alt_diff = layer_to_core - border_to_core;
-    
+
     for (int i = 0; i < 4; i++) {
       if ( layer[i] != NULL ) {
         layer_transform->removeChild(layer[i].get()); // automatic delete
       }
-      
+
       vl[i] = new osg::Vec3Array;
       cl[i] = new osg::Vec4Array;
       tl[i] = new osg::Vec2Array;
-      
-      
+
+
       osg::Vec3 vertex(layer_span*(i-2)/2, -layer_span,
                        alt_diff * (sin(i*mpi) - 2));
       osg::Vec2 tc(layer_scale * i/4, 0.0f);
       osg::Vec4 color(cloudColors[0], (i == 0) ? 0.0f : 0.15f);
-      
+
       cl[i]->push_back(color);
       vl[i]->push_back(vertex);
       tl[i]->push_back(tc);
-      
+
       for (int j = 0; j < 4; j++) {
         vertex = osg::Vec3(layer_span*(i-1)/2, layer_span*(j-2)/2,
                            alt_diff * (sin((i+1)*mpi) + sin(j*mpi) - 2));
         tc = osg::Vec2(layer_scale * (i+1)/4, layer_scale * j/4);
         color = osg::Vec4(cloudColors[0],
-                          ( (j == 0) || (i == 3)) ?  
+                          ( (j == 0) || (i == 3)) ?
                           ( (j == 0) && (i == 3)) ? 0.0f : 0.15f : 1.0f );
-        
+
         cl[i]->push_back(color);
         vl[i]->push_back(vertex);
         tl[i]->push_back(tc);
-        
+
         vertex = osg::Vec3(layer_span*(i-2)/2, layer_span*(j-1)/2,
                            alt_diff * (sin(i*mpi) + sin((j+1)*mpi) - 2) );
         tc = osg::Vec2(layer_scale * i/4, layer_scale * (j+1)/4 );
@@ -597,28 +597,27 @@ SGCloudLayer::rebuild()
         vl[i]->push_back(vertex);
         tl[i]->push_back(tc);
       }
-      
-      vertex = osg::Vec3(layer_span*(i-1)/2, layer_span, 
+
+      vertex = osg::Vec3(layer_span*(i-1)/2, layer_span,
                          alt_diff * (sin((i+1)*mpi) - 2));
-      
+
       tc = osg::Vec2(layer_scale * (i+1)/4, layer_scale);
-      
+
       color = osg::Vec4(cloudColors[0], (i == 3) ? 0.0f : 0.15f );
-      
+
       cl[i]->push_back( color );
       vl[i]->push_back( vertex );
       tl[i]->push_back( tc );
-      
+
       osg::Geometry* geometry = new osg::Geometry;
       geometry->setUseDisplayList(false);
       geometry->setVertexArray(vl[i].get());
       geometry->setNormalBinding(osg::Geometry::BIND_OFF);
-      geometry->setColorArray(cl[i].get());
-      geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
-      geometry->setTexCoordArray(0, tl[i].get());
+      geometry->setColorArray(cl[i].get(), osg::Array::BIND_PER_VERTEX);
+      geometry->setTexCoordArray(0, tl[i].get(), osg::Array::BIND_PER_VERTEX);
       geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl[i]->size()));
       layer[i] = new osg::Geode;
-      
+
       std::stringstream sstr;
       sstr << "Cloud Layer (" << i << ")";
       geometry->setName(sstr.str());
@@ -626,7 +625,7 @@ SGCloudLayer::rebuild()
       layer[i]->addDrawable(geometry);
       layer_transform->addChild(layer[i].get());
     }
-    
+
     //OSGFIXME: true
     if ( layer_states[layer_coverage].valid() ) {
       osg::CopyOp copyOp;    // shallow copy
@@ -661,7 +660,7 @@ bool SGCloudLayer::repaint( const SGVec3f& fog_color ) {
 bool SGCloudLayer::reposition( const SGVec3f& p, const SGVec3f& up, double lon, double lat,
                               double alt, double dt )
 {
-  
+
     if (getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR)
     {
         // combine p and asl (meters) to get translation offset
@@ -684,11 +683,11 @@ bool SGCloudLayer::reposition( const SGVec3f& p, const SGVec3f& up, double lon,
         // Point3D zero_elev = current_view.get_cur_zero_elev();
         T.makeTranslate( asl_offset );
 
-        // printf("  Translated to %.2f %.2f %.2f\n", 
+        // printf("  Translated to %.2f %.2f %.2f\n",
         //        zero_elev.x, zero_elev.y, zero_elev.z );
 
         // Rotate to proper orientation
-        // printf("  lon = %.2f  lat = %.2f\n", 
+        // printf("  lon = %.2f  lat = %.2f\n",
         //        lon * SGD_RADIANS_TO_DEGREES,
         //        lat * SGD_RADIANS_TO_DEGREES);
         LON.makeRotate(lon, osg::Vec3(0, 0, 1));
@@ -716,7 +715,7 @@ bool SGCloudLayer::reposition( const SGVec3f& p, const SGVec3f& up, double lon,
         } else {
           layer_root->setAllChildrenOff();
         }
-            
+
 
         // now calculate update texture coordinates
         SGGeod pos = SGGeod::fromRad(lon, lat);
@@ -725,10 +724,10 @@ bool SGCloudLayer::reposition( const SGVec3f& p, const SGVec3f& up, double lon,
         }
 
         double sp_dist = speed*dt;
-        
-        
+
+
         if ( lon != last_pos.getLongitudeRad() || lat != last_pos.getLatitudeRad() || sp_dist != 0 ) {
-            double course = SGGeodesy::courseDeg(last_pos, pos) * SG_DEGREES_TO_RADIANS, 
+            double course = SGGeodesy::courseDeg(last_pos, pos) * SG_DEGREES_TO_RADIANS,
                 dist = SGGeodesy::distanceM(last_pos, pos);
 
             // if start and dest are too close together,
@@ -804,7 +803,7 @@ bool SGCloudLayer::reposition( const SGVec3f& p, const SGVec3f& up, double lon,
 }
 
 void SGCloudLayer::set_enable3dClouds(bool enable) {
-     
+
     if (layer3D->isDefined3D() && enable) {
         cloud_root->setChildValue(layer3D->getNode(), true);
         cloud_root->setChildValue(layer_root.get(),   false);
index 50dbe33bfc2b18fb7545976ffa3baff78f76a5a0..01e8beeb03c22bbeed82d0db4fbcf67bde828bbb 100644 (file)
@@ -216,8 +216,7 @@ SGSkyDome::build( double hscale, double vscale, simgear::SGReaderWriterOptions *
     geom->setName("Dome Elements");
     geom->setUseDisplayList(false);
     geom->setVertexArray(dome_vl.get());
-    geom->setColorArray(dome_cl.get());
-    geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
+    geom->setColorArray(dome_cl.get(), osg::Array::BIND_PER_VERTEX);
     geom->setNormalBinding(osg::Geometry::BIND_OFF);
     geom->addPrimitiveSet(domeElements);
     geode->addDrawable(geom);
@@ -272,7 +271,7 @@ SGSkyDome::repaint( const SGVec3f& sun_color, const SGVec3f& sky_color,
        outer_diff = SGVec3f(0, 0, 0);
        middle_diff = SGVec3f(0, 0, 0);
     }
-    // printf("  outer_red_param = %.2f  outer_red_diff = %.2f\n", 
+    // printf("  outer_red_param = %.2f  outer_red_diff = %.2f\n",
     //        outer_red_param, outer_red_diff);
 
     // calculate transition colors between sky and fog
@@ -381,7 +380,7 @@ SGSkyDome::reposition( const SGVec3f& p, double _asl,
     // xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
     T.makeTranslate( toOsg(p) );
 
-    // printf("  Translated to %.2f %.2f %.2f\n", 
+    // printf("  Translated to %.2f %.2f %.2f\n",
     //        zero_elev.x, zero_elev.y, zero_elev.z );
 
     // Rotate to proper orientation
index f959200c60b3dd0079010600bcd7f3713f2e3c76..a267034fec4adaa716055087b17d0053ad6cc923 100644 (file)
@@ -1,9 +1,9 @@
 // oursun.hxx -- model earth's sun
 //
-// Written by Durk Talsma. Originally started October 1997, for distribution  
-// with the FlightGear project. Version 2 was written in August and 
-// September 1998. This code is based upon algorithms and data kindly 
-// provided by Mr. Paul Schlyter. (pausch@saaf.se). 
+// Written by Durk Talsma. Originally started October 1997, for distribution
+// with the FlightGear project. Version 2 was written in August and
+// September 1998. This code is based upon algorithms and data kindly
+// provided by Mr. Paul Schlyter. (pausch@saaf.se).
 //
 // Separated out rendering pieces and converted to ssg by Curt Olson,
 // March 2000
@@ -79,7 +79,7 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node )
     osg::TexEnv* texEnv = new osg::TexEnv;
     texEnv->setMode(osg::TexEnv::MODULATE);
     stateSet->setTextureAttribute(0, texEnv, osg::StateAttribute::ON);
+
     osg::Material* material = new osg::Material;
     material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
     material->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,1));
@@ -135,10 +135,9 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node )
     osg::Geometry* geometry = new osg::Geometry;
     geometry->setUseDisplayList(false);
     geometry->setVertexArray(sun_vl);
-    geometry->setColorArray(sun_cl.get());
-    geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
+    geometry->setColorArray(sun_cl.get(), osg::Array::BIND_OVERALL);
     geometry->setNormalBinding(osg::Geometry::BIND_OFF);
-    geometry->setTexCoordArray(0, sun_tl);
+    geometry->setTexCoordArray(0, sun_tl, osg::Array::BIND_PER_VERTEX);
     geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, 4));
     geode->addDrawable(geometry);
 
@@ -148,7 +147,7 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node )
     geode = new osg::Geode;
     stateSet = geode->getOrCreateStateSet();
     stateSet->setRenderBinDetails(-7, "RenderBin");
-    
+
     texture = SGLoadTexture2D("inner_halo.png", options.get());
     stateSet->setTextureAttributeAndModes(0, texture);
 
@@ -172,17 +171,16 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node )
     geometry = new osg::Geometry;
     geometry->setUseDisplayList(false);
     geometry->setVertexArray(ihalo_vl);
-    geometry->setColorArray(ihalo_cl.get());
-    geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
+    geometry->setColorArray(ihalo_cl.get(), osg::Array::BIND_OVERALL);
     geometry->setNormalBinding(osg::Geometry::BIND_OFF);
-    geometry->setTexCoordArray(0, ihalo_tl);
+    geometry->setTexCoordArray(0, ihalo_tl, osg::Array::BIND_PER_VERTEX);
     geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, 4));
     geode->addDrawable(geometry);
 
     sun_transform->addChild( geode );
-    
+
     // set up the outer halo state
-    
+
     geode = new osg::Geode;
     stateSet = geode->getOrCreateStateSet();
     stateSet->setRenderBinDetails(-8, "RenderBin");
@@ -210,10 +208,9 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node )
     geometry = new osg::Geometry;
     geometry->setUseDisplayList(false);
     geometry->setVertexArray(ohalo_vl);
-    geometry->setColorArray(ohalo_cl.get());
-    geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
+    geometry->setColorArray(ohalo_cl.get(), osg::Array::BIND_OVERALL);
     geometry->setNormalBinding(osg::Geometry::BIND_OFF);
-    geometry->setTexCoordArray(0, ohalo_tl);
+    geometry->setTexCoordArray(0, ohalo_tl, osg::Array::BIND_PER_VERTEX);
     geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, 4));
     geode->addDrawable(geometry);
 
@@ -260,14 +257,14 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
             density_avg = 0.7;
         }
         else {
-            rel_humidity = env_node->getFloatValue( "relative-humidity" ); 
+            rel_humidity = env_node->getFloatValue( "relative-humidity" );
             density_avg =  env_node->getFloatValue( "atmosphere/density-tropo-avg" );
         }
 
         // ok, now let's go and generate the sun and scene color
         osg::Vec4 i_halo_color, o_halo_color, scene_color, sun_color;
 
-        // Some comments: 
+        // Some comments:
         // * When the sunangle changes, light has to travel a longer
         //   distance through the atmosphere. So it's scattered more due
         //   to raleigh scattering, which affects blue more than green
@@ -277,12 +274,12 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
         // * Visability also affects suncolor inasmuch as more particles
         //   are in the air that cause more scattering.
         // * We base our calculation on the halo's color, which is most
-        //   scattered. 
+        //   scattered.
         double red_scat_f, red_scat_corr_f, green_scat_f, blue_scat_f;
-        // Red - is almost not scattered     
+
+        // Red - is almost not scattered
         // Lambda is 700 nm
-        
+
         red_scat_f = (aerosol_factor * path_distance * density_avg)/5E+07;
         red_scat_corr_f = sun_exp2_punch_through / (1 - red_scat_f);
         sun_color[0] = 1;
@@ -292,7 +289,7 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
         green_scat_f = (aerosol_factor * path_distance * density_avg)/8.8938E+06;
         sun_color[1] = 1 - green_scat_f * red_scat_corr_f;
         scene_color[1] = 1 - green_scat_f;
+
         // Blue - 435.8 nm
         blue_scat_f = (aerosol_factor * path_distance * density_avg)/3.607E+06;
         sun_color[2] = 1 - blue_scat_f * red_scat_corr_f;
@@ -302,7 +299,7 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
         sun_color[3] = 1;
         scene_color[3] = 1;
 
-        // Now that we have the color calculated 
+        // Now that we have the color calculated
         // let's consider the saturation which is produced by mie scattering
         double saturation = 1 - ( rel_humidity / 200 );
         scene_color[1] += (( 1 - saturation ) * ( 1 - scene_color[1] ));
@@ -341,7 +338,7 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
 
         gamma_correct_rgb( i_halo_color._v );
         gamma_correct_rgb( o_halo_color._v );
-        gamma_correct_rgb( scene_color._v );    
+        gamma_correct_rgb( scene_color._v );
         gamma_correct_rgb( sun_color._v );
 
         (*sun_cl)[0] = sun_color;
@@ -363,10 +360,10 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
 // fixed at a great distance from the viewer.  Also add in an optional
 // rotation (i.e. for the current time of day.)
 // Then calculate stuff needed for the sun-coloring
-bool SGSun::reposition( double rightAscension, double declination, 
+bool SGSun::reposition( double rightAscension, double declination,
                         double sun_dist, double lat, double alt_asl, double sun_angle)
 {
-    // GST - GMT sidereal time 
+    // GST - GMT sidereal time
     osg::Matrix T2, RA, DEC;
 
     // xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0),
@@ -391,7 +388,7 @@ bool SGSun::reposition( double rightAscension, double declination,
 
          double r_tropo = r_tropo_pole / sqrt ( 1 - ( epsilon_tropo2 * pow ( cos( lat ), 2 )));
          double r_earth = r_earth_pole / sqrt ( 1 - ( epsilon_earth2 * pow ( cos( lat ), 2 )));
+
          double position_radius = r_earth + alt_asl;
 
          double gamma =  SG_PI - sun_angle;
index 042c56f67a34db6b0437e6ed1d7efc8ce2881d27..30fc34a9438416a71e415ad6d8cb02263983e81f 100644 (file)
@@ -635,12 +635,8 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
       // Set the vertex, texture and normals.  Colors will be set per-instance
       // later.
       sharedGeometry->setVertexArray(v);
-      sharedGeometry->setTexCoordArray(0, t);
-      sharedGeometry->setNormalArray(n);
-
-      // Work around a bug in OSG 3.2.0 where BIND_PER_VERTEX appears
-      // not to take effect if the normal array is set subsequently.
-      sharedGeometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
+      sharedGeometry->setTexCoordArray(0, t, Array::BIND_PER_VERTEX);
+      sharedGeometry->setNormalArray(n, Array::BIND_PER_VERTEX);
     }
   }
 
index 23d47fcb3d6553e3fa38eb289088001819005805..890dff988eaa1a12b06e2d5bc343df906820147a 100644 (file)
@@ -233,8 +233,7 @@ public:
       Geometry* createNewBuildingGeometryInstance(const BuildingInstance& building) const
       {
         Geometry* geom = simgear::clone(building.sharedGeometry.get(), CopyOp::SHALLOW_COPY);
-        geom->setColorArray(new Vec4Array);
-        geom->setColorBinding(Geometry::BIND_PER_VERTEX);
+        geom->setColorArray(new Vec4Array, Array::BIND_PER_VERTEX);
         geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS));
         return geom;
       }
index accac4110e1a72e62506f7dab87f4570399cfead..9b8aa3bcb9f613a0f7e2b546916b65d1e095bb53 100644 (file)
@@ -143,7 +143,7 @@ Geometry* makeSharedTreeGeometry(int numQuads)
     }
     Geometry* result = new Geometry;
     result->setVertexArray(v);
-    result->setTexCoordArray(0, t);
+    result->setTexCoordArray(0, t, Array::BIND_PER_VERTEX);
     result->setComputeBoundingBoxCallback(new TreesBoundingBoxCallback);
     result->setUseDisplayList(false);
     return result;
@@ -232,11 +232,11 @@ struct MakeTreesLeaf
     LOD* operator() () const
     {
         LOD* result = new LOD;
-        
+
         // Create a series of LOD nodes so trees cover decreases slightly
         // gradually with distance from _range to 2*_range
         for (float i = 0.0; i < SG_TREE_FADE_OUT_LEVELS; i++)
-        {        
+        {
             EffectGeode* geode = createTreeGeode(_width, _height, _varieties);
             geode->setEffect(_effect.get());
             result->addChild(geode, 0, _range * (1.0 + i / (SG_TREE_FADE_OUT_LEVELS - 1.0)));
@@ -335,7 +335,7 @@ osg::Group* createForest(SGTreeBinList& forestList, const osg::Matrix& transform
 
     for (i = forestList.begin(); i != forestList.end(); ++i) {
         TreeBin* forest = *i;
-      
+
         ref_ptr<Effect> effect;
         EffectMap::iterator iter = treeEffectMap.find(forest->texture);
 
@@ -374,10 +374,10 @@ osg::Group* createForest(SGTreeBinList& forestList, const osg::Matrix& transform
 
         for (size_t i = 0; i < group->getNumChildren(); ++i)
             mt->addChild(group->getChild(i));
-            
+
         delete forest;
     }
-    
+
     forestList.clear();
     QuadTreeCleaner cleaner;
     mt->accept(cleaner);
index edb35f268de78e3a410180afdd85c56e4879cd58..4a9d8b5957d1f0e36682620090bc109fa93e5baf 100644 (file)
@@ -950,7 +950,7 @@ public:
       if (!_tileGeometryBin->vasiLights.empty()) {
         EffectGeode* vasiGeode = new EffectGeode;
         Effect* vasiEffect
-            = getLightEffect(24, osg::Vec3(1, 0.0001, 0.000001), 1, 24, true);
+            = getLightEffect(24, osg::Vec3(1, 0.0001, 0.000001), 1, 24, true, _options);
         vasiGeode->setEffect(vasiEffect);
         SGVec4f red(1, 0, 0, 1);
         SGMaterial* mat = 0;
@@ -979,7 +979,7 @@ public:
           || !_tileGeometryBin->reilLights.empty()
           || !_tileGeometryBin->odalLights.empty()
           || _tileGeometryBin->taxiLights.getNumLights() > 0)
-          runwayEffect = getLightEffect(16, osg::Vec3(1, 0.001, 0.0002), 1, 16, true);
+          runwayEffect = getLightEffect(16, osg::Vec3(1, 0.001, 0.0002), 1, 16, true, _options);
       if (_tileGeometryBin->runwayLights.getNumLights() > 0
           || !_tileGeometryBin->rabitLights.empty()
           || !_tileGeometryBin->reilLights.empty()
@@ -998,24 +998,24 @@ public:
         SGDirectionalLightListBin::const_iterator i;
         for (i = _tileGeometryBin->rabitLights.begin();
              i != _tileGeometryBin->rabitLights.end(); ++i) {
-          rwyLights->addChild(SGLightFactory::getSequenced(*i));
+          rwyLights->addChild(SGLightFactory::getSequenced(*i, _options));
         }
         for (i = _tileGeometryBin->reilLights.begin();
              i != _tileGeometryBin->reilLights.end(); ++i) {
-          rwyLights->addChild(SGLightFactory::getSequenced(*i));
+          rwyLights->addChild(SGLightFactory::getSequenced(*i, _options));
         }
         for (i = _tileGeometryBin->holdshortLights.begin();
              i != _tileGeometryBin->holdshortLights.end(); ++i) {
-          rwyLights->addChild(SGLightFactory::getHoldShort(*i));
+          rwyLights->addChild(SGLightFactory::getHoldShort(*i, _options));
         }
         for (i = _tileGeometryBin->guardLights.begin();
              i != _tileGeometryBin->guardLights.end(); ++i) {
-          rwyLights->addChild(SGLightFactory::getGuard(*i));
+          rwyLights->addChild(SGLightFactory::getGuard(*i, _options));
         }
         SGLightListBin::const_iterator j;
         for (j = _tileGeometryBin->odalLights.begin();
              j != _tileGeometryBin->odalLights.end(); ++j) {
-          rwyLights->addChild(SGLightFactory::getOdal(*j));
+          rwyLights->addChild(SGLightFactory::getOdal(*j, _options));
         }
         lightGroup->addChild(rwyLights);
       }
index eb8dd048f5bb904d1396e36b3d5294bf69ca4cd5..d6374b6fa98cbaa5d51bd6dd6049d77158f40806 100644 (file)
 #include <osg/BlendFunc>
 #include <osg/TexEnv>
 #include <osg/Sequence>
-#include <osg/PolygonMode>
 #include <osg/Fog>
 #include <osg/FragmentProgram>
 #include <osg/VertexProgram>
 #include <osg/Point>
-#include <osg/PointSprite>
 #include <osg/Material>
 #include <osg/Group>
 #include <osg/StateSet>
@@ -76,166 +74,44 @@ using OpenThreads::ScopedLock;
 using namespace osg;
 using namespace simgear;
 
-static void
-setPointSpriteImage(unsigned char* data, unsigned log2resolution,
-                    unsigned charsPerPixel)
-{
-  int env_tex_res = (1 << log2resolution);
-  for (int i = 0; i < env_tex_res; ++i) {
-    for (int j = 0; j < env_tex_res; ++j) {
-      int xi = 2*i + 1 - env_tex_res;
-      int yi = 2*j + 1 - env_tex_res;
-      if (xi < 0)
-        xi = -xi;
-      if (yi < 0)
-        yi = -yi;
-      
-      xi -= 1;
-      yi -= 1;
-      
-      if (xi < 0)
-        xi = 0;
-      if (yi < 0)
-        yi = 0;
-      
-      float x = 1.5*xi/(float)(env_tex_res);
-      float y = 1.5*yi/(float)(env_tex_res);
-      //       float x = 2*xi/(float)(env_tex_res);
-      //       float y = 2*yi/(float)(env_tex_res);
-      float dist = sqrt(x*x + y*y);
-      float bright = SGMiscf::clip(255*(1-dist), 0, 255);
-      for (unsigned l = 0; l < charsPerPixel; ++l)
-        data[charsPerPixel*(i*env_tex_res + j) + l] = (unsigned char)bright;
-    }
-  }
-}
-
-static osg::Image*
-getPointSpriteImage(int logResolution)
-{
-  osg::Image* image = new osg::Image;
-  
-  osg::Image::MipmapDataType mipmapOffsets;
-  unsigned off = 0;
-  for (int i = logResolution; 0 <= i; --i) {
-    unsigned res = 1 << i;
-    off += res*res;
-    mipmapOffsets.push_back(off);
-  }
-  
-  int env_tex_res = (1 << logResolution);
-  
-  unsigned char* imageData = new unsigned char[off];
-  image->setImage(env_tex_res, env_tex_res, 1,
-                  GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, imageData,
-                  osg::Image::USE_NEW_DELETE);
-  image->setMipmapLevels(mipmapOffsets);
-  
-  for (int k = logResolution; 0 <= k; --k) {
-    setPointSpriteImage(image->getMipmapData(logResolution - k), k, 1);
-  }
-  
-  return image;
-}
-
 static Mutex lightMutex;
 
-static osg::Texture2D*
-gen_standard_light_sprite(void)
-{
-  // Always called from when the lightMutex is already taken
-  static osg::ref_ptr<osg::Texture2D> texture;
-  if (texture.valid())
-    return texture.get();
-  
-  texture = new osg::Texture2D;
-  texture->setImage(getPointSpriteImage(6));
-  texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
-  texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP);
-  
-  return texture.get();
-}
-
 namespace
 {
 typedef boost::tuple<float, osg::Vec3, float, float, bool> PointParams;
 typedef std::map<PointParams, observer_ptr<Effect> > EffectMap;
 
 EffectMap effectMap;
-
-ref_ptr<PolygonMode> polyMode = new PolygonMode(PolygonMode::FRONT,
-                                                PolygonMode::POINT);
-ref_ptr<PointSprite> pointSprite = new PointSprite;
 }
 
 Effect* getLightEffect(float size, const Vec3& attenuation,
-                       float minSize, float maxSize, bool directional)
+                       float minSize, float maxSize, bool directional,
+                       const SGReaderWriterOptions* options)
 {
     PointParams pointParams(size, attenuation, minSize, maxSize, directional);
     ScopedLock<Mutex> lock(lightMutex);
+    ref_ptr<Effect> effect;
     EffectMap::iterator eitr = effectMap.find(pointParams);
     if (eitr != effectMap.end())
     {
-        ref_ptr<Effect> 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");
-    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);
-    ref_ptr<Effect> effect = new Effect;
-    std::vector<std::string> parameterExtensions;
-
-    if (SGSceneFeatures::instance()->getEnablePointSpriteLights())
-    {
-        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);
-        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);
+    SGPropertyNode_ptr effectProp = new SGPropertyNode;
+    makeChild(effectProp, "inherits-from")->setStringValue("Effects/surface-lights");
+
+    SGPropertyNode* params = makeChild(effectProp, "parameters");
+    params->getNode("size",true)->setValue(size);
+    params->getNode("attenuation",true)->getNode("x", true)->setValue(attenuation.x());
+    params->getNode("attenuation",true)->getNode("y", true)->setValue(attenuation.y());
+    params->getNode("attenuation",true)->getNode("z", true)->setValue(attenuation.z());
+    params->getNode("min-size",true)->setValue(minSize);
+    params->getNode("max-size",true)->setValue(maxSize);
+    params->getNode("cull-face",true)->setValue(directional ? "back" : "off");
+
+    effect = makeEffect(effectProp, true, options);
+
     if (eitr == effectMap.end())
         effectMap.insert(std::make_pair(pointParams, effect));
     else
@@ -252,7 +128,7 @@ SGLightFactory::getLightDrawable(const SGLightBin::Light& light)
 
   vertices->push_back(toOsg(light.position));
   colors->push_back(toOsg(light.color));
-  
+
   osg::Geometry* geometry = new osg::Geometry;
   geometry->setDataVariance(osg::Object::STATIC);
   geometry->setVertexArray(vertices);
@@ -263,7 +139,7 @@ SGLightFactory::getLightDrawable(const SGLightBin::Light& light)
   // Enlarge the bounding box to avoid such light nodes being victim to
   // small feature culling.
   geometry->setComputeBoundingBoxCallback(new SGEnlargeBoundingBox(1));
-  
+
   osg::DrawArrays* drawArrays;
   drawArrays = new osg::DrawArrays(osg::PrimitiveSet::POINTS,
                                    0, vertices->size());
@@ -290,7 +166,7 @@ SGLightFactory::getLightDrawable(const SGDirectionalLightBin::Light& light)
   colors->push_back(toOsg(visibleColor));
   colors->push_back(toOsg(invisibleColor));
   colors->push_back(toOsg(invisibleColor));
-  
+
   osg::Geometry* geometry = new osg::Geometry;
   geometry->setDataVariance(osg::Object::STATIC);
   geometry->setVertexArray(vertices);
@@ -300,7 +176,7 @@ SGLightFactory::getLightDrawable(const SGDirectionalLightBin::Light& light)
   // Enlarge the bounding box to avoid such light nodes being victim to
   // small feature culling.
   geometry->setComputeBoundingBoxCallback(new SGEnlargeBoundingBox(1));
-  
+
   osg::DrawArrays* drawArrays;
   drawArrays = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,
                                    0, vertices->size());
@@ -317,7 +193,7 @@ SGLightFactory::getLights(const SGLightBin& lights, unsigned inc, float alphaOff
 {
   if (lights.getNumLights() <= 0)
     return 0;
-  
+
   osg::Vec3Array* vertices = new osg::Vec3Array;
   osg::Vec4Array* colors = new osg::Vec4Array;
 
@@ -327,14 +203,14 @@ SGLightFactory::getLights(const SGLightBin& lights, unsigned inc, float alphaOff
     color[3] = SGMiscf::max(0, SGMiscf::min(1, color[3] + alphaOff));
     colors->push_back(toOsg(color));
   }
-  
+
   osg::Geometry* geometry = new osg::Geometry;
   geometry->setDataVariance(osg::Object::STATIC);
   geometry->setVertexArray(vertices);
   geometry->setNormalBinding(osg::Geometry::BIND_OFF);
   geometry->setColorArray(colors);
   geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
-  
+
   osg::DrawArrays* drawArrays;
   drawArrays = new osg::DrawArrays(osg::PrimitiveSet::POINTS,
                                    0, vertices->size());
@@ -361,7 +237,7 @@ SGLightFactory::getLights(const SGDirectionalLightBin& lights)
 {
   if (lights.getNumLights() <= 0)
     return 0;
-  
+
   osg::Vec3Array* vertices = new osg::Vec3Array;
   osg::Vec4Array* colors = new osg::Vec4Array;
 
@@ -380,14 +256,14 @@ SGLightFactory::getLights(const SGDirectionalLightBin& lights)
     colors->push_back(toOsg(invisibleColor));
     colors->push_back(toOsg(invisibleColor));
   }
-  
+
   osg::Geometry* geometry = new osg::Geometry;
   geometry->setDataVariance(osg::Object::STATIC);
   geometry->setVertexArray(vertices);
   geometry->setNormalBinding(osg::Geometry::BIND_OFF);
   geometry->setColorArray(colors);
   geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
-  
+
   osg::DrawArrays* drawArrays;
   drawArrays = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,
                                    0, vertices->size());
@@ -433,7 +309,7 @@ buildVasi(const SGDirectionalLightBin& lights, const SGVec3f& up,
 
   } else if (count == 12) {
     SGVasiDrawable* drawable = new SGVasiDrawable(red, white);
-    
+
     // probably vasi, first 6 are downwind bar (2.5 deg)
     for (unsigned i = 0; i < 6; ++i)
       drawable->addLight(lights.getLight(i).position,
@@ -467,7 +343,7 @@ SGLightFactory::getVasi(const SGVec3f& up, const SGDirectionalLightBin& lights,
   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);
@@ -477,7 +353,7 @@ SGLightFactory::getVasi(const SGVec3f& up, const SGDirectionalLightBin& lights,
 }
 
 osg::Node*
-SGLightFactory::getSequenced(const SGDirectionalLightBin& lights)
+SGLightFactory::getSequenced(const SGDirectionalLightBin& lights, const SGReaderWriterOptions* options)
 {
   if (lights.getNumLights() <= 0)
     return 0;
@@ -488,7 +364,7 @@ SGLightFactory::getSequenced(const SGDirectionalLightBin& lights)
   osg::Sequence* sequence = new osg::Sequence;
   sequence->setDefaultTime(flashTime);
   Effect* effect = getLightEffect(10.0f, osg::Vec3(1.0, 0.0001, 0.00000001),
-                                  6.0f, 10.0f, true);
+                                  6.0f, 10.0f, true, options);
   for (int i = lights.getNumLights() - 1; 0 <= i; --i) {
     EffectGeode* egeode = new EffectGeode;
     egeode->setEffect(effect);
@@ -504,7 +380,7 @@ SGLightFactory::getSequenced(const SGDirectionalLightBin& lights)
 }
 
 osg::Node*
-SGLightFactory::getOdal(const SGLightBin& lights)
+SGLightFactory::getOdal(const SGLightBin& lights, const SGReaderWriterOptions* options)
 {
   if (lights.getNumLights() < 2)
     return 0;
@@ -515,7 +391,7 @@ SGLightFactory::getOdal(const SGLightBin& lights)
   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);
+                                  6.0, 10.0, false, options);
   // centerline lights
   for (int i = lights.getNumLights(); i > 1; --i) {
     EffectGeode* egeode = new EffectGeode;
@@ -545,7 +421,7 @@ SGLightFactory::getOdal(const SGLightBin& lights)
 
 // Blinking hold short line lights
 osg::Node*
-SGLightFactory::getHoldShort(const SGDirectionalLightBin& lights)
+SGLightFactory::getHoldShort(const SGDirectionalLightBin& lights, const SGReaderWriterOptions* options)
 {
   if (lights.getNumLights() < 2)
     return 0;
@@ -559,7 +435,7 @@ SGLightFactory::getHoldShort(const SGDirectionalLightBin& lights)
   // ...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.0f, i, true);
+                                      0.0f, i, true, options);
       EffectGeode* egeode = new EffectGeode;
       for (unsigned int j = 0; j < lights.getNumLights(); ++j) {
           egeode->addDrawable(getLightDrawable(lights.getLight(j)));
@@ -577,7 +453,7 @@ SGLightFactory::getHoldShort(const SGDirectionalLightBin& lights)
 
 // Alternating runway guard lights ("wig-wag")
 osg::Node*
-SGLightFactory::getGuard(const SGDirectionalLightBin& lights)
+SGLightFactory::getGuard(const SGDirectionalLightBin& lights, const SGReaderWriterOptions* options)
 {
   if (lights.getNumLights() < 2)
     return 0;
@@ -588,7 +464,7 @@ SGLightFactory::getGuard(const SGDirectionalLightBin& lights)
   osg::Sequence* sequence = new osg::Sequence;
   sequence->setDefaultTime(flashTime);
   Effect* effect = getLightEffect(10.0f, osg::Vec3(1.0, 0.001, 0.000002),
-                                  0.0f, 8.0f, true);
+                                  0.0f, 8.0f, true, options);
   for (unsigned int i = 0; i < lights.getNumLights(); ++i) {
     EffectGeode* egeode = new EffectGeode;
     egeode->setEffect(effect);
index bbe28ad747dcf3d00072ced69dd6e52b8bb16f58..863328dc60bffafcd90500e4aca615bcc8e854e7 100644 (file)
@@ -40,6 +40,7 @@
 
 #include <simgear/math/sg_types.hxx>
 #include <simgear/scene/material/matlib.hxx>
+#include <simgear/scene/util/SGReaderWriterOptions.hxx>
 #include <simgear/scene/util/SGSceneFeatures.hxx>
 
 #include "SGLightBin.hxx"
@@ -85,18 +86,19 @@ public:
           const SGVec4f& red, const SGVec4f& white);
 
   static osg::Node*
-  getSequenced(const SGDirectionalLightBin& lights);
+  getSequenced(const SGDirectionalLightBin& lights, const simgear::SGReaderWriterOptions* options);
 
   static osg::Node*
-  getOdal(const SGLightBin& lights);
+  getOdal(const SGLightBin& lights, const simgear::SGReaderWriterOptions* options);
 
   static osg::Node*
-  getHoldShort(const SGDirectionalLightBin& lights);
+  getHoldShort(const SGDirectionalLightBin& lights, const simgear::SGReaderWriterOptions* options);
 
   static osg::Node*
-  getGuard(const SGDirectionalLightBin& lights);
+  getGuard(const SGDirectionalLightBin& lights, const simgear::SGReaderWriterOptions* options);
 };
 
 simgear::Effect* getLightEffect(float size, const osg::Vec3& attenuation,
-                                float minSize, float maxSize, bool directional);
+                                float minSize, float maxSize, bool directional,
+                                const simgear::SGReaderWriterOptions* options);
 #endif // _SG_PT_LIGHTS_HXX