/************************************************************************** * panel.cxx -- routines to draw an instrument panel * * Written by Friedemann Reinhard, started June 1998. * * Copyright(C)1998 Friedemann Reinhard-reinhard@theorie2.physik.uni-erlangen.de * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id$ * (Log is kept at end of this file) **************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_WINDOWS_H # include #endif #include #include #include #include #include #include #include #include #include #include
#include
#include "panel.hxx" #include "cockpit.hxx" #include "hud.hxx" #define IMAGIC 0x01da #define IMAGIC_SWAP 0xda01 #define SWAP_SHORT_BYTES(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) #define SWAP_LONG_BYTES(x) (((((x) & 0xff) << 24) | (((x) & 0xff00) << 8)) | \ ((((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))) typedef struct { unsigned short imagic; unsigned short type; unsigned short dim; unsigned short sizeX, sizeY, sizeZ; unsigned long min, max; unsigned long wasteBytes; char name[80]; unsigned long colorMap; FILE *file; unsigned char *tmp[5]; unsigned long rleEnd; unsigned long *rowStart; unsigned long *rowSize; } Image; IMAGE *imag; IMAGE *img2; IMAGE *img; static GLuint panel_list; static GLuint panel_tex_id; static GLubyte tex[32][128][3]; static GLint stencil[1024][768]; static float alphahist; static float Xzoom, Yzoom; // static GLint viewport[4]; // static GLdouble mvmatrix[16], projmatrix[16]; static Pointer pointer[20]; static float NumPoint = 4; static double var[20]; static double offset; static float alpha; /* image.c THIS FILE WAS COPIED FROM THE MESA GRAPHICS LIBRARY */ static Image *ImageOpen(char *fileName) { Image *image; unsigned long *rowStart, *rowSize, ulTmp; int x, i; image = (Image *)malloc(sizeof(Image)); if (image == NULL) { fprintf(stderr, "Out of memory!\n"); exit(-1); } if ((image->file = fopen(fileName, "rb")) == NULL) { perror(fileName); exit(-1); } /* * Read the image header */ fread(image, 1, 12, image->file); /* * Check byte order */ if (image->imagic == IMAGIC_SWAP) { image->type = SWAP_SHORT_BYTES(image->type); image->dim = SWAP_SHORT_BYTES(image->dim); image->sizeX = SWAP_SHORT_BYTES(image->sizeX); image->sizeY = SWAP_SHORT_BYTES(image->sizeY); image->sizeZ = SWAP_SHORT_BYTES(image->sizeZ); } for ( i = 0 ; i <= image->sizeZ ; i++ ) { image->tmp[i] = (unsigned char *)malloc(image->sizeX*256); if (image->tmp[i] == NULL ) { fprintf(stderr, "Out of memory!\n"); exit(-1); } } if ((image->type & 0xFF00) == 0x0100) /* RLE image */ { x = image->sizeY * image->sizeZ * sizeof(long); image->rowStart = (unsigned long *)malloc(x); image->rowSize = (unsigned long *)malloc(x); if (image->rowStart == NULL || image->rowSize == NULL) { fprintf(stderr, "Out of memory!\n"); exit(-1); } image->rleEnd = 512 + (2 * x); fseek(image->file, 512, SEEK_SET); fread(image->rowStart, 1, x, image->file); fread(image->rowSize, 1, x, image->file); if (image->imagic == IMAGIC_SWAP) { x /= sizeof(long); rowStart = image->rowStart; rowSize = image->rowSize; while (x--) { ulTmp = *rowStart; *rowStart++ = SWAP_LONG_BYTES(ulTmp); ulTmp = *rowSize; *rowSize++ = SWAP_LONG_BYTES(ulTmp); } } } return image; } static void ImageClose( Image *image) { int i; fclose(image->file); for ( i = 0 ; i <= image->sizeZ ; i++ ) free(image->tmp[i]); free(image); } static void ImageGetRow( Image *image, unsigned char *buf, int y, int z) { unsigned char *iPtr, *oPtr, pixel; int count; if ((image->type & 0xFF00) == 0x0100) /* RLE image */ { fseek(image->file, image->rowStart[y+z*image->sizeY], SEEK_SET); fread(image->tmp[0], 1, (unsigned int)image->rowSize[y+z*image->sizeY], image->file); iPtr = image->tmp[0]; oPtr = buf; while (1) { pixel = *iPtr++; count = (int)(pixel & 0x7F); if (!count) return; if (pixel & 0x80) { while (count--) { *oPtr++ = *iPtr++; } } else { pixel = *iPtr++; while (count--) { *oPtr++ = pixel; } } } } else /* verbatim image */ { fseek(image->file, 512+(y*image->sizeX)+(z*image->sizeX*image->sizeY), SEEK_SET); fread(buf, 1, image->sizeX, image->file); } } static void ImageGetRawData( Image *image, char *data) { int i, j, k; int remain; switch ( image->sizeZ ) { case 1: remain = image->sizeX % 4; break; case 2: remain = image->sizeX % 2; break; case 3: remain = (image->sizeX * 3) & 0x3; if (remain) remain = 4 - remain; break; case 4: remain = 0; break; } for (i = 0; i < image->sizeY; i++) { for ( k = 0; k < image->sizeZ ; k++ ) ImageGetRow(image, image->tmp[k+1], i, k); for (j = 0; j < image->sizeX; j++) for ( k = 1; k <= image->sizeZ ; k++ ) *data++ = *(image->tmp[k] + j); data += remain; } } static IMAGE *ImageLoad(char *fileName) { Image *image; IMAGE *final; int sx; image = ImageOpen(fileName); final = (IMAGE *)malloc(sizeof(IMAGE)); if (final == NULL) { fprintf(stderr, "Out of memory!\n"); exit(-1); } final->imagic = image->imagic; final->type = image->type; final->dim = image->dim; final->sizeX = image->sizeX; final->sizeY = image->sizeY; final->sizeZ = image->sizeZ; /* * Round up so rows are long-word aligned */ sx = ( (image->sizeX) * (image->sizeZ) + 3) >> 2; final->data = (unsigned char *)malloc( sx * image->sizeY * sizeof(unsigned int)); if (final->data == NULL) { fprintf(stderr, "Out of memory!\n"); exit(-1); } ImageGetRawData(image, final->data); ImageClose(image); return final; } /* Beginning of the "panel-code" */ void fgPanelInit ( void ) { fgVIEW *v; string tpath; // char *root; int x, y, i; v = ¤t_view; Xzoom = (float)((float)(current_view.winWidth)/1024); Yzoom = (float)((float)(current_view.winHeight)/768); pointer[1].XPos = 352; pointer[1].YPos = 156; pointer[1].radius = 4; pointer[1].length = 32; pointer[1].width = 3; pointer[1].angle = 30; pointer[1].value1 = 0; pointer[1].value2 = 3000; pointer[1].alpha1 = 0; pointer[1].alpha2 = 1080; pointer[1].variable = 1; pointer[1].teXpos = 59; pointer[1].texYpos = 199; pointer[0].XPos = 352; pointer[0].YPos = 156; pointer[0].radius = 4; pointer[0].length = 25; pointer[0].width = 4; pointer[0].angle = 30; pointer[0].value1 = 0; pointer[0].value2 = 10000; pointer[0].alpha1 = 0; pointer[0].alpha2 = 360; pointer[0].variable = 1; pointer[0].teXpos = 59; pointer[0].texYpos = 199; pointer[2].XPos = 352; pointer[2].YPos = 48; pointer[2].radius = 4; pointer[2].length = 30; pointer[2].width = 3; pointer[2].angle = 30; pointer[2].value1 = -3; pointer[2].value2 = 3; pointer[2].alpha1 = 100; pointer[2].alpha2 = 440; pointer[2].variable = 2; pointer[2].teXpos = 63; pointer[2].texYpos = 68; pointer[3].XPos = 451; pointer[3].YPos = 125; pointer[3].radius = 9; pointer[3].length = 20; pointer[3].width = 5; pointer[3].angle = 50; pointer[3].value1 = 0.0; pointer[3].value2 = 1.0; pointer[3].alpha1 = 280; pointer[3].alpha2 = 540; pointer[3].variable = 3; pointer[3].teXpos = 162; pointer[3].texYpos = 40; for(i=0;idata[(y+x*768)*3] == 0) && (img2->data[(y+x*768)*3+1] == 0) && (img2->data[(y+x*768)*3+2] == 0) ) { stencil[x][y]=0x0;//0x0 } else { stencil[x][y]=0x1;//0x1 } } } xglPixelZoom(Xzoom, Yzoom); xglPixelStorei(GL_UNPACK_ALIGNMENT, 1); xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024); xglStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); xglRasterPos2i(0,0); xglDrawPixels(1024, 768, GL_STENCIL_INDEX, GL_UNSIGNED_INT, (GLvoid *)(stencil)); xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024); xglStencilFunc(GL_EQUAL, 0x1, 0x1);//0x1.. xglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); xglRasterPos2i(0,0); xglPixelZoom(Xzoom, Yzoom); // xglDrawPixels(1024, 768, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *)(img2->data)); xglStencilFunc(GL_NOTEQUAL, 0x1, 0x1); xglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); xglEnable(GL_STENCIL_TEST); xglPixelStorei(GL_UNPACK_ROW_LENGTH, 256); xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *)(img->data)); // #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 // xglPixelStorei(GL_UNPACK_ROW_LENGTH, 256); // xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *)(img->data)); xglMatrixMode(GL_MODELVIEW); xglPopMatrix(); } void fgPanelReInit( void){ fgVIEW *v; fgOPTIONS *o; int x, y, i; o = ¤t_options; v = ¤t_view; Xzoom = (float)((float)(current_view.winWidth)/1024); Yzoom = (float)((float)(current_view.winHeight)/768); xglMatrixMode(GL_PROJECTION); xglPushMatrix(); xglLoadIdentity(); xglViewport(0, 0, 640, 480); gluOrtho2D(0, 640, 0, 480); xglMatrixMode(GL_MODELVIEW); xglPushMatrix(); xglLoadIdentity(); xglClearStencil(0x0); xglClear(GL_STENCIL_BUFFER_BIT); xglEnable(GL_STENCIL_TEST); xglPixelStorei(GL_UNPACK_ALIGNMENT, 1); xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); xglPixelZoom(Xzoom, Yzoom); xglPixelStorei(GL_UNPACK_ALIGNMENT, 1); xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024); xglStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); xglRasterPos2i(0,0); xglDrawPixels(1024, 768, GL_STENCIL_INDEX, GL_UNSIGNED_INT, (GLvoid *)(stencil)); xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024); xglStencilFunc(GL_EQUAL, 0x1, 0x1);//0x1.. xglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); xglRasterPos2i(0,0); xglPixelZoom(Xzoom, Yzoom); xglDrawPixels(1024, 768, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *)(img2->data)); xglStencilFunc(GL_NOTEQUAL, 0x1, 0x1); xglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); xglEnable(GL_STENCIL_TEST); } void fgPanelUpdate ( void ) { fgVIEW *v; float alpha; double pitch; double roll; float alpharad; double speed; int i; var[0] = get_speed(); var[1] = get_altitude(); var[2] = get_aoa(); // A placeholder. It should be the vertical speed once. var[3] = get_throttleval(); v = ¤t_view; xglMatrixMode(GL_PROJECTION); xglPushMatrix(); xglLoadIdentity(); gluOrtho2D(0, 640, 0, 480); xglMatrixMode(GL_MODELVIEW); xglPushMatrix(); xglLoadIdentity(); xglDisable(GL_DEPTH_TEST); xglDisable(GL_LIGHTING); xglStencilFunc(GL_EQUAL, 0x1, 0x1); xglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // xglEnable(GL_STENCIL_TEST); xglEnable(GL_TEXTURE_2D); #ifdef GL_VERSION_1_1 xglBindTexture(GL_TEXTURE_2D, panel_tex_id); #elif GL_EXT_texture_object xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id); #else # error port me #endif xglMatrixMode(GL_MODELVIEW); xglPopMatrix(); xglPushMatrix(); for(i=0;i pointer.alpha2) alpha = pointer.alpha2; xglMatrixMode(GL_MODELVIEW); xglPushMatrix(); xglLoadIdentity(); xglDisable(GL_TEXTURE_2D); xglTranslatef(pointer.XPos, pointer.YPos, 0); xglRotatef(-alpha, 0.0, 0.0, 1.0); xglColor4f(1.0, 1.0, 1.0, 1.0); glDrawArrays(GL_POLYGON, 0, 10); return alpha; xglEnable(GL_TEXTURE_2D); glDisableClientState(GL_VERTEX_ARRAY); } void ErasePointer(Pointer pointer){ int i, j; 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); //glTexGenfv(GL_S, GL_EYE_PLANE, currentCoeff); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); //glTexGenfv(GL_T, GL_EYE_PLANE, currentCoeff); 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); #elif GL_EXT_texture_object xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id); #else # error port me #endif xglMatrixMode(GL_TEXTURE); xglLoadIdentity(); xglTranslatef(-((float)(((float)(pointer.XPos)/0.625)/256)) /* - 0.057143*/, -((float)(((float)(pointer.YPos)/0.625)/256)), 0.0); xglTranslatef(pointer.teXpos/256 , pointer.texYpos/256, 0.0); xglScalef(0.00625, 0.00625, 1.0); //xglTranslatef(-pointer.teXpos , -pointer.texYpos, 0.0); xglBegin(GL_POLYGON); xglVertex2f(pointer.vertices[0], pointer.vertices[1]); xglVertex2f(pointer.vertices[2], pointer.vertices[3]); xglVertex2f(pointer.vertices[4], pointer.vertices[5]); xglVertex2f(pointer.vertices[16], pointer.vertices[17]); xglVertex2f(pointer.vertices[18], pointer.vertices[19]); xglEnd(); xglLoadIdentity(); xglMatrixMode(GL_MODELVIEW); xglPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); xglPixelStorei(GL_UNPACK_SKIP_ROWS, 0); xglDisable(GL_TEXTURE_2D); xglDisable(GL_TEXTURE_GEN_S); xglDisable(GL_TEXTURE_GEN_T); } void CreatePointer(Pointer *pointer){ int i; float alpha; float alphastep; float r = pointer->radius; float angle = pointer->angle; float length = pointer->length; float width = pointer->width; pointer->vertices[0] = 0; pointer->vertices[1] = length; pointer->vertices[2] = -(width/2); pointer->vertices[3] = length - ((width/2)/(tan(angle*DEG_TO_RAD/2))); pointer->vertices[4] = -(width/2); pointer->vertices[5] = cos(asin((width/2)/r))*r; alphastep = (asin((width/2)/r)+asin((width/2)/r))/5; alpha = asin(-(width/2)/r); for(i=0;i<5;i++){ alpha += alphastep; pointer->vertices[(i*2)+6] = sin(alpha)*r; } alpha = asin(-(width/2)/r); for(i=0;i<5;i++){ alpha +=alphastep; pointer->vertices[(i*2)+7]= cos(alpha)*r; } pointer->vertices[16] = - pointer->vertices[4]; pointer->vertices[17] = pointer->vertices[5]; pointer->vertices[18] = - pointer->vertices[2]; pointer->vertices[19] = pointer->vertices[3]; } /* $Log$ /* Revision 1.7 1998/08/31 20:45:31 curt /* Tweaks from Friedemann. /* * Revision 1.6 1998/08/28 18:14:40 curt * Added new cockpit code from Friedemann Reinhard * * * Revision 1.1 1998/06/27 16:47:54 curt * Incorporated Friedemann Reinhard's * first pass at an isntrument panel. * */