]> git.mxchange.org Git - simgear.git/blob - simgear/sky/skysun.cxx
Starting to work on an independent sky implimentation that can be used by
[simgear.git] / simgear / sky / skysun.cxx
1 // skysun.hxx -- draw a sun object
2 //
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). 
7 //
8 // Separated out rendering pieces and converted to ssg by Curt Olson,
9 // March 2000
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.
14 //
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.
19 //
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.
23 //
24 // $Id$
25
26
27 // #ifdef __BORLANDC__
28 // #  define exception c_exception
29 // #endif
30 // #include <math.h>
31
32 // #include <simgear/debug/logstream.hxx>
33
34 // #include <Time/sunpos.hxx>
35 // #include <Time/light.hxx>
36 // #include <Main/options.hxx>
37
38
39 #include "skysun.hxx"
40
41
42 // Constructor
43 FGSkySun::FGSkySun( void ) {
44 }
45
46
47 // Destructor
48 FGSkySun::~FGSkySun( void ) {
49 }
50
51
52 // initialize the sun object and connect it into our scene graph root
53 bool FGSkySun::initialize() {
54     sgVec3 color;
55
56     float theta;
57     int i;
58
59     // create the scene graph for the dome
60     skysun = new ssgRoot;
61     skysun->setName( "Sky Sun" );
62
63     // set up the state
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 );
72
73     // initially seed to all white
74     sgSetVec3( color, 1.0, 1.0, 1.0 );
75
76     // generate the raw vertex data
77     sgVec3 center_vertex;
78     sgVec3 upper_vertex[12];
79     sgVec3 middle_vertex[12];
80     sgVec3 lower_vertex[12];
81     sgVec3 bottom_vertex[12];
82
83     sgSetVec3( center_vertex, 0.0, 0.0, CENTER_ELEV );
84
85     for ( i = 0; i < 12; i++ ) {
86         theta = (i * 30.0) * DEG_TO_RAD;
87
88         sgSetVec3( upper_vertex[i],
89                    cos(theta) * UPPER_RADIUS,
90                    sin(theta) * UPPER_RADIUS,
91                    UPPER_ELEV );
92         
93         sgSetVec3( middle_vertex[i],
94                    cos((double)theta) * MIDDLE_RADIUS,
95                    sin((double)theta) * MIDDLE_RADIUS,
96                    MIDDLE_ELEV );
97
98         sgSetVec3( lower_vertex[i],
99                    cos((double)theta) * LOWER_RADIUS,
100                    sin((double)theta) * LOWER_RADIUS,
101                    LOWER_ELEV );
102
103         sgSetVec3( bottom_vertex[i],
104                    cos((double)theta) * BOTTOM_RADIUS,
105                    sin((double)theta) * BOTTOM_RADIUS,
106                    BOTTOM_ELEV );
107     }
108
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 );
115     }
116     center_disk_vl->add( upper_vertex[11] );
117     center_disk_cl->add( color );
118
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 );
123
124         upper_ring_vl->add( upper_vertex[i] );
125         upper_ring_cl->add( color );
126     }
127     upper_ring_vl->add( middle_vertex[0] );
128     upper_ring_cl->add( color );
129
130     upper_ring_vl->add( upper_vertex[0] );
131     upper_ring_cl->add( color );
132
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 );
137
138         middle_ring_vl->add( middle_vertex[i] );
139         middle_ring_cl->add( color );
140     }
141     middle_ring_vl->add( lower_vertex[0] );
142     middle_ring_cl->add( color );
143
144     middle_ring_vl->add( middle_vertex[0] );
145     middle_ring_cl->add( color );
146
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 );
151
152         lower_ring_vl->add( lower_vertex[i] );
153         lower_ring_cl->add( color );
154     }
155     lower_ring_vl->add( bottom_vertex[0] );
156     lower_ring_cl->add( color );
157
158     lower_ring_vl->add( lower_vertex[0] );
159     lower_ring_cl->add( color );
160
161     // force a repaint of the sky colors with ugly defaults
162     sgVec3 fog_color;
163     sgSetVec3( fog_color, 1.0, 1.0, 1.0 );
164     repaint( color, fog_color, 0.0 );
165
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;
170
171     ssgVtxTable *center_disk, *upper_ring, *middle_ring, *lower_ring;
172
173     center_disk = new ssgVtxTable( GL_TRIANGLE_FAN, 
174                                    center_disk_vl, NULL, NULL, center_disk_cl );
175
176     upper_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, 
177                                   upper_ring_vl, NULL, NULL, upper_ring_cl );
178
179     middle_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, 
180                                    middle_ring_vl, NULL, NULL, middle_ring_cl );
181
182     lower_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, 
183                                   lower_ring_vl, NULL, NULL, lower_ring_cl );
184
185     center_disk->setState( dome_state );
186     upper_ring->setState( dome_state );
187     middle_ring->setState( dome_state );
188     lower_ring->setState( dome_state );
189
190     dome_transform->addKid( center_disk );
191     dome_transform->addKid( upper_ring );
192     dome_transform->addKid( middle_ring );
193     dome_transform->addKid( lower_ring );
194
195     dome_selector->addKid( dome_transform );
196     dome_selector->clrTraversalMaskBits( SSGTRAV_HOT );
197
198     dome->addKid( dome_selector );
199
200     return true;
201 }
202
203
204 #if 0
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,
216                  0.0000,    0.00000,
217                  282.9404,  4.7093500E-5,       
218                  1.0000000, 0.000000,   
219                  0.016709,  -1.151E-9,
220                  356.0470,  0.98560025850, t)
221 {
222     
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);
230 #else
231 #  error port me
232 #endif
233
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);
237   setTexture();
238   glTexImage2D( GL_TEXTURE_2D,
239                 0,
240                 GL_RGBA,
241                 256, 256,
242                 0,
243                 GL_RGBA, GL_UNSIGNED_BYTE,
244                 sun_texbuf);
245      
246   SunObject = gluNewQuadric();
247   if(SunObject == NULL)
248     {
249       printf("gluNewQuadric(SunObject) failed  !\n");
250       exit(0);
251     }
252   
253   //SunList = 0;
254   distance = 0.0;
255 }
256
257 Star::~Star()
258 {
259   //delete SunObject;
260   delete [] sun_texbuf;
261 }
262
263
264
265 static int texWidth = 256;      /* 64x64 is plenty */
266
267 void Star::setTexture()
268 {
269   int texSize;
270   //void *textureBuf;
271   GLubyte *p;
272   int i,j;
273   double radius;
274   
275   texSize = texWidth*texWidth;
276   
277   sun_texbuf = new GLubyte[texSize*4];
278   if (!sun_texbuf) 
279     return;  // Ugly!
280   
281   p = sun_texbuf;
282   
283   radius = (double)(texWidth / 2);
284   
285   for (i=0; i < texWidth; i++) {
286     for (j=0; j < texWidth; j++) {
287       double x, y, d;
288             
289       *p = 0xff;
290       *(p+1) = 0xff;
291       *(p+2) = 0xff;
292
293       x = fabs((double)(i - (texWidth / 2)));
294       y = fabs((double)(j - (texWidth / 2)));
295
296       d = sqrt((x * x) + (y * y));
297       if (d < radius) {
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));
301       } else {
302           *(p+3) = 0x00;
303       }
304       p += 4;
305     }
306   }
307   //gluBuild2DMipmaps(GL_TEXTURE_2D, 1, texWidth, texWidth, 
308   //        GL_LUMINANCE,
309   //        GL_UNSIGNED_BYTE, textureBuf);
310   //free(textureBuf);
311 }
312 /*************************************************************************
313  * void Jupiter::updatePosition(FGTime *t, Star *ourSun)
314  * 
315  * calculates the current position of our sun.
316  *************************************************************************/
317 void Star::updatePosition(FGTime *t)
318 {
319   double 
320     actTime, eccAnom, 
321     xv, yv, v, r,
322     xe, ye, ze, ecl;
323
324   updateOrbElements(t);
325   
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)
329   
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
334
335   lonEcl = v + w; // the sun's true longitude
336   latEcl = 0;
337
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);
342
343   // convert ecliptic coordinates to equatorial rectangular
344   // geocentric coordinates
345
346   xe = xs;
347   ye = ys * cos (ecl);
348   ze = ys * sin (ecl);
349
350   // And finally, calculate right ascension and declination
351   rightAscension = atan2 (ye, xe);
352   declination = atan2 (ze, sqrt (xe*xe + ye*ye));
353 }
354   
355 void Star::newImage(void)
356 {
357   /*static float stars[3];
358   stars[0] = 0.0;
359   stars[1] = 0.0;
360   stars[2] = 1.0;*/
361
362   fgLIGHT *l = &cur_light_params;
363   float sun_angle = l->sun_angle;
364   
365   if( sun_angle*RAD_TO_DEG < 100 ) { // else no need to draw sun
366     
367     
368     double x_2, x_4, x_8, x_10;
369     GLfloat ambient;
370     GLfloat amb[4];
371     int sun_size = 550;
372     
373     // daily variation sun gets larger near horizon
374     /*if(sun_angle*RAD_TO_DEG > 84.0 && sun_angle*RAD_TO_DEG < 95)
375       {
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));
378       }*/
379     x_2 = sun_angle * sun_angle;
380     x_4 = x_2 * x_2;
381     x_8 = x_4 * x_4;
382     x_10 = x_8 * x_2;
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;
386     
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
390     amb[3] = 1.00;
391     
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;
395     xglColor3fv(amb);
396     glPushMatrix();
397     {
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())
402         {
403           glEnable(GL_TEXTURE_2D); // TEXTURE ENABLED
404           glEnable(GL_BLEND);   // BLEND ENABLED
405           
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);
410
411           glBegin(GL_QUADS);
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);
416           glEnd();
417         }
418       xglDisable(GL_TEXTURE_2D); // TEXTURE DISABLED
419       xglDisable(GL_BLEND);     // BLEND DISABLED
420     }
421
422     glPopMatrix();
423     glDisable(GL_LIGHTING);     // LIGHTING DISABLED
424     glDisable(GL_BLEND);        // BLEND DISABLED
425     glPushMatrix();
426     {     
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);
429       xglColor4fv(amb);
430       xglTranslatef(0,60000,0);
431       gluSphere( SunObject,  sun_size, 10, 10 );
432       }
433     glPopMatrix();
434     glDisable(GL_TEXTURE_2D);   // TEXTURE DISABLED
435     glDisable(GL_BLEND);        // BLEND DISABLED  
436   }
437 }
438 #endif