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
72 // static float inner_vertex[12][3];
73 // static float middle_vertex[12][3];
74 // static float outer_vertex[12][3];
75 // static float bottom_vertex[12][3];
77 // static GLubyte upper_color[12][4];
78 // static GLubyte middle_color[12][4];
79 // static GLubyte lower_color[12][4];
82 // Defined the shared sky object here
83 FGSkyDome current_sky;
87 FGSkyDome::FGSkyDome( void ) {
92 FGSkyDome::~FGSkyDome( void ) {
96 // initialize the sky object and connect it into our scene graph
97 bool FGSkyDome::initialize( ) {
103 // create the scene graph for the dome
105 dome->setName( "Sky Dome" );
108 dome_state = new ssgSimpleState();
109 dome_state->setShadeModel( GL_SMOOTH );
110 dome_state->disable( GL_LIGHTING );
111 dome_state->disable( GL_DEPTH_TEST );
112 dome_state->disable( GL_CULL_FACE );
113 dome_state->disable( GL_TEXTURE_2D );
114 dome_state->enable( GL_COLOR_MATERIAL );
115 dome_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
118 center_disk_vl = new ssgVertexArray( 14 );
119 center_disk_cl = new ssgColourArray( 14 );
121 upper_ring_vl = new ssgVertexArray( 26 );
122 upper_ring_cl = new ssgColourArray( 26 );
124 middle_ring_vl = new ssgVertexArray( 26 );
125 middle_ring_cl = new ssgColourArray( 26 );
127 lower_ring_vl = new ssgVertexArray( 26 );
128 lower_ring_cl = new ssgColourArray( 26 );
130 // initially seed to all blue
131 sgSetVec3( color, 0.0, 0.0, 1.0 );
133 // generate the raw vertex data
134 sgVec3 center_vertex;
135 sgVec3 upper_vertex[12];
136 sgVec3 middle_vertex[12];
137 sgVec3 lower_vertex[12];
138 sgVec3 bottom_vertex[12];
140 sgSetVec3( center_vertex, 0.0, 0.0, CENTER_ELEV );
142 for ( i = 0; i < 12; i++ ) {
143 theta = (i * 30.0) * DEG_TO_RAD;
145 sgSetVec3( upper_vertex[i],
146 cos(theta) * UPPER_RADIUS,
147 sin(theta) * UPPER_RADIUS,
150 sgSetVec3( middle_vertex[i],
151 cos((double)theta) * MIDDLE_RADIUS,
152 sin((double)theta) * MIDDLE_RADIUS,
155 sgSetVec3( lower_vertex[i],
156 cos((double)theta) * LOWER_RADIUS,
157 sin((double)theta) * LOWER_RADIUS,
160 sgSetVec3( bottom_vertex[i],
161 cos((double)theta) * BOTTOM_RADIUS,
162 sin((double)theta) * BOTTOM_RADIUS,
166 // generate the center disk vertex/color arrays
167 center_disk_vl->add( center_vertex );
168 center_disk_cl->add( color );
169 for ( i = 11; i >= 0; i-- ) {
170 center_disk_vl->add( upper_vertex[i] );
171 center_disk_cl->add( color );
173 center_disk_vl->add( upper_vertex[11] );
174 center_disk_cl->add( color );
176 // generate the upper ring
177 for ( i = 0; i < 12; i++ ) {
178 upper_ring_vl->add( middle_vertex[i] );
179 upper_ring_cl->add( color );
181 upper_ring_vl->add( upper_vertex[i] );
182 upper_ring_cl->add( color );
184 upper_ring_vl->add( middle_vertex[0] );
185 upper_ring_cl->add( color );
187 upper_ring_vl->add( upper_vertex[0] );
188 upper_ring_cl->add( color );
190 // generate middle ring
191 for ( i = 0; i < 12; i++ ) {
192 middle_ring_vl->add( lower_vertex[i] );
193 middle_ring_cl->add( color );
195 middle_ring_vl->add( middle_vertex[i] );
196 middle_ring_cl->add( color );
198 middle_ring_vl->add( lower_vertex[0] );
199 middle_ring_cl->add( color );
201 middle_ring_vl->add( middle_vertex[0] );
202 middle_ring_cl->add( color );
204 // generate lower ring
205 for ( i = 0; i < 12; i++ ) {
206 lower_ring_vl->add( bottom_vertex[i] );
207 lower_ring_cl->add( color );
209 lower_ring_vl->add( lower_vertex[i] );
210 lower_ring_cl->add( color );
212 lower_ring_vl->add( bottom_vertex[0] );
213 lower_ring_cl->add( color );
215 lower_ring_vl->add( lower_vertex[0] );
216 lower_ring_cl->add( color );
218 // force a repaint of the sky colors with ugly defaults
220 sgSetVec3( fog_color, 1.0, 1.0, 1.0 );
221 repaint( color, fog_color, 0.0 );
223 // build the ssg scene graph sub tree for the sky and connected
224 // into the provide scene graph branch
225 dome_selector = new ssgSelector;
226 dome_transform = new ssgTransform;
228 ssgVtxTable *center_disk, *upper_ring, *middle_ring, *lower_ring;
230 center_disk = new ssgVtxTable( GL_TRIANGLE_FAN,
231 center_disk_vl, NULL, NULL, center_disk_cl );
233 upper_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
234 upper_ring_vl, NULL, NULL, upper_ring_cl );
236 middle_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
237 middle_ring_vl, NULL, NULL, middle_ring_cl );
239 lower_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
240 lower_ring_vl, NULL, NULL, lower_ring_cl );
242 center_disk->setState( dome_state );
243 upper_ring->setState( dome_state );
244 middle_ring->setState( dome_state );
245 lower_ring->setState( dome_state );
247 dome_transform->addKid( center_disk );
248 dome_transform->addKid( upper_ring );
249 dome_transform->addKid( middle_ring );
250 dome_transform->addKid( lower_ring );
252 dome_selector->addKid( dome_transform );
253 dome_selector->clrTraversalMaskBits( SSGTRAV_HOT );
255 dome->addKid( dome_selector );
261 // repaint the sky colors based on current value of sun_angle, sky,
262 // and fog colors. This updates the color arrays for ssgVtxTable.
263 // sun angle in degrees relative to verticle
264 // 0 degrees = high noon
265 // 90 degrees = sun rise/set
266 // 180 degrees = darkest midnight
267 bool FGSkyDome::repaint( sgVec3 sky_color, sgVec3 fog_color, double sun_angle ) {
269 sgVec3 outer_param, outer_amt, outer_diff;
270 sgVec3 middle_param, middle_amt, middle_diff;
273 // Check for sunrise/sunset condition
274 if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) {
276 sgSetVec3( outer_param,
277 (10.0 - fabs(90.0 - sun_angle)) / 20.0,
278 (10.0 - fabs(90.0 - sun_angle)) / 40.0,
279 -(10.0 - fabs(90.0 - sun_angle)) / 30.0 );
281 sgSetVec3( middle_param,
282 (10.0 - fabs(90.0 - sun_angle)) / 40.0,
283 (10.0 - fabs(90.0 - sun_angle)) / 80.0,
286 sgScaleVec3( outer_diff, outer_param, 1.0 / 6.0 );
288 sgScaleVec3( middle_diff, middle_param, 1.0 / 6.0 );
290 sgSetVec3( outer_param, 0.0, 0.0, 0.0 );
291 sgSetVec3( middle_param, 0.0, 0.0, 0.0 );
293 sgSetVec3( outer_diff, 0.0, 0.0, 0.0 );
294 sgSetVec3( middle_diff, 0.0, 0.0, 0.0 );
296 // printf(" outer_red_param = %.2f outer_red_diff = %.2f\n",
297 // outer_red_param, outer_red_diff);
299 // calculate transition colors between sky and fog
300 sgCopyVec3( outer_amt, outer_param );
301 sgCopyVec3( middle_amt, middle_param );
304 // First, recalulate the basic colors
307 sgVec3 upper_color[12];
308 sgVec3 middle_color[12];
309 sgVec3 lower_color[12];
310 sgVec3 bottom_color[12];
312 for ( i = 0; i < 6; i++ ) {
313 for ( j = 0; j < 3; j++ ) {
314 diff = sky_color[j] - fog_color[j];
316 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
317 // l->sky_color[j], l->fog_color[j], diff);
319 upper_color[i][j] = sky_color[j] - diff * 0.3;
320 middle_color[i][j] = sky_color[j] - diff * 0.9 + middle_amt[j];
321 lower_color[i][j] = fog_color[j] + outer_amt[j];
323 if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
324 if ( upper_color[i][j] < 0.1 ) { upper_color[i][j] = 0.1; }
325 if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
326 if ( middle_color[i][j] < 0.1 ) { middle_color[i][j] = 0.1; }
327 if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
328 if ( lower_color[i][j] < 0.1 ) { lower_color[i][j] = 0.1; }
330 // upper_color[i][3] = middle_color[i][3] = lower_color[i][3] =
331 // (GLubyte)(sky_color[3] * 1.0);
333 for ( j = 0; j < 3; j++ ) {
334 outer_amt[j] -= outer_diff[j];
335 middle_amt[j] -= middle_diff[j];
339 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
340 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
341 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
342 middle_color[i][0], middle_color[i][1], middle_color[i][2],
344 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
345 lower_color[i][0], lower_color[i][1], lower_color[i][2],
350 sgSetVec3( outer_amt, 0.0, 0.0, 0.0 );
351 sgSetVec3( middle_amt, 0.0, 0.0, 0.0 );
353 for ( i = 6; i < 12; i++ ) {
354 for ( j = 0; j < 3; j++ ) {
355 diff = sky_color[j] - fog_color[j];
357 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
358 // sky_color[j], fog_color[j], diff);
360 upper_color[i][j] = sky_color[j] - diff * 0.3;
361 middle_color[i][j] = sky_color[j] - diff * 0.9 + middle_amt[j];
362 lower_color[i][j] = fog_color[j] + outer_amt[j];
364 if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
365 if ( upper_color[i][j] < 0.1 ) { upper_color[i][j] = 0.1; }
366 if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
367 if ( middle_color[i][j] < 0.1 ) { middle_color[i][j] = 0.1; }
368 if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
369 if ( lower_color[i][j] < 35 ) { lower_color[i][j] = 35; }
371 // upper_color[i][3] = middle_color[i][3] = lower_color[i][3] =
372 // (GLubyte)(sky_color[3] * 1.0);
374 for ( j = 0; j < 3; j++ ) {
375 outer_amt[j] += outer_diff[j];
376 middle_amt[j] += middle_diff[j];
380 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
381 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
382 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
383 middle_color[i][0], middle_color[i][1], middle_color[i][2],
385 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
386 lower_color[i][0], lower_color[i][1], lower_color[i][2],
391 for ( i = 0; i < 12; i++ ) {
392 sgCopyVec3( bottom_color[i], fog_color );
396 // Second, assign the basic colors to the object color arrays
402 // update the center disk color arrays
404 slot = center_disk_cl->get( counter++ );
406 // sgSetVec3( red, 1.0, 0.0, 0.0 );
407 sgCopyVec3( slot, sky_color );
408 for ( i = 11; i >= 0; i-- ) {
409 slot = center_disk_cl->get( counter++ );
410 sgCopyVec3( slot, upper_color[i] );
412 slot = center_disk_cl->get( counter++ );
413 sgCopyVec3( slot, upper_color[11] );
415 // generate the upper ring
417 for ( i = 0; i < 12; i++ ) {
418 slot = upper_ring_cl->get( counter++ );
419 sgCopyVec3( slot, middle_color[i] );
421 slot = upper_ring_cl->get( counter++ );
422 sgCopyVec3( slot, upper_color[i] );
424 slot = upper_ring_cl->get( counter++ );
425 sgCopyVec3( slot, middle_color[0] );
427 slot = upper_ring_cl->get( counter++ );
428 sgCopyVec3( slot, upper_color[0] );
430 // generate middle ring
432 for ( i = 0; i < 12; i++ ) {
433 slot = middle_ring_cl->get( counter++ );
434 sgCopyVec3( slot, lower_color[i] );
436 slot = middle_ring_cl->get( counter++ );
437 sgCopyVec3( slot, middle_color[i] );
439 slot = middle_ring_cl->get( counter++ );
440 sgCopyVec3( slot, lower_color[0] );
442 slot = middle_ring_cl->get( counter++ );
443 sgCopyVec3( slot, middle_color[0] );
445 // generate lower ring
447 for ( i = 0; i < 12; i++ ) {
448 slot = lower_ring_cl->get( counter++ );
449 sgCopyVec3( slot, bottom_color[i] );
451 slot = lower_ring_cl->get( counter++ );
452 sgCopyVec3( slot, lower_color[i] );
454 slot = lower_ring_cl->get( counter++ );
455 sgCopyVec3( slot, bottom_color[0] );
457 slot = lower_ring_cl->get( counter++ );
458 sgCopyVec3( slot, lower_color[0] );
464 // reposition the sky at the specified origin and orientation
465 // lon specifies a rotation about the Z axis
466 // lat specifies a rotation about the new Y axis
467 // spin specifies a rotation about the new Z axis (and orients the
468 // sunrise/set effects
469 bool FGSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) {
470 sgMat4 T, LON, LAT, SPIN;
473 // Translate to view position
474 // Point3D zero_elev = current_view.get_cur_zero_elev();
475 // xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
476 sgMakeTransMat4( T, p );
478 // printf(" Translated to %.2f %.2f %.2f\n",
479 // zero_elev.x, zero_elev.y, zero_elev.z );
481 // Rotate to proper orientation
482 // printf(" lon = %.2f lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
483 // FG_Latitude * RAD_TO_DEG);
484 // xglRotatef( f->get_Longitude() * RAD_TO_DEG, 0.0, 0.0, 1.0 );
485 sgSetVec3( axis, 0.0, 0.0, 1.0 );
486 sgMakeRotMat4( LON, lon * RAD_TO_DEG, axis );
488 // xglRotatef( 90.0 - f->get_Latitude() * RAD_TO_DEG, 0.0, 1.0, 0.0 );
489 sgSetVec3( axis, 0.0, 1.0, 0.0 );
490 sgMakeRotMat4( LAT, 90.0 - lat * RAD_TO_DEG, axis );
492 // xglRotatef( l->sun_rotation * RAD_TO_DEG, 0.0, 0.0, 1.0 );
493 sgSetVec3( axis, 0.0, 0.0, 1.0 );
494 sgMakeRotMat4( SPIN, spin * RAD_TO_DEG, axis );
498 sgCopyMat4( TRANSFORM, T );
499 sgPreMultMat4( TRANSFORM, LON );
500 sgPreMultMat4( TRANSFORM, LAT );
501 sgPreMultMat4( TRANSFORM, SPIN );
504 sgSetCoord( &skypos, TRANSFORM );
506 dome_transform->setTransform( &skypos );
513 bool FGSkyDome::draw() {
514 ssgCullAndDraw( dome );
522 // depricated code from here to the end
525 // Calculate the sky structure vertices
526 void fgSkyVerticesInit() {
530 FG_LOG(FG_ASTRO, FG_INFO, " Generating the sky dome vertices.");
532 for ( i = 0; i < 12; i++ ) {
533 theta = (i * 30.0) * DEG_TO_RAD;
535 inner_vertex[i][0] = cos(theta) * UPPER_RADIUS;
536 inner_vertex[i][1] = sin(theta) * UPPER_RADIUS;
537 inner_vertex[i][2] = UPPER_ELEV;
539 // printf(" %.2f %.2f\n", cos(theta) * UPPER_RADIUS,
540 // sin(theta) * UPPER_RADIUS);
542 middle_vertex[i][0] = cos((double)theta) * MIDDLE_RADIUS;
543 middle_vertex[i][1] = sin((double)theta) * MIDDLE_RADIUS;
544 middle_vertex[i][2] = MIDDLE_ELEV;
546 outer_vertex[i][0] = cos((double)theta) * LOWER_RADIUS;
547 outer_vertex[i][1] = sin((double)theta) * LOWER_RADIUS;
548 outer_vertex[i][2] = LOWER_ELEV;
550 bottom_vertex[i][0] = cos((double)theta) * BOTTOM_RADIUS;
551 bottom_vertex[i][1] = sin((double)theta) * BOTTOM_RADIUS;
552 bottom_vertex[i][2] = BOTTOM_ELEV;
557 // (Re)calculate the sky colors at each vertex
558 void fgSkyColorsInit() {
560 double sun_angle, diff;
561 double outer_param[3], outer_amt[3], outer_diff[3];
562 double middle_param[3], middle_amt[3], middle_diff[3];
565 l = &cur_light_params;
567 FG_LOG( FG_ASTRO, FG_INFO,
568 " Generating the sky colors for each vertex." );
570 // setup for the possibility of sunset effects
571 sun_angle = l->sun_angle * RAD_TO_DEG;
572 // fgPrintf( FG_ASTRO, FG_INFO,
573 // " Sun angle in degrees = %.2f\n", sun_angle);
575 if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) {
577 outer_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 20.0;
578 outer_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
579 outer_param[2] = -(10.0 - fabs(90.0 - sun_angle)) / 30.0;
580 // outer_param[2] = 0.0;
582 middle_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
583 middle_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 80.0;
584 middle_param[2] = 0.0;
586 outer_diff[0] = outer_param[0] / 6.0;
587 outer_diff[1] = outer_param[1] / 6.0;
588 outer_diff[2] = outer_param[2] / 6.0;
590 middle_diff[0] = middle_param[0] / 6.0;
591 middle_diff[1] = middle_param[1] / 6.0;
592 middle_diff[2] = middle_param[2] / 6.0;
594 outer_param[0] = outer_param[1] = outer_param[2] = 0.0;
595 middle_param[0] = middle_param[1] = middle_param[2] = 0.0;
597 outer_diff[0] = outer_diff[1] = outer_diff[2] = 0.0;
598 middle_diff[0] = middle_diff[1] = middle_diff[2] = 0.0;
600 // printf(" outer_red_param = %.2f outer_red_diff = %.2f\n",
601 // outer_red_param, outer_red_diff);
603 // calculate transition colors between sky and fog
604 for ( j = 0; j < 3; j++ ) {
605 outer_amt[j] = outer_param[j];
606 middle_amt[j] = middle_param[j];
609 for ( i = 0; i < 6; i++ ) {
610 for ( j = 0; j < 3; j++ ) {
611 diff = l->sky_color[j] - l->fog_color[j];
613 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
614 // l->sky_color[j], l->fog_color[j], diff);
616 upper_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255);
617 middle_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.9
618 + middle_amt[j]) * 255);
619 lower_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j])
622 if ( upper_color[i][j] > 255 ) { upper_color[i][j] = 255; }
623 if ( upper_color[i][j] < 25 ) { upper_color[i][j] = 25; }
624 if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; }
625 if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; }
626 if ( lower_color[i][j] > 255 ) { lower_color[i][j] = 255; }
627 if ( lower_color[i][j] < 25 ) { lower_color[i][j] = 25; }
629 upper_color[i][3] = middle_color[i][3] = lower_color[i][3] =
630 (GLubyte)(l->sky_color[3] * 255);
632 for ( j = 0; j < 3; j++ ) {
633 outer_amt[j] -= outer_diff[j];
634 middle_amt[j] -= middle_diff[j];
638 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
639 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
640 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
641 middle_color[i][0], middle_color[i][1], middle_color[i][2],
643 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
644 lower_color[i][0], lower_color[i][1], lower_color[i][2],
649 for ( j = 0; j < 3; j++ ) {
654 for ( i = 6; i < 12; i++ ) {
656 for ( j = 0; j < 3; j++ ) {
657 diff = l->sky_color[j] - l->fog_color[j];
659 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
660 // l->sky_color[j], l->fog_color[j], diff);
662 upper_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255);
663 middle_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.9
664 + middle_amt[j]) * 255);
665 lower_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j])
668 if ( upper_color[i][j] > 255 ) { upper_color[i][j] = 255; }
669 if ( upper_color[i][j] < 25 ) { upper_color[i][j] = 25; }
670 if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; }
671 if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; }
672 if ( lower_color[i][j] > 255 ) { lower_color[i][j] = 255; }
673 if ( lower_color[i][j] < 35 ) { lower_color[i][j] = 35; }
675 upper_color[i][3] = middle_color[i][3] = lower_color[i][3] =
676 (GLubyte)(l->sky_color[3] * 255);
678 for ( j = 0; j < 3; j++ ) {
679 outer_amt[j] += outer_diff[j];
680 middle_amt[j] += middle_diff[j];
684 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
685 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
686 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
687 middle_color[i][0], middle_color[i][1], middle_color[i][2],
689 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
690 lower_color[i][0], lower_color[i][1], lower_color[i][2],
697 // Initialize the sky structure and colors
699 FG_LOG( FG_ASTRO, FG_INFO, "Initializing the sky" );
703 // regester fgSkyColorsInit() as an event to be run periodically
704 global_events.Register( "fgSkyColorsInit()", fgSkyColorsInit,
705 fgEVENT::FG_EVENT_READY, 30000);
713 GLubyte sky_color[4];
714 GLubyte upper_color[4];
715 GLubyte middle_color[4];
716 GLubyte lower_color[4];
720 f = current_aircraft.fdm_state;
721 l = &cur_light_params;
723 // printf("Rendering the sky.\n");
725 // calculate the proper colors
726 for ( i = 0; i < 3; i++ ) {
727 diff = l->sky_color[i] - l->adj_fog_color[i];
729 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
730 // l->sky_color[j], l->adj_fog_color[j], diff);
732 upper_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.3) * 255);
733 middle_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.9) * 255);
734 lower_color[i] = (GLubyte)(l->adj_fog_color[i] * 255);
736 upper_color[3] = middle_color[3] = lower_color[3] =
737 (GLubyte)(l->adj_fog_color[3] * 255);
741 // Translate to view position
742 Point3D zero_elev = current_view.get_cur_zero_elev();
743 xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
744 // printf(" Translated to %.2f %.2f %.2f\n",
745 // zero_elev.x, zero_elev.y, zero_elev.z );
747 // Rotate to proper orientation
748 // printf(" lon = %.2f lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
749 // FG_Latitude * RAD_TO_DEG);
750 xglRotatef( f->get_Longitude() * RAD_TO_DEG, 0.0, 0.0, 1.0 );
751 xglRotatef( 90.0 - f->get_Latitude() * RAD_TO_DEG, 0.0, 1.0, 0.0 );
752 xglRotatef( l->sun_rotation * RAD_TO_DEG, 0.0, 0.0, 1.0 );
754 // Draw inner/center section of sky*/
755 xglBegin( GL_TRIANGLE_FAN );
756 for ( i = 0; i < 4; i++ ) {
757 sky_color[i] = (GLubyte)(l->sky_color[i] * 255);
759 xglColor4fv(l->sky_color);
760 xglVertex3f(0.0, 0.0, CENTER_ELEV);
761 for ( i = 11; i >= 0; i-- ) {
762 xglColor4ubv( upper_color );
763 xglVertex3fv( inner_vertex[i] );
765 xglColor4ubv( upper_color );
766 xglVertex3fv( inner_vertex[11] );
769 // Draw the middle ring
770 xglBegin( GL_TRIANGLE_STRIP );
771 for ( i = 0; i < 12; i++ ) {
772 xglColor4ubv( middle_color );
773 // printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
774 // middle_color[i][0], middle_color[i][1], middle_color[i][2],
775 // middle_color[i][3]);
776 // xglColor4f(1.0, 0.0, 0.0, 1.0);
777 xglVertex3fv( middle_vertex[i] );
778 xglColor4ubv( upper_color );
779 // printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i,
780 // upper_color[i][0], upper_color[i][1], upper_color[i][2],
781 // upper_color[i][3]);
782 // xglColor4f(0.0, 0.0, 1.0, 1.0);
783 xglVertex3fv( inner_vertex[i] );
785 xglColor4ubv( middle_color );
786 // xglColor4f(1.0, 0.0, 0.0, 1.0);
787 xglVertex3fv( middle_vertex[0] );
788 xglColor4ubv( upper_color );
789 // xglColor4f(0.0, 0.0, 1.0, 1.0);
790 xglVertex3fv( inner_vertex[0] );
793 // Draw the outer ring
794 xglBegin( GL_TRIANGLE_STRIP );
795 for ( i = 0; i < 12; i++ ) {
796 xglColor4ubv( lower_color );
797 xglVertex3fv( outer_vertex[i] );
798 xglColor4ubv( middle_color );
799 xglVertex3fv( middle_vertex[i] );
801 xglColor4ubv( lower_color );
802 xglVertex3fv( outer_vertex[0] );
803 xglColor4ubv( middle_color );
804 xglVertex3fv( middle_vertex[0] );
807 // Draw the bottom skirt
808 xglBegin( GL_TRIANGLE_STRIP );
809 xglColor4ubv( lower_color );
810 for ( i = 0; i < 12; i++ ) {
811 xglVertex3fv( bottom_vertex[i] );
812 xglVertex3fv( outer_vertex[i] );
814 xglVertex3fv( bottom_vertex[0] );
815 xglVertex3fv( outer_vertex[0] );