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.
// 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),
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;
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 );
}
}
/*
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;
}
}
/** 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();
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];
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();
-
- 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
- }
+ 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
+
+ // 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)
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 ) {
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
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;