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 the scene graph
97 bool FGSkyDome::initialize( ssgRoot *root ) {
104 sky_state = new ssgSimpleState();
105 if ( current_options.get_shading() == 1 ) {
106 sky_state->setShadeModel( GL_SMOOTH );
108 sky_state->setShadeModel( GL_FLAT );
110 sky_state->disable( GL_LIGHTING );
111 sky_state->disable( GL_DEPTH_TEST );
112 sky_state->disable( GL_CULL_FACE );
113 sky_state->disable( GL_TEXTURE );
114 sky_state->enable( GL_COLOR_MATERIAL );
115 sky_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 sky_selector = new ssgSelector;
226 sky_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( sky_state );
243 upper_ring->setState( sky_state );
244 middle_ring->setState( sky_state );
245 lower_ring->setState( sky_state );
247 sky_transform->addKid( center_disk );
248 sky_transform->addKid( upper_ring );
249 sky_transform->addKid( middle_ring );
250 sky_transform->addKid( lower_ring );
252 sky_selector->addKid( sky_transform );
253 sky_selector->clrTraversalMaskBits( SSGTRAV_HOT );
255 root->addKid( sky_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 sky_transform->setTransform( &skypos );
514 // depricated code from here to the end
517 // Calculate the sky structure vertices
518 void fgSkyVerticesInit() {
522 FG_LOG(FG_ASTRO, FG_INFO, " Generating the sky dome vertices.");
524 for ( i = 0; i < 12; i++ ) {
525 theta = (i * 30.0) * DEG_TO_RAD;
527 inner_vertex[i][0] = cos(theta) * UPPER_RADIUS;
528 inner_vertex[i][1] = sin(theta) * UPPER_RADIUS;
529 inner_vertex[i][2] = UPPER_ELEV;
531 // printf(" %.2f %.2f\n", cos(theta) * UPPER_RADIUS,
532 // sin(theta) * UPPER_RADIUS);
534 middle_vertex[i][0] = cos((double)theta) * MIDDLE_RADIUS;
535 middle_vertex[i][1] = sin((double)theta) * MIDDLE_RADIUS;
536 middle_vertex[i][2] = MIDDLE_ELEV;
538 outer_vertex[i][0] = cos((double)theta) * LOWER_RADIUS;
539 outer_vertex[i][1] = sin((double)theta) * LOWER_RADIUS;
540 outer_vertex[i][2] = LOWER_ELEV;
542 bottom_vertex[i][0] = cos((double)theta) * BOTTOM_RADIUS;
543 bottom_vertex[i][1] = sin((double)theta) * BOTTOM_RADIUS;
544 bottom_vertex[i][2] = BOTTOM_ELEV;
549 // (Re)calculate the sky colors at each vertex
550 void fgSkyColorsInit() {
552 double sun_angle, diff;
553 double outer_param[3], outer_amt[3], outer_diff[3];
554 double middle_param[3], middle_amt[3], middle_diff[3];
557 l = &cur_light_params;
559 FG_LOG( FG_ASTRO, FG_INFO,
560 " Generating the sky colors for each vertex." );
562 // setup for the possibility of sunset effects
563 sun_angle = l->sun_angle * RAD_TO_DEG;
564 // fgPrintf( FG_ASTRO, FG_INFO,
565 // " Sun angle in degrees = %.2f\n", sun_angle);
567 if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) {
569 outer_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 20.0;
570 outer_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
571 outer_param[2] = -(10.0 - fabs(90.0 - sun_angle)) / 30.0;
572 // outer_param[2] = 0.0;
574 middle_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
575 middle_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 80.0;
576 middle_param[2] = 0.0;
578 outer_diff[0] = outer_param[0] / 6.0;
579 outer_diff[1] = outer_param[1] / 6.0;
580 outer_diff[2] = outer_param[2] / 6.0;
582 middle_diff[0] = middle_param[0] / 6.0;
583 middle_diff[1] = middle_param[1] / 6.0;
584 middle_diff[2] = middle_param[2] / 6.0;
586 outer_param[0] = outer_param[1] = outer_param[2] = 0.0;
587 middle_param[0] = middle_param[1] = middle_param[2] = 0.0;
589 outer_diff[0] = outer_diff[1] = outer_diff[2] = 0.0;
590 middle_diff[0] = middle_diff[1] = middle_diff[2] = 0.0;
592 // printf(" outer_red_param = %.2f outer_red_diff = %.2f\n",
593 // outer_red_param, outer_red_diff);
595 // calculate transition colors between sky and fog
596 for ( j = 0; j < 3; j++ ) {
597 outer_amt[j] = outer_param[j];
598 middle_amt[j] = middle_param[j];
601 for ( i = 0; i < 6; i++ ) {
602 for ( j = 0; j < 3; j++ ) {
603 diff = l->sky_color[j] - l->fog_color[j];
605 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
606 // l->sky_color[j], l->fog_color[j], diff);
608 upper_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255);
609 middle_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.9
610 + middle_amt[j]) * 255);
611 lower_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j])
614 if ( upper_color[i][j] > 255 ) { upper_color[i][j] = 255; }
615 if ( upper_color[i][j] < 25 ) { upper_color[i][j] = 25; }
616 if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; }
617 if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; }
618 if ( lower_color[i][j] > 255 ) { lower_color[i][j] = 255; }
619 if ( lower_color[i][j] < 25 ) { lower_color[i][j] = 25; }
621 upper_color[i][3] = middle_color[i][3] = lower_color[i][3] =
622 (GLubyte)(l->sky_color[3] * 255);
624 for ( j = 0; j < 3; j++ ) {
625 outer_amt[j] -= outer_diff[j];
626 middle_amt[j] -= middle_diff[j];
630 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
631 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
632 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
633 middle_color[i][0], middle_color[i][1], middle_color[i][2],
635 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
636 lower_color[i][0], lower_color[i][1], lower_color[i][2],
641 for ( j = 0; j < 3; j++ ) {
646 for ( i = 6; i < 12; i++ ) {
648 for ( j = 0; j < 3; j++ ) {
649 diff = l->sky_color[j] - l->fog_color[j];
651 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
652 // l->sky_color[j], l->fog_color[j], diff);
654 upper_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255);
655 middle_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.9
656 + middle_amt[j]) * 255);
657 lower_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j])
660 if ( upper_color[i][j] > 255 ) { upper_color[i][j] = 255; }
661 if ( upper_color[i][j] < 25 ) { upper_color[i][j] = 25; }
662 if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; }
663 if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; }
664 if ( lower_color[i][j] > 255 ) { lower_color[i][j] = 255; }
665 if ( lower_color[i][j] < 35 ) { lower_color[i][j] = 35; }
667 upper_color[i][3] = middle_color[i][3] = lower_color[i][3] =
668 (GLubyte)(l->sky_color[3] * 255);
670 for ( j = 0; j < 3; j++ ) {
671 outer_amt[j] += outer_diff[j];
672 middle_amt[j] += middle_diff[j];
676 printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
677 upper_color[i][1], upper_color[i][2], upper_color[i][3]);
678 printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
679 middle_color[i][0], middle_color[i][1], middle_color[i][2],
681 printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
682 lower_color[i][0], lower_color[i][1], lower_color[i][2],
689 // Initialize the sky structure and colors
691 FG_LOG( FG_ASTRO, FG_INFO, "Initializing the sky" );
695 // regester fgSkyColorsInit() as an event to be run periodically
696 global_events.Register( "fgSkyColorsInit()", fgSkyColorsInit,
697 fgEVENT::FG_EVENT_READY, 30000);
705 GLubyte sky_color[4];
706 GLubyte upper_color[4];
707 GLubyte middle_color[4];
708 GLubyte lower_color[4];
712 f = current_aircraft.fdm_state;
713 l = &cur_light_params;
715 // printf("Rendering the sky.\n");
717 // calculate the proper colors
718 for ( i = 0; i < 3; i++ ) {
719 diff = l->sky_color[i] - l->adj_fog_color[i];
721 // printf("sky = %.2f fog = %.2f diff = %.2f\n",
722 // l->sky_color[j], l->adj_fog_color[j], diff);
724 upper_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.3) * 255);
725 middle_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.9) * 255);
726 lower_color[i] = (GLubyte)(l->adj_fog_color[i] * 255);
728 upper_color[3] = middle_color[3] = lower_color[3] =
729 (GLubyte)(l->adj_fog_color[3] * 255);
733 // Translate to view position
734 Point3D zero_elev = current_view.get_cur_zero_elev();
735 xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
736 // printf(" Translated to %.2f %.2f %.2f\n",
737 // zero_elev.x, zero_elev.y, zero_elev.z );
739 // Rotate to proper orientation
740 // printf(" lon = %.2f lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
741 // FG_Latitude * RAD_TO_DEG);
742 xglRotatef( f->get_Longitude() * RAD_TO_DEG, 0.0, 0.0, 1.0 );
743 xglRotatef( 90.0 - f->get_Latitude() * RAD_TO_DEG, 0.0, 1.0, 0.0 );
744 xglRotatef( l->sun_rotation * RAD_TO_DEG, 0.0, 0.0, 1.0 );
746 // Draw inner/center section of sky*/
747 xglBegin( GL_TRIANGLE_FAN );
748 for ( i = 0; i < 4; i++ ) {
749 sky_color[i] = (GLubyte)(l->sky_color[i] * 255);
751 xglColor4fv(l->sky_color);
752 xglVertex3f(0.0, 0.0, CENTER_ELEV);
753 for ( i = 11; i >= 0; i-- ) {
754 xglColor4ubv( upper_color );
755 xglVertex3fv( inner_vertex[i] );
757 xglColor4ubv( upper_color );
758 xglVertex3fv( inner_vertex[11] );
761 // Draw the middle ring
762 xglBegin( GL_TRIANGLE_STRIP );
763 for ( i = 0; i < 12; i++ ) {
764 xglColor4ubv( middle_color );
765 // printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
766 // middle_color[i][0], middle_color[i][1], middle_color[i][2],
767 // middle_color[i][3]);
768 // xglColor4f(1.0, 0.0, 0.0, 1.0);
769 xglVertex3fv( middle_vertex[i] );
770 xglColor4ubv( upper_color );
771 // printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i,
772 // upper_color[i][0], upper_color[i][1], upper_color[i][2],
773 // upper_color[i][3]);
774 // xglColor4f(0.0, 0.0, 1.0, 1.0);
775 xglVertex3fv( inner_vertex[i] );
777 xglColor4ubv( middle_color );
778 // xglColor4f(1.0, 0.0, 0.0, 1.0);
779 xglVertex3fv( middle_vertex[0] );
780 xglColor4ubv( upper_color );
781 // xglColor4f(0.0, 0.0, 1.0, 1.0);
782 xglVertex3fv( inner_vertex[0] );
785 // Draw the outer ring
786 xglBegin( GL_TRIANGLE_STRIP );
787 for ( i = 0; i < 12; i++ ) {
788 xglColor4ubv( lower_color );
789 xglVertex3fv( outer_vertex[i] );
790 xglColor4ubv( middle_color );
791 xglVertex3fv( middle_vertex[i] );
793 xglColor4ubv( lower_color );
794 xglVertex3fv( outer_vertex[0] );
795 xglColor4ubv( middle_color );
796 xglVertex3fv( middle_vertex[0] );
799 // Draw the bottom skirt
800 xglBegin( GL_TRIANGLE_STRIP );
801 xglColor4ubv( lower_color );
802 for ( i = 0; i < 12; i++ ) {
803 xglVertex3fv( bottom_vertex[i] );
804 xglVertex3fv( outer_vertex[i] );
806 xglVertex3fv( bottom_vertex[0] );
807 xglVertex3fv( outer_vertex[0] );