]> git.mxchange.org Git - flightgear.git/blob - Main/GLmain.c
Elevator trim added.
[flightgear.git] / Main / GLmain.c
1 /**************************************************************************
2  * GLmain.c -- top level sim routines
3  *
4  * Written by Curtis Olson for OpenGL, started May 1997.
5  *
6  * Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
7  *
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.
12  *
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.
17  *
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.
21  *
22  * $Id$
23  * (Log is kept at end of this file)
24  **************************************************************************/
25
26
27 #include <math.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <signal.h>    /* for timer routines */
31
32 #if defined(__WATCOMC__) || defined(__MSC__)
33 #  include <time.h>
34 #else
35 #  include <sys/time.h>
36 #endif
37
38 #ifdef GLUT
39     #include <GL/glut.h>
40     #include "GLUTkey.h"
41 #elif MESA_TK
42     /* assumes -I/usr/include/mesa in compile command */
43     #include "gltk.h"
44     #include "GLTKkey.h"
45 #endif
46
47 #include "../aircraft/aircraft.h"
48 #include "../scenery/scenery.h"
49 #include "../mat3/mat3.h"
50
51
52 #define DEG_TO_RAD       0.017453292
53 #define RAD_TO_DEG       57.29577951
54
55 /* This is a record containing all the info for the aircraft currently
56    being operated */
57 struct aircraft_params current_aircraft;
58
59 /* view parameters */
60 static GLfloat win_ratio = 1.0;
61
62 /* sun direction */
63 static GLfloat sun_vec[4] = {-3.0, 1.0, 2.0, 0.0 };
64
65 /* temporary hack */
66 extern struct mesh *mesh_ptr;
67 /* Function prototypes */
68 GLint fgSceneryCompile();
69 static void fgSceneryDraw();
70 /* pointer to terrain mesh structure */
71 static GLint mesh;
72
73 /* Another hack */
74 double fogDensity = 2000.0;
75
76 /* Another hack */
77 #define DEFAULT_MODEL_HZ 20
78 #define DEFAULT_MULTILOOP 6
79 double Simtime;
80
81
82 /**************************************************************************
83  * fgInitVisuals() -- Initialize various GL/view parameters
84  **************************************************************************/
85
86 static void fgInitVisuals() {
87     /* if the 4th field is 0.0, this specifies a direction ... */
88     static GLfloat color[4] = { 0.3, 0.7, 0.2, 1.0 };
89     static GLfloat fogColor[4] = {0.65, 0.65, 0.85, 1.0};
90     
91     glEnable( GL_DEPTH_TEST );
92     glFrontFace(GL_CW);
93     glEnable( GL_CULL_FACE );
94
95     /* If enabled, normal vectors specified with glNormal are scaled
96        to unit length after transformation.  See glNormal. */
97     glEnable( GL_NORMALIZE );
98
99     glLightfv( GL_LIGHT0, GL_POSITION, sun_vec );
100     glEnable( GL_LIGHTING );
101     glEnable( GL_LIGHT0 );
102
103     glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color );
104     glShadeModel( GL_FLAT ); /* glShadeModel( GL_SMOOTH ); */
105
106     glEnable( GL_FOG );
107     glFogi (GL_FOG_MODE, GL_LINEAR);
108     /* glFogf (GL_FOG_START, 1.0); */
109     glFogf (GL_FOG_END, fogDensity);
110     glFogfv (GL_FOG_COLOR, fogColor);
111     /* glFogf (GL_FOG_DENSITY, fogDensity); */
112     /* glHint (GL_FOG_HINT, GL_FASTEST); */
113
114     glClearColor(0.6, 0.6, 0.9, 1.0);
115 }
116
117
118 /**************************************************************************
119  * Update the view volume, position, and orientation
120  **************************************************************************/
121
122 static void fgUpdateViewParams() {
123     double pos_x, pos_y, pos_z;
124     struct flight_params *f;
125     MAT3mat R, tmp;
126     MAT3vec vec, forward, up;
127
128     f = &current_aircraft.flight;
129
130     /* Tell GL we are about to modify the projection parameters */
131     glMatrixMode(GL_PROJECTION);
132     glLoadIdentity();
133     gluPerspective(45.0, 1.0/win_ratio, 1.0, 6000.0);
134
135     glMatrixMode(GL_MODELVIEW);
136     glLoadIdentity();
137     
138     /* calculate position in arc seconds */
139     pos_x = (FG_Longitude * RAD_TO_DEG) * 3600.0;
140     pos_y = (FG_Latitude   * RAD_TO_DEG) * 3600.0;
141     pos_z = FG_Altitude * 0.01; /* (Convert feet to aproximate arcsecs) */
142
143     /* build current rotation matrix */
144     MAT3_SET_VEC(vec, 1.0, 0.0, 0.0);
145     MAT3rotate(R, vec, FG_Phi);
146     /* printf("Roll matrix\n"); */
147     /* MAT3print(R, stdout); */
148
149     MAT3_SET_VEC(vec, 0.0, -1.0, 0.0);
150     MAT3rotate(tmp, vec, FG_Theta);
151     /* printf("Pitch matrix\n"); */
152     /* MAT3print(tmp, stdout); */
153     MAT3mult(R, R, tmp);
154
155     MAT3_SET_VEC(vec, 0.0, 0.0, -1.0);
156     MAT3rotate(tmp, vec, M_PI + M_PI_2 + FG_Psi );
157     /* printf("Yaw matrix\n");
158     MAT3print(tmp, stdout); */
159     MAT3mult(R, R, tmp);
160
161     /* MAT3print(R, stdout); */
162
163     /* generate the current forward and up vectors */
164     MAT3_SET_VEC(vec, 1.0, 0.0, 0.0);
165     MAT3mult_vec(forward, vec, R);
166     printf("Forward vector is (%.2f,%.2f,%.2f)\n", forward[0], forward[1], 
167            forward[2]);
168     MAT3_SET_VEC(vec, 0.0, 0.0, 1.0);
169     MAT3mult_vec(up, vec, R);
170
171     gluLookAt(pos_x, pos_y, pos_z,
172               pos_x + forward[0], pos_y + forward[1], pos_z + forward[2],
173               up[0], up[1], up[2]);
174
175     glLightfv( GL_LIGHT0, GL_POSITION, sun_vec );
176 }
177
178
179 /**************************************************************************
180  * Update all Visuals (redraws anything graphics related)
181  **************************************************************************/
182
183 static void fgUpdateVisuals( void ) {
184     /* update view volume parameters */
185     fgUpdateViewParams();
186
187     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
188
189     /* Tell GL we are switching to model view parameters */
190     glMatrixMode(GL_MODELVIEW);
191     /* glLoadIdentity(); */
192
193     /* draw terrain mesh */
194     fgSceneryDraw();
195
196     #ifdef GLUT
197       glutSwapBuffers();
198     #elif MESA_TK
199       tkSwapBuffers();
200     #endif
201 }
202
203
204 /**************************************************************************
205  * Timer management routines
206  **************************************************************************/
207
208 static struct itimerval t, ot;
209
210 /* This routine catches the SIGALRM */
211 void fgTimerCatch() {
212     struct flight_params *f;
213     static double lastSimtime = -99.9;
214     int Overrun;
215
216     /* ignore any SIGALRM's until we come back from our EOM iteration */
217     signal(SIGALRM, SIG_IGN);
218
219     f = &current_aircraft.flight;
220
221     /* printf("In fgTimerCatch()\n"); */
222
223     Overrun = (lastSimtime == Simtime);
224
225     /* add this back in when you get simtime working */
226     /* if ( Overrun ) {
227         printf("OVERRUN!!!\n");
228     } */
229
230     /* update the flight model */
231     fgFlightModelUpdate(FG_LARCSIM, f, DEFAULT_MULTILOOP);
232
233     lastSimtime = Simtime;
234     signal(SIGALRM, fgTimerCatch);
235 }
236
237 /* this routine initializes the interval timer to generate a SIGALRM after
238  * the specified interval (dt) */
239 void fgTimerInit(float dt) {
240     int terr;
241     int isec;
242     float usec;
243
244     isec = (int) dt;
245     usec = 1000000* (dt - (float) isec);
246
247     t.it_interval.tv_sec = isec;
248     t.it_interval.tv_usec = usec;
249     t.it_value.tv_sec = isec;
250     t.it_value.tv_usec = usec;
251     /* printf("fgTimerInit() called\n"); */
252     fgTimerCatch();   /* set up for SIGALRM signal catch */
253     terr = setitimer( ITIMER_REAL, &t, &ot );
254     if (terr) perror("Error returned from setitimer");
255 }
256
257
258 /**************************************************************************
259  * Scenery management routines
260  **************************************************************************/
261
262 static void fgSceneryInit() {
263     /* make terrain mesh */
264     mesh = fgSceneryCompile();
265 }
266
267
268 /* create the terrain mesh */
269 GLint fgSceneryCompile() {
270     GLint mesh;
271
272     mesh = mesh2GL(mesh_ptr);
273
274     return(mesh);
275 }
276
277
278 /* draw the terrain mesh */
279 static void fgSceneryDraw() {
280     glCallList(mesh);
281 }
282
283
284 /* What should we do when we have nothing else to do?  How about get
285  * ready for the next move?*/
286 static void fgMainLoop( void )
287 {
288     fgSlewUpdate();
289     aircraft_debug(1);
290
291     fgUpdateVisuals();
292 }
293
294
295 /**************************************************************************
296  * Handle new window size or exposure
297  **************************************************************************/
298
299 static void fgReshape( int width, int height ) {
300     /* Do this so we can call fgReshape(0,0) ourselves without having to know
301      * what the values of width & height are. */
302     if ( (height > 0) && (width > 0) ) {
303         win_ratio = (GLfloat) height / (GLfloat) width;
304     }
305
306     /* Inform gl of our view window size */
307     glViewport(0, 0, (GLint)width, (GLint)height);
308
309     fgUpdateViewParams();
310     
311     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
312 }
313
314
315 /**************************************************************************
316  * Main ...
317  **************************************************************************/
318
319 int main( int argc, char *argv[] ) {
320     struct flight_params *f;
321
322     f = &current_aircraft.flight;
323
324     /* parse the scenery file */
325     parse_scenery(argv[1]);
326
327     #ifdef GLUT
328       /* initialize GLUT */
329       glutInit(&argc, argv);
330
331       /* Define Display Parameters */
332       glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
333
334       /* Define initial window size */
335       glutInitWindowSize(640, 480);
336
337       /* Initialize the main window */
338       glutCreateWindow("Terrain Demo");
339     #elif MESA_TK
340       /* Define initial window size */
341       tkInitPosition(0, 0, 640, 480);
342
343       /* Define Display Parameters */
344       tkInitDisplayMode( TK_RGB | TK_DEPTH | TK_DOUBLE | TK_DIRECT );
345
346       /* Initialize the main window */
347       if (tkInitWindow("Terrain Demo") == GL_FALSE) {
348           tkQuit();
349       }
350     #endif
351
352     /* setup view parameters, only makes GL calls */
353     fgInitVisuals();
354
355     /* Globe Aiport, AZ */
356     FG_Runway_altitude = 3234.5;
357     FG_Runway_latitude = 120070.41;
358     FG_Runway_longitude = -398391.28;
359     FG_Runway_heading = 102.0 * DEG_TO_RAD;
360
361     /* Initial Position */
362     FG_Latitude  = (  120070.41 / 3600.0 ) * DEG_TO_RAD;
363     FG_Longitude = ( -398391.28 / 3600.0 ) * DEG_TO_RAD;
364     FG_Altitude  = FG_Runway_altitude + 3.758099;
365
366     printf("Initial position is: (%.4f, %.4f, %.2f)\n", FG_Latitude, 
367            FG_Longitude, FG_Altitude);
368
369   
370     /* Initial Velocity */
371     FG_V_north = 0.0 /*  7.287719E+00 */;
372     FG_V_east  = 0.0 /*  1.521770E+03 */;
373     FG_V_down  = 0.0 /* -1.265722E-05 */;
374
375     /* Initial Orientation */
376     FG_Phi   = -2.658474E-06;
377     FG_Theta =  7.401790E-03;
378     FG_Psi   =  102.0 * DEG_TO_RAD;
379
380     /* Initial Angular B rates */
381     FG_P_body = 7.206685E-05;
382     FG_Q_body = 0.000000E+00;
383     FG_R_body = 9.492658E-05;
384
385     FG_Earth_position_angle = 0.000000E+00;
386
387     /* Mass properties and geometry values */
388     FG_Mass = 8.547270E+01;
389     FG_I_xx = 1.048000E+03;
390     FG_I_yy = 3.000000E+03;
391     FG_I_zz = 3.530000E+03;
392     FG_I_xz = 0.000000E+00;
393
394     /* CG position w.r.t. ref. point */
395     FG_Dx_cg = 0.000000E+00;
396     FG_Dy_cg = 0.000000E+00;
397     FG_Dz_cg = 0.000000E+00;
398
399     /* Set initial position and slew parameters */
400     /* fgSlewInit(-398391.3, 120070.41, 244, 3.1415); */ /* GLOBE Airport */
401     /* fgSlewInit(-335340,162540, 15, 4.38); */
402     /* fgSlewInit(-398673.28,120625.64, 53, 4.38); */
403
404     fgFlightModelInit(FG_LARCSIM, f, 1.0/(DEFAULT_MODEL_HZ*DEFAULT_MULTILOOP));
405
406     /* build all objects */
407     fgSceneryInit();
408
409     /* initialize timer */
410     fgTimerInit( 1.0 / DEFAULT_MODEL_HZ );
411
412     #ifdef GLUT
413       /* call fgReshape() on window resizes */
414       glutReshapeFunc( fgReshape );
415
416       /* call key() on keyboard event */
417       glutKeyboardFunc( GLUTkey );
418       glutSpecialFunc( GLUTspecialkey );
419
420       /* call fgMainLoop() whenever there is nothing else to do */
421       glutIdleFunc( fgMainLoop );
422
423       /* draw the scene */
424       glutDisplayFunc( fgUpdateVisuals );
425
426       /* pass control off to the GLUT event handler */
427       glutMainLoop();
428     #elif MESA_TK
429       /* call fgReshape() on expose events */
430       tkExposeFunc( fgReshape );
431
432       /* call fgReshape() on window resizes */
433       tkReshapeFunc( fgReshape );
434
435       /* call key() on keyboard event */
436       tkKeyDownFunc( GLTKkey );
437
438       /* call fgMainLoop() whenever there is nothing else to do */
439       tkIdleFunc( fgMainLoop );
440
441       /* draw the scene */
442       tkDisplayFunc( fgUpdateVisuals );
443
444       /* pass control off to the tk event handler */
445       tkExec();
446     #endif
447
448     return(0);
449 }
450
451
452 /* $Log$
453 /* Revision 1.11  1997/05/31 19:16:25  curt
454 /* Elevator trim added.
455 /*
456  * Revision 1.10  1997/05/31 04:13:52  curt
457  * WE CAN NOW FLY!!!
458  *
459  * Continuing work on the LaRCsim flight model integration.
460  * Added some MSFS-like keyboard input handling.
461  *
462  * Revision 1.9  1997/05/30 19:27:01  curt
463  * The LaRCsim flight model is starting to look like it is working.
464  *
465  * Revision 1.8  1997/05/30 03:54:10  curt
466  * Made a bit more progress towards integrating the LaRCsim flight model.
467  *
468  * Revision 1.7  1997/05/29 22:39:49  curt
469  * Working on incorporating the LaRCsim flight model.
470  *
471  * Revision 1.6  1997/05/29 12:31:39  curt
472  * Minor tweaks, moving towards general flight model integration.
473  *
474  * Revision 1.5  1997/05/29 02:33:23  curt
475  * Updated to reflect changing interfaces in other "modules."
476  *
477  * Revision 1.4  1997/05/27 17:44:31  curt
478  * Renamed & rearranged variables and routines.   Added some initial simple
479  * timer/alarm routines so the flight model can be updated on a regular 
480  * interval.
481  *
482  * Revision 1.3  1997/05/23 15:40:25  curt
483  * Added GNU copyright headers.
484  * Fog now works!
485  *
486  * Revision 1.2  1997/05/23 00:35:12  curt
487  * Trying to get fog to work ...
488  *
489  * Revision 1.1  1997/05/21 15:57:51  curt
490  * Renamed due to added GLUT support.
491  *
492  * Revision 1.3  1997/05/19 18:22:42  curt
493  * Parameter tweaking ... starting to stub in fog support.
494  *
495  * Revision 1.2  1997/05/17 00:17:34  curt
496  * Trying to stub in support for standard OpenGL.
497  *
498  * Revision 1.1  1997/05/16 16:05:52  curt
499  * Initial revision.
500  *
501  */