Add a method to SGCloudLayer to set overall cloud alpha. This gives us the

capability to slowly fade a cloud layer in or out.

We use this effect in combination with lowering visibility as we approach
a cloud layer to hide the fact that it is simply a 2d textured polygon being
drawn across the sky.
This commit is contained in:
curt 2005-01-11 15:21:58 +00:00
parent a5f0e0395a
commit 01608b7e18
3 changed files with 69 additions and 26 deletions

View File

@ -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;
}
}

View File

@ -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];

View File

@ -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;