From: timoore Date: Wed, 10 Dec 2008 22:39:48 +0000 (+0000) Subject: Use a singleton Fog attribute for all 3D clouds. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=966b9e5c2bbcb27a3ad90d6f4d059d3a4fa1fd27;p=simgear.git Use a singleton Fog attribute for all 3D clouds. Don't update this Fog with any kind of update callback; instead, update from the sky repaint method. --- diff --git a/simgear/scene/sky/cloudfield.cxx b/simgear/scene/sky/cloudfield.cxx index 337831cc..bb2bb527 100644 --- a/simgear/scene/sky/cloudfield.cxx +++ b/simgear/scene/sky/cloudfield.cxx @@ -24,8 +24,10 @@ # include #endif +#include #include #include +#include #include @@ -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(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(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 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); +} diff --git a/simgear/scene/sky/cloudfield.hxx b/simgear/scene/sky/cloudfield.hxx index d39c1512..75a94091 100644 --- a/simgear/scene/sky/cloudfield.hxx +++ b/simgear/scene/sky/cloudfield.hxx @@ -26,7 +26,7 @@ #include #include #include -#include + #include #include @@ -34,9 +34,16 @@ #include #include #include -#include + +namespace osg +{ + class Fog; + class StateSet; + class Vec4f; +} #include +#include using std::vector; @@ -78,6 +85,11 @@ private: float last_coverage; SGGeoc cld_pos; int reposition_count; + struct CloudFog : public simgear::Singleton + { + CloudFog(); + osg::ref_ptr fog; + }; public: SGCloudField(); @@ -126,6 +138,12 @@ public: typedef std::map > 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 diff --git a/simgear/scene/sky/newcloud.cxx b/simgear/scene/sky/newcloud.cxx index 3624a53c..61dcb8b6 100644 --- a/simgear/scene/sky/newcloud.cxx +++ b/simgear/scene/sky/newcloud.cxx @@ -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(nv); - osg::Fog* fog = static_cast(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()); diff --git a/simgear/scene/sky/sky.cxx b/simgear/scene/sky/sky.cxx index 2aee1a2e..7ff81da8 100644 --- a/simgear/scene/sky/sky.cxx +++ b/simgear/scene/sky/sky.cxx @@ -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; }