From 2d77178ba3758707a581c21cdf142ebf2692460e Mon Sep 17 00:00:00 2001 From: fredb Date: Sat, 6 Dec 2008 23:02:42 +0000 Subject: [PATCH] Stuart Buchanan : - Replaces simple shader attributes with vectors (this was missed out of the last patch by mistake) - Includes Yon's Fog update code (Thanks!) - Fixes a bug since 1.0 where --enable-real-weather-fetch stopped the other weather scenarios from working. --- simgear/scene/sky/CloudShaderGeometry.cxx | 12 +++---- simgear/scene/sky/CloudShaderGeometry.hxx | 10 ++---- simgear/scene/sky/cloudfield.cxx | 27 ++++++++++++++- simgear/scene/sky/cloudfield.hxx | 3 ++ simgear/scene/sky/newcloud.cxx | 40 ++++++++++------------- simgear/scene/sky/newcloud.hxx | 3 +- 6 files changed, 56 insertions(+), 39 deletions(-) diff --git a/simgear/scene/sky/CloudShaderGeometry.cxx b/simgear/scene/sky/CloudShaderGeometry.cxx index bed0b02d..dee1e742 100755 --- a/simgear/scene/sky/CloudShaderGeometry.cxx +++ b/simgear/scene/sky/CloudShaderGeometry.cxx @@ -59,7 +59,7 @@ void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const float p = view_dir*_cloudsprites[0]->position.osg(); // Do a single iteration of a bubble sort, sorting // back to front. - for(int i = 0; i < _cloudsprites.size() - 1; i++) + for(unsigned int i = 0; i < _cloudsprites.size() - 1; i++) { float q = view_dir*_cloudsprites[i+1]->position.osg(); if (p > q) { @@ -103,12 +103,10 @@ void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const for(CloudSpriteList::const_iterator t = _cloudsprites.begin(); t != _cloudsprites.end(); ++t) { - extensions->glVertexAttrib1f(TEXTURE_INDEX_X, (GLfloat) (*t)->texture_index_x/varieties_x); - extensions->glVertexAttrib1f(TEXTURE_INDEX_Y, (GLfloat) (*t)->texture_index_y/varieties_y); - extensions->glVertexAttrib1f(WIDTH, (GLfloat) (*t)->width); - extensions->glVertexAttrib1f(HEIGHT, (GLfloat) (*t)->height); - extensions->glVertexAttrib1f(SHADE, (GLfloat) (*t)->shade); - extensions->glVertexAttrib1f(CLOUD_HEIGHT, (GLfloat) (*t)->cloud_height); + GLfloat ua1[3] = { (GLfloat) (*t)->texture_index_x/varieties_x, (GLfloat) (*t)->texture_index_y/varieties_y, (*t)->width }; + GLfloat ua2[3] = { (GLfloat) (*t)->height, (*t)->shade, (GLfloat) (*t)->cloud_height }; + extensions->glVertexAttrib3fv(USR_ATTR_1, ua1 ); + extensions->glVertexAttrib3fv(USR_ATTR_2, ua2 ); glColor4f((*t)->position.x(), (*t)->position.y(), (*t)->position.z(), 1.0); _geometry->draw(renderInfo); } diff --git a/simgear/scene/sky/CloudShaderGeometry.hxx b/simgear/scene/sky/CloudShaderGeometry.hxx index 57bd1720..66727406 100755 --- a/simgear/scene/sky/CloudShaderGeometry.hxx +++ b/simgear/scene/sky/CloudShaderGeometry.hxx @@ -43,12 +43,8 @@ class CloudShaderGeometry : public osg::Drawable { public: - const static unsigned int CLOUD_HEIGHT = 10; - const static unsigned int TEXTURE_INDEX_X = 11; - const static unsigned int TEXTURE_INDEX_Y = 12; - const static unsigned int WIDTH = 13; - const static unsigned int HEIGHT = 14; - const static unsigned int SHADE = 15; + const static unsigned int USR_ATTR_1 = 10; + const static unsigned int USR_ATTR_2 = 11; CloudShaderGeometry() { @@ -148,7 +144,7 @@ class CloudShaderGeometry : public osg::Drawable virtual ~CloudShaderGeometry() { delete skip_info; - for (int i = 0; i < _cloudsprites.size(); i++) + for (unsigned int i = 0; i < _cloudsprites.size(); i++) { delete _cloudsprites[i]; } diff --git a/simgear/scene/sky/cloudfield.cxx b/simgear/scene/sky/cloudfield.cxx index 18ecd53a..337831cc 100644 --- a/simgear/scene/sky/cloudfield.cxx +++ b/simgear/scene/sky/cloudfield.cxx @@ -41,6 +41,7 @@ using std::vector; #include #include +#include #include "sky.hxx" #include "newcloud.hxx" #include "cloudfield.hxx" @@ -69,7 +70,7 @@ float SGCloudField::coverage = 1.0f; double SGCloudField::timer_dt = 0.0; float SGCloudField::view_distance = 20000.0f; sgVec3 SGCloudField::view_vec, SGCloudField::view_X, SGCloudField::view_Y; - +SGCloudField::StateSetMap SGCloudField::cloudTextureMap; // reposition the cloud layer at the specified origin and orientation bool SGCloudField::reposition( const SGVec3f& p, const SGVec3f& up, double lon, double lat, @@ -136,6 +137,29 @@ 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), @@ -147,6 +171,7 @@ 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(); diff --git a/simgear/scene/sky/cloudfield.hxx b/simgear/scene/sky/cloudfield.hxx index f5027b43..d39c1512 100644 --- a/simgear/scene/sky/cloudfield.hxx +++ b/simgear/scene/sky/cloudfield.hxx @@ -123,6 +123,9 @@ public: void applyCoverage(void); void applyVisRange(void); + + typedef std::map > StateSetMap; + static StateSetMap cloudTextureMap; }; #endif // _CLOUDFIELD_HXX diff --git a/simgear/scene/sky/newcloud.cxx b/simgear/scene/sky/newcloud.cxx index d67ca971..62e75501 100644 --- a/simgear/scene/sky/newcloud.cxx +++ b/simgear/scene/sky/newcloud.cxx @@ -61,21 +61,23 @@ typedef std::map > StateSetMap; typedef std::vector< osg::ref_ptr > GeodeList; typedef std::map CloudMap; -static StateSetMap cloudTextureMap; +StateSetMap cloudTextureMap; static CloudMap cloudMap; double SGNewCloud::sprite_density = 1.0; -int SGNewCloud::num_flavours = 10; +unsigned int SGNewCloud::num_flavours = 10; static char vertexShaderSource[] = "#version 120\n" "\n" "varying float fogFactor;\n" - "attribute float textureIndexX;\n" - "attribute float textureIndexY;\n" - "attribute float wScale;\n" - "attribute float hScale;\n" - "attribute float shade;\n" - "attribute float cloud_height;\n" + "attribute vec3 usrAttr1;\n" + "attribute vec3 usrAttr2;\n" + "float textureIndexX = usrAttr1.r;\n" + "float textureIndexY = usrAttr1.g;\n" + "float wScale = usrAttr1.b;\n" + "float hScale = usrAttr2.r;\n" + "float shade = usrAttr2.g;\n" + "float cloud_height = usrAttr2.b;\n" "void main(void)\n" "{\n" " gl_TexCoord[0] = gl_MultiTexCoord0 + vec4(textureIndexX, textureIndexY, 0.0, 0.0);\n" @@ -171,9 +173,9 @@ SGNewCloud::SGNewCloud(string type, name(type) { // Create a new StateSet for the texture, if required. - StateSetMap::iterator iter = cloudTextureMap.find(texture); + StateSetMap::iterator iter = SGCloudField::cloudTextureMap.find(texture); - if (iter == cloudTextureMap.end()) { + if (iter == SGCloudField::cloudTextureMap.end()) { stateSet = new osg::StateSet; osg::ref_ptr options = makeOptionsFromPath(tex_path); @@ -213,13 +215,8 @@ SGNewCloud::SGNewCloud(string type, baseTextureSampler = new osg::Uniform("baseTexture", 0); Shader* vertex_shader = new Shader(Shader::VERTEX, vertexShaderSource); program->addShader(vertex_shader); - program->addBindAttribLocation("textureIndexX", CloudShaderGeometry::TEXTURE_INDEX_X); - program->addBindAttribLocation("textureIndexY", CloudShaderGeometry::TEXTURE_INDEX_Y); - program->addBindAttribLocation("wScale", CloudShaderGeometry::WIDTH); - program->addBindAttribLocation("hScale", CloudShaderGeometry::HEIGHT); - program->addBindAttribLocation("shade", CloudShaderGeometry::SHADE); - program->addBindAttribLocation("cloud_height", CloudShaderGeometry::CLOUD_HEIGHT); - + program->addBindAttribLocation("usrAttr1", CloudShaderGeometry::USR_ATTR_1); + program->addBindAttribLocation("usrAttr2", CloudShaderGeometry::USR_ATTR_2); Shader* fragment_shader = new Shader(Shader::FRAGMENT, fragmentShaderSource); program->addShader(fragment_shader); material = new Material; @@ -240,7 +237,7 @@ SGNewCloud::SGNewCloud(string type, stateSet->setAttribute(material.get()); // Add the newly created texture to the map for use later. - cloudTextureMap.insert(StateSetMap::value_type(texture, stateSet)); + SGCloudField::cloudTextureMap.insert(StateSetMap::value_type(texture, stateSet)); } else { stateSet = iter->second.get(); } @@ -310,10 +307,9 @@ osg::ref_ptr SGNewCloud::genCloud() { // allows us to strike a balance between performance and // visual complexity. - GeodeList* g = (*iter).second; - - if (iter == cloudMap.end() || g->size() < num_flavours) + if (iter == cloudMap.end() || (*iter).second->size() < num_flavours) { + geode = new Geode; CloudShaderGeometry* sg = new CloudShaderGeometry(num_textures_x, num_textures_y, max_width, max_height); @@ -405,7 +401,7 @@ osg::ref_ptr SGNewCloud::genCloud() { else { // Add the new cloud to the list of geodes - (*iter).second->push_back(geode.get()); + (*iter).second->push_back(geode); } } else { diff --git a/simgear/scene/sky/newcloud.hxx b/simgear/scene/sky/newcloud.hxx index a4ff8be4..fabf073d 100644 --- a/simgear/scene/sky/newcloud.hxx +++ b/simgear/scene/sky/newcloud.hxx @@ -105,7 +105,7 @@ private: osg::Geometry* quad; osg::ref_ptr stateSet; static double sprite_density; - static int num_flavours; + static unsigned int num_flavours; osg::Geometry* createOrthQuad(float w, float h, int varieties_x, int varieties_y); @@ -113,5 +113,4 @@ private: - #endif // _NEWCLOUD_HXX -- 2.39.2