From ecc5c9865b74629772baee2d5947db0545e7e077 Mon Sep 17 00:00:00 2001 From: curt Date: Mon, 28 Feb 2000 12:58:41 +0000 Subject: [PATCH] Beginning work on a restructure of the sky code. --- simgear/ephemeris/sky.cxx | 315 +++++++++++++++++++++++++++++++------- simgear/ephemeris/sky.hxx | 73 ++++++++- 2 files changed, 326 insertions(+), 62 deletions(-) diff --git a/simgear/ephemeris/sky.cxx b/simgear/ephemeris/sky.cxx index 3277d0e7..5d7c39f1 100644 --- a/simgear/ephemeris/sky.cxx +++ b/simgear/ephemeris/sky.cxx @@ -55,14 +55,14 @@ // in meters of course #define CENTER_ELEV 25000.0 -#define INNER_RADIUS 50000.0 -#define INNER_ELEV 20000.0 +#define UPPER_RADIUS 50000.0 +#define UPPER_ELEV 20000.0 #define MIDDLE_RADIUS 70000.0 #define MIDDLE_ELEV 8000.0 -#define OUTER_RADIUS 80000.0 -#define OUTER_ELEV 0.0 +#define LOWER_RADIUS 80000.0 +#define LOWER_ELEV 0.0 #define BOTTOM_RADIUS 50000.0 #define BOTTOM_ELEV -2000.0 @@ -73,13 +73,214 @@ static float middle_vertex[12][3]; static float outer_vertex[12][3]; static float bottom_vertex[12][3]; -static GLubyte inner_color[12][4]; +static GLubyte upper_color[12][4]; static GLubyte middle_color[12][4]; -static GLubyte outer_color[12][4]; +static GLubyte lower_color[12][4]; + + +// Constructor +FGSky::FGSky( void ) { +} + + +// Destructor +FGSky::~FGSky( void ) { +} + + +// initialize the sky object and connect it into the scene graph +bool FGSky::initialize() { + sgVec3 vertex; + sgVec3 color; + + float theta; + int i; + + // initialize arrays + upper_ring_vl = new ssgVertexArray( 12 ); + upper_ring_cl = new ssgColourArray( 12 ); + + middle_ring_vl = new ssgVertexArray( 12 ); + middle_ring_cl = new ssgColourArray( 12 ); + + lower_ring_vl = new ssgVertexArray( 12 ); + lower_ring_cl = new ssgColourArray( 12 ); + + bottom_ring_vl = new ssgVertexArray( 12 ); + bottom_ring_cl = new ssgColourArray( 12 ); + + // generate the sky dome vertices + + sgSetVec3( color, 0.0, 0.0, 1.0 ); // seed to all blue + + for ( i = 0; i < 12; i++ ) { + theta = (i * 30.0) * DEG_TO_RAD; + + sgSetVec3( vertex, + cos(theta) * UPPER_RADIUS, + sin(theta) * UPPER_RADIUS, + UPPER_ELEV ); + upper_ring_vl->add( vertex ); + upper_ring_cl->add( color ); + + sgSetVec3( vertex, + cos((double)theta) * MIDDLE_RADIUS, + sin((double)theta) * MIDDLE_RADIUS, + MIDDLE_ELEV ); + middle_ring_vl->add( vertex ); + middle_ring_cl->add( color ); + + sgSetVec3( vertex, + cos((double)theta) * LOWER_RADIUS, + sin((double)theta) * LOWER_RADIUS, + LOWER_ELEV ); + lower_ring_vl->add( vertex ); + lower_ring_cl->add( color ); + + sgSetVec3( vertex, + cos((double)theta) * BOTTOM_RADIUS, + sin((double)theta) * BOTTOM_RADIUS, + BOTTOM_ELEV ); + bottom_ring_vl->add( vertex ); + bottom_ring_cl->add( color ); + } + + // force a rebuild of the colors + rebuild(); + + return true; +} + + +// rebuild the sky colors based on current value of sun_angle, sky, +// and fog colors. This updates the color arrays for ssgVtxTable. +bool FGSky::rebuild() { + double diff; + sgVec3 outer_param, outer_amt, outer_diff; + sgVec3 middle_param, middle_amt, middle_diff; + int i, j; + + if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) { + // 0.0 - 0.4 + sgSetVec3( outer_param, + (10.0 - fabs(90.0 - sun_angle)) / 20.0, + (10.0 - fabs(90.0 - sun_angle)) / 40.0, + -(10.0 - fabs(90.0 - sun_angle)) / 30.0 ); + + sgSetVec3( middle_param, + (10.0 - fabs(90.0 - sun_angle)) / 40.0, + (10.0 - fabs(90.0 - sun_angle)) / 80.0, + 0.0 ); + + sgScaleVec3( outer_diff, outer_param, 1.0 / 6.0 ); + + sgScaleVec3( middle_diff, middle_param, 1.0 / 6.0 ); + } else { + sgSetVec3( outer_param, 0.0, 0.0, 0.0 ); + sgSetVec3( middle_param, 0.0, 0.0, 0.0 ); + + sgSetVec3( outer_diff, 0.0, 0.0, 0.0 ); + sgSetVec3( middle_diff, 0.0, 0.0, 0.0 ); + } + // printf(" outer_red_param = %.2f outer_red_diff = %.2f\n", + // outer_red_param, outer_red_diff); + + // calculate transition colors between sky and fog + sgCopyVec3( outer_amt, outer_param ); + sgCopyVec3( middle_amt, middle_param ); + + // float *upper_color, *middle_color, *lower_color; + + for ( i = 0; i < 6; i++ ) { + // inner_color = + for ( j = 0; j < 3; j++ ) { + diff = sky_color[j] - fog_color[j]; + + // printf("sky = %.2f fog = %.2f diff = %.2f\n", + // l->sky_color[j], l->fog_color[j], diff); + + upper_color[i][j] = (GLubyte)((sky_color[j] - diff * 0.3) * 255); + middle_color[i][j] = (GLubyte)((sky_color[j] - diff * 0.9 + + middle_amt[j]) * 255); + lower_color[i][j] = (GLubyte)((fog_color[j] + outer_amt[j]) + * 255); + + if ( upper_color[i][j] > 255 ) { upper_color[i][j] = 255; } + if ( upper_color[i][j] < 25 ) { upper_color[i][j] = 25; } + if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; } + if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; } + if ( lower_color[i][j] > 255 ) { lower_color[i][j] = 255; } + if ( lower_color[i][j] < 25 ) { lower_color[i][j] = 25; } + } + upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = + (GLubyte)(sky_color[3] * 255); + + for ( j = 0; j < 3; j++ ) { + outer_amt[j] -= outer_diff[j]; + middle_amt[j] -= middle_diff[j]; + } + + /* + printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0], + upper_color[i][1], upper_color[i][2], upper_color[i][3]); + printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i, + middle_color[i][0], middle_color[i][1], middle_color[i][2], + middle_color[i][3]); + printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i, + lower_color[i][0], lower_color[i][1], lower_color[i][2], + lower_color[i][3]); + */ + } + + sgSetVec3( outer_amt, 0.0, 0.0, 0.0 ); + sgSetVec3( middle_amt, 0.0, 0.0, 0.0 ); + + for ( i = 6; i < 12; i++ ) { + for ( j = 0; j < 3; j++ ) { + diff = sky_color[j] - fog_color[j]; + + // printf("sky = %.2f fog = %.2f diff = %.2f\n", + // sky_color[j], fog_color[j], diff); + + upper_color[i][j] = (GLubyte)((sky_color[j] - diff * 0.3) * 255); + middle_color[i][j] = (GLubyte)((sky_color[j] - diff * 0.9 + + middle_amt[j]) * 255); + lower_color[i][j] = (GLubyte)((fog_color[j] + outer_amt[j]) + * 255); + + if ( upper_color[i][j] > 255 ) { upper_color[i][j] = 255; } + if ( upper_color[i][j] < 25 ) { upper_color[i][j] = 25; } + if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; } + if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; } + if ( lower_color[i][j] > 255 ) { lower_color[i][j] = 255; } + if ( lower_color[i][j] < 35 ) { lower_color[i][j] = 35; } + } + upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = + (GLubyte)(sky_color[3] * 255); + + for ( j = 0; j < 3; j++ ) { + outer_amt[j] += outer_diff[j]; + middle_amt[j] += middle_diff[j]; + } + + /* + printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0], + upper_color[i][1], upper_color[i][2], upper_color[i][3]); + printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i, + middle_color[i][0], middle_color[i][1], middle_color[i][2], + middle_color[i][3]); + printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i, + lower_color[i][0], lower_color[i][1], lower_color[i][2], + lower_color[i][3]); + */ + } + + return true; +} // Calculate the sky structure vertices -void fgSkyVerticesInit( void ) { +void fgSkyVerticesInit() { float theta; int i; @@ -88,20 +289,20 @@ void fgSkyVerticesInit( void ) { for ( i = 0; i < 12; i++ ) { theta = (i * 30.0) * DEG_TO_RAD; - inner_vertex[i][0] = cos(theta) * INNER_RADIUS; - inner_vertex[i][1] = sin(theta) * INNER_RADIUS; - inner_vertex[i][2] = INNER_ELEV; + inner_vertex[i][0] = cos(theta) * UPPER_RADIUS; + inner_vertex[i][1] = sin(theta) * UPPER_RADIUS; + inner_vertex[i][2] = UPPER_ELEV; - // printf(" %.2f %.2f\n", cos(theta) * INNER_RADIUS, - // sin(theta) * INNER_RADIUS); + // printf(" %.2f %.2f\n", cos(theta) * UPPER_RADIUS, + // sin(theta) * UPPER_RADIUS); middle_vertex[i][0] = cos((double)theta) * MIDDLE_RADIUS; middle_vertex[i][1] = sin((double)theta) * MIDDLE_RADIUS; middle_vertex[i][2] = MIDDLE_ELEV; - outer_vertex[i][0] = cos((double)theta) * OUTER_RADIUS; - outer_vertex[i][1] = sin((double)theta) * OUTER_RADIUS; - outer_vertex[i][2] = OUTER_ELEV; + outer_vertex[i][0] = cos((double)theta) * LOWER_RADIUS; + outer_vertex[i][1] = sin((double)theta) * LOWER_RADIUS; + outer_vertex[i][2] = LOWER_ELEV; bottom_vertex[i][0] = cos((double)theta) * BOTTOM_RADIUS; bottom_vertex[i][1] = sin((double)theta) * BOTTOM_RADIUS; @@ -111,7 +312,7 @@ void fgSkyVerticesInit( void ) { // (Re)calculate the sky colors at each vertex -void fgSkyColorsInit( void ) { +void fgSkyColorsInit() { fgLIGHT *l; double sun_angle, diff; double outer_param[3], outer_amt[3], outer_diff[3]; @@ -169,20 +370,20 @@ void fgSkyColorsInit( void ) { // printf("sky = %.2f fog = %.2f diff = %.2f\n", // l->sky_color[j], l->fog_color[j], diff); - inner_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255); + upper_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255); middle_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.9 + middle_amt[j]) * 255); - outer_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j]) + lower_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j]) * 255); - if ( inner_color[i][j] > 255 ) { inner_color[i][j] = 255; } - if ( inner_color[i][j] < 25 ) { inner_color[i][j] = 25; } + if ( upper_color[i][j] > 255 ) { upper_color[i][j] = 255; } + if ( upper_color[i][j] < 25 ) { upper_color[i][j] = 25; } if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; } if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; } - if ( outer_color[i][j] > 255 ) { outer_color[i][j] = 255; } - if ( outer_color[i][j] < 25 ) { outer_color[i][j] = 25; } + if ( lower_color[i][j] > 255 ) { lower_color[i][j] = 255; } + if ( lower_color[i][j] < 25 ) { lower_color[i][j] = 25; } } - inner_color[i][3] = middle_color[i][3] = outer_color[i][3] = + upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = (GLubyte)(l->sky_color[3] * 255); for ( j = 0; j < 3; j++ ) { @@ -191,14 +392,14 @@ void fgSkyColorsInit( void ) { } /* - printf("inner_color[%d] = %.2f %.2f %.2f %.2f\n", i, inner_color[i][0], - inner_color[i][1], inner_color[i][2], inner_color[i][3]); + printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0], + upper_color[i][1], upper_color[i][2], upper_color[i][3]); printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i, middle_color[i][0], middle_color[i][1], middle_color[i][2], middle_color[i][3]); - printf("outer_color[%d] = %.2f %.2f %.2f %.2f\n", i, - outer_color[i][0], outer_color[i][1], outer_color[i][2], - outer_color[i][3]); + printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i, + lower_color[i][0], lower_color[i][1], lower_color[i][2], + lower_color[i][3]); */ } @@ -215,20 +416,20 @@ void fgSkyColorsInit( void ) { // printf("sky = %.2f fog = %.2f diff = %.2f\n", // l->sky_color[j], l->fog_color[j], diff); - inner_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255); + upper_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255); middle_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.9 + middle_amt[j]) * 255); - outer_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j]) + lower_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j]) * 255); - if ( inner_color[i][j] > 255 ) { inner_color[i][j] = 255; } - if ( inner_color[i][j] < 25 ) { inner_color[i][j] = 25; } + if ( upper_color[i][j] > 255 ) { upper_color[i][j] = 255; } + if ( upper_color[i][j] < 25 ) { upper_color[i][j] = 25; } if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; } if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; } - if ( outer_color[i][j] > 255 ) { outer_color[i][j] = 255; } - if ( outer_color[i][j] < 35 ) { outer_color[i][j] = 35; } + if ( lower_color[i][j] > 255 ) { lower_color[i][j] = 255; } + if ( lower_color[i][j] < 35 ) { lower_color[i][j] = 35; } } - inner_color[i][3] = middle_color[i][3] = outer_color[i][3] = + upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = (GLubyte)(l->sky_color[3] * 255); for ( j = 0; j < 3; j++ ) { @@ -237,21 +438,21 @@ void fgSkyColorsInit( void ) { } /* - printf("inner_color[%d] = %.2f %.2f %.2f %.2f\n", i, inner_color[i][0], - inner_color[i][1], inner_color[i][2], inner_color[i][3]); + printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0], + upper_color[i][1], upper_color[i][2], upper_color[i][3]); printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i, middle_color[i][0], middle_color[i][1], middle_color[i][2], middle_color[i][3]); - printf("outer_color[%d] = %.2f %.2f %.2f %.2f\n", i, - outer_color[i][0], outer_color[i][1], outer_color[i][2], - outer_color[i][3]); + printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i, + lower_color[i][0], lower_color[i][1], lower_color[i][2], + lower_color[i][3]); */ } } // Initialize the sky structure and colors -void fgSkyInit( void ) { +void fgSkyInit() { FG_LOG( FG_ASTRO, FG_INFO, "Initializing the sky" ); fgSkyVerticesInit(); @@ -263,13 +464,13 @@ void fgSkyInit( void ) { // Draw the Sky -void fgSkyRender( void ) { +void fgSkyRender() { FGInterface *f; fgLIGHT *l; GLubyte sky_color[4]; - GLubyte inner_color[4]; + GLubyte upper_color[4]; GLubyte middle_color[4]; - GLubyte outer_color[4]; + GLubyte lower_color[4]; double diff; int i; @@ -285,11 +486,11 @@ void fgSkyRender( void ) { // printf("sky = %.2f fog = %.2f diff = %.2f\n", // l->sky_color[j], l->adj_fog_color[j], diff); - inner_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.3) * 255); + upper_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.3) * 255); middle_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.9) * 255); - outer_color[i] = (GLubyte)(l->adj_fog_color[i] * 255); + lower_color[i] = (GLubyte)(l->adj_fog_color[i] * 255); } - inner_color[3] = middle_color[3] = outer_color[3] = + upper_color[3] = middle_color[3] = lower_color[3] = (GLubyte)(l->adj_fog_color[3] * 255); xglPushMatrix(); @@ -315,10 +516,10 @@ void fgSkyRender( void ) { xglColor4fv(l->sky_color); xglVertex3f(0.0, 0.0, CENTER_ELEV); for ( i = 11; i >= 0; i-- ) { - xglColor4ubv( inner_color ); + xglColor4ubv( upper_color ); xglVertex3fv( inner_vertex[i] ); } - xglColor4ubv( inner_color ); + xglColor4ubv( upper_color ); xglVertex3fv( inner_vertex[11] ); xglEnd(); @@ -331,17 +532,17 @@ void fgSkyRender( void ) { // middle_color[i][3]); // xglColor4f(1.0, 0.0, 0.0, 1.0); xglVertex3fv( middle_vertex[i] ); - xglColor4ubv( inner_color ); - // printf("inner_color[%d] = %.2f %.2f %.2f %.2f\n", i, - // inner_color[i][0], inner_color[i][1], inner_color[i][2], - // inner_color[i][3]); + xglColor4ubv( upper_color ); + // printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, + // upper_color[i][0], upper_color[i][1], upper_color[i][2], + // upper_color[i][3]); // xglColor4f(0.0, 0.0, 1.0, 1.0); xglVertex3fv( inner_vertex[i] ); } xglColor4ubv( middle_color ); // xglColor4f(1.0, 0.0, 0.0, 1.0); xglVertex3fv( middle_vertex[0] ); - xglColor4ubv( inner_color ); + xglColor4ubv( upper_color ); // xglColor4f(0.0, 0.0, 1.0, 1.0); xglVertex3fv( inner_vertex[0] ); xglEnd(); @@ -349,12 +550,12 @@ void fgSkyRender( void ) { // Draw the outer ring xglBegin( GL_TRIANGLE_STRIP ); for ( i = 0; i < 12; i++ ) { - xglColor4ubv( outer_color ); + xglColor4ubv( lower_color ); xglVertex3fv( outer_vertex[i] ); xglColor4ubv( middle_color ); xglVertex3fv( middle_vertex[i] ); } - xglColor4ubv( outer_color ); + xglColor4ubv( lower_color ); xglVertex3fv( outer_vertex[0] ); xglColor4ubv( middle_color ); xglVertex3fv( middle_vertex[0] ); @@ -362,7 +563,7 @@ void fgSkyRender( void ) { // Draw the bottom skirt xglBegin( GL_TRIANGLE_STRIP ); - xglColor4ubv( outer_color ); + xglColor4ubv( lower_color ); for ( i = 0; i < 12; i++ ) { xglVertex3fv( bottom_vertex[i] ); xglVertex3fv( outer_vertex[i] ); diff --git a/simgear/ephemeris/sky.hxx b/simgear/ephemeris/sky.hxx index a63a826b..dfc2a3d2 100644 --- a/simgear/ephemeris/sky.hxx +++ b/simgear/ephemeris/sky.hxx @@ -33,19 +33,82 @@ #include // plib include -class fgSky : ssgLeaf -{ +class FGSky { + double sun_angle; // sun angle in degrees relative to verticle + // 0 degrees = high noon + // 90 degrees = sun rise/set + // 180 degrees = darkest midnight + + sgVec3 sky_color; // base sky color + sgVec3 fog_color; // fog color + + sgVec3 origin; // coordinates of sky placement origin + // I recommend (lon, lat, 0) relative to + // your world coordinate scheme + + double lon, lat; // current lon and lat (for properly rotating + // sky) + + + ssgVertexArray *upper_ring_vl; + ssgColourArray *upper_ring_cl; + + ssgVertexArray *middle_ring_vl; + ssgColourArray *middle_ring_cl; + + ssgVertexArray *lower_ring_vl; + ssgColourArray *lower_ring_cl; + + ssgVertexArray *bottom_ring_vl; + ssgColourArray *bottom_ring_cl; + +public: + + // Constructor + FGSky( void ); + + // Destructor + ~FGSky( void ); + + // initialize the sky object and connect it into the scene graph + bool initialize(); + + // rebuild the sky colors based on current value of sun_angle, + // sky, and fog colors. This updates the color arrays for + // ssgVtxTable. + bool rebuild(); + + // enable the sky in the scene graph (default) + bool enable(); + + // disable the sky in the scene graph. The leaf node is still + // there, how ever it won't be traversed on the cullandrender + // phase. + bool disable(); + + inline void set_sun_angle( double a ) { sun_angle = a; } + inline void set_sky_color( sgVec3 color ) { + sgCopyVec3(sky_color, color); + } + inline void set_fog_color( sgVec3 color ) { + sgCopyVec3(fog_color, color); + } + inline void set_origin( sgVec3 p ) { + sgCopyVec3(origin, p); + } + inline void set_lon( double l ) { lon = l; } + inline void set_lat( double l ) { lat = l; } }; // (Re)generate the display list -void fgSkyInit( void ); +void fgSkyInit(); // (Re)calculate the sky colors at each vertex -void fgSkyColorsInit( void ); +void fgSkyColorsInit(); // Draw the Sky -void fgSkyRender( void ); +void fgSkyRender(); #endif // _SKY_HXX -- 2.39.5