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];
83 FGSkyDome::FGSkyDome( void ) {
88 FGSkyDome::~FGSkyDome( void ) {
92 // initialize the sky object and connect it into our scene graph
93 bool FGSkyDome::initialize( ) {
99 // create the scene graph for the dome
101 dome->setName( "Sky Dome" );
104 dome_state = new ssgSimpleState();
105 dome_state->setShadeModel( GL_SMOOTH );
106 dome_state->disable( GL_LIGHTING );
107 dome_state->disable( GL_DEPTH_TEST );
108 dome_state->disable( GL_CULL_FACE );
109 dome_state->disable( GL_TEXTURE_2D );
110 dome_state->enable( GL_COLOR_MATERIAL );
111 dome_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
114 center_disk_vl = new ssgVertexArray( 14 );
115 center_disk_cl = new ssgColourArray( 14 );
117 upper_ring_vl = new ssgVertexArray( 26 );
118 upper_ring_cl = new ssgColourArray( 26 );
120 middle_ring_vl = new ssgVertexArray( 26 );
121 middle_ring_cl = new ssgColourArray( 26 );
123 lower_ring_vl = new ssgVertexArray( 26 );
124 lower_ring_cl = new ssgColourArray( 26 );
126 // initially seed to all blue
127 sgSetVec3( color, 0.0, 0.0, 1.0 );
129 // generate the raw vertex data
130 sgVec3 center_vertex;
131 sgVec3 upper_vertex[12];
132 sgVec3 middle_vertex[12];
133 sgVec3 lower_vertex[12];
134 sgVec3 bottom_vertex[12];
136 sgSetVec3( center_vertex, 0.0, 0.0, CENTER_ELEV );
138 for ( i = 0; i < 12; i++ ) {
139 theta = (i * 30.0) * DEG_TO_RAD;
141 sgSetVec3( upper_vertex[i],
142 cos(theta) * UPPER_RADIUS,
143 sin(theta) * UPPER_RADIUS,
146 sgSetVec3( middle_vertex[i],
147 cos((double)theta) * MIDDLE_RADIUS,
148 sin((double)theta) * MIDDLE_RADIUS,
151 sgSetVec3( lower_vertex[i],
152 cos((double)theta) * LOWER_RADIUS,
153 sin((double)theta) * LOWER_RADIUS,
156 sgSetVec3( bottom_vertex[i],
157 cos((double)theta) * BOTTOM_RADIUS,
158 sin((double)theta) * BOTTOM_RADIUS,
162 // generate the center disk vertex/color arrays
163 center_disk_vl->add( center_vertex );
164 center_disk_cl->add( color );
165 for ( i = 11; i >= 0; i-- ) {
166 center_disk_vl->add( upper_vertex[i] );
167 center_disk_cl->add( color );
169 center_disk_vl->add( upper_vertex[11] );
170 center_disk_cl->add( color );
172 // generate the upper ring
173 for ( i = 0; i < 12; i++ ) {
174 upper_ring_vl->add( middle_vertex[i] );
175 upper_ring_cl->add( color );
177 upper_ring_vl->add( upper_vertex[i] );
178 upper_ring_cl->add( color );
180 upper_ring_vl->add( middle_vertex[0] );
181 upper_ring_cl->add( color );
183 upper_ring_vl->add( upper_vertex[0] );
184 upper_ring_cl->add( color );
186 // generate middle ring
187 for ( i = 0; i < 12; i++ ) {
188 middle_ring_vl->add( lower_vertex[i] );
189 middle_ring_cl->add( color );
191 middle_ring_vl->add( middle_vertex[i] );
192 middle_ring_cl->add( color );
194 middle_ring_vl->add( lower_vertex[0] );
195 middle_ring_cl->add( color );
197 middle_ring_vl->add( middle_vertex[0] );
198 middle_ring_cl->add( color );
200 // generate lower ring
201 for ( i = 0; i < 12; i++ ) {
202 lower_ring_vl->add( bottom_vertex[i] );
203 lower_ring_cl->add( color );
205 lower_ring_vl->add( lower_vertex[i] );
206 lower_ring_cl->add( color );
208 lower_ring_vl->add( bottom_vertex[0] );
209 lower_ring_cl->add( color );
211 lower_ring_vl->add( lower_vertex[0] );
212 lower_ring_cl->add( color );
214 // force a repaint of the sky colors with ugly defaults
216 sgSetVec3( fog_color, 1.0, 1.0, 1.0 );
217 repaint( color, fog_color, 0.0 );
219 // build the ssg scene graph sub tree for the sky and connected
220 // into the provide scene graph branch
221 dome_selector = new ssgSelector;
222 dome_transform = new ssgTransform;
224 ssgVtxTable *center_disk, *upper_ring, *middle_ring, *lower_ring;
226 center_disk = new ssgVtxTable( GL_TRIANGLE_FAN,
227 center_disk_vl, NULL, NULL, center_disk_cl );
229 upper_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
230 upper_ring_vl, NULL, NULL, upper_ring_cl );
232 middle_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
233 middle_ring_vl, NULL, NULL, middle_ring_cl );
235 lower_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
236 lower_ring_vl, NULL, NULL, lower_ring_cl );
238 center_disk->setState( dome_state );
239 upper_ring->setState( dome_state );
240 middle_ring->setState( dome_state );
241 lower_ring->setState( dome_state );
243 dome_transform->addKid( center_disk );
244 dome_transform->addKid( upper_ring );
245 dome_transform->addKid( middle_ring );
246 dome_transform->addKid( lower_ring );
248 dome_selector->addKid( dome_transform );
249 dome_selector->clrTraversalMaskBits( SSGTRAV_HOT );
251 dome->addKid( dome_selector );
257 // repaint the sky colors based on current value of sun_angle, sky,
258 // and fog colors. This updates the color arrays for ssgVtxTable.
259 // sun angle in degrees relative to verticle
260 // 0 degrees = high noon
261 // 90 degrees = sun rise/set
262 // 180 degrees = darkest midnight
263 bool FGSkyDome::repaint( sgVec3 sky_color, sgVec3 fog_color, double sun_angle ) {
265 sgVec3 outer_param, outer_amt, outer_diff;
266 sgVec3 middle_param, middle_amt, middle_diff;
269 // Check for sunrise/sunset condition
270 if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) {
272 sgSetVec3( outer_param,
273 (10.0 - fabs(90.0 - sun_angle)) / 20.0,
274 (10.0 - fabs(90.0 - sun_angle)) / 40.0,
275 -(10.0 - fabs(90.0 - sun_angle)) / 30.0 );
277 sgSetVec3( middle_param,
278 (10.0 - fabs(90.0 - sun_angle)) / 40.0,
279 (10.0 - fabs(90.0 - sun_angle)) / 80.0,
282 sgScaleVec3( outer_diff, outer_param, 1.0 / 6.0 );
284 sgScaleVec3( middle_diff, middle_param, 1.0 / 6.0 );
286 sgSetVec3( outer_param, 0.0, 0.0, 0.0 );
287 sgSetVec3( middle_param, 0.0, 0.0, 0.0 );
289 sgSetVec3( outer_diff, 0.0, 0.0, 0.0 );
290 sgSetVec3( middle_diff, 0.0, 0.0, 0.0 );
292 // printf(" outer_red_param = %.2f outer_red_diff = %.2f\n",
293 // outer_red_param, outer_red_diff);
295 // calculate transition colors between sky and fog
296 sgCopyVec3( outer_amt, outer_param );
297 sgCopyVec3( middle_amt, middle_param );
300 // First, recalulate the basic colors
303 sgVec3 upper_color[12];
304 sgVec3 middle_color[12];
305 sgVec3 lower_color[12];
306 sgVec3 bottom_color[12];
308 for ( i = 0; i < 6; i++ ) {
309 for ( j = 0; j < 3; j++ ) {
310 diff = sky_color[j] - fog_color[j];
312 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
313 // l->sky_color[j], l->fog_color[j], diff);
315 upper_color[i][j] = sky_color[j] - diff * 0.3;
316 middle_color[i][j] = sky_color[j] - diff * 0.9 + middle_amt[j];
317 lower_color[i][j] = fog_color[j] + outer_amt[j];
319 if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
320 if ( upper_color[i][j] < 0.1 ) { upper_color[i][j] = 0.1; }
321 if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
322 if ( middle_color[i][j] < 0.1 ) { middle_color[i][j] = 0.1; }
323 if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
324 if ( lower_color[i][j] < 0.1 ) { lower_color[i][j] = 0.1; }
326 // upper_color[i][3] = middle_color[i][3] = lower_color[i][3] =
327 // (GLubyte)(sky_color[3] * 1.0);
329 for ( j = 0; j < 3; j++ ) {
330 outer_amt[j] -= outer_diff[j];
331 middle_amt[j] -= middle_diff[j];
335 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
336 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
337 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
338 middle_color[i][0], middle_color[i][1], middle_color[i][2],
340 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
341 lower_color[i][0], lower_color[i][1], lower_color[i][2],
346 sgSetVec3( outer_amt, 0.0, 0.0, 0.0 );
347 sgSetVec3( middle_amt, 0.0, 0.0, 0.0 );
349 for ( i = 6; i < 12; i++ ) {
350 for ( j = 0; j < 3; j++ ) {
351 diff = sky_color[j] - fog_color[j];
353 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
354 // sky_color[j], fog_color[j], diff);
356 upper_color[i][j] = sky_color[j] - diff * 0.3;
357 middle_color[i][j] = sky_color[j] - diff * 0.9 + middle_amt[j];
358 lower_color[i][j] = fog_color[j] + outer_amt[j];
360 if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
361 if ( upper_color[i][j] < 0.1 ) { upper_color[i][j] = 0.1; }
362 if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
363 if ( middle_color[i][j] < 0.1 ) { middle_color[i][j] = 0.1; }
364 if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
365 if ( lower_color[i][j] < 0.1 ) { lower_color[i][j] = 0.1; }
367 // upper_color[i][3] = middle_color[i][3] = lower_color[i][3] =
368 // (GLubyte)(sky_color[3] * 1.0);
370 for ( j = 0; j < 3; j++ ) {
371 outer_amt[j] += outer_diff[j];
372 middle_amt[j] += middle_diff[j];
376 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
377 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
378 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
379 middle_color[i][0], middle_color[i][1], middle_color[i][2],
381 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
382 lower_color[i][0], lower_color[i][1], lower_color[i][2],
387 for ( i = 0; i < 12; i++ ) {
388 sgCopyVec3( bottom_color[i], fog_color );
392 // Second, assign the basic colors to the object color arrays
398 // update the center disk color arrays
400 slot = center_disk_cl->get( counter++ );
402 // sgSetVec3( red, 1.0, 0.0, 0.0 );
403 sgCopyVec3( slot, sky_color );
404 for ( i = 11; i >= 0; i-- ) {
405 slot = center_disk_cl->get( counter++ );
406 sgCopyVec3( slot, upper_color[i] );
408 slot = center_disk_cl->get( counter++ );
409 sgCopyVec3( slot, upper_color[11] );
411 // generate the upper ring
413 for ( i = 0; i < 12; i++ ) {
414 slot = upper_ring_cl->get( counter++ );
415 sgCopyVec3( slot, middle_color[i] );
417 slot = upper_ring_cl->get( counter++ );
418 sgCopyVec3( slot, upper_color[i] );
420 slot = upper_ring_cl->get( counter++ );
421 sgCopyVec3( slot, middle_color[0] );
423 slot = upper_ring_cl->get( counter++ );
424 sgCopyVec3( slot, upper_color[0] );
426 // generate middle ring
428 for ( i = 0; i < 12; i++ ) {
429 slot = middle_ring_cl->get( counter++ );
430 sgCopyVec3( slot, lower_color[i] );
432 slot = middle_ring_cl->get( counter++ );
433 sgCopyVec3( slot, middle_color[i] );
435 slot = middle_ring_cl->get( counter++ );
436 sgCopyVec3( slot, lower_color[0] );
438 slot = middle_ring_cl->get( counter++ );
439 sgCopyVec3( slot, middle_color[0] );
441 // generate lower ring
443 for ( i = 0; i < 12; i++ ) {
444 slot = lower_ring_cl->get( counter++ );
445 sgCopyVec3( slot, bottom_color[i] );
447 slot = lower_ring_cl->get( counter++ );
448 sgCopyVec3( slot, lower_color[i] );
450 slot = lower_ring_cl->get( counter++ );
451 sgCopyVec3( slot, bottom_color[0] );
453 slot = lower_ring_cl->get( counter++ );
454 sgCopyVec3( slot, lower_color[0] );
460 // reposition the sky at the specified origin and orientation
461 // lon specifies a rotation about the Z axis
462 // lat specifies a rotation about the new Y axis
463 // spin specifies a rotation about the new Z axis (and orients the
464 // sunrise/set effects
465 bool FGSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) {
466 sgMat4 T, LON, LAT, SPIN;
469 // Translate to view position
470 // Point3D zero_elev = current_view.get_cur_zero_elev();
471 // xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
472 sgMakeTransMat4( T, p );
474 // printf(" Translated to %.2f %.2f %.2f\n",
475 // zero_elev.x, zero_elev.y, zero_elev.z );
477 // Rotate to proper orientation
478 // printf(" lon = %.2f lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
479 // FG_Latitude * RAD_TO_DEG);
480 // xglRotatef( f->get_Longitude() * RAD_TO_DEG, 0.0, 0.0, 1.0 );
481 sgSetVec3( axis, 0.0, 0.0, 1.0 );
482 sgMakeRotMat4( LON, lon * RAD_TO_DEG, axis );
484 // xglRotatef( 90.0 - f->get_Latitude() * RAD_TO_DEG, 0.0, 1.0, 0.0 );
485 sgSetVec3( axis, 0.0, 1.0, 0.0 );
486 sgMakeRotMat4( LAT, 90.0 - lat * RAD_TO_DEG, axis );
488 // xglRotatef( l->sun_rotation * RAD_TO_DEG, 0.0, 0.0, 1.0 );
489 sgSetVec3( axis, 0.0, 0.0, 1.0 );
490 sgMakeRotMat4( SPIN, spin * RAD_TO_DEG, axis );
494 sgCopyMat4( TRANSFORM, T );
495 sgPreMultMat4( TRANSFORM, LON );
496 sgPreMultMat4( TRANSFORM, LAT );
497 sgPreMultMat4( TRANSFORM, SPIN );
500 sgSetCoord( &skypos, TRANSFORM );
502 dome_transform->setTransform( &skypos );
509 bool FGSkyDome::draw() {
510 ssgCullAndDraw( dome );
518 // depricated code from here to the end
521 // Calculate the sky structure vertices
522 void fgSkyVerticesInit() {
526 FG_LOG(FG_ASTRO, FG_INFO, " Generating the sky dome vertices.");
528 for ( i = 0; i < 12; i++ ) {
529 theta = (i * 30.0) * DEG_TO_RAD;
531 inner_vertex[i][0] = cos(theta) * UPPER_RADIUS;
532 inner_vertex[i][1] = sin(theta) * UPPER_RADIUS;
533 inner_vertex[i][2] = UPPER_ELEV;
535 // printf(" %.2f %.2f\n", cos(theta) * UPPER_RADIUS,
536 // sin(theta) * UPPER_RADIUS);
538 middle_vertex[i][0] = cos((double)theta) * MIDDLE_RADIUS;
539 middle_vertex[i][1] = sin((double)theta) * MIDDLE_RADIUS;
540 middle_vertex[i][2] = MIDDLE_ELEV;
542 outer_vertex[i][0] = cos((double)theta) * LOWER_RADIUS;
543 outer_vertex[i][1] = sin((double)theta) * LOWER_RADIUS;
544 outer_vertex[i][2] = LOWER_ELEV;
546 bottom_vertex[i][0] = cos((double)theta) * BOTTOM_RADIUS;
547 bottom_vertex[i][1] = sin((double)theta) * BOTTOM_RADIUS;
548 bottom_vertex[i][2] = BOTTOM_ELEV;
553 // (Re)calculate the sky colors at each vertex
554 void fgSkyColorsInit() {
556 double sun_angle, diff;
557 double outer_param[3], outer_amt[3], outer_diff[3];
558 double middle_param[3], middle_amt[3], middle_diff[3];
561 l = &cur_light_params;
563 FG_LOG( FG_ASTRO, FG_INFO,
564 " Generating the sky colors for each vertex." );
566 // setup for the possibility of sunset effects
567 sun_angle = l->sun_angle * RAD_TO_DEG;
568 // fgPrintf( FG_ASTRO, FG_INFO,
569 // " Sun angle in degrees = %.2f\n", sun_angle);
571 if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) {
573 outer_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 20.0;
574 outer_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
575 outer_param[2] = -(10.0 - fabs(90.0 - sun_angle)) / 30.0;
576 // outer_param[2] = 0.0;
578 middle_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
579 middle_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 80.0;
580 middle_param[2] = 0.0;
582 outer_diff[0] = outer_param[0] / 6.0;
583 outer_diff[1] = outer_param[1] / 6.0;
584 outer_diff[2] = outer_param[2] / 6.0;
586 middle_diff[0] = middle_param[0] / 6.0;
587 middle_diff[1] = middle_param[1] / 6.0;
588 middle_diff[2] = middle_param[2] / 6.0;
590 outer_param[0] = outer_param[1] = outer_param[2] = 0.0;
591 middle_param[0] = middle_param[1] = middle_param[2] = 0.0;
593 outer_diff[0] = outer_diff[1] = outer_diff[2] = 0.0;
594 middle_diff[0] = middle_diff[1] = middle_diff[2] = 0.0;
596 // printf(" outer_red_param = %.2f outer_red_diff = %.2f\n",
597 // outer_red_param, outer_red_diff);
599 // calculate transition colors between sky and fog
600 for ( j = 0; j < 3; j++ ) {
601 outer_amt[j] = outer_param[j];
602 middle_amt[j] = middle_param[j];
605 for ( i = 0; i < 6; i++ ) {
606 for ( j = 0; j < 3; j++ ) {
607 diff = l->sky_color[j] - l->fog_color[j];
609 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
610 // l->sky_color[j], l->fog_color[j], diff);
612 upper_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255);
613 middle_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.9
614 + middle_amt[j]) * 255);
615 lower_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j])
618 if ( upper_color[i][j] > 255 ) { upper_color[i][j] = 255; }
619 if ( upper_color[i][j] < 25 ) { upper_color[i][j] = 25; }
620 if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; }
621 if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; }
622 if ( lower_color[i][j] > 255 ) { lower_color[i][j] = 255; }
623 if ( lower_color[i][j] < 25 ) { lower_color[i][j] = 25; }
625 upper_color[i][3] = middle_color[i][3] = lower_color[i][3] =
626 (GLubyte)(l->sky_color[3] * 255);
628 for ( j = 0; j < 3; j++ ) {
629 outer_amt[j] -= outer_diff[j];
630 middle_amt[j] -= middle_diff[j];
634 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
635 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
636 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
637 middle_color[i][0], middle_color[i][1], middle_color[i][2],
639 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
640 lower_color[i][0], lower_color[i][1], lower_color[i][2],
645 for ( j = 0; j < 3; j++ ) {
650 for ( i = 6; i < 12; i++ ) {
652 for ( j = 0; j < 3; j++ ) {
653 diff = l->sky_color[j] - l->fog_color[j];
655 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
656 // l->sky_color[j], l->fog_color[j], diff);
658 upper_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255);
659 middle_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.9
660 + middle_amt[j]) * 255);
661 lower_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j])
664 if ( upper_color[i][j] > 255 ) { upper_color[i][j] = 255; }
665 if ( upper_color[i][j] < 25 ) { upper_color[i][j] = 25; }
666 if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; }
667 if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; }
668 if ( lower_color[i][j] > 255 ) { lower_color[i][j] = 255; }
669 if ( lower_color[i][j] < 35 ) { lower_color[i][j] = 35; }
671 upper_color[i][3] = middle_color[i][3] = lower_color[i][3] =
672 (GLubyte)(l->sky_color[3] * 255);
674 for ( j = 0; j < 3; j++ ) {
675 outer_amt[j] += outer_diff[j];
676 middle_amt[j] += middle_diff[j];
680 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
681 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
682 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
683 middle_color[i][0], middle_color[i][1], middle_color[i][2],
685 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
686 lower_color[i][0], lower_color[i][1], lower_color[i][2],
693 // Initialize the sky structure and colors
695 FG_LOG( FG_ASTRO, FG_INFO, "Initializing the sky" );
699 // regester fgSkyColorsInit() as an event to be run periodically
700 global_events.Register( "fgSkyColorsInit()", fgSkyColorsInit,
701 fgEVENT::FG_EVENT_READY, 30000);
709 GLubyte sky_color[4];
710 GLubyte upper_color[4];
711 GLubyte middle_color[4];
712 GLubyte lower_color[4];
716 f = current_aircraft.fdm_state;
717 l = &cur_light_params;
719 // printf("Rendering the sky.\n");
721 // calculate the proper colors
722 for ( i = 0; i < 3; i++ ) {
723 diff = l->sky_color[i] - l->adj_fog_color[i];
725 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
726 // l->sky_color[j], l->adj_fog_color[j], diff);
728 upper_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.3) * 255);
729 middle_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.9) * 255);
730 lower_color[i] = (GLubyte)(l->adj_fog_color[i] * 255);
732 upper_color[3] = middle_color[3] = lower_color[3] =
733 (GLubyte)(l->adj_fog_color[3] * 255);
737 // Translate to view position
738 Point3D zero_elev = current_view.get_cur_zero_elev();
739 xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
740 // printf(" Translated to %.2f %.2f %.2f\n",
741 // zero_elev.x, zero_elev.y, zero_elev.z );
743 // Rotate to proper orientation
744 // printf(" lon = %.2f lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
745 // FG_Latitude * RAD_TO_DEG);
746 xglRotatef( f->get_Longitude() * RAD_TO_DEG, 0.0, 0.0, 1.0 );
747 xglRotatef( 90.0 - f->get_Latitude() * RAD_TO_DEG, 0.0, 1.0, 0.0 );
748 xglRotatef( l->sun_rotation * RAD_TO_DEG, 0.0, 0.0, 1.0 );
750 // Draw inner/center section of sky*/
751 xglBegin( GL_TRIANGLE_FAN );
752 for ( i = 0; i < 4; i++ ) {
753 sky_color[i] = (GLubyte)(l->sky_color[i] * 255);
755 xglColor4fv(l->sky_color);
756 xglVertex3f(0.0, 0.0, CENTER_ELEV);
757 for ( i = 11; i >= 0; i-- ) {
758 xglColor4ubv( upper_color );
759 xglVertex3fv( inner_vertex[i] );
761 xglColor4ubv( upper_color );
762 xglVertex3fv( inner_vertex[11] );
765 // Draw the middle ring
766 xglBegin( GL_TRIANGLE_STRIP );
767 for ( i = 0; i < 12; i++ ) {
768 xglColor4ubv( middle_color );
769 // printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
770 // middle_color[i][0], middle_color[i][1], middle_color[i][2],
771 // middle_color[i][3]);
772 // xglColor4f(1.0, 0.0, 0.0, 1.0);
773 xglVertex3fv( middle_vertex[i] );
774 xglColor4ubv( upper_color );
775 // printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i,
776 // upper_color[i][0], upper_color[i][1], upper_color[i][2],
777 // upper_color[i][3]);
778 // xglColor4f(0.0, 0.0, 1.0, 1.0);
779 xglVertex3fv( inner_vertex[i] );
781 xglColor4ubv( middle_color );
782 // xglColor4f(1.0, 0.0, 0.0, 1.0);
783 xglVertex3fv( middle_vertex[0] );
784 xglColor4ubv( upper_color );
785 // xglColor4f(0.0, 0.0, 1.0, 1.0);
786 xglVertex3fv( inner_vertex[0] );
789 // Draw the outer ring
790 xglBegin( GL_TRIANGLE_STRIP );
791 for ( i = 0; i < 12; i++ ) {
792 xglColor4ubv( lower_color );
793 xglVertex3fv( outer_vertex[i] );
794 xglColor4ubv( middle_color );
795 xglVertex3fv( middle_vertex[i] );
797 xglColor4ubv( lower_color );
798 xglVertex3fv( outer_vertex[0] );
799 xglColor4ubv( middle_color );
800 xglVertex3fv( middle_vertex[0] );
803 // Draw the bottom skirt
804 xglBegin( GL_TRIANGLE_STRIP );
805 xglColor4ubv( lower_color );
806 for ( i = 0; i < 12; i++ ) {
807 xglVertex3fv( bottom_vertex[i] );
808 xglVertex3fv( outer_vertex[i] );
810 xglVertex3fv( bottom_vertex[0] );
811 xglVertex3fv( outer_vertex[0] );