1 // skydome.cxx -- model sky with an upside down "bowl"
3 // Written by Curtis Olson, started December 1997.
4 // SSG-ified by Curtis Olson, February 2000.
6 // Copyright (C) 1997-2000 Curtis L. Olson - curt@flightgear.org
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 #include <simgear/xgl/xgl.h>
38 #include <simgear/constants.h>
39 #include <simgear/debug/logstream.hxx>
40 #include <simgear/math/fg_random.h>
42 // #include <Aircraft/aircraft.hxx>
43 // #include <FDM/flight.hxx>
44 // #include <Main/views.hxx>
45 // #include <Time/event.hxx>
46 // #include <Time/fg_time.hxx>
48 #include "skydome.hxx"
52 # pragma global_optimizer off
56 // in meters of course
57 #define CENTER_ELEV 25000.0
59 #define UPPER_RADIUS 50000.0
60 #define UPPER_ELEV 20000.0
62 #define MIDDLE_RADIUS 70000.0
63 #define MIDDLE_ELEV 8000.0
65 #define LOWER_RADIUS 80000.0
66 #define LOWER_ELEV 0.0
68 #define BOTTOM_RADIUS 50000.0
69 #define BOTTOM_ELEV -2000.0
73 FGSkyDome::FGSkyDome( void ) {
78 FGSkyDome::~FGSkyDome( void ) {
82 // initialize the sky object and connect it into our scene graph
83 bool FGSkyDome::initialize( ) {
89 // create the scene graph for the dome
91 dome->setName( "Sky Dome" );
94 dome_state = new ssgSimpleState();
95 dome_state->setShadeModel( GL_SMOOTH );
96 dome_state->disable( GL_LIGHTING );
97 dome_state->disable( GL_CULL_FACE );
98 dome_state->disable( GL_TEXTURE_2D );
99 dome_state->enable( GL_COLOR_MATERIAL );
100 dome_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
101 dome_state->disable( GL_BLEND );
102 dome_state->disable( GL_ALPHA_TEST );
105 center_disk_vl = new ssgVertexArray( 14 );
106 center_disk_cl = new ssgColourArray( 14 );
108 upper_ring_vl = new ssgVertexArray( 26 );
109 upper_ring_cl = new ssgColourArray( 26 );
111 middle_ring_vl = new ssgVertexArray( 26 );
112 middle_ring_cl = new ssgColourArray( 26 );
114 lower_ring_vl = new ssgVertexArray( 26 );
115 lower_ring_cl = new ssgColourArray( 26 );
117 // initially seed to all blue
118 sgSetVec4( color, 0.0, 0.0, 1.0, 1.0 );
120 // generate the raw vertex data
121 sgVec3 center_vertex;
122 sgVec3 upper_vertex[12];
123 sgVec3 middle_vertex[12];
124 sgVec3 lower_vertex[12];
125 sgVec3 bottom_vertex[12];
127 sgSetVec3( center_vertex, 0.0, 0.0, CENTER_ELEV );
129 for ( i = 0; i < 12; i++ ) {
130 theta = (i * 30.0) * DEG_TO_RAD;
132 sgSetVec3( upper_vertex[i],
133 cos(theta) * UPPER_RADIUS,
134 sin(theta) * UPPER_RADIUS,
137 sgSetVec3( middle_vertex[i],
138 cos((double)theta) * MIDDLE_RADIUS,
139 sin((double)theta) * MIDDLE_RADIUS,
142 sgSetVec3( lower_vertex[i],
143 cos((double)theta) * LOWER_RADIUS,
144 sin((double)theta) * LOWER_RADIUS,
147 sgSetVec3( bottom_vertex[i],
148 cos((double)theta) * BOTTOM_RADIUS,
149 sin((double)theta) * BOTTOM_RADIUS,
153 // generate the center disk vertex/color arrays
154 center_disk_vl->add( center_vertex );
155 center_disk_cl->add( color );
156 for ( i = 11; i >= 0; i-- ) {
157 center_disk_vl->add( upper_vertex[i] );
158 center_disk_cl->add( color );
160 center_disk_vl->add( upper_vertex[11] );
161 center_disk_cl->add( color );
163 // generate the upper ring
164 for ( i = 0; i < 12; i++ ) {
165 upper_ring_vl->add( middle_vertex[i] );
166 upper_ring_cl->add( color );
168 upper_ring_vl->add( upper_vertex[i] );
169 upper_ring_cl->add( color );
171 upper_ring_vl->add( middle_vertex[0] );
172 upper_ring_cl->add( color );
174 upper_ring_vl->add( upper_vertex[0] );
175 upper_ring_cl->add( color );
177 // generate middle ring
178 for ( i = 0; i < 12; i++ ) {
179 middle_ring_vl->add( lower_vertex[i] );
180 middle_ring_cl->add( color );
182 middle_ring_vl->add( middle_vertex[i] );
183 middle_ring_cl->add( color );
185 middle_ring_vl->add( lower_vertex[0] );
186 middle_ring_cl->add( color );
188 middle_ring_vl->add( middle_vertex[0] );
189 middle_ring_cl->add( color );
191 // generate lower ring
192 for ( i = 0; i < 12; i++ ) {
193 lower_ring_vl->add( bottom_vertex[i] );
194 lower_ring_cl->add( color );
196 lower_ring_vl->add( lower_vertex[i] );
197 lower_ring_cl->add( color );
199 lower_ring_vl->add( bottom_vertex[0] );
200 lower_ring_cl->add( color );
202 lower_ring_vl->add( lower_vertex[0] );
203 lower_ring_cl->add( color );
205 // force a repaint of the sky colors with ugly defaults
207 sgSetVec3( fog_color, 1.0, 1.0, 1.0 );
208 repaint( color, fog_color, 0.0 );
210 // build the ssg scene graph sub tree for the sky and connected
211 // into the provide scene graph branch
212 dome_selector = new ssgSelector;
213 dome_transform = new ssgTransform;
215 ssgVtxTable *center_disk, *upper_ring, *middle_ring, *lower_ring;
217 center_disk = new ssgVtxTable( GL_TRIANGLE_FAN,
218 center_disk_vl, NULL, NULL, center_disk_cl );
220 upper_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
221 upper_ring_vl, NULL, NULL, upper_ring_cl );
223 middle_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
224 middle_ring_vl, NULL, NULL, middle_ring_cl );
226 lower_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
227 lower_ring_vl, NULL, NULL, lower_ring_cl );
229 center_disk->setState( dome_state );
230 upper_ring->setState( dome_state );
231 middle_ring->setState( dome_state );
232 lower_ring->setState( dome_state );
234 dome_transform->addKid( center_disk );
235 dome_transform->addKid( upper_ring );
236 dome_transform->addKid( middle_ring );
237 dome_transform->addKid( lower_ring );
239 dome_selector->addKid( dome_transform );
240 dome_selector->clrTraversalMaskBits( SSGTRAV_HOT );
242 dome->addKid( dome_selector );
248 // repaint the sky colors based on current value of sun_angle, sky,
249 // and fog colors. This updates the color arrays for ssgVtxTable.
250 // sun angle in degrees relative to verticle
251 // 0 degrees = high noon
252 // 90 degrees = sun rise/set
253 // 180 degrees = darkest midnight
254 bool FGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle )
257 sgVec3 outer_param, outer_amt, outer_diff;
258 sgVec3 middle_param, middle_amt, middle_diff;
261 // Check for sunrise/sunset condition
262 if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) {
264 sgSetVec3( outer_param,
265 (10.0 - fabs(90.0 - sun_angle)) / 20.0,
266 (10.0 - fabs(90.0 - sun_angle)) / 40.0,
267 -(10.0 - fabs(90.0 - sun_angle)) / 30.0 );
269 sgSetVec3( middle_param,
270 (10.0 - fabs(90.0 - sun_angle)) / 40.0,
271 (10.0 - fabs(90.0 - sun_angle)) / 80.0,
274 sgScaleVec3( outer_diff, outer_param, 1.0 / 6.0 );
276 sgScaleVec3( middle_diff, middle_param, 1.0 / 6.0 );
278 sgSetVec3( outer_param, 0.0, 0.0, 0.0 );
279 sgSetVec3( middle_param, 0.0, 0.0, 0.0 );
281 sgSetVec3( outer_diff, 0.0, 0.0, 0.0 );
282 sgSetVec3( middle_diff, 0.0, 0.0, 0.0 );
284 // printf(" outer_red_param = %.2f outer_red_diff = %.2f\n",
285 // outer_red_param, outer_red_diff);
287 // calculate transition colors between sky and fog
288 sgCopyVec3( outer_amt, outer_param );
289 sgCopyVec3( middle_amt, middle_param );
292 // First, recalulate the basic colors
295 sgVec4 upper_color[12];
296 sgVec4 middle_color[12];
297 sgVec4 lower_color[12];
298 sgVec4 bottom_color[12];
300 for ( i = 0; i < 6; i++ ) {
301 for ( j = 0; j < 3; j++ ) {
302 diff = sky_color[j] - fog_color[j];
304 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
305 // l->sky_color[j], l->fog_color[j], diff);
307 upper_color[i][j] = sky_color[j] - diff * 0.3;
308 middle_color[i][j] = sky_color[j] - diff * 0.9 + middle_amt[j];
309 lower_color[i][j] = fog_color[j] + outer_amt[j];
311 if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
312 if ( upper_color[i][j] < 0.1 ) { upper_color[i][j] = 0.1; }
313 if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
314 if ( middle_color[i][j] < 0.1 ) { middle_color[i][j] = 0.1; }
315 if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
316 if ( lower_color[i][j] < 0.1 ) { lower_color[i][j] = 0.1; }
318 upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0;
320 for ( j = 0; j < 3; j++ ) {
321 outer_amt[j] -= outer_diff[j];
322 middle_amt[j] -= middle_diff[j];
326 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
327 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
328 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
329 middle_color[i][0], middle_color[i][1], middle_color[i][2],
331 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
332 lower_color[i][0], lower_color[i][1], lower_color[i][2],
337 sgSetVec3( outer_amt, 0.0, 0.0, 0.0 );
338 sgSetVec3( middle_amt, 0.0, 0.0, 0.0 );
340 for ( i = 6; i < 12; i++ ) {
341 for ( j = 0; j < 3; j++ ) {
342 diff = sky_color[j] - fog_color[j];
344 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
345 // sky_color[j], fog_color[j], diff);
347 upper_color[i][j] = sky_color[j] - diff * 0.3;
348 middle_color[i][j] = sky_color[j] - diff * 0.9 + middle_amt[j];
349 lower_color[i][j] = fog_color[j] + outer_amt[j];
351 if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
352 if ( upper_color[i][j] < 0.1 ) { upper_color[i][j] = 0.1; }
353 if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
354 if ( middle_color[i][j] < 0.1 ) { middle_color[i][j] = 0.1; }
355 if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
356 if ( lower_color[i][j] < 0.1 ) { lower_color[i][j] = 0.1; }
358 upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0;
360 for ( j = 0; j < 3; j++ ) {
361 outer_amt[j] += outer_diff[j];
362 middle_amt[j] += middle_diff[j];
366 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
367 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
368 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
369 middle_color[i][0], middle_color[i][1], middle_color[i][2],
371 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
372 lower_color[i][0], lower_color[i][1], lower_color[i][2],
377 for ( i = 0; i < 12; i++ ) {
378 sgCopyVec4( bottom_color[i], fog_color );
382 // Second, assign the basic colors to the object color arrays
388 // update the center disk color arrays
390 slot = center_disk_cl->get( counter++ );
392 // sgSetVec4( red, 1.0, 0.0, 0.0, 1.0 );
393 sgCopyVec4( slot, sky_color );
394 for ( i = 11; i >= 0; i-- ) {
395 slot = center_disk_cl->get( counter++ );
396 sgCopyVec4( slot, upper_color[i] );
398 slot = center_disk_cl->get( counter++ );
399 sgCopyVec4( slot, upper_color[11] );
401 // generate the upper ring
403 for ( i = 0; i < 12; i++ ) {
404 slot = upper_ring_cl->get( counter++ );
405 sgCopyVec4( slot, middle_color[i] );
407 slot = upper_ring_cl->get( counter++ );
408 sgCopyVec4( slot, upper_color[i] );
410 slot = upper_ring_cl->get( counter++ );
411 sgCopyVec4( slot, middle_color[0] );
413 slot = upper_ring_cl->get( counter++ );
414 sgCopyVec4( slot, upper_color[0] );
416 // generate middle ring
418 for ( i = 0; i < 12; i++ ) {
419 slot = middle_ring_cl->get( counter++ );
420 sgCopyVec4( slot, lower_color[i] );
422 slot = middle_ring_cl->get( counter++ );
423 sgCopyVec4( slot, middle_color[i] );
425 slot = middle_ring_cl->get( counter++ );
426 sgCopyVec4( slot, lower_color[0] );
428 slot = middle_ring_cl->get( counter++ );
429 sgCopyVec4( slot, middle_color[0] );
431 // generate lower ring
433 for ( i = 0; i < 12; i++ ) {
434 slot = lower_ring_cl->get( counter++ );
435 sgCopyVec4( slot, bottom_color[i] );
437 slot = lower_ring_cl->get( counter++ );
438 sgCopyVec4( slot, lower_color[i] );
440 slot = lower_ring_cl->get( counter++ );
441 sgCopyVec4( slot, bottom_color[0] );
443 slot = lower_ring_cl->get( counter++ );
444 sgCopyVec4( slot, lower_color[0] );
450 // reposition the sky at the specified origin and orientation
451 // lon specifies a rotation about the Z axis
452 // lat specifies a rotation about the new Y axis
453 // spin specifies a rotation about the new Z axis (and orients the
454 // sunrise/set effects
455 bool FGSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) {
456 sgMat4 T, LON, LAT, SPIN;
459 // Translate to view position
460 // Point3D zero_elev = current_view.get_cur_zero_elev();
461 // xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
462 sgMakeTransMat4( T, p );
464 // printf(" Translated to %.2f %.2f %.2f\n",
465 // zero_elev.x, zero_elev.y, zero_elev.z );
467 // Rotate to proper orientation
468 // printf(" lon = %.2f lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
469 // FG_Latitude * RAD_TO_DEG);
470 // xglRotatef( f->get_Longitude() * RAD_TO_DEG, 0.0, 0.0, 1.0 );
471 sgSetVec3( axis, 0.0, 0.0, 1.0 );
472 sgMakeRotMat4( LON, lon * RAD_TO_DEG, axis );
474 // xglRotatef( 90.0 - f->get_Latitude() * RAD_TO_DEG, 0.0, 1.0, 0.0 );
475 sgSetVec3( axis, 0.0, 1.0, 0.0 );
476 sgMakeRotMat4( LAT, 90.0 - lat * RAD_TO_DEG, axis );
478 // xglRotatef( l->sun_rotation * RAD_TO_DEG, 0.0, 0.0, 1.0 );
479 sgSetVec3( axis, 0.0, 0.0, 1.0 );
480 sgMakeRotMat4( SPIN, spin * RAD_TO_DEG, axis );
484 sgCopyMat4( TRANSFORM, T );
485 sgPreMultMat4( TRANSFORM, LON );
486 sgPreMultMat4( TRANSFORM, LAT );
487 sgPreMultMat4( TRANSFORM, SPIN );
490 sgSetCoord( &skypos, TRANSFORM );
492 dome_transform->setTransform( &skypos );
499 bool FGSkyDome::draw() {
500 ssgCullAndDraw( dome );
508 // depricated code from here to the end
511 // Calculate the sky structure vertices
512 void fgSkyVerticesInit() {
516 FG_LOG(FG_ASTRO, FG_INFO, " Generating the sky dome vertices.");
518 for ( i = 0; i < 12; i++ ) {
519 theta = (i * 30.0) * DEG_TO_RAD;
521 inner_vertex[i][0] = cos(theta) * UPPER_RADIUS;
522 inner_vertex[i][1] = sin(theta) * UPPER_RADIUS;
523 inner_vertex[i][2] = UPPER_ELEV;
525 // printf(" %.2f %.2f\n", cos(theta) * UPPER_RADIUS,
526 // sin(theta) * UPPER_RADIUS);
528 middle_vertex[i][0] = cos((double)theta) * MIDDLE_RADIUS;
529 middle_vertex[i][1] = sin((double)theta) * MIDDLE_RADIUS;
530 middle_vertex[i][2] = MIDDLE_ELEV;
532 outer_vertex[i][0] = cos((double)theta) * LOWER_RADIUS;
533 outer_vertex[i][1] = sin((double)theta) * LOWER_RADIUS;
534 outer_vertex[i][2] = LOWER_ELEV;
536 bottom_vertex[i][0] = cos((double)theta) * BOTTOM_RADIUS;
537 bottom_vertex[i][1] = sin((double)theta) * BOTTOM_RADIUS;
538 bottom_vertex[i][2] = BOTTOM_ELEV;
543 // (Re)calculate the sky colors at each vertex
544 void fgSkyColorsInit() {
546 double sun_angle, diff;
547 double outer_param[3], outer_amt[3], outer_diff[3];
548 double middle_param[3], middle_amt[3], middle_diff[3];
551 l = &cur_light_params;
553 FG_LOG( FG_ASTRO, FG_INFO,
554 " Generating the sky colors for each vertex." );
556 // setup for the possibility of sunset effects
557 sun_angle = l->sun_angle * RAD_TO_DEG;
558 // fgPrintf( FG_ASTRO, FG_INFO,
559 // " Sun angle in degrees = %.2f\n", sun_angle);
561 if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) {
563 outer_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 20.0;
564 outer_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
565 outer_param[2] = -(10.0 - fabs(90.0 - sun_angle)) / 30.0;
566 // outer_param[2] = 0.0;
568 middle_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
569 middle_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 80.0;
570 middle_param[2] = 0.0;
572 outer_diff[0] = outer_param[0] / 6.0;
573 outer_diff[1] = outer_param[1] / 6.0;
574 outer_diff[2] = outer_param[2] / 6.0;
576 middle_diff[0] = middle_param[0] / 6.0;
577 middle_diff[1] = middle_param[1] / 6.0;
578 middle_diff[2] = middle_param[2] / 6.0;
580 outer_param[0] = outer_param[1] = outer_param[2] = 0.0;
581 middle_param[0] = middle_param[1] = middle_param[2] = 0.0;
583 outer_diff[0] = outer_diff[1] = outer_diff[2] = 0.0;
584 middle_diff[0] = middle_diff[1] = middle_diff[2] = 0.0;
586 // printf(" outer_red_param = %.2f outer_red_diff = %.2f\n",
587 // outer_red_param, outer_red_diff);
589 // calculate transition colors between sky and fog
590 for ( j = 0; j < 3; j++ ) {
591 outer_amt[j] = outer_param[j];
592 middle_amt[j] = middle_param[j];
595 for ( i = 0; i < 6; i++ ) {
596 for ( j = 0; j < 3; j++ ) {
597 diff = l->sky_color[j] - l->fog_color[j];
599 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
600 // l->sky_color[j], l->fog_color[j], diff);
602 upper_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255);
603 middle_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.9
604 + middle_amt[j]) * 255);
605 lower_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j])
608 if ( upper_color[i][j] > 255 ) { upper_color[i][j] = 255; }
609 if ( upper_color[i][j] < 25 ) { upper_color[i][j] = 25; }
610 if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; }
611 if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; }
612 if ( lower_color[i][j] > 255 ) { lower_color[i][j] = 255; }
613 if ( lower_color[i][j] < 25 ) { lower_color[i][j] = 25; }
615 upper_color[i][3] = middle_color[i][3] = lower_color[i][3] =
616 (GLubyte)(l->sky_color[3] * 255);
618 for ( j = 0; j < 3; j++ ) {
619 outer_amt[j] -= outer_diff[j];
620 middle_amt[j] -= middle_diff[j];
624 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
625 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
626 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
627 middle_color[i][0], middle_color[i][1], middle_color[i][2],
629 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
630 lower_color[i][0], lower_color[i][1], lower_color[i][2],
635 for ( j = 0; j < 3; j++ ) {
640 for ( i = 6; i < 12; i++ ) {
642 for ( j = 0; j < 3; j++ ) {
643 diff = l->sky_color[j] - l->fog_color[j];
645 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
646 // l->sky_color[j], l->fog_color[j], diff);
648 upper_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255);
649 middle_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.9
650 + middle_amt[j]) * 255);
651 lower_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j])
654 if ( upper_color[i][j] > 255 ) { upper_color[i][j] = 255; }
655 if ( upper_color[i][j] < 25 ) { upper_color[i][j] = 25; }
656 if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; }
657 if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; }
658 if ( lower_color[i][j] > 255 ) { lower_color[i][j] = 255; }
659 if ( lower_color[i][j] < 35 ) { lower_color[i][j] = 35; }
661 upper_color[i][3] = middle_color[i][3] = lower_color[i][3] =
662 (GLubyte)(l->sky_color[3] * 255);
664 for ( j = 0; j < 3; j++ ) {
665 outer_amt[j] += outer_diff[j];
666 middle_amt[j] += middle_diff[j];
670 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
671 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
672 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
673 middle_color[i][0], middle_color[i][1], middle_color[i][2],
675 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
676 lower_color[i][0], lower_color[i][1], lower_color[i][2],
683 // Initialize the sky structure and colors
685 FG_LOG( FG_ASTRO, FG_INFO, "Initializing the sky" );
689 // regester fgSkyColorsInit() as an event to be run periodically
690 global_events.Register( "fgSkyColorsInit()", fgSkyColorsInit,
691 fgEVENT::FG_EVENT_READY, 30000);
699 GLubyte sky_color[4];
700 GLubyte upper_color[4];
701 GLubyte middle_color[4];
702 GLubyte lower_color[4];
706 f = current_aircraft.fdm_state;
707 l = &cur_light_params;
709 // printf("Rendering the sky.\n");
711 // calculate the proper colors
712 for ( i = 0; i < 3; i++ ) {
713 diff = l->sky_color[i] - l->adj_fog_color[i];
715 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
716 // l->sky_color[j], l->adj_fog_color[j], diff);
718 upper_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.3) * 255);
719 middle_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.9) * 255);
720 lower_color[i] = (GLubyte)(l->adj_fog_color[i] * 255);
722 upper_color[3] = middle_color[3] = lower_color[3] =
723 (GLubyte)(l->adj_fog_color[3] * 255);
727 // Translate to view position
728 Point3D zero_elev = current_view.get_cur_zero_elev();
729 xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
730 // printf(" Translated to %.2f %.2f %.2f\n",
731 // zero_elev.x, zero_elev.y, zero_elev.z );
733 // Rotate to proper orientation
734 // printf(" lon = %.2f lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
735 // FG_Latitude * RAD_TO_DEG);
736 xglRotatef( f->get_Longitude() * RAD_TO_DEG, 0.0, 0.0, 1.0 );
737 xglRotatef( 90.0 - f->get_Latitude() * RAD_TO_DEG, 0.0, 1.0, 0.0 );
738 xglRotatef( l->sun_rotation * RAD_TO_DEG, 0.0, 0.0, 1.0 );
740 // Draw inner/center section of sky*/
741 xglBegin( GL_TRIANGLE_FAN );
742 for ( i = 0; i < 4; i++ ) {
743 sky_color[i] = (GLubyte)(l->sky_color[i] * 255);
745 xglColor4fv(l->sky_color);
746 xglVertex3f(0.0, 0.0, CENTER_ELEV);
747 for ( i = 11; i >= 0; i-- ) {
748 xglColor4ubv( upper_color );
749 xglVertex3fv( inner_vertex[i] );
751 xglColor4ubv( upper_color );
752 xglVertex3fv( inner_vertex[11] );
755 // Draw the middle ring
756 xglBegin( GL_TRIANGLE_STRIP );
757 for ( i = 0; i < 12; i++ ) {
758 xglColor4ubv( middle_color );
759 // printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
760 // middle_color[i][0], middle_color[i][1], middle_color[i][2],
761 // middle_color[i][3]);
762 // xglColor4f(1.0, 0.0, 0.0, 1.0);
763 xglVertex3fv( middle_vertex[i] );
764 xglColor4ubv( upper_color );
765 // printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i,
766 // upper_color[i][0], upper_color[i][1], upper_color[i][2],
767 // upper_color[i][3]);
768 // xglColor4f(0.0, 0.0, 1.0, 1.0);
769 xglVertex3fv( inner_vertex[i] );
771 xglColor4ubv( middle_color );
772 // xglColor4f(1.0, 0.0, 0.0, 1.0);
773 xglVertex3fv( middle_vertex[0] );
774 xglColor4ubv( upper_color );
775 // xglColor4f(0.0, 0.0, 1.0, 1.0);
776 xglVertex3fv( inner_vertex[0] );
779 // Draw the outer ring
780 xglBegin( GL_TRIANGLE_STRIP );
781 for ( i = 0; i < 12; i++ ) {
782 xglColor4ubv( lower_color );
783 xglVertex3fv( outer_vertex[i] );
784 xglColor4ubv( middle_color );
785 xglVertex3fv( middle_vertex[i] );
787 xglColor4ubv( lower_color );
788 xglVertex3fv( outer_vertex[0] );
789 xglColor4ubv( middle_color );
790 xglVertex3fv( middle_vertex[0] );
793 // Draw the bottom skirt
794 xglBegin( GL_TRIANGLE_STRIP );
795 xglColor4ubv( lower_color );
796 for ( i = 0; i < 12; i++ ) {
797 xglVertex3fv( bottom_vertex[i] );
798 xglVertex3fv( outer_vertex[i] );
800 xglVertex3fv( bottom_vertex[0] );
801 xglVertex3fv( outer_vertex[0] );