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.
29 #include <simgear/constants.h>
36 FGSkySun::FGSkySun( void ) {
41 FGSkySun::~FGSkySun( void ) {
45 // initialize the sun object and connect it into our scene graph root
46 bool FGSkySun::initialize() {
48 // create the scene graph for the dome
50 skysun->setName( "Sky Sun" );
53 orb_state = new ssgSimpleState();
54 orb_state->setShadeModel( GL_SMOOTH );
55 orb_state->disable( GL_LIGHTING );
56 orb_state->disable( GL_DEPTH_TEST );
57 orb_state->disable( GL_CULL_FACE );
58 orb_state->disable( GL_TEXTURE_2D );
59 orb_state->disable( GL_COLOR_MATERIAL );
60 orb_state->setMaterial( GL_AMBIENT_AND_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
62 ssgBranch *orb = ssgMakeSphere( orb_state, 550.0, 10, 10 );
64 // force a repaint of the sun colors with arbitrary defaults
67 // build the ssg scene graph sub tree for the sky and connected
68 // into the provide scene graph branch
69 sun_selector = new ssgSelector;
70 sun_transform = new ssgTransform;
72 // orb->setState( orb_state );
74 sun_transform->addKid( orb );
76 sun_selector->addKid( sun_transform );
77 sun_selector->clrTraversalMaskBits( SSGTRAV_HOT );
79 skysun->addKid( sun_selector );
85 // repaint the sun colors based on current value of sun_angle in
86 // degrees relative to verticle
87 // 0 degrees = high noon
88 // 90 degrees = sun rise/set
89 // 180 degrees = darkest midnight
90 bool FGSkySun::repaint( double sun_angle ) {
91 if ( sun_angle * RAD_TO_DEG < 100 ) {
92 // else sun is well below horizon (so no point in repainting it)
94 // x_10 = sun_angle^10
95 double x_10 = sun_angle * sun_angle * sun_angle * sun_angle * sun_angle
96 * sun_angle * sun_angle * sun_angle * sun_angle * sun_angle;
98 float ambient = (float)(0.4 * pow (1.1, - x_10 / 30.0));
99 if (ambient < 0.3) { ambient = 0.3; }
100 if (ambient > 1.0) { ambient = 1.0; }
104 (ambient * 6.0) - 1.0, // minimum value = 0.8
105 (ambient * 11.0) - 3.0, // minimum value = 0.3
106 (ambient * 12.0) - 3.6 // minimum value = 0.0
109 if (color[0] > 1.0) color[0] = 1.0;
110 if (color[1] > 1.0) color[1] = 1.0;
111 if (color[2] > 1.0) color[2] = 1.0;
113 orb_state->setMaterial( GL_AMBIENT_AND_DIFFUSE,
114 color[0], color[1], color[2], 1.0 );
121 // reposition the sun at the specified right ascension and declination
122 bool FGSkySun::reposition( double rightAscension, double declination ) {
127 // xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
128 sgSetVec3( axis, 0.0, 0.0, 1.0 );
129 sgMakeRotMat4( RA, (rightAscension * RAD_TO_DEG) - 90.0, axis );
131 // xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
132 sgSetVec3( axis, 1.0, 0.0, 0.0 );
133 sgMakeRotMat4( DEC, declination * RAD_TO_DEG, axis );
135 // xglTranslatef(0,60000,0);
136 sgSetVec3( v, 0.0, 60000.0, 0.0 );
137 sgMakeTransMat4( T, v );
140 sgCopyMat4( TRANSFORM, RA );
141 sgPreMultMat4( TRANSFORM, DEC );
142 sgPreMultMat4( TRANSFORM, T );
145 sgSetCoord( &skypos, TRANSFORM );
147 sun_transform->setTransform( &skypos );
154 bool FGSkySun::draw() {
155 ssgCullAndDraw( skysun );
162 /*************************************************************************
163 * Star::Star(FGTime *t)
164 * Public constructor for class Star
165 * Argument: The current time.
166 * the hard coded orbital elements our sun are passed to
167 * CelestialBody::CelestialBody();
168 * note that the word sun is avoided, in order to prevent some compilation
169 * problems on sun systems
170 ************************************************************************/
171 Star::Star(FGTime *t) :
172 CelestialBody (0.000000, 0.0000000000,
174 282.9404, 4.7093500E-5,
177 356.0470, 0.98560025850, t)
180 FG_LOG( FG_GENERAL, FG_INFO, "Initializing Sun Texture");
181 #ifdef GL_VERSION_1_1
182 xglGenTextures(1, &sun_texid);
183 xglBindTexture(GL_TEXTURE_2D, sun_texid);
184 #elif GL_EXT_texture_object
185 xglGenTexturesEXT(1, &sun_texid);
186 xglBindTextureEXT(GL_TEXTURE_2D, sun_texid);
191 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
192 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
193 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
195 glTexImage2D( GL_TEXTURE_2D,
200 GL_RGBA, GL_UNSIGNED_BYTE,
203 SunObject = gluNewQuadric();
204 if(SunObject == NULL)
206 printf("gluNewQuadric(SunObject) failed !\n");
217 delete [] sun_texbuf;
222 static int texWidth = 256; /* 64x64 is plenty */
224 void Star::setTexture()
232 texSize = texWidth*texWidth;
234 sun_texbuf = new GLubyte[texSize*4];
240 radius = (double)(texWidth / 2);
242 for (i=0; i < texWidth; i++) {
243 for (j=0; j < texWidth; j++) {
250 x = fabs((double)(i - (texWidth / 2)));
251 y = fabs((double)(j - (texWidth / 2)));
253 d = sqrt((x * x) + (y * y));
255 double t = 1.0 - (d / radius); // t is 1.0 at center, 0.0 at edge */
256 // inverse square looks nice
257 *(p+3) = (int)((double) 0xff * (t*t));
264 //gluBuild2DMipmaps(GL_TEXTURE_2D, 1, texWidth, texWidth,
266 // GL_UNSIGNED_BYTE, textureBuf);
269 /*************************************************************************
270 * void Jupiter::updatePosition(FGTime *t, Star *ourSun)
272 * calculates the current position of our sun.
273 *************************************************************************/
274 void Star::updatePosition(FGTime *t)
281 updateOrbElements(t);
283 actTime = fgCalcActTime(t);
284 ecl = DEG_TO_RAD * (23.4393 - 3.563E-7 * actTime); // Angle in Radians
285 eccAnom = fgCalcEccAnom(M, e); // Calculate the eccentric Anomaly (also known as solving Kepler's equation)
287 xv = cos(eccAnom) - e;
288 yv = sqrt (1.0 - e*e) * sin(eccAnom);
289 v = atan2 (yv, xv); // the sun's true anomaly
290 distance = r = sqrt (xv*xv + yv*yv); // and its distance
292 lonEcl = v + w; // the sun's true longitude
295 // convert the sun's true longitude to ecliptic rectangular
296 // geocentric coordinates (xs, ys)
297 xs = r * cos (lonEcl);
298 ys = r * sin (lonEcl);
300 // convert ecliptic coordinates to equatorial rectangular
301 // geocentric coordinates
307 // And finally, calculate right ascension and declination
308 rightAscension = atan2 (ye, xe);
309 declination = atan2 (ze, sqrt (xe*xe + ye*ye));
312 void Star::newImage(void)
314 /*static float stars[3];
319 fgLIGHT *l = &cur_light_params;
320 float sun_angle = l->sun_angle;
322 if( sun_angle*RAD_TO_DEG < 100 ) { // else no need to draw sun
325 double x_2, x_4, x_8, x_10;
330 // daily variation sun gets larger near horizon
331 /*if(sun_angle*RAD_TO_DEG > 84.0 && sun_angle*RAD_TO_DEG < 95)
333 double sun_grow = 9*fabs(94-sun_angle*RAD_TO_DEG);
334 sun_size = (int)(sun_size + sun_size * cos(sun_grow*DEG_TO_RAD));
336 x_2 = sun_angle * sun_angle;
340 ambient = (float)(0.4 * pow (1.1, - x_10 / 30.0));
341 if (ambient < 0.3) ambient = 0.3;
342 if (ambient > 1.0) ambient = 1.0;
344 amb[0] = ((ambient * 6.0) - 1.0); // minimum value = 0.8
345 amb[1] = ((ambient * 11.0) - 3.0); // minimum value = 0.3
346 amb[2] = ((ambient * 12.0) - 3.6); // minimum value = 0.0
349 if (amb[0] > 1.0) amb[0] = 1.0;
350 if (amb[1] > 1.0) amb[1] = 1.0;
351 if (amb[2] > 1.0) amb[2] = 1.0;
355 xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
356 xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
357 xglTranslatef(0,60000,0);
358 if (current_options.get_textures())
360 glEnable(GL_TEXTURE_2D); // TEXTURE ENABLED
361 glEnable(GL_BLEND); // BLEND ENABLED
363 // glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
364 glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
365 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
366 glBindTexture(GL_TEXTURE_2D, sun_texid);
369 glTexCoord2f(0.0f, 0.0f); glVertex3f(-5000, 0.0, -5000);
370 glTexCoord2f(1.0f, 0.0f); glVertex3f( 5000, 0.0, -5000);
371 glTexCoord2f(1.0f, 1.0f); glVertex3f( 5000, 0.0, 5000);
372 glTexCoord2f(0.0f, 1.0f); glVertex3f(-5000, 0.0, 5000);
375 xglDisable(GL_TEXTURE_2D); // TEXTURE DISABLED
376 xglDisable(GL_BLEND); // BLEND DISABLED
380 glDisable(GL_LIGHTING); // LIGHTING DISABLED
381 glDisable(GL_BLEND); // BLEND DISABLED
384 xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
385 xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
387 xglTranslatef(0,60000,0);
388 gluSphere( SunObject, sun_size, 10, 10 );
391 glDisable(GL_TEXTURE_2D); // TEXTURE DISABLED
392 glDisable(GL_BLEND); // BLEND DISABLED