# include <simgear_config.h>
#endif
+#include <osg/Fog>
#include <osg/Texture2D>
#include <osg/PositionAttitudeTransform>
+#include <osg/Vec4f>
#include <simgear/compiler.h>
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),
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();
}
}
+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);
+}
#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;
float last_coverage;
SGGeoc cld_pos;
int reposition_count;
+ struct CloudFog : public simgear::Singleton<CloudFog>
+ {
+ CloudFog();
+ osg::ref_ptr<osg::Fog> fog;
+ };
public:
SGCloudField();
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
"{\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,
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());
// turn off sky
disable();
}
-
+ SGCloudField::updateFog((double)effective_visibility,
+ osg::Vec4f(sc.fog_color.osg(), 1.0f));
return true;
}