1 // skysun.hxx -- draw a sun object
3 // Written by Durk Talsma. Originally started October 1997, for distribution
4 // with the FlightGear project. Version 2 was written in August and
5 // September 1998. This code is based upon algorithms and data kindly
6 // provided by Mr. Paul Schlyter. (pausch@saaf.se).
8 // Separated out rendering pieces and converted to ssg by Curt Olson,
10 // This program is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU General Public License as
12 // published by the Free Software Foundation; either version 2 of the
13 // License, or (at your option) any later version.
15 // This program is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // General Public License for more details.
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 // #ifdef __BORLANDC__
28 // # define exception c_exception
32 // #include <simgear/debug/logstream.hxx>
34 // #include <Time/sunpos.hxx>
35 // #include <Time/light.hxx>
36 // #include <Main/options.hxx>
43 FGSkySun::FGSkySun( void ) {
48 FGSkySun::~FGSkySun( void ) {
52 // initialize the sun object and connect it into our scene graph root
53 bool FGSkySun::initialize() {
59 // create the scene graph for the dome
61 skysun->setName( "Sky Sun" );
64 sun_state = new ssgSimpleState();
65 sun_state->setShadeModel( GL_SMOOTH );
66 sun_state->disable( GL_LIGHTING );
67 sun_state->disable( GL_DEPTH_TEST );
68 sun_state->disable( GL_CULL_FACE );
69 sun_state->disable( GL_TEXTURE_2D );
70 sun_state->disable( GL_COLOR_MATERIAL );
71 sun_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
73 // initially seed to all white
74 sgSetVec3( color, 1.0, 1.0, 1.0 );
76 // generate the raw vertex data
78 sgVec3 upper_vertex[12];
79 sgVec3 middle_vertex[12];
80 sgVec3 lower_vertex[12];
81 sgVec3 bottom_vertex[12];
83 sgSetVec3( center_vertex, 0.0, 0.0, CENTER_ELEV );
85 for ( i = 0; i < 12; i++ ) {
86 theta = (i * 30.0) * DEG_TO_RAD;
88 sgSetVec3( upper_vertex[i],
89 cos(theta) * UPPER_RADIUS,
90 sin(theta) * UPPER_RADIUS,
93 sgSetVec3( middle_vertex[i],
94 cos((double)theta) * MIDDLE_RADIUS,
95 sin((double)theta) * MIDDLE_RADIUS,
98 sgSetVec3( lower_vertex[i],
99 cos((double)theta) * LOWER_RADIUS,
100 sin((double)theta) * LOWER_RADIUS,
103 sgSetVec3( bottom_vertex[i],
104 cos((double)theta) * BOTTOM_RADIUS,
105 sin((double)theta) * BOTTOM_RADIUS,
109 // generate the center disk vertex/color arrays
110 center_disk_vl->add( center_vertex );
111 center_disk_cl->add( color );
112 for ( i = 11; i >= 0; i-- ) {
113 center_disk_vl->add( upper_vertex[i] );
114 center_disk_cl->add( color );
116 center_disk_vl->add( upper_vertex[11] );
117 center_disk_cl->add( color );
119 // generate the upper ring
120 for ( i = 0; i < 12; i++ ) {
121 upper_ring_vl->add( middle_vertex[i] );
122 upper_ring_cl->add( color );
124 upper_ring_vl->add( upper_vertex[i] );
125 upper_ring_cl->add( color );
127 upper_ring_vl->add( middle_vertex[0] );
128 upper_ring_cl->add( color );
130 upper_ring_vl->add( upper_vertex[0] );
131 upper_ring_cl->add( color );
133 // generate middle ring
134 for ( i = 0; i < 12; i++ ) {
135 middle_ring_vl->add( lower_vertex[i] );
136 middle_ring_cl->add( color );
138 middle_ring_vl->add( middle_vertex[i] );
139 middle_ring_cl->add( color );
141 middle_ring_vl->add( lower_vertex[0] );
142 middle_ring_cl->add( color );
144 middle_ring_vl->add( middle_vertex[0] );
145 middle_ring_cl->add( color );
147 // generate lower ring
148 for ( i = 0; i < 12; i++ ) {
149 lower_ring_vl->add( bottom_vertex[i] );
150 lower_ring_cl->add( color );
152 lower_ring_vl->add( lower_vertex[i] );
153 lower_ring_cl->add( color );
155 lower_ring_vl->add( bottom_vertex[0] );
156 lower_ring_cl->add( color );
158 lower_ring_vl->add( lower_vertex[0] );
159 lower_ring_cl->add( color );
161 // force a repaint of the sky colors with ugly defaults
163 sgSetVec3( fog_color, 1.0, 1.0, 1.0 );
164 repaint( color, fog_color, 0.0 );
166 // build the ssg scene graph sub tree for the sky and connected
167 // into the provide scene graph branch
168 dome_selector = new ssgSelector;
169 dome_transform = new ssgTransform;
171 ssgVtxTable *center_disk, *upper_ring, *middle_ring, *lower_ring;
173 center_disk = new ssgVtxTable( GL_TRIANGLE_FAN,
174 center_disk_vl, NULL, NULL, center_disk_cl );
176 upper_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
177 upper_ring_vl, NULL, NULL, upper_ring_cl );
179 middle_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
180 middle_ring_vl, NULL, NULL, middle_ring_cl );
182 lower_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
183 lower_ring_vl, NULL, NULL, lower_ring_cl );
185 center_disk->setState( dome_state );
186 upper_ring->setState( dome_state );
187 middle_ring->setState( dome_state );
188 lower_ring->setState( dome_state );
190 dome_transform->addKid( center_disk );
191 dome_transform->addKid( upper_ring );
192 dome_transform->addKid( middle_ring );
193 dome_transform->addKid( lower_ring );
195 dome_selector->addKid( dome_transform );
196 dome_selector->clrTraversalMaskBits( SSGTRAV_HOT );
198 dome->addKid( dome_selector );
205 /*************************************************************************
206 * Star::Star(FGTime *t)
207 * Public constructor for class Star
208 * Argument: The current time.
209 * the hard coded orbital elements our sun are passed to
210 * CelestialBody::CelestialBody();
211 * note that the word sun is avoided, in order to prevent some compilation
212 * problems on sun systems
213 ************************************************************************/
214 Star::Star(FGTime *t) :
215 CelestialBody (0.000000, 0.0000000000,
217 282.9404, 4.7093500E-5,
220 356.0470, 0.98560025850, t)
223 FG_LOG( FG_GENERAL, FG_INFO, "Initializing Sun Texture");
224 #ifdef GL_VERSION_1_1
225 xglGenTextures(1, &sun_texid);
226 xglBindTexture(GL_TEXTURE_2D, sun_texid);
227 #elif GL_EXT_texture_object
228 xglGenTexturesEXT(1, &sun_texid);
229 xglBindTextureEXT(GL_TEXTURE_2D, sun_texid);
234 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
235 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
236 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
238 glTexImage2D( GL_TEXTURE_2D,
243 GL_RGBA, GL_UNSIGNED_BYTE,
246 SunObject = gluNewQuadric();
247 if(SunObject == NULL)
249 printf("gluNewQuadric(SunObject) failed !\n");
260 delete [] sun_texbuf;
265 static int texWidth = 256; /* 64x64 is plenty */
267 void Star::setTexture()
275 texSize = texWidth*texWidth;
277 sun_texbuf = new GLubyte[texSize*4];
283 radius = (double)(texWidth / 2);
285 for (i=0; i < texWidth; i++) {
286 for (j=0; j < texWidth; j++) {
293 x = fabs((double)(i - (texWidth / 2)));
294 y = fabs((double)(j - (texWidth / 2)));
296 d = sqrt((x * x) + (y * y));
298 double t = 1.0 - (d / radius); // t is 1.0 at center, 0.0 at edge */
299 // inverse square looks nice
300 *(p+3) = (int)((double) 0xff * (t*t));
307 //gluBuild2DMipmaps(GL_TEXTURE_2D, 1, texWidth, texWidth,
309 // GL_UNSIGNED_BYTE, textureBuf);
312 /*************************************************************************
313 * void Jupiter::updatePosition(FGTime *t, Star *ourSun)
315 * calculates the current position of our sun.
316 *************************************************************************/
317 void Star::updatePosition(FGTime *t)
324 updateOrbElements(t);
326 actTime = fgCalcActTime(t);
327 ecl = DEG_TO_RAD * (23.4393 - 3.563E-7 * actTime); // Angle in Radians
328 eccAnom = fgCalcEccAnom(M, e); // Calculate the eccentric Anomaly (also known as solving Kepler's equation)
330 xv = cos(eccAnom) - e;
331 yv = sqrt (1.0 - e*e) * sin(eccAnom);
332 v = atan2 (yv, xv); // the sun's true anomaly
333 distance = r = sqrt (xv*xv + yv*yv); // and its distance
335 lonEcl = v + w; // the sun's true longitude
338 // convert the sun's true longitude to ecliptic rectangular
339 // geocentric coordinates (xs, ys)
340 xs = r * cos (lonEcl);
341 ys = r * sin (lonEcl);
343 // convert ecliptic coordinates to equatorial rectangular
344 // geocentric coordinates
350 // And finally, calculate right ascension and declination
351 rightAscension = atan2 (ye, xe);
352 declination = atan2 (ze, sqrt (xe*xe + ye*ye));
355 void Star::newImage(void)
357 /*static float stars[3];
362 fgLIGHT *l = &cur_light_params;
363 float sun_angle = l->sun_angle;
365 if( sun_angle*RAD_TO_DEG < 100 ) { // else no need to draw sun
368 double x_2, x_4, x_8, x_10;
373 // daily variation sun gets larger near horizon
374 /*if(sun_angle*RAD_TO_DEG > 84.0 && sun_angle*RAD_TO_DEG < 95)
376 double sun_grow = 9*fabs(94-sun_angle*RAD_TO_DEG);
377 sun_size = (int)(sun_size + sun_size * cos(sun_grow*DEG_TO_RAD));
379 x_2 = sun_angle * sun_angle;
383 ambient = (float)(0.4 * pow (1.1, - x_10 / 30.0));
384 if (ambient < 0.3) ambient = 0.3;
385 if (ambient > 1.0) ambient = 1.0;
387 amb[0] = ((ambient * 6.0) - 1.0); // minimum value = 0.8
388 amb[1] = ((ambient * 11.0) - 3.0); // minimum value = 0.3
389 amb[2] = ((ambient * 12.0) - 3.6); // minimum value = 0.0
392 if (amb[0] > 1.0) amb[0] = 1.0;
393 if (amb[1] > 1.0) amb[1] = 1.0;
394 if (amb[2] > 1.0) amb[2] = 1.0;
398 xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
399 xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
400 xglTranslatef(0,60000,0);
401 if (current_options.get_textures())
403 glEnable(GL_TEXTURE_2D); // TEXTURE ENABLED
404 glEnable(GL_BLEND); // BLEND ENABLED
406 // glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
407 glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
408 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
409 glBindTexture(GL_TEXTURE_2D, sun_texid);
412 glTexCoord2f(0.0f, 0.0f); glVertex3f(-5000, 0.0, -5000);
413 glTexCoord2f(1.0f, 0.0f); glVertex3f( 5000, 0.0, -5000);
414 glTexCoord2f(1.0f, 1.0f); glVertex3f( 5000, 0.0, 5000);
415 glTexCoord2f(0.0f, 1.0f); glVertex3f(-5000, 0.0, 5000);
418 xglDisable(GL_TEXTURE_2D); // TEXTURE DISABLED
419 xglDisable(GL_BLEND); // BLEND DISABLED
423 glDisable(GL_LIGHTING); // LIGHTING DISABLED
424 glDisable(GL_BLEND); // BLEND DISABLED
427 xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
428 xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
430 xglTranslatef(0,60000,0);
431 gluSphere( SunObject, sun_size, 10, 10 );
434 glDisable(GL_TEXTURE_2D); // TEXTURE DISABLED
435 glDisable(GL_BLEND); // BLEND DISABLED