]> git.mxchange.org Git - simgear.git/commitdiff
Use a singleton Fog attribute for all 3D clouds.
authortimoore <timoore>
Wed, 10 Dec 2008 22:39:48 +0000 (22:39 +0000)
committertimoore <timoore>
Wed, 10 Dec 2008 22:39:48 +0000 (22:39 +0000)
Don't update this Fog with any kind of update callback; instead, update from
the sky repaint method.

simgear/scene/sky/cloudfield.cxx
simgear/scene/sky/cloudfield.hxx
simgear/scene/sky/newcloud.cxx
simgear/scene/sky/sky.cxx

index 337831cc8e6c4db2e1280932a01da973aa444a91..bb2bb5270d3ce05e3e78536c815a521e190f0e71 100644 (file)
 #  include <simgear_config.h>
 #endif
 
+#include <osg/Fog>
 #include <osg/Texture2D>
 #include <osg/PositionAttitudeTransform>
+#include <osg/Vec4f>
 
 #include <simgear/compiler.h>
 
@@ -137,29 +139,6 @@ bool SGCloudField::reposition( const SGVec3f& p, const SGVec3f& up, double lon,
     return true;
 }
 
-struct threeDCloudsFogUpdater : public osg::NodeCallback {
-    threeDCloudsFogUpdater() {};
-
-    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
-        SGUpdateVisitor* updateVisitor = static_cast<SGUpdateVisitor*>(nv);
-        //running at 5 times frame
-        SGCloudField::StateSetMap::iterator iter;
-        osg::Fog * fog;
-        for( iter = SGCloudField::cloudTextureMap.begin(); iter != SGCloudField::cloudTextureMap.end(); ++iter) {
-            fog = static_cast<osg::Fog*>(iter->second->getAttribute( osg::StateAttribute::FOG, 0 ));
-            fog->setMode(osg::Fog::EXP);
-            osg::Vec4f fogC = updateVisitor->getFogColor().osg();
-            fogC[3] = 0.0;
-            fog->setColor(fogC);
-            fog->setDensity(updateVisitor->getFogExpDensity());
-        }
-
-        if (node->getNumChildrenRequiringUpdateTraversal()>0)
-          traverse(node,nv);
-    }
-};
-
-
 SGCloudField::SGCloudField() :
         field_root(new osg::Group),
         field_transform(new osg::MatrixTransform),
@@ -171,11 +150,11 @@ SGCloudField::SGCloudField() :
         reposition_count(0)
 {
     cld_pos = SGGeoc();
-    field_root->setUpdateCallback( new threeDCloudsFogUpdater() );
     field_root->addChild(field_transform.get());
     field_root->setName("3D Cloud field root");
     osg::StateSet *rootSet = field_root->getOrCreateStateSet();
     rootSet->setRenderBinDetails(CLOUDS_BIN, "DepthSortedBin");
+    rootSet->setAttributeAndModes(getFog());
     
     osg::ref_ptr<osg::Group> quad_root = new osg::Group();
     
@@ -309,3 +288,17 @@ void SGCloudField::applyVisRange(void) {
     }
 }
 
+SGCloudField::CloudFog::CloudFog()
+{
+    fog = new osg::Fog;
+    fog->setMode(osg::Fog::EXP2);
+    fog->setDataVariance(osg::Object::DYNAMIC);
+}
+
+void SGCloudField::updateFog(double visibility, const osg::Vec4f& color)
+{
+    const double sqrt_m_log01 = sqrt(-log(0.01));
+    osg::Fog* fog = CloudFog::instance()->fog.get();
+    fog->setColor(color);
+    fog->setDensity(sqrt_m_log01 / visibility);
+}
index d39c1512254ba9b0aa5fdbad11a44c3449b616f7..75a94091e6250f38f6229bd5b48cef0cba24a87d 100644 (file)
@@ -26,7 +26,7 @@
 #include <plib/sg.h>
 #include <simgear/compiler.h>
 #include <vector>
-#include <osgSim/Impostor>
+
 #include <osgDB/ReaderWriter>
 
 #include <osg/ref_ptr>
 #include <osg/Geometry>
 #include <osg/Group>
 #include <osg/Switch>
-#include <osg/Billboard>
+
+namespace osg
+{
+        class Fog;
+        class StateSet;
+        class Vec4f;
+}
 
 #include <simgear/misc/sg_path.hxx>
+#include <simgear/structure/Singleton.hxx>
 
 using std::vector;
 
@@ -78,6 +85,11 @@ private:
        float   last_coverage;
         SGGeoc cld_pos;
         int reposition_count;
+        struct CloudFog : public simgear::Singleton<CloudFog>
+        {
+                CloudFog();
+                osg::ref_ptr<osg::Fog> fog;
+        };
 public:
 
        SGCloudField();
@@ -126,6 +138,12 @@ public:
         
         typedef std::map<std::string, osg::ref_ptr<osg::StateSet> > StateSetMap;
         static StateSetMap cloudTextureMap;
+
+        static osg::Fog* getFog()
+        {
+                return CloudFog::instance()->fog.get();
+        }
+        static void updateFog(double visibility, const osg::Vec4f& color);
 };
 
 #endif // _CLOUDFIELD_HXX
index 3624a53cf7cd708310ac6c203ffa9c58b5bda7ae..61dcb8b6fc73653fa279007ef729dba6c940c38c 100644 (file)
@@ -129,21 +129,10 @@ static char fragmentShaderSource[] =
     "{\n"
     "  vec4 base = texture2D( baseTexture, gl_TexCoord[0].st);\n"
     "  vec4 finalColor = base * gl_Color;\n"
-    "  gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor );\n"
+    "  gl_FragColor.rgb = mix(gl_Fog.color.rgb, finalColor.rgb, fogFactor );\n"
+    "  gl_FragColor.a = finalColor.a;\n"
     "}\n";
 
-class SGCloudFogUpdateCallback : public osg::StateAttribute::Callback {
-    public:
-        virtual void operator () (osg::StateAttribute* sa, osg::NodeVisitor* nv)
-        {
-            SGUpdateVisitor* updateVisitor = static_cast<SGUpdateVisitor*>(nv);
-            osg::Fog* fog = static_cast<osg::Fog*>(sa);
-            fog->setMode(osg::Fog::EXP);
-            fog->setColor(updateVisitor->getFogColor().osg());
-            fog->setDensity(updateVisitor->getFogExpDensity());
-        }
-};
-
 SGNewCloud::SGNewCloud(string type,
                        const SGPath &tex_path, 
                        string tex,
@@ -193,11 +182,6 @@ SGNewCloud::SGNewCloud(string type,
         stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
         
         // Fog handling
-        osg::Fog* fog = new osg::Fog;
-        fog->setUpdateCallback(new SGCloudFogUpdateCallback);
-        stateSet->setAttributeAndModes(fog);
-        stateSet->setDataVariance(osg::Object::DYNAMIC);
-        
         stateSet->setAttributeAndModes(attribFactory->getSmoothShadeModel());
         stateSet->setAttributeAndModes(attribFactory->getStandardBlendFunc());
 
index 2aee1a2edbdbcb3dd0cfa35908c0c558253ba759..7ff81da832c5960ffed634a8e13c12354181adf2 100644 (file)
@@ -128,7 +128,8 @@ bool SGSky::repaint( const SGSkyColor &sc )
        // turn off sky
        disable();
     }
-
+    SGCloudField::updateFog((double)effective_visibility,
+                            osg::Vec4f(sc.fog_color.osg(), 1.0f));
     return true;
 }