From 7da417530f8dc06e8c4cb62adc2d20fd2a7a3809 Mon Sep 17 00:00:00 2001 From: curt Date: Thu, 23 Dec 1999 17:37:18 +0000 Subject: [PATCH] Panel code reorganization contributed by David Megginson: I've reorganized the code in panel.cxx and panel.hxx so that it will be a little easier to extend the panel later if someone wants to. It's still basically Friedemann's code at the core, but I've repackaged it into a saner class hierarchy and encapsulated as much as I could (there are still a couple of circular dependencies that need swatting). If someone wants to modify it to use SSG or to add new gauges, it should be a lot easier now. There are no user-visible changes. --- src/Cockpit/panel.cxx | 1013 +++++++++++++++++++---------------------- src/Cockpit/panel.hxx | 392 ++++++++-------- 2 files changed, 672 insertions(+), 733 deletions(-) diff --git a/src/Cockpit/panel.cxx b/src/Cockpit/panel.cxx index 90c1dd331..23a29540f 100644 --- a/src/Cockpit/panel.cxx +++ b/src/Cockpit/panel.cxx @@ -2,6 +2,8 @@ // // Written by Friedemann Reinhard, started June 1998. // +// Major code reorganization by David Megginson, November 1999. +// // Copyright(C)1998 Friedemann Reinhard-reinhard@theorie2.physik.uni-erlangen.de // // This program is free software; you can redistribute it and/or @@ -51,46 +53,25 @@ #include "cockpit.hxx" #include "hud.hxx" -GLubyte *imag; -int imag_width, imag_height; -GLubyte *img; -int img_width, img_height; + +//////////////////////////////////////////////////////////////////////// +// Implementation of FGPanel. +//////////////////////////////////////////////////////////////////////// -static float value[4]; -static GLuint panel_tex_id[2]; -static GLubyte tex[32][128][3]; -static float alphahist; -static float Xzoom, Yzoom; -static Pointer pointer[20]; -static int NumPoint = 4; -static int i = 0; -static GLdouble mvmatrix[16]; -static GLdouble matrix[16]; -static double var[20]; -static double offset; -static float alpha; -static int n1; -static int n2; - -static GLfloat Wings[] = { - -1.25, -28.125, 1.255, -28.125, 1.255, 28.125, -1.25, 28.125}; - -static GLfloat Elevator[] = { - 3.0, -10.9375, 4.5, -10.9375, 4.5, 10.9375, 3.0, 10.9375}; - -static GLfloat Rudder[] = { - 2.0, -0.45, 10.625, -0.45, 10.625, 0.55, 2.0, 0.55}; +// Global panel. FGPanel* FGPanel::OurPanel = 0; -// FGPanel::FGPanel() - constructor to initialize the panel. -FGPanel::FGPanel(void){ + +// Constructor (ensures that the panel is a singleton). +FGPanel::FGPanel(void) { int x, y; FILE *f; char line[256]; GLint test; GLubyte *tex = new GLubyte[262144]; + float Xzoom, Yzoom; if(OurPanel) { FG_LOG( FG_GENERAL, FG_ALERT, "Error: only one Panel allowed" ); @@ -102,23 +83,15 @@ FGPanel::FGPanel(void){ Xzoom = (float)((float)(current_view.get_winWidth())/1024); Yzoom = (float)((float)(current_view.get_winHeight())/768); - test_instr[3] = new FGTexInstrument(144.375, 166.875, 4, 32, 3, 30, 15.0, - 260.0, -20.0, 360, 65, 193, 0); - test_instr[4] = new FGTexInstrument(358, 52, 4, 30, 3, 30, -3.0, 3.0, 100, - 440, 66.15, 66, 2); - test_instr[5] = new FGTexInstrument(357.5, 167, 5, 25, 4, 30, 0, 10000, 0, - 360, 194, 191, 1); - test_instr[6] = new FGTexInstrument(357.5, 167, 5, 32, 3, 30, 0, 3000, 0, - 1080, 194, 191, 1); - test_instr[0] = new FGHorizon(251, 166.75); - test_instr[1] = new FGTurnCoordinator(143.75, 51.75); - //test_instr[2] = new FGRpmGauge(462.5, 133); - test_instr[2] = new FGTexInstrument(462.5, 133, 10, 20, 5.5, 60, 0.0, 1.0, - -67, 180, 174, 83, 3); - - // FontList = glGenLists (256); - // glListBase(FontList); - // InitLists(); + airspeedIndicator = new FGAirspeedIndicator(144.375, 166.875); + verticalSpeedIndicator = new FGVerticalSpeedIndicator(358, 52); + // Each hand of the altimeter is a + // separate instrument for now... + altimeter = new FGAltimeter(357.5, 167); + altimeter2 = new FGAltimeter2(357.5, 167); + horizonIndicator = new FGHorizon(251, 166.75); + turnCoordinator = new FGTurnCoordinator(143.75, 51.75); + rpmIndicator = new FGRPMIndicator(462.5, 133); #ifdef GL_VERSION_1_1 xglGenTextures(2, panel_tex_id); @@ -165,22 +138,6 @@ FGPanel::FGPanel(void){ if ((background = read_rgb_texture( (char *)tpath.c_str(), &width, &height ))==NULL ){ } - // for(y=0;y<256;y++){ - // for(x=0;x<256;x++){ - // tex[(y+x*256)*3] = imag[(y+x*256)*3]; - // tex[(y+x*256)*3 + 1] = imag[(y+x*256)*3 + 1]; - // tex[(y+x*256)*3 + 2] = imag[(y+x*256)*3 + 2]; - // 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; - // - // if((imag[(y+x*256)*3] < 150) && (imag[(y+x*256)*3 +1] < 150) && // (imag[(y+x*256)*3 + 2] < 150) ){ - // tex[(y+x*256)*3 + 3] = 0x0; - // } - // else{ - // tex[(y+x*256)*3 + 3] = 0xff; - // } - // } - // } - xglPixelZoom(Xzoom, Yzoom); xglPixelStorei(GL_UNPACK_ALIGNMENT, 1); xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024); @@ -206,13 +163,25 @@ FGPanel::FGPanel(void){ xglPopMatrix(); } + +// Destructor. +FGPanel::~FGPanel () +{ + delete airspeedIndicator; + delete verticalSpeedIndicator; + delete altimeter; + delete altimeter2; + delete horizonIndicator; + delete turnCoordinator; + delete rpmIndicator; + OurPanel = 0; +} + + +// Reinitialize the panel. void FGPanel::ReInit( int x, int y, int finx, int finy){ - fgOPTIONS *o; - FGView *v = ¤t_view; - int i; GLint buffer; - - o = ¤t_options; + float Xzoom, Yzoom; xglDisable(GL_DEPTH_TEST); @@ -249,24 +218,9 @@ void FGPanel::ReInit( int x, int y, int finx, int finy){ xglEnable(GL_DEPTH_TEST); } + +// Update the panel. void FGPanel::Update ( void ) { - - float alpha; - double pitch; - double roll; - float alpharad; - double speed; - int i; - - // static bool beech_drawn = false; - // char *test = "ALM 100"; - - var[0] = get_speed() /* * 1.4 */; // We have to multiply the airspeed by a - // factor, to simulate flying a Bonanza - var[1] = get_altitude(); - var[2] = get_climb_rate() / 1000.0; - var[3] = get_throttleval(); - xglMatrixMode(GL_PROJECTION); xglPushMatrix(); xglLoadIdentity(); @@ -284,22 +238,20 @@ void FGPanel::Update ( void ) { xglPushMatrix(); xglDisable(GL_LIGHTING); - test_instr[3]->Render(); - test_instr[4]->Render(); - test_instr[5]->Render(); - test_instr[6]->Render(); + airspeedIndicator->Render(); + verticalSpeedIndicator->Render(); + altimeter->Render(); + altimeter2->Render(); + xglPopMatrix(); xglPushMatrix(); - test_instr[1]->Render(); - test_instr[2]->Render(); - - // DrawBeechcraftLogo(230, 235, 30, 10); - // DrawScale(144.375, 166.875, 38, 41.0, 18, 340, 44, 2.0, 1.0, 1.0, 1.0); + turnCoordinator->Render(); + rpmIndicator->Render(); xglEnable(GL_LIGHTING); - test_instr[0]->Render(); + horizonIndicator->Render(); xglDisable(GL_TEXTURE_2D); @@ -314,8 +266,75 @@ void FGPanel::Update ( void ) { xglPopMatrix(); } -// horizon - Let's draw an artificial horizon using both texture mapping and -// primitive drawing + +// fgEraseArea - 'Erases' a drawn Polygon by overlaying it with a textured +// area. Shall be a method of a panel class once. +// This should migrate into FGPanel somehow. +void fgEraseArea(GLfloat *array, int NumVerti, GLfloat texXPos, GLfloat texYPos, GLfloat XPos, GLfloat YPos, int Texid, float ScaleFactor){ + int i, j; + int n; + float a; + float ififth; + + xglEnable(GL_TEXTURE_2D); + xglEnable(GL_TEXTURE_GEN_S); + xglEnable(GL_TEXTURE_GEN_T); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + xglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + xglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + xglMatrixMode(GL_TEXTURE); + xglLoadIdentity(); + +#ifdef GL_VERSION_1_1 + xglBindTexture(GL_TEXTURE_2D, FGPanel::OurPanel->panel_tex_id[Texid]); +#elif GL_EXT_texture_object + xglBindTextureEXT(GL_TEXTURE_2D, FGPanel::OurPanel->panel_tex_id[Texid]); +#else +# error port me +#endif + + xglMatrixMode(GL_TEXTURE); + xglLoadIdentity(); + xglTranslatef(-((float)((XPos/0.625)/256)), -((float)((YPos/0.625)/256)), 0.0); + xglTranslatef(texXPos/256 , texYPos/256, 0.0); + xglScalef(0.00625, 0.00625, 1.0); + + xglBegin(GL_POLYGON); + for(n=0;npanel_tex_id[1]); #elif GL_EXT_texture_object - xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]); + // FIXME!! + xglBindTextureEXT(GL_TEXTURE_2D, FGPanel::OurPanel->panel_tex_id[1]); #else # error port me #endif @@ -425,7 +446,9 @@ void FGHorizon::Render(void){ xglMatrixMode(GL_MODELVIEW); xglBegin(GL_TRIANGLES); - for(i=45;i<225;i++){ + + int i; + for(i=45; i < 225; i++){ xglTexCoord2f(0.0, 0.0); xglNormal3f(0.0, 0.0, 0.6); xglVertex3f(0.0, 0.0, 0.0); @@ -566,15 +589,174 @@ void FGHorizon::Init(void){ } } + + +//////////////////////////////////////////////////////////////////////// +// Implementation of FGTurnCoordinator. +//////////////////////////////////////////////////////////////////////// + + +// Static constants + +GLfloat FGTurnCoordinator::wingArea[] = { + -1.25, -28.125, 1.255, -28.125, 1.255, 28.125, -1.25, 28.125 }; + +GLfloat FGTurnCoordinator::elevatorArea[] = { + 3.0, -10.9375, 4.5, -10.9375, 4.5, 10.9375, 3.0, 10.9375 }; + +GLfloat FGTurnCoordinator::rudderArea[] = { + 2.0, -0.45, 10.625, -0.45, 10.625, 0.55, 2.0, 0.55}; + + +FGTurnCoordinator::FGTurnCoordinator (float inXPos, float inYPos) +{ + XPos = inXPos; + YPos = inYPos; + Init(); +} + +FGTurnCoordinator::~FGTurnCoordinator () +{ +} + + +// fgUpdateTurnCoordinator - draws turn coordinator related stuff + +void FGTurnCoordinator::Render(void){ + int n; + + xglDisable(GL_LIGHTING); + xglDisable(GL_BLEND); + xglEnable(GL_TEXTURE_2D); + + alpha = (get_sideslip() / 1.5) * 560; + if(alpha > 56){ + alpha = 56; + } + if(alpha < -56){ + alpha = -56; + } + + PlaneAlpha = get_roll(); + + xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + xglMatrixMode(GL_MODELVIEW); + xglLoadIdentity(); + xglTranslatef(BallXPos, BallYPos, 0.0); + xglTranslatef(0.75 * sin(alphahist[0] * DEG_TO_RAD) * 31, 0.3 * (39 - (cos(alphahist[0] * DEG_TO_RAD) * 39)), 0.0); + 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); + xglDisable(GL_TEXTURE_2D); + xglEnable(GL_BLEND); + xglBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE); + xglMatrixMode(GL_MODELVIEW); + xglLoadIdentity(); + xglTranslatef(BallXPos, BallYPos, 0.0); + xglTranslatef(0.75 * sin(alpha * DEG_TO_RAD) * 31, 0.3 * (39 - (cos(alpha * DEG_TO_RAD) * 39)), 0.0); + xglBegin(GL_POLYGON); + xglColor3f(0.8, 0.8, 0.8); + + int i; + for(i=0;i<36;i++){ + xglVertex2f(vertices[2 * i], vertices[(2 * i) + 1]); + } + xglEnd(); + + xglDisable(GL_TEXTURE_2D); + xglDisable(GL_BLEND); + + xglMatrixMode(GL_MODELVIEW); + xglLoadIdentity(); + xglTranslatef(XPos, YPos, 0.0); + xglRotatef(rollhist[0] * RAD_TO_DEG + 90, 0.0, 0.0, 1.0); + + fgEraseArea(wingArea, 8, PlaneTexXPos, PlaneTexYPos, XPos, YPos, 1, 1); + fgEraseArea(elevatorArea, 8, PlaneTexXPos, PlaneTexYPos, XPos, YPos, 1, 1); + fgEraseArea(rudderArea, 8, PlaneTexXPos, PlaneTexYPos, XPos, YPos, 1, 1); + + xglLoadIdentity(); + xglTranslatef(XPos, YPos, 0.0); + xglRotatef(-get_roll() * RAD_TO_DEG + 90, 0.0, 0.0, 1.0); + + xglBegin(GL_POLYGON); + xglColor3f(1.0, 1.0, 1.0); + for(i=0;i<90;i++){ + xglVertex2f(cos(i * 4 * DEG_TO_RAD) * 5, sin(i * 4 * DEG_TO_RAD) * 5); + } + xglEnd(); + + xglBegin(GL_POLYGON); + xglVertex2f(wingArea[0], wingArea[1]); + xglVertex2f(wingArea[2], wingArea[3]); + xglVertex2f(wingArea[4], wingArea[5]); + xglVertex2f(wingArea[6], wingArea[7]); + xglVertex2f(wingArea[0], wingArea[1]); + xglEnd(); + + xglBegin(GL_POLYGON); + xglVertex2f(elevatorArea[0], elevatorArea[1]); + xglVertex2f(elevatorArea[2], elevatorArea[3]); + xglVertex2f(elevatorArea[4], elevatorArea[5]); + xglVertex2f(elevatorArea[6], elevatorArea[7]); + xglVertex2f(elevatorArea[0], elevatorArea[1]); + xglEnd(); + + xglBegin(GL_POLYGON); + xglVertex2f(rudderArea[0], rudderArea[1]); + xglVertex2f(rudderArea[2], rudderArea[3]); + xglVertex2f(rudderArea[4], rudderArea[5]); + xglVertex2f(rudderArea[6], rudderArea[7]); + xglVertex2f(rudderArea[0], rudderArea[1]); + xglEnd(); + + + alphahist[0] = alphahist[1]; + alphahist[1] = alpha; + rollhist[0] = rollhist[1]; + rollhist[1] = -get_roll(); + + xglDisable(GL_BLEND); +} + +void FGTurnCoordinator::Init(void){ + int n; + PlaneTexXPos = 49; + PlaneTexYPos = 59.75; + BallXPos = 145; + BallYPos = 24; + BallTexXPos = 49; + BallTexYPos = 16; + BallRadius = 3.5; + + for(n=0;n<36;n++){ + vertices[2 * n] = cos(10 * n * DEG_TO_RAD) * BallRadius; + vertices[(2 * n) + 1] = sin(10 * n * DEG_TO_RAD) * BallRadius; + } +} + + + +//////////////////////////////////////////////////////////////////////// +// Implementation of FGTexInstrument base class. +//////////////////////////////////////////////////////////////////////// + +FGTexInstrument::FGTexInstrument (void) +{ +} + +FGTexInstrument::~FGTexInstrument (void) +{ +} + void FGTexInstrument::UpdatePointer(void){ - double pitch; - double roll; - float alpharad; - double speed; + float alpha; + glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, vertices); - alpha=((((float)((var[variable]) - (value1))) / + alpha=((((float)(getValue() - (value1))) / (value2 - value1))* (alpha2 - alpha1) + alpha1); if (alpha < alpha1) @@ -595,56 +777,6 @@ void FGTexInstrument::UpdatePointer(void){ glDisableClientState(GL_VERTEX_ARRAY); } -// fgEraseArea - 'Erases' a drawn Polygon by overlaying it with a textured -// area. Shall be a method of a panel class once. - -void fgEraseArea(GLfloat *array, int NumVerti, GLfloat texXPos, GLfloat texYPos, GLfloat XPos, GLfloat YPos, int Texid, float ScaleFactor){ - int i, j; - int n; - float a; - float ififth; - - xglEnable(GL_TEXTURE_2D); - xglEnable(GL_TEXTURE_GEN_S); - xglEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - xglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - xglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - xglMatrixMode(GL_TEXTURE); - xglLoadIdentity(); - -#ifdef GL_VERSION_1_1 - xglBindTexture(GL_TEXTURE_2D, panel_tex_id[Texid]); -#elif GL_EXT_texture_object - xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[Texid]); -#else -# error port me -#endif - - xglMatrixMode(GL_TEXTURE); - xglLoadIdentity(); - xglTranslatef(-((float)((XPos/0.625)/256)), -((float)((YPos/0.625)/256)), 0.0); - xglTranslatef(texXPos/256 , texYPos/256, 0.0); - xglScalef(0.00625, 0.00625, 1.0); - - xglBegin(GL_POLYGON); - for(n=0;n 56){ - alpha = 56; - } - if(alpha < -56){ - alpha = -56; - } - - PlaneAlpha = get_roll(); - - xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - - xglMatrixMode(GL_MODELVIEW); - xglLoadIdentity(); - xglTranslatef(BallXPos, BallYPos, 0.0); - xglTranslatef(0.75 * sin(alphahist[0] * DEG_TO_RAD) * 31, 0.3 * (39 - (cos(alphahist[0] * DEG_TO_RAD) * 39)), 0.0); - 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); - xglDisable(GL_TEXTURE_2D); - xglEnable(GL_BLEND); - xglBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE); - xglMatrixMode(GL_MODELVIEW); - xglLoadIdentity(); - xglTranslatef(BallXPos, BallYPos, 0.0); - xglTranslatef(0.75 * sin(alpha * DEG_TO_RAD) * 31, 0.3 * (39 - (cos(alpha * DEG_TO_RAD) * 39)), 0.0); - xglBegin(GL_POLYGON); - xglColor3f(0.8, 0.8, 0.8); - for(i=0;i<36;i++){ - xglVertex2f(vertices[2 * i], vertices[(2 * i) + 1]); - } - xglEnd(); - - xglDisable(GL_TEXTURE_2D); - xglDisable(GL_BLEND); - - xglMatrixMode(GL_MODELVIEW); - xglLoadIdentity(); - xglTranslatef(XPos, YPos, 0.0); - xglRotatef(rollhist[0] * RAD_TO_DEG + 90, 0.0, 0.0, 1.0); - - fgEraseArea(Wings, 8, PlaneTexXPos, PlaneTexYPos, XPos, YPos, 1, 1); - fgEraseArea(Elevator, 8, PlaneTexXPos, PlaneTexYPos, XPos, YPos, 1, 1); - fgEraseArea(Rudder, 8, PlaneTexXPos, PlaneTexYPos, XPos, YPos, 1, 1); - - xglLoadIdentity(); - xglTranslatef(XPos, YPos, 0.0); - xglRotatef(-get_roll() * RAD_TO_DEG + 90, 0.0, 0.0, 1.0); - - xglBegin(GL_POLYGON); - xglColor3f(1.0, 1.0, 1.0); - for(i=0;i<90;i++){ - xglVertex2f(cos(i * 4 * DEG_TO_RAD) * 5, sin(i * 4 * DEG_TO_RAD) * 5); - } - xglEnd(); - - xglBegin(GL_POLYGON); - xglVertex2f(Wings[0], Wings[1]); - xglVertex2f(Wings[2], Wings[3]); - xglVertex2f(Wings[4], Wings[5]); - xglVertex2f(Wings[6], Wings[7]); - xglVertex2f(Wings[0], Wings[1]); - xglEnd(); - - xglBegin(GL_POLYGON); - xglVertex2f(Elevator[0], Elevator[1]); - xglVertex2f(Elevator[2], Elevator[3]); - xglVertex2f(Elevator[4], Elevator[5]); - xglVertex2f(Elevator[6], Elevator[7]); - xglVertex2f(Elevator[0], Elevator[1]); - xglEnd(); - - xglBegin(GL_POLYGON); - xglVertex2f(Rudder[0], Rudder[1]); - xglVertex2f(Rudder[2], Rudder[3]); - xglVertex2f(Rudder[4], Rudder[5]); - xglVertex2f(Rudder[6], Rudder[7]); - xglVertex2f(Rudder[0], Rudder[1]); - xglEnd(); - - - alphahist[0] = alphahist[1]; - alphahist[1] = alpha; - rollhist[0] = rollhist[1]; - rollhist[1] = -get_roll(); - - xglDisable(GL_BLEND); -} - -void FGTurnCoordinator::Init(void){ - int n; - PlaneTexXPos = 49; - PlaneTexYPos = 59.75; - BallXPos = 145; - BallYPos = 24; - BallTexXPos = 49; - BallTexYPos = 16; - BallRadius = 3.5; - - for(n=0;n<36;n++){ - vertices[2 * n] = cos(10 * n * DEG_TO_RAD) * BallRadius; - vertices[(2 * n) + 1] = sin(10 * n * DEG_TO_RAD) * BallRadius; - } -} - -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){ - int i; - float diff = (alpha2 - alpha1) / (float)(steps - 1); - -#define ANTIALIASED_INSTRUMENTS - -#ifdef ANTIALIASED_INSTRUMENTS - xglEnable(GL_LINE_SMOOTH); - xglEnable(GL_BLEND); - xglHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); -#endif - - xglMatrixMode(GL_MODELVIEW); - xglLoadIdentity(); - - xglTranslatef(XPos, YPos, 0.0); - xglRotatef(-alpha1, 0.0, 0.0, 1.0); - - xglLineWidth(LineWidth); - xglColor3f(red, green, blue); - - if(!filled){ - xglBegin(GL_LINES); - } - else{ - xglBegin(GL_QUAD_STRIP); - } - - for(i=0;i < steps; i++){ - xglVertex3f(sin(i * diff * DEG_TO_RAD) * OuterRadius, - cos(i * diff * DEG_TO_RAD) * OuterRadius, - 0.0); - xglVertex3f(sin(i * diff * DEG_TO_RAD) * InnerRadius, - cos(i * diff * DEG_TO_RAD) * InnerRadius, - 0.0); - } - xglEnd(); - - xglLoadIdentity(); - xglDisable(GL_LINE_SMOOTH); - xglDisable(GL_BLEND); -} - -void DrawBeechcraftLogo(float XPos, float YPos, float width, float height){ - xglMatrixMode(GL_MODELVIEW); - xglLoadIdentity(); - xglTranslatef(XPos, YPos, 0.0); - xglEnable(GL_BLEND); - xglEnable(GL_TEXTURE_2D); - // xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); - // xglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - -#ifdef GL_VERSION_1_1 - xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]); -#elif GL_EXT_texture_object - xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]); -#else -# error port me -#endif - - xglBegin(GL_POLYGON); - - xglTexCoord2f(.39844, .01953); - xglVertex2f(0.0, 0.0); - xglTexCoord2f(.58594, .01953); - xglVertex2f(width, 0.0); - xglTexCoord2f(.58594, .074219); - xglVertex2f(width, height); - xglTexCoord2f(.39844, .074219); - xglVertex2f(0.0, height); - - xglEnd(); - - xglDisable(GL_BLEND); - xglDisable(GL_TEXTURE_2D); -} - - -// PrintMatrix - routine to print the current modelview matrix. - -void PrintMatrix( void){ - xglGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix); - printf("matrix2 = %f %f %f %f \n", - mvmatrix[0], mvmatrix[1], mvmatrix[2], mvmatrix[3]); - printf(" %f %f %f %f \n", - mvmatrix[4], mvmatrix[5], mvmatrix[6], mvmatrix[7]); - printf(" %f %f %f %f \n", - mvmatrix[8], mvmatrix[9], mvmatrix[10], mvmatrix[11]); - printf(" %f %f %f %f \n", - mvmatrix[12], mvmatrix[13], mvmatrix[14], mvmatrix[15]); -} - -void FGRpmGauge::Init(void){ - list = xglGenLists (1); - int n; - - xglNewList(list, GL_COMPILE); - - xglColor3f(.26, .289, .3281); - xglBegin(GL_POLYGON); - for(n = 0; n < 180; n++){ - xglVertex2f(cos(n * 0.0349066) * 24.5, sin(n * 0.0349066) * 24.5); - } - xglEnd(); - - DrawScale(XPos, YPos, 22.5, 25.625, 50, 135, 10, 1.0, 0.0, 0.7, 0.0,FILLED); - DrawScale(XPos, YPos, 21.0, 25.625, -70, 180, 8, 1.8, 0.88, 0.88, 0.88, false); - DrawScale(XPos, YPos, 22.5, 25.0, -70, 180, 40, 0.6, 0.5, 0.5, 0.5, false); - - xglEndList(); -} - -void FGRpmGauge::Render(void){ - xglMatrixMode(GL_MODELVIEW); - xglLoadIdentity(); - xglTranslatef(XPos, YPos, 0.0); - - xglCallList(list); - -} - -void FGPanel::DrawTestLetter(float X, float Y){ - xglEnable(GL_TEXTURE_2D); - xglEnable(GL_BLEND); - - xglMatrixMode(GL_TEXTURE); - xglLoadIdentity(); - xglTranslatef(X, Y, 0.0); - - DrawLetter(); - - xglMatrixMode(GL_MODELVIEW); - xglTranslatef(6.0, 0.0, 0.0); - xglDisable(GL_TEXTURE_2D); - xglDisable(GL_BLEND); -} - -void FGPanel::InitLists(void){ - xglNewList(FontList + 'A', GL_COMPILE); - DrawTestLetter(0.391625, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'B', GL_COMPILE); - DrawTestLetter(0.391625 + 1 * LETTER_OFFSET, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'C', GL_COMPILE); - DrawTestLetter(0.391625 + 2 * LETTER_OFFSET, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'D', GL_COMPILE); - DrawTestLetter(0.391625 + 3 * LETTER_OFFSET, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'E', GL_COMPILE); - DrawTestLetter(0.391625 + 4 * LETTER_OFFSET, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'F', GL_COMPILE); - DrawTestLetter(0.391625 + 5 * LETTER_OFFSET, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'G', GL_COMPILE); - DrawTestLetter(0.391625 + 6 * LETTER_OFFSET, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'H', GL_COMPILE); - DrawTestLetter(0.391625 + 7 * LETTER_OFFSET, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'I', GL_COMPILE); - DrawTestLetter(0.391625 + 8 * LETTER_OFFSET, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'J', GL_COMPILE); - DrawTestLetter(0.391625 + 9 * LETTER_OFFSET, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'K', GL_COMPILE); - DrawTestLetter(0.391625 + 9.7 * LETTER_OFFSET, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'L', GL_COMPILE); - DrawTestLetter(0.399625 + 10.6 * LETTER_OFFSET, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'M', GL_COMPILE); - DrawTestLetter(0.80459375, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'N', GL_COMPILE); - DrawTestLetter(0.83975, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'O', GL_COMPILE); - DrawTestLetter(0.871, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'P', GL_COMPILE); - DrawTestLetter(0.90715625, 0.29296875); - xglEndList(); - - xglNewList(FontList + 'Q', GL_COMPILE); - DrawTestLetter(0.9413125, 0.29296875); - xglEndList(); - - xglNewList(FontList + '1', GL_COMPILE); - DrawTestLetter(0.390625, 0.35546875); - xglEndList(); - - xglNewList(FontList + '2', GL_COMPILE); - DrawTestLetter(0.390625 + 1*LETTER_OFFSET, 0.3515625); - xglEndList(); - - xglNewList(FontList + '3', GL_COMPILE); - DrawTestLetter(0.390625 + 2*LETTER_OFFSET, 0.3515625); - xglEndList(); - - xglNewList(FontList + '4', GL_COMPILE); - DrawTestLetter(0.390625 + 3*LETTER_OFFSET, 0.3515625); - xglEndList(); - - xglNewList(FontList + '5', GL_COMPILE); - DrawTestLetter(0.390625 + 4*LETTER_OFFSET, 0.3515625); - xglEndList(); - - xglNewList(FontList + '6', GL_COMPILE); - DrawTestLetter(0.390625 + 5*LETTER_OFFSET, 0.3515625); - xglEndList(); - - xglNewList(FontList + '7', GL_COMPILE); - DrawTestLetter(0.390625 + 6*LETTER_OFFSET, 0.3515625); - xglEndList(); - - xglNewList(FontList + '8', GL_COMPILE); - DrawTestLetter(0.390625 + 7*LETTER_OFFSET, 0.3515625); - xglEndList(); - - xglNewList(FontList + '9', GL_COMPILE); - DrawTestLetter(0.390625 + 8*LETTER_OFFSET, 0.3515625); - xglEndList(); - - xglNewList(FontList + '0', GL_COMPILE); - DrawTestLetter(0.383625 + 9*LETTER_OFFSET, 0.3515625); - xglEndList(); - - xglNewList(FontList + ' ', GL_COMPILE); - xglTranslatef(8.0, 0.0, 0.0); - xglEndList(); -} - -void FGPanel::TexString(char *s, float XPos, float YPos, float size){ - xglMatrixMode(GL_MODELVIEW); - xglLoadIdentity(); - xglTranslatef(XPos, YPos, 0.0); - xglScalef(size, size, 1.0); - -#ifdef GL_VERSION_1_1 - xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]); -#elif GL_EXT_texture_object - xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]); -#else -# error port me -#endif - - while((*s) != '\0'){ - xglCallList(FontList + (*s)); - s++; - } - xglLoadIdentity(); -} - void FGTexInstrument::Init(void){ CreatePointer(); } @@ -1078,9 +823,189 @@ void FGTexInstrument::Render(void){ xglLoadIdentity(); xglTranslatef(XPos, YPos, 0.0); xglRotatef(-tape[0], 0.0, 0.0, 1.0); - fgEraseArea(vertices, 20, (GLfloat)(teXpos), (GLfloat)(texYpos), (GLfloat)(XPos), (GLfloat)(YPos), 0, 1); + fgEraseArea(vertices, 20, (GLfloat)(textureXPos), (GLfloat)(textureYPos), (GLfloat)(XPos), (GLfloat)(YPos), 0, 1); UpdatePointer(); xglDisable(GL_TEXTURE_2D); } + + + +//////////////////////////////////////////////////////////////////////// +// Implementation of FGAirspeedIndicator. +//////////////////////////////////////////////////////////////////////// + + +FGAirspeedIndicator::FGAirspeedIndicator (int x, int y) +{ + XPos = x; + YPos = y; + radius = 4; + length = 32; + width = 3; + angle = 30; + value1 = 15.0; + value2 = 260.0; + alpha1 = -20.0; + alpha2 = 360; + textureXPos = 65; + textureYPos = 193; + Init(); +} + + +FGAirspeedIndicator::~FGAirspeedIndicator () +{ +} + + +double +FGAirspeedIndicator::getValue () const +{ + return get_speed(); +} + + + +//////////////////////////////////////////////////////////////////////// +// Implementation of FGVerticalSpeedIndicator. +//////////////////////////////////////////////////////////////////////// + + +FGVerticalSpeedIndicator::FGVerticalSpeedIndicator (int x, int y) +{ + XPos = x; + YPos = y; + radius = 4; + length = 30; + width = 3; + angle = 30; + value1 = -3.0; + value2 = 3.0; + alpha1 = 100; + alpha2 = 440; + textureXPos = 66.15; + textureYPos = 66; + Init(); +} + + +FGVerticalSpeedIndicator::~FGVerticalSpeedIndicator () +{ +} + + +double +FGVerticalSpeedIndicator::getValue () const +{ + return get_climb_rate() / 1000.0; +} + + + +//////////////////////////////////////////////////////////////////////// +// Implementation of FGAltimeter. +//////////////////////////////////////////////////////////////////////// + + +FGAltimeter::FGAltimeter (int x, int y) +{ + XPos = x; + YPos = y; + radius = 5; + length = 25; + width = 4; + angle = 30; + value1 = 0; + value2 = 10000; + alpha1 = 0; + alpha2 = 360; + textureXPos = 194; + textureYPos = 191; + Init(); +} + + +FGAltimeter::~FGAltimeter () +{ +} + + +double +FGAltimeter::getValue () const +{ + return get_altitude(); +} + + + +//////////////////////////////////////////////////////////////////////// +// Implementation of FGAltimeter2. +//////////////////////////////////////////////////////////////////////// + + +FGAltimeter2::FGAltimeter2 (int x, int y) +{ + XPos = x; + YPos = y; + radius = 5; + length = 32; + width = 3; + angle = 30; + value1 = 0; + value2 = 3000; + alpha1 = 0; + alpha2 = 1080; + textureXPos = 194; + textureYPos = 191; + Init(); +} + + +FGAltimeter2::~FGAltimeter2 () +{ +} + + +double +FGAltimeter2::getValue () const +{ + return get_altitude(); +} + + + +//////////////////////////////////////////////////////////////////////// +// Implementation of FGRPMIndicator. +//////////////////////////////////////////////////////////////////////// + + +FGRPMIndicator::FGRPMIndicator (int x, int y) +{ + XPos = x; + YPos = y; + radius = 10; + length = 20; + width = 5.5; + angle = 60; + value1 = 0.0; + value2 = 1.0; + alpha1 = -67; + alpha2 = 180; + textureXPos = 174; + textureYPos = 83; + Init(); +} + + +FGRPMIndicator::~FGRPMIndicator () +{ +} + + +double +FGRPMIndicator::getValue () const +{ + return get_throttleval(); +} diff --git a/src/Cockpit/panel.hxx b/src/Cockpit/panel.hxx index 80c73e606..21f82662d 100644 --- a/src/Cockpit/panel.hxx +++ b/src/Cockpit/panel.hxx @@ -1,6 +1,8 @@ // panel.hxx -- instrument panel defines and prototypes // // Written by Friedemann Reinhard, started June 1998. +// +// Major code reorganization by David Megginson, November 1999. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -18,7 +20,6 @@ // // $Id$ -#define LETTER_OFFSET 0.03515625 #ifndef _PANEL_HXX #define _PANEL_HXX @@ -40,212 +41,225 @@ #include #include -class FGInstrument; +class FGInstrument; // FIXME: rearrange to avoid this? + +/** + * Top-level class to hold an instance of a panel. + */ class FGPanel{ - - private: - int height, width; - GLuint FontList; - - GLubyte *background; - - // FGInstrument **instr_list; - FGInstrument *test_instr[7]; - - void GetData(void); - - public: - static FGPanel *OurPanel; - - FGPanel(void); - - float get_height(void){ - return height; - } - - void ReInit( int x, int y, int finx, int finy); - void Update(void); - - void DrawLetter(void){ - glBegin(GL_POLYGON); - glTexCoord2f(0.0, 0.0); - glVertex2f(0.0, 0.0); - glTexCoord2f(LETTER_OFFSET + 0.004, 0.0); - glVertex2f(7.0, 0.0); - glTexCoord2f(LETTER_OFFSET + 0.004, 0.0390625); - glVertex2f(7.0, 9.0); - glTexCoord2f(0.0, 0.0390625); - glVertex2f(0.0, 9.0); - glEnd(); - } - - void DrawTestLetter(float X, float Y); - void InitLists(void); - void TexString(char *s, float XPos, float YPos, float size); - + +public: + static FGPanel *OurPanel; // current_panel would be better + + // FIXME: a few other classes have a + // dependency on this information; it + // would be nice to fix that. + GLuint panel_tex_id[2]; + + FGPanel(); + virtual ~FGPanel (); + virtual float get_height(void) { return height; } + virtual void ReInit( int x, int y, int finx, int finy); + virtual void Update(void); + +private: + + int height; + int width; + GLubyte *background; + GLubyte *imag; + int imag_width, imag_height; + GLubyte *img; + int img_width, img_height; + // The instruments on the panel. + FGInstrument * horizonIndicator; + FGInstrument * turnCoordinator; + FGInstrument * rpmIndicator; + FGInstrument * airspeedIndicator; + FGInstrument * verticalSpeedIndicator; + FGInstrument * altimeter; + FGInstrument * altimeter2; }; + +/** + * Abstract base class for all panel instruments. + */ class FGInstrument{ - friend class FGPanel; - - protected: - float XPos, YPos; - - public: - FGInstrument(void){ - } - - virtual ~FGInstrument(void){} - - virtual void Init(void) = 0; - virtual void Render(void) = 0; + +public: + FGInstrument (void) {} + virtual ~FGInstrument (void) {} + virtual void Init(void) = 0; + virtual void Render(void) = 0; + +protected: + float XPos; + float YPos; }; -class FGHorizon : public FGInstrument { - private: - float texXPos; - float texYPos; - float radius; - float bottom; // tell the program the offset between midpoint and bottom - float top; // guess what ;-) - float vertices[180][2]; - float normals[180][3]; - float texCoord[180][2]; - - public: - FGHorizon(void){ - XPos = 0.0; YPos = 0.0; - Init(); - } - - FGHorizon(float inXPos, float inYPos){ - XPos = inXPos; YPos = inYPos; - Init(); - } - - virtual void Init(void); - virtual void Render(void); + +/** + * Instrument: the artificial horizon. + */ +class FGHorizon : public FGInstrument +{ + +public: + FGHorizon (float inXPos, float inYPos); + virtual ~FGHorizon (void); + virtual void Init (void); + virtual void Render (void); +private: + float texXPos; + float texYPos; + float radius; + float bottom; // tell the program the offset between midpoint and bottom + float top; // guess what ;-) + float vertices[180][2]; + float normals[180][3]; + float texCoord[180][2]; }; -class FGTurnCoordinator : public FGInstrument { - private: - float PlaneTexXPos; - float PlaneTexYPos; - float alpha; - float PlaneAlpha; - float alphahist[2]; - float rollhist[2]; - float BallXPos; - float BallYPos; - float BallTexXPos; - float BallTexYPos; - float BallRadius; - GLfloat vertices[72]; - - public: - FGTurnCoordinator(void){ - XPos = 0.0; YPos = 0.0; - Init(); - } - - FGTurnCoordinator(float inXPos, float inYPos){ - XPos = inXPos; YPos = inYPos; - Init(); - } - - virtual void Init (void); - virtual void Render(void); - + +/** + * Instrument: the turn co-ordinator. + */ +class FGTurnCoordinator : public FGInstrument +{ + +public: + FGTurnCoordinator (float inXPos, float inYPos); + virtual FGTurnCoordinator::~FGTurnCoordinator (void); + virtual void Init (void); + virtual void Render(void); + +private: + float PlaneTexXPos; + float PlaneTexYPos; + float alpha; + float PlaneAlpha; + float alphahist[2]; + float rollhist[2]; + float BallXPos; + float BallYPos; + float BallTexXPos; + float BallTexYPos; + float BallRadius; + GLfloat vertices[72]; + static GLfloat wingArea[]; + static GLfloat elevatorArea[]; + static GLfloat rudderArea[]; }; -class FGRpmGauge : public FGInstrument { - private: - GLuint list; - - public: - FGRpmGauge(void){ - XPos = 0.0; YPos = 0.0; - Init(); - } - - FGRpmGauge(float inXPos, float inYPos){ - XPos = inXPos; YPos = inYPos; - Init(); - } - - virtual void Init(void); - virtual void Render(void); + +/** + * Abstract base class for gauges with needles and textured backgrounds. + * + * The airspeed indicator, vertical speed indicator, altimeter, and RPM + * gauge are all derived from this class. + */ +class FGTexInstrument : public FGInstrument +{ +public: + FGTexInstrument (void); + virtual ~FGTexInstrument (); + virtual void Init(void); + virtual void Render(void); + +protected: + virtual void CreatePointer(void); + virtual void UpdatePointer(void); + virtual double getValue () const = 0; + + float radius; + float length; + float width; + float angle; + float tape[2]; + float value1; + float value2; + float alpha1; + float alpha2; + float textureXPos; + float textureYPos; + GLfloat vertices[20]; }; -// temporary class until I get the software-only routines for the -// instruments run -class FGTexInstrument : public FGInstrument { - - private: - float radius; - float length; - float width; - float angle; - float tape[2]; - float value1; - float value2; - float alpha1; - float alpha2; - float teXpos; - float texYpos; - int variable; - GLfloat vertices[20]; - - public: - FGTexInstrument(void){ - XPos = 0.0; YPos = 0.0; - Init(); - } - - FGTexInstrument(float inXPos, float inYPos, float inradius, float inlength, float inwidth, float inangle, float invalue1, float invalue2, float inalpha1, float inalpha2, float intexXPos, float intexYPos, int invariable){ - - XPos = inXPos; YPos = inYPos; - radius = inradius; angle = inangle; - length = inlength; width = inwidth; - value1 = invalue1; value2 = invalue2; - alpha1 = inalpha1; alpha2 = inalpha2; - teXpos = intexXPos; texYpos = intexYPos; - variable = invariable; - Init(); - } - - void CreatePointer(void); - void UpdatePointer(void); - - void Init(void); - void Render(void); +/** + * Instrument: the airspeed indicator. + */ +class FGAirspeedIndicator : public FGTexInstrument +{ +public: + FGAirspeedIndicator (int x, int y); + virtual ~FGAirspeedIndicator (); + +protected: + double getValue () const; }; -typedef struct{ - float XPos; - float YPos; - float radius; - float length; - float width; - float angle; - float tape[2]; - float value1; - float value2; - float alpha1; - float alpha2; - float teXpos; - float texYpos; - int variable; - GLfloat vertices[20]; -}Pointer; +/** + * Instrument: the vertical speed indicator. + */ +class FGVerticalSpeedIndicator : public FGTexInstrument +{ +public: + FGVerticalSpeedIndicator (int x, int y); + virtual ~FGVerticalSpeedIndicator (); + +protected: + double getValue () const; +}; + + +/** + * Instrument: the altimeter (big hand?) + */ +class FGAltimeter : public FGTexInstrument +{ +public: + FGAltimeter (int x, int y); + virtual ~FGAltimeter (); + +protected: + double getValue () const; +}; + + +/** + * Instrument: the altimeter (little hand?) + */ +class FGAltimeter2 : public FGTexInstrument +{ +public: + FGAltimeter2 (int x, int y); + virtual ~FGAltimeter2 (); + +protected: + double getValue () const; +}; + + +/** + * Instrument: the RPM gauge (actually manifold pressure right now). + */ +class FGRPMIndicator : public FGTexInstrument +{ +public: + FGRPMIndicator (int x, int y); + virtual ~FGRPMIndicator (); + +protected: + double getValue () const; +}; + + + // FIXME: move to FGPanel, somehow void fgEraseArea(GLfloat *array, int NumVerti, GLfloat texXPos, GLfloat texYPos, GLfloat XPos, GLfloat YPos, int Texid, float ScaleFactor); -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); -void DrawBeechcraftLogo(float XPos, float YPos, float Width, float Height); - -void PrintMatrix( void); #endif // _PANEL_HXX