diff --git a/simgear/scene/sky/cloud.cxx b/simgear/scene/sky/cloud.cxx index dbc7d03d..d567f729 100644 --- a/simgear/scene/sky/cloud.cxx +++ b/simgear/scene/sky/cloud.cxx @@ -197,9 +197,12 @@ generateNormalizationCubeMap() // Constructor SGCloudLayer::SGCloudLayer( const string &tex_path ) : + vertices(0), + indices(0), layer_root(new ssgRoot), layer_transform(new ssgTransform), state_sel(0), + cloud_alpha(1.0), texture_path(tex_path), layer_span(0.0), layer_asl(0.0), @@ -210,9 +213,7 @@ SGCloudLayer::SGCloudLayer( const string &tex_path ) : speed(0.0), direction(0.0), last_lon(0.0), - last_lat(0.0), - vertices(0), - indices(0) + last_lat(0.0) { cl[0] = cl[1] = cl[2] = cl[3] = NULL; vl[0] = vl[1] = vl[2] = vl[3] = NULL; @@ -495,7 +496,7 @@ SGCloudLayer::rebuild() cos( j * half_angle ), -sin( j * half_angle ) ); sgVectorProductVec3( v1.normal, v1.tTangent, v1.sTangent ); - sgSetVec4( v1.color, 1.0f, 1.0f, 1.0f, (i == 0) ? 0.0f : 0.15f ); + sgSetVec4( v1.color, 1.0f, 1.0f, 1.0f, (i == 0) ? 0.0f : cloud_alpha * 0.15f ); } } /* @@ -630,10 +631,27 @@ bool SGCloudLayer::repaint( sgVec3 fog_color ) { float *color; for ( int i = 0; i < 4; i++ ) { - for ( int j = 0; j < 10; ++j ) { - color = cl[i]->get( j ); + color = cl[i]->get( 0 ); + sgCopyVec3( color, fog_color ); + color[3] = (i == 0) ? 0.0f : 0.15f; + + for ( int j = 0; j < 4; ++j ) { + color = cl[i]->get( (2*j) ); sgCopyVec3( color, fog_color ); + color[3] = + ((j == 0) || (i == 3)) ? + ((j == 0) && (i == 3)) ? 0.0f : 0.15f : 1.0f; + + color = cl[i]->get( (2*j) + 1 ); + sgCopyVec3( color, fog_color ); + color[3] = + ((j == 3) || (i == 0)) ? + ((j == 3) && (i == 0)) ? 0.0f : 0.15f : 1.0f; } + + color = cl[i]->get( 9 ); + sgCopyVec3( color, fog_color ); + color[3] = (i == 3) ? 0.0f : 0.15f; } } diff --git a/simgear/scene/sky/cloud.hxx b/simgear/scene/sky/cloud.hxx index 73ca8322..dbd7c8fb 100644 --- a/simgear/scene/sky/cloud.hxx +++ b/simgear/scene/sky/cloud.hxx @@ -143,6 +143,18 @@ public: /** get the cloud movement speed */ inline float getSpeed() { return speed; } + /** + * set the alpha component of the cloud base color. Normally this + * should be 1.0, but you can set it anywhere in the range of 0.0 + * to 1.0 to fade a cloud layer in or out. + * @param alpha cloud alpha value (0.0 to 1.0) + */ + inline void setAlpha( float alpha ) { + if ( alpha < 0.0 ) { alpha = 0.0; } + if ( alpha > 1.0 ) { alpha = 1.0; } + cloud_alpha = alpha; + } + /** build the cloud object */ void rebuild(); @@ -191,6 +203,8 @@ private: ssgLeaf *layer[4]; ssgStateSelector *state_sel; + float cloud_alpha; // 1.0 = drawn fully, 0.0 faded out completely + ssgColourArray *cl[4]; ssgVertexArray *vl[4]; ssgTexCoordArray *tl[4]; diff --git a/simgear/scene/sky/sky.cxx b/simgear/scene/sky/sky.cxx index ad8e8ae0..ae1a2c0a 100644 --- a/simgear/scene/sky/sky.cxx +++ b/simgear/scene/sky/sky.cxx @@ -171,34 +171,34 @@ bool SGSky::reposition( SGSkyState &st, double dt ) void SGSky::preDraw( float alt, float fog_exp2_density ) { ssgCullAndDraw( pre_root ); - // if we are closer than this to a cloud layer, don't draw clouds + // if we are closer than this to a cloud layer, don't draw clouds static const float slop = 5.0; int i; // check where we are relative to the cloud layers in_cloud = -1; for ( i = 0; i < (int)cloud_layers.size(); ++i ) { - float asl = cloud_layers[i]->getElevation_m(); - float thickness = cloud_layers[i]->getThickness_m(); + float asl = cloud_layers[i]->getElevation_m(); + float thickness = cloud_layers[i]->getThickness_m(); - if ( alt < asl - slop ) { - // below cloud layer - } else if ( alt < asl + thickness + slop ) { - // in cloud layer + if ( alt < asl - slop ) { + // below cloud layer + } else if ( alt < asl + thickness + slop ) { + // in cloud layer - // bail now and don't draw any clouds - in_cloud = i; - } else { - // above cloud layer - } + // bail now and don't draw any clouds + in_cloud = i; + } else { + // above cloud layer + } } // determine rendering order cur_layer_pos = 0; while ( cur_layer_pos < (int)cloud_layers.size() && - alt > cloud_layers[cur_layer_pos]->getElevation_m()) + alt > cloud_layers[cur_layer_pos]->getElevation_m() ) { - ++cur_layer_pos; + ++cur_layer_pos; } // FIXME: This should not be needed, but at this time (08/15/2003) @@ -266,7 +266,10 @@ void SGSky::modify_vis( float alt, float time_factor ) { double ratio = 1.0; - if ( cloud_layers[i]->getCoverage() == SGCloudLayer::SG_CLOUD_CLEAR || cloud_layers[i]->getCoverage() == SGCloudLayer::SG_CLOUD_FEW || cloud_layers[i]->getCoverage() == SGCloudLayer::SG_CLOUD_SCATTERED) { + if ( cloud_layers[i]->getCoverage() == SGCloudLayer::SG_CLOUD_CLEAR || + cloud_layers[i]->getCoverage() == SGCloudLayer::SG_CLOUD_FEW || + cloud_layers[i]->getCoverage() == SGCloudLayer::SG_CLOUD_SCATTERED) + { // less than 50% coverage -- assume we're in the clear for now ratio = 1.0; } else if ( alt < asl - transition ) { @@ -286,9 +289,15 @@ void SGSky::modify_vis( float alt, float time_factor ) { ratio = 1.0; } + // set the alpha fade value for the cloud layer + float temp = ratio * 2.0; + if ( temp > 1.0 ) { temp = 1.0; } + cloud_layers[i]->setAlpha( temp ); + // accumulate effects from multiple cloud layers effvis *= ratio; +#if 0 if ( ratio < 1.0 ) { if ( ! in_puff ) { // calc chance of entering cloud puff @@ -345,12 +354,14 @@ void SGSky::modify_vis( float alt, float time_factor ) { in_puff = false; } } - - // never let visibility drop below 25 meters - if ( effvis <= 25.0 ) { - effvis = 25.0; - } } +#endif + + // never let visibility drop below 25 meters + if ( effvis <= 25.0 ) { + effvis = 25.0; + } + } // for effective_visibility = effvis;