]> git.mxchange.org Git - flightgear.git/blob - Simulator/Cockpit/panel.cxx
Initial revision.
[flightgear.git] / Simulator / Cockpit / panel.cxx
1 // panel.cxx -- routines to draw an instrument panel
2 //
3 // Written by Friedemann Reinhard, started June 1998.
4 //
5 // Copyright(C)1998 Friedemann Reinhard-reinhard@theorie2.physik.uni-erlangen.de
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #ifdef HAVE_WINDOWS_H          
29 #  include <windows.h>
30 #endif
31
32 #define FILLED true
33
34 #include <GL/glut.h>
35 #include <XGL/xgl.h>
36
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <string>
41 #include <math.h>
42
43 #include <Debug/logstream.hxx>
44 #include <Aircraft/aircraft.hxx>
45 #include <Main/options.hxx>
46 #include <Main/views.hxx>
47 #include <Objects/texload.h>
48
49 #include "panel.hxx"
50 #include "cockpit.hxx"
51 #include "hud.hxx"
52
53 GLubyte *imag;
54 int imag_width, imag_height;
55
56 GLubyte *img;
57 int img_width, img_height;
58
59 static float value[4];
60 static GLuint panel_tex_id[2];
61 static GLubyte tex[32][128][3];
62 static float alphahist;
63 static float Xzoom, Yzoom;
64 static Pointer pointer[20];
65 static int NumPoint = 4;
66 static int i = 0;
67 static GLdouble mvmatrix[16];
68 static GLdouble matrix[16];
69 static double var[20];
70 static double offset;
71 static float alpha;
72 static int n1;
73 static int n2;
74
75 static GLfloat Wings[] = {-1.25, -28.125, 1.255, -28.125, 1.255, 28.125,                                  -1.25, 28.125};
76 static GLfloat Elevator[] = { 3.0, -10.9375, 4.5, -10.9375, 4.5, 10.9375,                                  3.0, 10.9375};
77 static GLfloat Rudder[] = {2.0, -0.45, 10.625, -0.45, 10.625, 0.55,                                           2.0, 0.55};
78
79 FGPanel* FGPanel::OurPanel = 0;
80
81 // FGPanel::FGPanel() - constructor to initialize the panel.                 
82 FGPanel::FGPanel(void){
83
84     string tpath;
85     int x, y;
86     FILE *f;
87     char line[256];
88     GLint test;
89     GLubyte tex[262144];
90
91 OurPanel = this;   
92
93     Xzoom = (float)((float)(current_view.get_winWidth())/1024);
94     Yzoom = (float)((float)(current_view.get_winHeight())/768);
95
96 test_instr[3] = new FGTexInstrument(144.375, 166.875, 4, 32, 3, 30, 15.0,                                           260.0, -20.0, 360, 65, 193, 0);
97 test_instr[4] = new FGTexInstrument(358, 52, 4, 30, 3, 30, -3.0, 3.0, 100,                                          440, 66.15, 66, 2);
98 test_instr[5] = new FGTexInstrument(357.5, 167, 5, 25, 4, 30, 0, 10000, 0,                                          360, 194, 191, 1);
99 test_instr[6] = new FGTexInstrument(357.5, 167, 5, 32, 3, 30, 0, 3000, 0,                                           1080, 194, 191, 1);
100 test_instr[0] = new FGHorizon(251, 166.75);
101 test_instr[1] = new FGTurnCoordinator(143.75, 51.75);
102 //test_instr[2] = new FGRpmGauge(462.5, 133);
103 test_instr[2] = new FGTexInstrument(462.5, 133, 10, 20, 5.5, 60, 0.0, 1.0,                                            -67, 180, 174, 83, 3); 
104
105 // FontList = glGenLists (256);
106 // glListBase(FontList);
107 // InitLists();
108
109 #ifdef GL_VERSION_1_1
110     xglGenTextures(2, panel_tex_id);
111     xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]);
112 #elif GL_EXT_texture_object
113     xglGenTexturesEXT(2, panel_tex_id);
114     xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]);
115 #else
116 #  error port me
117 #endif
118
119     xglMatrixMode(GL_PROJECTION);
120     xglPushMatrix();
121     xglLoadIdentity();
122     xglViewport(0, 0, 640, 480);
123     xglOrtho(0, 640, 0, 480, 1, -1);
124     xglMatrixMode(GL_MODELVIEW);
125     xglPushMatrix();
126     xglLoadIdentity();
127     xglPixelStorei(GL_UNPACK_ALIGNMENT, 4);
128     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
129     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);   
130     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
131     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
132
133     // load in the texture data 
134     
135     xglPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
136     tpath = current_options.get_fg_root() + "/Textures/gauges.rgb";
137     if((img = read_rgb_texture( (char *)tpath.c_str(), &img_width,                      &img_height ))==NULL){
138     }
139
140     xglPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
141     tpath = current_options.get_fg_root() + "/Textures/gauges2.rgb";
142     if((imag = read_rgb_texture( (char *)tpath.c_str(), &imag_width,                     &imag_height ))==NULL){
143     }
144
145     xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
146
147     tpath = current_options.get_fg_root() + "/Textures/Fullone.rgb";
148     if ((background = read_rgb_texture( (char *)tpath.c_str(), &width,                         &height ))==NULL ){
149         }
150
151 //    for(y=0;y<256;y++){
152 //      for(x=0;x<256;x++){
153 //      tex[(y+x*256)*3] = imag[(y+x*256)*3];
154 //      tex[(y+x*256)*3 + 1] = imag[(y+x*256)*3 + 1];
155 //      tex[(y+x*256)*3 + 2] = imag[(y+x*256)*3 + 2];
156 //      tex[(y+x*256)*3 + 3] = (imag[(y+x*256)*3 + 1] + imag[(y+x*256)*3 + 2]   //                               + imag[(y+x*256)*3 + 0])/3;
157 //      
158 //      if((imag[(y+x*256)*3] < 150) && (imag[(y+x*256)*3 +1] < 150) &&         //             (imag[(y+x*256)*3 + 2] < 150) ){
159 //              tex[(y+x*256)*3 + 3] = 0x0;
160 //               }
161 //           else{
162 //             tex[(y+x*256)*3 + 3] = 0xff;
163 //             }
164 //       }
165 // }
166
167     xglPixelZoom(Xzoom, Yzoom);
168     xglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
169     xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
170       xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
171     xglRasterPos2i(0,0);
172     xglPixelZoom(Xzoom, Yzoom);
173     xglPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
174     xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB,                                   GL_UNSIGNED_BYTE, imag);
175                   
176 #ifdef GL_VERSION_1_1
177     xglBindTexture(GL_TEXTURE_2D, panel_tex_id[0]);
178 #elif GL_EXT_texture_object
179     xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[0]);
180 #else
181 #  error port me
182 #endif
183     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
184     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);   
185     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
186     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
187    xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB,                                  GL_UNSIGNED_BYTE, (GLvoid *)(img)); 
188                   
189     xglMatrixMode(GL_MODELVIEW);
190     xglPopMatrix();
191 }
192
193 void FGPanel::ReInit( int x, int y, int finx, int finy){
194     fgOPTIONS *o;
195     int i;
196     GLint buffer;
197     
198     o = &current_options;
199     
200     xglDisable(GL_DEPTH_TEST);
201     
202     Xzoom = (float)((float)(current_view.get_winWidth())/1024);
203     Yzoom = (float)((float)(current_view.get_winHeight())/768);
204     
205     // save the current buffer state
206     xglGetIntegerv(GL_DRAW_BUFFER, &buffer);
207     
208     // and enable both buffers for writing
209     xglDrawBuffer(GL_FRONT_AND_BACK);
210     
211     xglMatrixMode(GL_PROJECTION);
212     xglPushMatrix();
213     xglLoadIdentity();
214     xglViewport(0, 0, 640, 480);
215     xglOrtho(0, 640, 0, 480, 1, -1);
216     xglMatrixMode(GL_MODELVIEW);
217     xglPushMatrix();
218     xglLoadIdentity();
219      xglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
220     xglPixelZoom(Xzoom, Yzoom);
221     xglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
222     xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
223     xglPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
224     xglPixelStorei(GL_UNPACK_SKIP_ROWS, y);
225     xglRasterPos2i(x, y);
226     xglPixelZoom(Xzoom, Yzoom);
227     xglDrawPixels(finx - x, finy - y, GL_RGB, GL_UNSIGNED_BYTE,                     (GLvoid *)(background));
228
229     // restore original buffer state
230     xglDrawBuffer( buffer );
231     xglEnable(GL_DEPTH_TEST);
232 }
233
234 void FGPanel::Update ( void ) {
235
236     float alpha;
237     double pitch;
238     double roll;
239     float alpharad;
240     double speed;
241     int i;
242     
243 //    static bool beech_drawn = false;
244 //    char *test = "ALM 100";
245                           
246     var[0] = get_speed() /* * 1.4 */; // We have to multiply the airspeed by a 
247                                 // factor, to simulate flying a Bonanza 
248     var[1] = get_altitude();
249     var[2] = get_climb_rate() / 1000.0; 
250     var[3] = get_throttleval();
251
252     xglMatrixMode(GL_PROJECTION);
253     xglPushMatrix();
254     xglLoadIdentity();
255     xglOrtho(0, 640, 0, 480, 10, -10);
256     xglMatrixMode(GL_MODELVIEW);
257     xglPushMatrix();
258     xglLoadIdentity();
259     xglDisable(GL_DEPTH_TEST);
260     xglEnable(GL_LIGHTING);
261     xglEnable(GL_TEXTURE_2D);
262     xglDisable(GL_BLEND);
263
264     xglMatrixMode(GL_MODELVIEW);
265     xglPopMatrix();
266     xglPushMatrix();
267
268     xglDisable(GL_LIGHTING);
269      test_instr[3]->Render();
270      test_instr[4]->Render();
271      test_instr[5]->Render();
272      test_instr[6]->Render();
273     xglPopMatrix();
274     xglPushMatrix();
275     
276     test_instr[1]->Render();
277     test_instr[2]->Render();
278
279 //   DrawBeechcraftLogo(230, 235, 30, 10);
280 //   DrawScale(144.375, 166.875, 38, 41.0, 18, 340, 44, 2.0, 1.0, 1.0, 1.0);
281     
282     xglEnable(GL_LIGHTING);
283             
284     test_instr[0]->Render();
285     
286     
287     xglDisable(GL_TEXTURE_2D);
288     xglPopMatrix();   
289     xglEnable(GL_DEPTH_TEST);
290     xglEnable(GL_LIGHTING);
291     xglDisable(GL_TEXTURE_2D);
292     xglDisable(GL_BLEND);
293     xglMatrixMode(GL_PROJECTION);
294     xglPopMatrix();
295     xglMatrixMode(GL_MODELVIEW);
296     xglPopMatrix();
297 }
298
299 // horizon - Let's draw an artificial horizon using both texture mapping and 
300 //           primitive drawing
301  
302 void FGHorizon::Render(void){ 
303     double pitch;
304     double roll;
305     float shifted, alpha, theta;
306     float epsi = 360 / 180;
307     GLboolean Light;
308     GLfloat normal[2];
309     
310    static int n, dn, rot, tmp1, tmp2;
311    float a;
312     
313     GLfloat material[] = { 0.714844, 0.265625, 0.056875 ,1.0};
314     GLfloat material2[] = {0.6640625, 0.921875, 0.984375, 1.0};
315     GLfloat material3[] = {0.2, 0.2, 0.2, 1.0};
316     GLfloat material4[] = {0.8, 0.8, 0.8, 1.0};
317     GLfloat material5[] = {0.0, 0.0, 0.0, 1.0};
318     GLfloat direction[] = {0.0, 0.0, 0.0};
319     GLfloat light_position[4];
320     GLfloat light_ambient[] = {0.7, 0.7, 0.7, 1.0};
321     GLfloat light_ambient2[] = {0.7, 0.7, 0.7, 1.0};
322     GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
323     GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
324     
325     pitch = get_pitch() * RAD_TO_DEG;
326     if(pitch > 45)
327     pitch = 45;
328     
329     if(pitch < -45)
330     pitch = -45;
331     
332     roll = get_roll() * RAD_TO_DEG;
333     
334     xglEnable(GL_NORMALIZE);
335     xglEnable(GL_LIGHTING);
336     xglEnable(GL_TEXTURE_2D);
337     xglEnable(GL_LIGHT1);
338     xglDisable(GL_LIGHT2);
339     xglDisable(GL_LIGHT0);
340     xglMatrixMode(GL_MODELVIEW);
341     xglLoadIdentity();
342     xglTranslatef(XPos, YPos, 0);
343     xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
344     xglMatrixMode(GL_TEXTURE);
345     xglPushMatrix();
346         
347     // computations for the non-textured parts of the AH
348     
349     shifted = -((pitch / 10) * 7.0588235);
350         
351     if(shifted > (bottom - radius)){
352     theta = (180 - (acos((bottom - shifted) / radius)*RAD_TO_DEG));
353     n = (int)(theta / epsi) - 1;
354     n1 = n;
355     n2 = (180 - n1) + 2;
356     dn = n2 - n1;
357     rot = (int)(roll / epsi);
358     n1 += rot + 45;
359     n2 += rot + 45;
360     }
361     
362     if(shifted < (-top + radius)){
363     theta = ((acos((-top - shifted) / radius)*RAD_TO_DEG));
364     n = (int)(theta / epsi) + 1;
365     n1 = n;
366     n2 = (180 - n1) + 2;
367     dn = n2 - n1;
368     rot = (int)(roll / epsi);
369     n1 += rot - 45;
370     n2 += rot - 45;
371     if(n1 < 0){ n1 += 180; n2 +=180;}
372     }
373     
374     // end of computations  
375        
376     light_position[0] = 0.0;
377     light_position[1] = 0.0; 
378     light_position[2] = 1.5;
379     light_position[3] = 0.0;
380     xglLightfv(GL_LIGHT1, GL_POSITION, light_position);
381     xglLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);  
382     xglLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
383     xglLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
384     xglLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, direction);
385
386     #ifdef GL_VERSION_1_1
387     xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]);
388     #elif GL_EXT_texture_object
389     xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]);
390     #else
391     #  error port me
392     #endif
393
394     xglLoadIdentity();
395     xglTranslatef(0.0, ((pitch / 10) * 0.046875), 0.0);
396     xglTranslatef((texXPos/256), (texYPos/256), 0.0);
397     xglRotatef(-roll, 0.0, 0.0, 1.0);
398     xglScalef(1.7, 1.7, 0.0);
399
400     // the following loop draws the textured part of the AH
401     
402    xglMaterialf(GL_FRONT, GL_SHININESS, 85.0);
403     
404    xglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material4);
405    xglMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material5);
406    xglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material3);
407    
408     xglMatrixMode(GL_MODELVIEW);
409     xglBegin(GL_TRIANGLES);
410            for(i=45;i<225;i++){
411                      xglTexCoord2f(0.0, 0.0);
412                      xglNormal3f(0.0, 0.0, 0.6);
413                      xglVertex3f(0.0, 0.0, 0.0);
414                      xglTexCoord2f(texCoord[i % 180][0], texCoord[i % 180][1]);
415                      xglNormal3f(normals[i % 180][0], normals[i % 180][1], 0.6);
416                      xglVertex3f(vertices[i % 180][0], vertices[i % 180][1],                                     0.0);
417                      n = (i + 1) % 180;
418                      xglTexCoord2f(texCoord[n][0], texCoord[n][1]);
419                      xglNormal3f(normals[n][0], normals[n][1], 0.6);
420                      xglVertex3f(vertices[n][0], vertices[n][1], 0.0);
421                 }
422      xglEnd();
423     
424             
425     if((shifted > (bottom - radius)) && (n1 < 1000) && (n1 > 0)){
426     
427     a = sin(theta * DEG_TO_RAD) * sin(theta * DEG_TO_RAD);
428 light_ambient2[0] = a;
429 light_ambient2[1] = a;
430 light_ambient2[2] = a;
431     
432  xglLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient2);
433  xglLightfv(GL_LIGHT1, GL_DIFFUSE, light_ambient2); 
434  xglLightfv(GL_LIGHT1, GL_SPECULAR, light_ambient2);
435         
436     xglBegin(GL_TRIANGLES);
437     
438     tmp1 = n1; tmp2 = n2;
439         
440             for(i = tmp1; i < tmp2 + 1; i++){
441                      n = i % 180;
442             xglNormal3f(0.0, 0.0, 1.5);
443               xglTexCoord2f((56 / 256), (140 / 256));
444             xglVertex3f(((vertices[n1 % 180][0] + vertices[n2 % 180][0]) / 2),                            ((vertices[n1 % 180][1] + vertices[n2 % 180][1]) / 2),                             0.0);
445                                                 
446              xglTexCoord2f((57 / 256), (139 / 256));        
447              xglNormal3f(normals[n][0], normals[n][1], normals[n][3]);
448                      xglVertex3f(vertices[n][0], vertices[n][1], 0.0);
449                      
450                      n = (i + 1) % 180;
451         xglTexCoord2f((57 / 256), (139 / 256));      
452         xglNormal3f(normals[n][0], normals[n][1], normals[n][3]);
453                      xglVertex3f(vertices[n][0], vertices[n][1], 0.0);       
454                 }
455      xglEnd();
456     }
457             
458     if((shifted < (-top + radius)) && (n1 < 1000) && (n1 > 0)){
459     a = sin(theta * DEG_TO_RAD) * sin(theta * DEG_TO_RAD);
460 light_ambient2[0] = a;
461 light_ambient2[1] = a;
462 light_ambient2[2] = a;
463      
464  xglLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient2);
465  xglLightfv(GL_LIGHT1, GL_DIFFUSE, light_ambient2); 
466  xglLightfv(GL_LIGHT1, GL_SPECULAR, light_ambient2);
467  xglMaterialf(GL_FRONT, GL_SHININESS, a * 85);
468     xglBegin(GL_TRIANGLES);
469     tmp1 = n1; tmp2 = n2;
470             for(i = tmp1; i <= tmp2; i++){
471                      n = i % 180;
472           xglNormal3f(0.0, 0.0, 1.5);
473           xglTexCoord2f((73 / 256), (237 / 256));
474           xglVertex3f(((vertices[n1 % 180][0] + vertices[n2 % 180][0]) / 2),                            ((vertices[n1 % 180][1] + vertices[n2 % 180][1]) / 2),                             0.0); 
475                       
476                      xglTexCoord2f((73 / 256), (236 / 256));
477                      xglNormal3f(normals[n][0], normals[n][1], normals[n][2]);
478                      xglVertex3f(vertices[n][0], vertices[n][1], 0.0);
479                      
480                      n = (i + 1) % 180;
481                     xglTexCoord2f((73 / 256), (236 / 256)); 
482                     xglNormal3f(normals[n][0], normals[n][1], normals[n][2]);
483                     xglVertex3f(vertices[n][0], vertices[n][1], 0.0); 
484                 }
485      xglEnd();
486     }
487     
488     // Now we will have to draw the small triangle indicating the roll value
489
490     xglDisable(GL_LIGHTING);
491     xglDisable(GL_TEXTURE_2D);
492     
493     xglRotatef(roll, 0.0, 0.0, 1.0);
494     
495     xglBegin(GL_TRIANGLES);
496     xglColor3f(1.0, 1.0, 1.0);
497     xglVertex3f(0.0, radius, 0.0);
498     xglVertex3f(-3.0, (radius - 7.0), 0.0);
499     xglVertex3f(3.0, (radius - 7.0), 0.0);    
500     xglEnd();
501     
502     xglLoadIdentity();
503
504     xglBegin(GL_POLYGON);
505     xglColor3f(0.2109375, 0.23046875, 0.203125);
506     xglVertex2f(275.625, 138.0);
507     xglVertex2f(275.625, 148.125);
508     xglVertex2f(258.125, 151.25);
509     xglVertex2f(246.875, 151.25);
510     xglVertex2f(226.875, 147.5);
511     xglVertex2f(226.875, 138.0);
512     xglVertex2f(275.625, 138.0);
513     xglEnd();
514
515     xglLoadIdentity();
516     
517     xglMatrixMode(GL_TEXTURE);
518     xglPopMatrix();
519     xglMatrixMode(GL_PROJECTION);
520     xglPopMatrix();
521     xglDisable(GL_TEXTURE_2D);
522     xglDisable(GL_NORMALIZE);
523     xglDisable(GL_LIGHTING);
524     xglDisable(GL_LIGHT1);
525     xglEnable(GL_LIGHT0);
526     }
527
528 // fgHorizonInit - initialize values for the AH
529
530 void FGHorizon::Init(void){
531         radius = 28.9;
532         texXPos = 56;
533         texYPos = 174;
534         bottom = 36.5;
535         top = 36.5;
536         int n;
537
538 float step = (360*DEG_TO_RAD)/180;
539
540 for(n=0;n<180;n++){
541            vertices[n][0] = cos(n * step) * radius;
542            vertices[n][1] = sin(n * step) * radius;
543            texCoord[n][0] = (cos(n * step) * radius)/256;
544            texCoord[n][1] = (sin(n * step) * radius)/256;
545          normals[n][0] = cos(n * step) * radius + sin(n * step);
546          normals[n][1] = sin(n * step) * radius + cos(n * step);
547            normals[n][2] = 0.0;
548            }
549 }
550
551 void FGTexInstrument::UpdatePointer(void){
552     double pitch;
553     double roll;
554     float alpharad;
555     double speed;    
556     glEnableClientState(GL_VERTEX_ARRAY);
557     glVertexPointer(2, GL_FLOAT, 0, vertices);
558
559     alpha=((((float)((var[variable]) - (value1))) /                                        (value2 - value1))*                                                             (alpha2 - alpha1) + alpha1);
560     
561         if (alpha < alpha1)
562                 alpha = alpha1;
563         if (alpha > alpha2)
564                 alpha = alpha2;
565     xglMatrixMode(GL_MODELVIEW);  
566     xglPushMatrix();
567     xglLoadIdentity();
568     xglDisable(GL_TEXTURE_2D);
569     xglTranslatef(XPos, YPos, 0);
570     xglRotatef(-alpha, 0.0, 0.0, 1.0);
571     xglColor4f(1.0, 1.0, 1.0, 1.0);
572     glDrawArrays(GL_POLYGON, 0, 10);
573     tape[0] = tape[1];
574     tape[1] = alpha;
575     xglEnable(GL_TEXTURE_2D);
576     glDisableClientState(GL_VERTEX_ARRAY);
577 }
578
579 // fgEraseArea - 'Erases' a drawn Polygon by overlaying it with a textured 
580 //                 area. Shall be a method of a panel class once.
581
582 void fgEraseArea(GLfloat *array, int NumVerti, GLfloat texXPos,                                  GLfloat texYPos, GLfloat XPos, GLfloat YPos,                                    int Texid, float ScaleFactor){
583 int i, j;
584 int n;
585 float a;
586 float ififth;
587
588 xglEnable(GL_TEXTURE_2D);
589 xglEnable(GL_TEXTURE_GEN_S);
590 xglEnable(GL_TEXTURE_GEN_T);
591 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
592 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
593 xglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
594 xglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
595 xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
596 xglMatrixMode(GL_TEXTURE);
597 xglLoadIdentity();
598         
599     #ifdef GL_VERSION_1_1
600     xglBindTexture(GL_TEXTURE_2D, panel_tex_id[Texid]);
601     #elif GL_EXT_texture_object
602     xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[Texid]);
603     #else
604     #  error port me
605     #endif
606
607 xglMatrixMode(GL_TEXTURE);
608 xglLoadIdentity();
609 xglTranslatef(-((float)((XPos/0.625)/256)),                                                   -((float)((YPos/0.625)/256)), 0.0);
610 xglTranslatef(texXPos/256 , texYPos/256, 0.0);
611 xglScalef(0.00625, 0.00625, 1.0);
612                         
613         xglBegin(GL_POLYGON);
614 for(n=0;n<NumVerti;n += 2){     
615 xglVertex2f(array[n] * ScaleFactor, array[n + 1] * ScaleFactor);
616
617         xglEnd();
618  
619         xglLoadIdentity();
620         xglMatrixMode(GL_MODELVIEW);
621         xglPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
622         xglPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
623         xglDisable(GL_TEXTURE_2D);
624         xglDisable(GL_TEXTURE_GEN_S);
625         xglDisable(GL_TEXTURE_GEN_T);
626         
627 }
628
629 // CreatePointer - calculate the vertices of a pointer 
630
631 void FGTexInstrument::CreatePointer(void){
632 int i;
633 float alpha;
634 float alphastep;
635 float r = radius;
636
637 vertices[0] = 0;
638 vertices[1] = length;
639 vertices[2] = -(width/2);
640 vertices[3] = length - ((width/2)/(tan(angle*DEG_TO_RAD/2)));
641 vertices[4] = -(width/2);
642 vertices[5] = cos(asin((width/2)/r))*r;
643
644 alphastep = (asin((width/2)/r)+asin((width/2)/r))/5;
645 alpha = asin(-(width/2)/r);
646
647 for(i=0;i<5;i++){
648 alpha += alphastep;
649 vertices[(i*2)+6] = sin(alpha)*r;
650    }
651
652 alpha = asin(-(width/2)/r);
653
654 for(i=0;i<5;i++){
655 alpha +=alphastep;
656 vertices[(i*2)+7]= cos(alpha)*r;
657    }
658
659 vertices[16] = - vertices[4];
660 vertices[17] = vertices[5];
661 vertices[18] = - vertices[2];
662 vertices[19] = vertices[3];
663
664 }
665
666 // fgUpdateTurnCoordinator - draws turn coordinator related stuff
667
668 void FGTurnCoordinator::Render(void){
669 int n;
670
671 xglDisable(GL_LIGHTING);
672 xglDisable(GL_BLEND);
673 xglEnable(GL_TEXTURE_2D);
674
675  alpha = (get_sideslip() / 1.5) * 560;
676  if(alpha > 56){
677  alpha = 56;
678  }
679  if(alpha < -56){
680  alpha = -56;
681  }
682  
683  PlaneAlpha = get_roll();
684
685     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
686     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
687      xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
688
689 xglMatrixMode(GL_MODELVIEW);
690 xglLoadIdentity();
691 xglTranslatef(BallXPos, BallYPos, 0.0);
692 xglTranslatef(0.75 * sin(alphahist[0] * DEG_TO_RAD) * 31,                                     0.3 * (39 - (cos(alphahist[0] * DEG_TO_RAD) * 39)),                             0.0);
693 fgEraseArea(vertices, 72, BallTexXPos +                                                     ((0.75 * sin(alphahist[0] * DEG_TO_RAD) * 31) / 0.625),                         BallTexYPos + ((0.3 * (39 - (cos(alphahist[0] * DEG_TO_RAD)                                  * 39))) / 0.625),                                                   BallXPos + (0.75 * sin(alphahist[0] * DEG_TO_RAD) * 31),                       BallYPos + (0.3 * (39 - (cos(alphahist[0] * DEG_TO_RAD)                         * 39))), 1, 1);
694 xglDisable(GL_TEXTURE_2D);
695 xglEnable(GL_BLEND);
696 xglBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE);
697 xglMatrixMode(GL_MODELVIEW);
698 xglLoadIdentity();
699 xglTranslatef(BallXPos, BallYPos, 0.0);
700 xglTranslatef(0.75 * sin(alpha * DEG_TO_RAD) * 31,                                            0.3 * (39 - (cos(alpha * DEG_TO_RAD) * 39)), 0.0);
701 xglBegin(GL_POLYGON);
702 xglColor3f(0.8, 0.8, 0.8);
703 for(i=0;i<36;i++){
704 xglVertex2f(vertices[2 * i],                                                                vertices[(2 * i) + 1]);
705 }
706 xglEnd(); 
707
708 xglDisable(GL_TEXTURE_2D);
709 xglDisable(GL_BLEND);
710
711 xglMatrixMode(GL_MODELVIEW);
712 xglLoadIdentity();
713 xglTranslatef(XPos, YPos, 0.0);
714 xglRotatef(rollhist[0] * RAD_TO_DEG + 90, 0.0, 0.0, 1.0);
715
716 fgEraseArea(Wings, 8, PlaneTexXPos, PlaneTexYPos,                                                     XPos, YPos, 1, 1); 
717 fgEraseArea(Elevator, 8, PlaneTexXPos, PlaneTexYPos,                                                     XPos, YPos, 1, 1); 
718 fgEraseArea(Rudder, 8, PlaneTexXPos, PlaneTexYPos,                                                     XPos, YPos, 1, 1); 
719
720 xglLoadIdentity();
721 xglTranslatef(XPos, YPos, 0.0);
722 xglRotatef(-get_roll() * RAD_TO_DEG + 90, 0.0, 0.0, 1.0);
723
724 xglBegin(GL_POLYGON);
725 xglColor3f(1.0, 1.0, 1.0);
726 for(i=0;i<90;i++){
727 xglVertex2f(cos(i * 4 * DEG_TO_RAD) * 5, sin(i * 4 * DEG_TO_RAD) * 5);
728 }
729 xglEnd();
730
731 xglBegin(GL_POLYGON);
732 xglVertex2f(Wings[0], Wings[1]);
733 xglVertex2f(Wings[2], Wings[3]);
734 xglVertex2f(Wings[4], Wings[5]);
735 xglVertex2f(Wings[6], Wings[7]);
736 xglVertex2f(Wings[0], Wings[1]);
737 xglEnd();
738
739 xglBegin(GL_POLYGON);
740 xglVertex2f(Elevator[0], Elevator[1]);
741 xglVertex2f(Elevator[2], Elevator[3]);
742 xglVertex2f(Elevator[4], Elevator[5]);
743 xglVertex2f(Elevator[6], Elevator[7]);
744 xglVertex2f(Elevator[0], Elevator[1]);
745 xglEnd();
746
747 xglBegin(GL_POLYGON);
748 xglVertex2f(Rudder[0], Rudder[1]);
749 xglVertex2f(Rudder[2], Rudder[3]);
750 xglVertex2f(Rudder[4], Rudder[5]);
751 xglVertex2f(Rudder[6], Rudder[7]);
752 xglVertex2f(Rudder[0], Rudder[1]);
753 xglEnd();
754
755
756 alphahist[0] = alphahist[1];
757 alphahist[1] = alpha;
758 rollhist[0] = rollhist[1];
759 rollhist[1] = -get_roll();
760
761 xglDisable(GL_BLEND);
762 }
763
764 void FGTurnCoordinator::Init(void){
765 int n;
766 PlaneTexXPos = 49;
767 PlaneTexYPos = 59.75;
768 BallXPos = 145;
769 BallYPos = 24;
770 BallTexXPos = 49;
771 BallTexYPos = 16;
772 BallRadius = 3.5;
773
774 for(n=0;n<36;n++){
775 vertices[2 * n] = cos(10 * n * DEG_TO_RAD) * BallRadius;
776 vertices[(2 * n) + 1] = sin(10 * n * DEG_TO_RAD) * BallRadius;
777         }       
778 }
779
780 void DrawScale(float XPos, float YPos, float InnerRadius, float OuterRadius,                   float alpha1, float alpha2, int steps, float LineWidth,                       float red, float green, float blue, bool filled){
781      int i;
782      float diff = (alpha2 - alpha1) / (float)(steps - 1);
783      
784      #define ANTIALIASED_INSTRUMENTS
785
786      #ifdef ANTIALIASED_INSTRUMENTS
787      xglEnable(GL_LINE_SMOOTH);
788      xglEnable(GL_BLEND);
789      xglHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
790      #endif
791      
792      xglMatrixMode(GL_MODELVIEW);
793      xglLoadIdentity();
794      
795      xglTranslatef(XPos, YPos, 0.0);
796      xglRotatef(-alpha1, 0.0, 0.0, 1.0);
797      
798      xglLineWidth(LineWidth);
799      xglColor3f(red, green, blue);
800      
801      if(!filled){
802      xglBegin(GL_LINES);
803      }
804      else{
805      xglBegin(GL_QUAD_STRIP);
806      }
807      
808      for(i=0;i < steps; i++){
809      xglVertex3f(sin(i * diff * DEG_TO_RAD) * OuterRadius,                                       cos(i * diff * DEG_TO_RAD) * OuterRadius, 0.0);
810      xglVertex3f(sin(i * diff * DEG_TO_RAD) * InnerRadius,                                       cos(i * diff * DEG_TO_RAD) * InnerRadius, 0.0);
811         }
812      xglEnd();
813      
814      xglLoadIdentity();
815      xglDisable(GL_LINE_SMOOTH);
816      xglDisable(GL_BLEND);
817      }
818
819 void DrawBeechcraftLogo(float XPos, float YPos, float width, float height){
820      xglMatrixMode(GL_MODELVIEW);
821      xglLoadIdentity();
822      xglTranslatef(XPos, YPos, 0.0);
823      xglEnable(GL_BLEND);
824      xglEnable(GL_TEXTURE_2D);
825 //   xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
826 //   xglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
827
828     #ifdef GL_VERSION_1_1
829     xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]);
830     #elif GL_EXT_texture_object
831     xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]);
832     #else
833     #  error port me
834     #endif
835
836     xglBegin(GL_POLYGON);
837     
838     xglTexCoord2f(.39844, .01953);
839     xglVertex2f(0.0, 0.0);
840     xglTexCoord2f(.58594, .01953);
841     xglVertex2f(width, 0.0);
842     xglTexCoord2f(.58594, .074219);
843     xglVertex2f(width, height);
844     xglTexCoord2f(.39844, .074219);
845     xglVertex2f(0.0, height);
846     
847     xglEnd();
848     
849     xglDisable(GL_BLEND);
850     xglDisable(GL_TEXTURE_2D);
851  }
852     
853
854 // PrintMatrix - routine to print the current modelview matrix.                 
855
856 void PrintMatrix( void){
857 xglGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
858 printf("matrix2 = %f %f %f %f \n", mvmatrix[0], mvmatrix[1], mvmatrix[2], mvmatrix[3]);
859 printf("         %f %f %f %f \n", mvmatrix[4], mvmatrix[5], mvmatrix[6], mvmatrix[7]);
860 printf("         %f %f %f %f \n", mvmatrix[8], mvmatrix[9], mvmatrix[10], mvmatrix[11]);
861 printf("         %f %f %f %f \n", mvmatrix[12], mvmatrix[13], mvmatrix[14], mvmatrix[15]);
862 }
863
864 void FGRpmGauge::Init(void){
865      list = xglGenLists (1);
866      int n;
867      
868      xglNewList(list, GL_COMPILE);
869      
870      xglColor3f(.26, .289, .3281);
871      xglBegin(GL_POLYGON);
872      for(n = 0; n < 180; n++){
873      xglVertex2f(cos(n * 0.0349066) * 24.5, sin(n * 0.0349066) * 24.5);
874      }
875      xglEnd();
876      
877 DrawScale(XPos, YPos, 22.5, 25.625, 50, 135, 10, 1.0, 0.0, 0.7,                           0.0,FILLED);
878 DrawScale(XPos, YPos, 21.0, 25.625, -70, 180, 8, 1.8, 0.88, 0.88, 0.88, false);
879 DrawScale(XPos, YPos, 22.5, 25.0, -70, 180, 40, 0.6, 0.5, 0.5, 0.5, false);
880           
881      xglEndList();
882      }
883      
884 void FGRpmGauge::Render(void){
885      xglMatrixMode(GL_MODELVIEW);
886      xglLoadIdentity();
887      xglTranslatef(XPos, YPos, 0.0);
888      
889      xglCallList(list);
890           
891      }
892      
893 void FGPanel::DrawTestLetter(float X, float Y){
894      xglEnable(GL_TEXTURE_2D);
895      xglEnable(GL_BLEND);
896      
897      xglMatrixMode(GL_TEXTURE);
898      xglLoadIdentity();
899      xglTranslatef(X, Y, 0.0);
900      
901     DrawLetter();
902     
903      xglMatrixMode(GL_MODELVIEW); 
904      xglTranslatef(6.0, 0.0, 0.0);
905      xglDisable(GL_TEXTURE_2D);
906      xglDisable(GL_BLEND);
907      }
908     
909 void FGPanel::InitLists(void){
910      xglNewList(FontList + 'A', GL_COMPILE);
911      DrawTestLetter(0.391625, 0.29296875);
912      xglEndList();
913      
914      xglNewList(FontList + 'B', GL_COMPILE);
915      DrawTestLetter(0.391625 + 1 * LETTER_OFFSET, 0.29296875);
916      xglEndList();
917      
918      xglNewList(FontList + 'C', GL_COMPILE);
919      DrawTestLetter(0.391625 + 2 * LETTER_OFFSET, 0.29296875);
920      xglEndList();
921      
922      xglNewList(FontList + 'D', GL_COMPILE);
923      DrawTestLetter(0.391625 + 3 * LETTER_OFFSET, 0.29296875);
924      xglEndList();
925      
926      xglNewList(FontList + 'E', GL_COMPILE);
927      DrawTestLetter(0.391625 + 4 * LETTER_OFFSET, 0.29296875);
928      xglEndList();
929      
930      xglNewList(FontList + 'F', GL_COMPILE);
931      DrawTestLetter(0.391625 + 5 * LETTER_OFFSET, 0.29296875);
932      xglEndList();
933      
934      xglNewList(FontList + 'G', GL_COMPILE);
935      DrawTestLetter(0.391625 + 6 * LETTER_OFFSET, 0.29296875);
936      xglEndList();
937      
938      xglNewList(FontList + 'H', GL_COMPILE);
939      DrawTestLetter(0.391625 + 7 * LETTER_OFFSET, 0.29296875);
940      xglEndList();
941      
942      xglNewList(FontList + 'I', GL_COMPILE);
943      DrawTestLetter(0.391625 + 8 * LETTER_OFFSET, 0.29296875);
944      xglEndList();
945      
946      xglNewList(FontList + 'J', GL_COMPILE);
947      DrawTestLetter(0.391625 + 9 * LETTER_OFFSET, 0.29296875);
948      xglEndList();
949      
950      xglNewList(FontList + 'K', GL_COMPILE);
951      DrawTestLetter(0.391625 + 9.7 * LETTER_OFFSET, 0.29296875);
952      xglEndList();
953      
954      xglNewList(FontList + 'L', GL_COMPILE);
955      DrawTestLetter(0.399625 + 10.6 * LETTER_OFFSET, 0.29296875);
956      xglEndList();
957      
958      xglNewList(FontList + 'M', GL_COMPILE);
959      DrawTestLetter(0.80459375, 0.29296875);
960      xglEndList();
961      
962      xglNewList(FontList + 'N', GL_COMPILE);
963      DrawTestLetter(0.83975, 0.29296875);
964      xglEndList();
965      
966      xglNewList(FontList + 'O', GL_COMPILE);
967      DrawTestLetter(0.871, 0.29296875);
968      xglEndList();
969      
970      xglNewList(FontList + 'P', GL_COMPILE);
971      DrawTestLetter(0.90715625, 0.29296875);
972      xglEndList();
973      
974      xglNewList(FontList + 'Q', GL_COMPILE);
975      DrawTestLetter(0.9413125, 0.29296875);
976      xglEndList();
977      
978      xglNewList(FontList + '1', GL_COMPILE);
979      DrawTestLetter(0.390625, 0.35546875);
980      xglEndList();
981      
982      xglNewList(FontList + '2', GL_COMPILE);
983      DrawTestLetter(0.390625 + 1*LETTER_OFFSET, 0.3515625); 
984      xglEndList();
985      
986      xglNewList(FontList + '3', GL_COMPILE);
987      DrawTestLetter(0.390625 + 2*LETTER_OFFSET, 0.3515625); 
988      xglEndList();
989      
990      xglNewList(FontList + '4', GL_COMPILE);
991      DrawTestLetter(0.390625 + 3*LETTER_OFFSET, 0.3515625); 
992      xglEndList();
993      
994      xglNewList(FontList + '5', GL_COMPILE);
995      DrawTestLetter(0.390625 + 4*LETTER_OFFSET, 0.3515625); 
996      xglEndList();
997      
998      xglNewList(FontList + '6', GL_COMPILE);
999      DrawTestLetter(0.390625 + 5*LETTER_OFFSET, 0.3515625); 
1000      xglEndList();
1001      
1002      xglNewList(FontList + '7', GL_COMPILE);
1003      DrawTestLetter(0.390625 + 6*LETTER_OFFSET, 0.3515625); 
1004      xglEndList();
1005      
1006      xglNewList(FontList + '8', GL_COMPILE);
1007      DrawTestLetter(0.390625 + 7*LETTER_OFFSET, 0.3515625); 
1008      xglEndList();
1009      
1010      xglNewList(FontList + '9', GL_COMPILE);
1011      DrawTestLetter(0.390625 + 8*LETTER_OFFSET, 0.3515625); 
1012      xglEndList();
1013      
1014      xglNewList(FontList + '0', GL_COMPILE);
1015      DrawTestLetter(0.383625 + 9*LETTER_OFFSET, 0.3515625); 
1016      xglEndList();
1017      
1018      xglNewList(FontList + ' ', GL_COMPILE);
1019      xglTranslatef(8.0, 0.0, 0.0);
1020      xglEndList();
1021      }
1022     
1023 void FGPanel::TexString(char *s, float XPos, float YPos, float size){
1024      xglMatrixMode(GL_MODELVIEW);
1025      xglLoadIdentity();
1026      xglTranslatef(XPos, YPos, 0.0);
1027      xglScalef(size, size, 1.0);
1028      
1029     #ifdef GL_VERSION_1_1
1030     xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]);
1031     #elif GL_EXT_texture_object
1032     xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]);
1033     #else
1034     #  error port me
1035     #endif
1036     
1037      while((*s) != '\0'){
1038      xglCallList(FontList + (*s));
1039      s++;
1040       }
1041       xglLoadIdentity();
1042      }
1043      
1044 void FGTexInstrument::Init(void){
1045      CreatePointer();
1046      }
1047      
1048 void FGTexInstrument::Render(void){
1049 xglEnable(GL_TEXTURE_2D);
1050      xglLoadIdentity();
1051      xglTranslatef(XPos, YPos, 0.0);
1052      xglRotatef(-tape[0], 0.0, 0.0, 1.0);
1053     fgEraseArea(vertices, 20, (GLfloat)(teXpos),                                               (GLfloat)(texYpos), (GLfloat)(XPos),                                            (GLfloat)(YPos), 0, 1);
1054      
1055      UpdatePointer();
1056      
1057      xglDisable(GL_TEXTURE_2D);
1058      }
1059