From: fredb Date: Thu, 6 Nov 2008 21:58:07 +0000 (+0000) Subject: Stuart Buchanan : X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=0b8b6ac56ab1efd3ad8cd1f430ec48641a1f2a13;p=simgear.git Stuart Buchanan : It fixes the following issues (to a greater or lesser extent): 1) Performance. Quad trees used to improve culling, and the sprites are placed on the surface of a sphere rather than randomly throughout the cloud, requiring fewer textures. This saves about 5-10fps on my machine. 2) Disabled 3D clouds have no performance impact. Previously they were still in the scenegraph. Now they are removed. 3) Clouds are now loaded on start-up, and don't require the scenario to be changed, they also work with METAR. 4) The cloud field is shifted as you travel. There's a small bug in that the clouds "jump" as you reach the edge of the field. 5) Iterative sorting of sprites. This doesn't appear to solve the alpha blending problem completely, but may help a bit. --- diff --git a/simgear/scene/sky/CloudShaderGeometry.cxx b/simgear/scene/sky/CloudShaderGeometry.cxx index 6fe9f8cf..eaa9450f 100755 --- a/simgear/scene/sky/CloudShaderGeometry.cxx +++ b/simgear/scene/sky/CloudShaderGeometry.cxx @@ -35,16 +35,36 @@ namespace simgear void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const { osg::State& state = *renderInfo.getState(); + osg::Matrix vm = state.getModelViewMatrix(); + + //TODO: It isn't clear whether this is worth the perf hit ATM. + + // Do a single iteration of a bubble sort. We do this in reverse + // so that elements closest to the camera bubble to the front than + // the elements further away + for(int i = (_cloudsprites.size() -2); i >= 0; i--) + { + osg::Vec4f p = vm * osg::Vec4f(_cloudsprites[i]->position.osg(), 1.0f); + osg::Vec4f q = vm * osg::Vec4f(_cloudsprites[i+1]->position.osg(), 1.0f); + + if (p.z() > q.z()) + { + CloudSprite c = *_cloudsprites[i]; + *_cloudsprites[i] = *_cloudsprites[i+1]; + *_cloudsprites[i+1] = c; + } + } + const Extensions* extensions = getExtensions(state.getContextID(),true); 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); - glColor4f(t->position.x(), t->position.y(), t->position.z(), 1.0); + 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); + glColor4f((*t)->position.x(), (*t)->position.y(), (*t)->position.z(), 1.0); _geometry->draw(renderInfo); } } @@ -56,10 +76,10 @@ BoundingBox CloudShaderGeometry::computeBound() const for(CloudSpriteList::const_iterator itr = _cloudsprites.begin(); itr != _cloudsprites.end(); ++itr) { - bb.expandBy(geom_box.corner(0)*itr->width + - osg::Vec3( itr->position.x(), itr->position.y(), itr->position.z() )); - bb.expandBy(geom_box.corner(7)*itr->height + - osg::Vec3( itr->position.x(), itr->position.y(), itr->position.z() )); + bb.expandBy(geom_box.corner(0)*(*itr)->width + + osg::Vec3( (*itr)->position.x(), (*itr)->position.y(), (*itr)->position.z() )); + bb.expandBy(geom_box.corner(7)*(*itr)->height + + osg::Vec3( (*itr)->position.x(), (*itr)->position.y(), (*itr)->position.z() )); } return bb; } @@ -95,7 +115,7 @@ bool CloudShaderGeometry_readLocalData(Object& obj, Input& fr) fr[4].getFloat(w) && fr[4].getFloat(h)&& fr[4].getFloat(s)) { fr += 5; //SGVec3f* v = new SGVec3f(v.x(), v.y(), v.z()); - geom._cloudsprites.push_back(CloudShaderGeometry::CloudSprite(v, tx, ty, w, h,s)); + geom._cloudsprites.push_back(new CloudShaderGeometry::CloudSprite(v, tx, ty, w, h,s)); } else { ++fr; } @@ -113,14 +133,14 @@ bool CloudShaderGeometry_writeLocalData(const Object& obj, Output& fw) fw.indent() << "instances " << geom._cloudsprites.size() << std::endl; fw.indent() << "{" << std::endl; fw.moveIn(); - for (CloudShaderGeometry::CloudSpriteList::const_iterator iter + for (CloudShaderGeometry::CloudSpriteList::const_iterator itr = geom._cloudsprites.begin(); - iter != geom._cloudsprites.end(); - ++iter) { - fw.indent() << iter->position.x() << " " << iter->position.y() << " " - << iter->position.z() << " " << iter->texture_index_x << " " - << iter->texture_index_y << " " - << iter->width << " " << iter->height << " " << iter->shade << std::endl; + itr != geom._cloudsprites.end(); + ++itr) { + fw.indent() << (*itr)->position.x() << " " << (*itr)->position.y() << " " + << (*itr)->position.z() << " " << (*itr)->texture_index_x << " " + << (*itr)->texture_index_y << " " + << (*itr)->width << " " << (*itr)->height << " " << (*itr)->shade << std::endl; } fw.moveOut(); fw.indent() << "}" << std::endl; diff --git a/simgear/scene/sky/CloudShaderGeometry.hxx b/simgear/scene/sky/CloudShaderGeometry.hxx index e28928ed..1f0dd10d 100755 --- a/simgear/scene/sky/CloudShaderGeometry.hxx +++ b/simgear/scene/sky/CloudShaderGeometry.hxx @@ -66,7 +66,7 @@ class CloudShaderGeometry : public osg::Drawable META_Object(flightgear, CloudShaderGeometry); struct CloudSprite { - CloudSprite(const SGVec3f& p, int tx, int ty, float w, float h, float s) : + CloudSprite(SGVec3f& p, int tx, int ty, float w, float h, float s) : position(p), texture_index_x(tx), texture_index_y(ty), width(w), height(h), shade(s) { } @@ -78,16 +78,16 @@ class CloudShaderGeometry : public osg::Drawable float shade; }; - typedef std::vector CloudSpriteList; + typedef std::vector CloudSpriteList; - void insert(const CloudSprite& t) + void insert(CloudSprite* t) { _cloudsprites.push_back(t); } - void insert(const SGVec3f& p, int tx, int ty, float w, float h, float s) - { insert(CloudSprite(p, tx, ty, w, h, s)); } + void insert(SGVec3f& p, int tx, int ty, float w, float h, float s) + { insert(new CloudSprite(p, tx, ty, w, h, s)); } unsigned getNumCloudSprite() const { return _cloudsprites.size(); } - const CloudSprite& getCloudSprite(unsigned i) const + CloudSprite* getCloudSprite(unsigned i) const { return _cloudsprites[i]; } CloudSpriteList _cloudsprites; @@ -102,28 +102,28 @@ class CloudShaderGeometry : public osg::Drawable _geometry = geometry; } - void addSprite(const SGVec3f& p, int tx, int ty, float w, float h, float s, float cull) + void addSprite(SGVec3f& p, int tx, int ty, float w, float h, float s, float cull) { // Only add the sprite if it is further than the cull distance to all other sprites - for (CloudShaderGeometry::CloudSpriteList::const_iterator iter = _cloudsprites.begin(); + for (CloudShaderGeometry::CloudSpriteList::iterator iter = _cloudsprites.begin(); iter != _cloudsprites.end(); ++iter) { - if (distSqr(iter->position, p) < cull) + if (distSqr((*iter)->position, p) < cull) { // Too close - cull it return; } } - _cloudsprites.push_back(CloudSprite(p, tx, ty, w, h, s)); + _cloudsprites.push_back(new CloudSprite(p, tx, ty, w, h, s)); } - + osg::ref_ptr _geometry; int varieties_x; int varieties_y; - + protected: virtual ~CloudShaderGeometry() {} diff --git a/simgear/scene/sky/cloudfield.cxx b/simgear/scene/sky/cloudfield.cxx index f23b0f5c..5012d942 100644 --- a/simgear/scene/sky/cloudfield.cxx +++ b/simgear/scene/sky/cloudfield.cxx @@ -74,92 +74,109 @@ void SGCloudField::set_density(float density) { bool SGCloudField::reposition( const SGVec3f& p, const SGVec3f& up, double lon, double lat, double dt ) { - osg::Matrix T, LON, LAT; - + osg::Matrix T, LON, LAT; + + SGGeoc pos = SGGeoc::fromGeod(SGGeod::fromRad(lon, lat)); + + double dist = SGGeodesy::distanceM(cld_pos, pos); + + if (dist > (fieldSize * 2)) { + // First time or very large distance + SGVec3 cart; + SGGeodesy::SGGeodToCart(SGGeod::fromRad(lon, lat), cart); + T.makeTranslate(cart.osg()); + LON.makeRotate(lon, osg::Vec3(0, 0, 1)); LAT.makeRotate(90.0 * SGD_DEGREES_TO_RADIANS - lat, osg::Vec3(0, 1, 0)); - osg::Vec3 u = up.osg(); - u.normalize(); - - if ((last_lon == 0.0f) || (fabs(last_lon - lon) > 1.0) || (fabs(last_lat - lat) > 1.0)) - { - // First time, or large delta requires repositioning from scratch. - // TODO: Make this calculation better - a 0.5 degree shift will take a number - // of reposition calls to correct at the moment. - - // combine p and asl (meters) to get translation offset. - osg::Vec3 pos = p.osg(); - pos += u; - - T.makeTranslate(pos); - - field_transform->setMatrix( LAT*LON*T ); - last_lon = lon; - last_lat = lat; - last_pos = p.osg(); + field_transform->setMatrix( LAT*LON*T ); + cld_pos = SGGeoc::fromGeod(SGGeod::fromRad(lon, lat)); + } else if (dist > fieldSize) { + // Distance requires repositioning of cloud field. + + // We can easily work out the direction to reposition + // from the course between the cloud position and the + // camera position. + SGGeoc pos = SGGeoc::fromGeod(SGGeod::fromRad(lon, lat)); + + float crs = SGGeoc::courseDeg(cld_pos, pos); + if ((crs < 45.0) || (crs > 315.0)) { + SGGeodesy::advanceRadM(cld_pos, 0.0, fieldSize, cld_pos); + } + + if ((crs > 45.0) && (crs < 135.0)) { + SGGeodesy::advanceRadM(cld_pos, SGD_PI_2, fieldSize, cld_pos); } - else - { - // Rotation positon back to simple X-Z space. - osg::Vec3 pos = last_pos; - pos += u; - - T.makeTranslate(pos); - - osg::Matrix U = LAT*LON; - osg::Vec3 x = osg::Vec3f(fieldSize, 0.0, 0.0)*U; - osg::Vec3 y = osg::Vec3f(0.0, fieldSize, 0.0)*U; - - osg::Matrix V; - V.makeIdentity(); - V.invert(U*T); - - osg::Vec3 q = pos*V; - - // Shift the field if we've moved away from the centre box. - if (q.x() > fieldSize) last_pos = last_pos + x; - if (q.x() < -fieldSize) last_pos = last_pos - x; - if (q.y() > fieldSize) last_pos = last_pos + y; - if (q.y() < -fieldSize) last_pos = last_pos - y; - - pos = last_pos; - pos += u; - - T.makeTranslate(pos); - field_transform->setMatrix( LAT*LON*T ); + + if ((crs > 135.0) && (crs < 225.0)) { + SGGeodesy::advanceRadM(cld_pos, SGD_PI, fieldSize, cld_pos); } + + if ((crs > 225.0) && (crs < 315.0)) { + SGGeodesy::advanceRadM(cld_pos, SGD_PI + SGD_PI_2, fieldSize, cld_pos); + } + + SGVec3 cart; + SGGeodesy::SGGeodToCart(SGGeod::fromRad(cld_pos.getLongitudeRad(), cld_pos.getLatitudeRad()), cart); + T.makeTranslate(cart.osg()); + + LON.makeRotate(cld_pos.getLongitudeRad(), osg::Vec3(0, 0, 1)); + LAT.makeRotate(90.0 * SGD_DEGREES_TO_RADIANS - cld_pos.getLatitudeRad(), osg::Vec3(0, 1, 0)); + + field_transform->setMatrix( LAT*LON*T ); + } return true; } SGCloudField::SGCloudField() : field_root(new osg::Group), field_transform(new osg::MatrixTransform), - field_group(new osg::Switch), deltax(0.0), deltay(0.0), - last_lon(0.0), - last_lat(0.0), last_course(0.0), last_density(0.0), defined3D(false) { - field_root->addChild(field_transform.get()); - field_group->setName("3Dcloud"); - - // We duplicate the defined field group in a 3x3 array. This way, - // we can simply shift entire groups around. - for(int x = -1 ; x <= 1 ; x++) { - for(int y = -1 ; y <= 1 ; y++ ) { - osg::ref_ptr transform = - new osg::PositionAttitudeTransform; - transform->addChild(field_group.get()); - transform->setPosition(osg::Vec3(x*fieldSize, y * fieldSize, 0.0)); - - field_transform->addChild(transform.get()); - } + cld_pos = SGGeoc(); + field_root->addChild(field_transform.get()); + + osg::ref_ptr quad_root = new osg::Group(); + osg::ref_ptr quad[BRANCH_SIZE][BRANCH_SIZE]; + + for (int i = 0; i < BRANCH_SIZE; i++) { + for (int j = 0; j < BRANCH_SIZE; j++) { + quad[i][j] = new osg::LOD(); + quad[i][j]->setName("Quad"); + quad_root->addChild(quad[i][j].get()); } - + } + + for (int x = 0; x < QUADTREE_SIZE; x++) { + for (int y = 0; y < QUADTREE_SIZE; y++) { + field_group[x][y]= new osg::Switch; + field_group[x][y]->setName("3D cloud group"); + + // Work out where to put this node in the quad tree + int i = (int) (BRANCH_SIZE * ((float) x) / ((float) QUADTREE_SIZE)); + int j = (int) (BRANCH_SIZE * ((float) y) / ((float) QUADTREE_SIZE)); + quad[i][j]->addChild(field_group[x][y].get(), 0.0f, 20000.0f); + } + } + + // We duplicate the defined field group in a 3x3 array. This way, + // we can simply shift entire groups around. + // TODO: "Bend" the edge groups so when shifted they line up. + // Currently the clouds "jump down" when we reposition them. + for(int x = -1 ; x <= 1 ; x++) { + for(int y = -1 ; y <= 1 ; y++ ) { + osg::ref_ptr transform = + new osg::PositionAttitudeTransform; + transform->addChild(quad_root.get()); + transform->setPosition(osg::Vec3(x*fieldSize, y * fieldSize, 0.0)); + + field_transform->addChild(transform.get()); + } + } } SGCloudField::~SGCloudField() { @@ -167,12 +184,17 @@ SGCloudField::~SGCloudField() { void SGCloudField::clear(void) { - int num_children = field_group->getNumChildren(); + for (int x = 0; x < QUADTREE_SIZE; x++) { + for (int y = 0; y < QUADTREE_SIZE; y++) { + int num_children = field_group[x][y]->getNumChildren(); - for (int i = 0; i < num_children; i++) { - field_group->removeChild(i); + for (int i = 0; i < num_children; i++) { + field_group[x][y]->removeChild(i); + } } - SGCloudField::defined3D = false; + } + + SGCloudField::defined3D = false; } // use a table or else we see poping when moving the slider... @@ -194,18 +216,22 @@ void SGCloudField::applyDensity(void) { int row = (int) (density / 10.0); int col = 0; - int num_children = field_group->getNumChildren(); if (density != last_density) { + for (int x = 0; x < QUADTREE_SIZE; x++) { + for (int y = 0; y < QUADTREE_SIZE; y++) { // Switch on/off the children depending on the required density. - for (int i = 0; i < num_children; i++) { + int num_children = field_group[x][y]->getNumChildren(); + for (int i = 0; i < num_children; i++) { if (++col > 9) col = 0; if ( densTable[row][col] ) { - field_group->setValue(i, true); + field_group[x][y]->setValue(i, true); } else { - field_group->setValue(i, false); + field_group[x][y]->setValue(i, false); } + } } + } } last_density = density; @@ -213,11 +239,21 @@ void SGCloudField::applyDensity(void) { void SGCloudField::addCloud( SGVec3f& pos, SGNewCloud *cloud) { defined3D = true; - osg::ref_ptr lod = cloud->genCloud(); + osg::ref_ptr geode = cloud->genCloud(); + + // Determine which quadtree to put it in. + int x = (int) floor((pos.x() + fieldSize/2.0) * QUADTREE_SIZE / fieldSize); + if (x >= QUADTREE_SIZE) x = (QUADTREE_SIZE - 1); + if (x < 0) x = 0; + + int y = (int) floor((pos.y() + fieldSize/2.0) * QUADTREE_SIZE / fieldSize); + if (y >= QUADTREE_SIZE) y = (QUADTREE_SIZE - 1); + if (y < 0) y = 0; + osg::ref_ptr transform = new osg::PositionAttitudeTransform; transform->setPosition(pos.osg()); - transform->addChild(lod.get()); - - field_group->addChild(transform.get()); + transform->addChild(geode.get()); + + field_group[x][y]->addChild(transform.get()); } diff --git a/simgear/scene/sky/cloudfield.hxx b/simgear/scene/sky/cloudfield.hxx index dd43669b..cd99f8af 100644 --- a/simgear/scene/sky/cloudfield.hxx +++ b/simgear/scene/sky/cloudfield.hxx @@ -56,6 +56,10 @@ private: }; float Rnd(float); + + // We create a quadtree two levels deep + static const int BRANCH_SIZE = 16; + static const int QUADTREE_SIZE = 32; // this is a relative position only, with that we can move all clouds at once sgVec3 relative_position; @@ -63,13 +67,14 @@ private: osg::ref_ptr field_root; osg::ref_ptr field_transform; - osg::ref_ptr field_group; + osg::ref_ptr field_group[QUADTREE_SIZE][QUADTREE_SIZE]; + osg::ref_ptr field_lod; double deltax, deltay, alt; - double last_lon, last_lat, last_course; + double last_course; sgSphere field_sphere; float last_density; - osg::Vec3 last_pos; + SGGeoc cld_pos; public: diff --git a/simgear/scene/sky/newcloud.cxx b/simgear/scene/sky/newcloud.cxx index 1ab787e6..bf2ffca4 100644 --- a/simgear/scene/sky/newcloud.cxx +++ b/simgear/scene/sky/newcloud.cxx @@ -65,7 +65,6 @@ static char vertexShaderSource[] = "#version 120\n" "\n" "varying float fogFactor;\n" - "varying float alphaBlend;\n" "attribute float textureIndexX;\n" "attribute float textureIndexY;\n" "attribute float wScale;\n" @@ -103,25 +102,22 @@ static char vertexShaderSource[] = " vec4 backlight = 0.8 * gl_LightSource[0].ambient + 0.2 * gl_LightSource[0].diffuse;\n" " gl_FrontColor = mix(backlight, gl_LightSource[0].diffuse, n);\n" " gl_FrontColor += gl_FrontLightModelProduct.sceneColor;\n" +// As we get within 100m of the sprite, it is faded out " gl_FrontColor.a = smoothstep(10.0, 100.0, fogCoord);\n" " gl_BackColor = gl_FrontColor;\n" // Fog doesn't affect clouds as much as other objects. - " fogFactor = exp( -gl_Fog.density * fogCoord);\n" + " fogFactor = exp( -gl_Fog.density * fogCoord * 0.5);\n" " fogFactor = clamp(fogFactor, 0.0, 1.0);\n" -// As we get within 100m of the sprite, it is faded out - " alphaBlend = smoothstep(10.0, 100.0, fogCoord);\n" "}\n"; static char fragmentShaderSource[] = "uniform sampler2D baseTexture; \n" "varying float fogFactor;\n" - "varying float alphaBlend;\n" "\n" "void main(void)\n" "{\n" " vec4 base = texture2D( baseTexture, gl_TexCoord[0].st);\n" " vec4 finalColor = base * gl_Color;\n" -// " finalColor.a = min(alphaBlend, finalColor.a);\n" " gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor );\n" "}\n"; @@ -238,12 +234,14 @@ SGNewCloud::SGNewCloud(const SGPath &tex_path, } else { stateSet = iter->second.get(); } + + quad = createOrthQuad(min_sprite_width, min_sprite_height, num_textures_x, num_textures_y); } SGNewCloud::~SGNewCloud() { } -osg::Geometry* createOrthQuad(float w, float h, int varieties_x, int varieties_y) +osg::Geometry* SGNewCloud::createOrthQuad(float w, float h, int varieties_x, int varieties_y) { // Create front and back polygons so we don't need to screw around // with two-sided lighting in the shader. @@ -292,16 +290,16 @@ static float Rnd(float n) { return n * (-0.5f + (sg_random() + sg_random()) / 2.0f); } -osg::ref_ptr SGNewCloud::genCloud() { - LOD* result = new LOD; +osg::ref_ptr SGNewCloud::genCloud() { Geode* geode = new Geode; CloudShaderGeometry* sg = new CloudShaderGeometry(num_textures_x, num_textures_y); - Geometry* quad = createOrthQuad(min_sprite_width, min_sprite_height, num_textures_x, num_textures_y); - // Determine how big this specific cloud instance is. - float width = min_width + sg_random() * (max_width - min_width); - float height = min_height + sg_random() * (max_height - min_height); + // Determine how big this specific cloud instance is. Note that we subtract + // the sprite size because the width/height is used to define the limits of + // the center of the sprites, not their edges. + float width = min_width + sg_random() * (max_width - min_width) - max_sprite_width; + float height = min_height + sg_random() * (max_height - min_height) - max_sprite_height; // Determine the cull distance. This is used to remove sprites that are too close together. // The value is squared as we use vector calculations. @@ -309,10 +307,14 @@ osg::ref_ptr SGNewCloud::genCloud() { for (int i = 0; i < num_sprites; i++) { - // Determine the position of the sprite. - SGVec3f *pos = new SGVec3f(Rnd(width), - Rnd(width), - Rnd(height)); + // Determine the position of the sprite. Rather than being completely random, + // sprites are placed on a squashed sphere. + double theta = sg_random() * SGD_2PI; + float x = width * cos(theta) * 0.5f; + float y = width * sin(theta) * 0.5f; + float z = height * cos(sg_random() * SGD_2PI) * 0.5f; + + SGVec3f *pos = new SGVec3f(x, y, z); // Determine the height and width as scaling factors on the minimum size (used to create the quad) float sprite_width = 1.0f + sg_random() * (max_sprite_width - min_sprite_width) / min_sprite_width; @@ -320,10 +322,10 @@ osg::ref_ptr SGNewCloud::genCloud() { // The shade varies from bottom_shade to 1.0 non-linearly float shade; - if (pos->z() > 0.0f) { + if (z > 0.0f) { shade = 1.0f; } else { - shade = ((2 * pos->z() + height) / height) * (1 - bottom_shade) + bottom_shade; + shade = ((2 * z + height) / height) * (1 - bottom_shade) + bottom_shade; } // Determine the sprite texture indexes; @@ -340,6 +342,5 @@ osg::ref_ptr SGNewCloud::genCloud() { geode->addDrawable(sg); geode->setName("3D cloud"); geode->setStateSet(stateSet.get()); - result->addChild(geode, 0, 20000); - return result; + return geode; } diff --git a/simgear/scene/sky/newcloud.hxx b/simgear/scene/sky/newcloud.hxx index 3cb93dd4..76ded5e9 100644 --- a/simgear/scene/sky/newcloud.hxx +++ b/simgear/scene/sky/newcloud.hxx @@ -58,7 +58,7 @@ public: ~SGNewCloud(); // Generate a Cloud - osg::ref_ptr genCloud (); + osg::ref_ptr genCloud (); private: @@ -75,9 +75,11 @@ private: int num_textures_x; int num_textures_y; const string texture; - + osg::Geometry* quad; osg::ref_ptr stateSet; + osg::Geometry* createOrthQuad(float w, float h, int varieties_x, int varieties_y); + public: }; diff --git a/simgear/scene/sky/sky.cxx b/simgear/scene/sky/sky.cxx index 4b6e4743..6772e260 100644 --- a/simgear/scene/sky/sky.cxx +++ b/simgear/scene/sky/sky.cxx @@ -187,19 +187,6 @@ SGSky::get_cloud_layer_count () const return cloud_layers.size(); } -void SGSky::set_3dClouds(bool enable) -{ - for ( unsigned i = 0; i < cloud_layers.size(); ++i ) { - cloud_layers[i]->set_enable3dClouds(enable); - } - - clouds_3d_enabled = enable; -} - -bool SGSky::get_3dClouds() const { - return clouds_3d_enabled; -} - double SGSky::get_3dCloudDensity() const { return SGCloudField::get_density(); } @@ -250,7 +237,7 @@ void SGSky::modify_vis( float alt, float time_factor ) { } if ( cloud_layers[i]->getCoverage() == SGCloudLayer::SG_CLOUD_CLEAR || - get_3dClouds()) { + cloud_layers[i]->get_layer3D()->defined3D) { // do nothing, clear layers aren't drawn, don't affect // visibility andn dont' need to be faded in or out. } else if ( (cloud_layers[i]->getCoverage() == diff --git a/simgear/scene/sky/sky.hxx b/simgear/scene/sky/sky.hxx index c7308784..899213d8 100644 --- a/simgear/scene/sky/sky.hxx +++ b/simgear/scene/sky/sky.hxx @@ -414,14 +414,6 @@ public: effective_visibility = visibility = (v <= 25.0) ? 25.0 : v; } - /** Get whether 3D clouds are enabled */ - virtual bool get_3dClouds() const; - - /** Set whether 3D clouds are enabled - * @param enable Whether to enable 3D clouds - */ - virtual void set_3dClouds(bool enable); - /** Get 3D cloud density */ virtual double get_3dCloudDensity() const;