tunnel.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:12k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /*
  2.  * This program is under the GNU GPL.
  3.  * Use at your own risk.
  4.  *
  5.  * written by David Bucciarelli (tech.hmw@plus.it)
  6.  *            Humanware s.r.l.
  7.  */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <math.h>
  12. #include <time.h>
  13. #ifdef _WIN32
  14. #include <windows.h>
  15. #endif
  16. #include <GL/glut.h>
  17. #if defined(GL_VERSION_1_1)
  18. /* Routines called directly. */
  19. #elif defined(GL_EXT_texture_object) && defined(GL_EXT_copy_texture) && defined(GL_EXT_subtexture)
  20. #define glBindTexture(A,B)     glBindTextureEXT(A,B)
  21. #define glGenTextures(A,B)     glGenTexturesEXT(A,B)
  22. #define glDeleteTextures(A,B)  glDeleteTexturesEXT(A,B)
  23. #else
  24. #define glBindTexture(A,B)
  25. #define glGenTextures(A,B)
  26. #define glDeleteTextures(A,B)
  27. #endif
  28. #include "image.h"
  29. static int WIDTH=640;
  30. static int HEIGHT=480;
  31. #define FRAME 50
  32. #define NUMBLOC 5
  33. /* Some <math.h> files do not define M_PI... */
  34. #ifndef M_PI
  35. #define M_PI 3.14159265358979323846
  36. #endif
  37. extern int striplength_skin_13[];
  38. extern float stripdata_skin_13[];
  39. extern int striplength_skin_12[];
  40. extern float stripdata_skin_12[];
  41. extern int striplength_skin_11[];
  42. extern float stripdata_skin_11[];
  43. extern int striplength_skin_9[];
  44. extern float stripdata_skin_9[];
  45. static float obs[3]={1000.0,0.0,2.0};
  46. static float dir[3];
  47. static float v=0.0;
  48. static float alpha=90.0;
  49. static float beta=90.0;
  50. static int fog=1;
  51. static int bfcull=1;
  52. static int usetex=1;
  53. static int cstrip=0;
  54. static int help=1;
  55. static int joyavailable=0;
  56. static int joyactive=0;
  57. static GLuint t1id,t2id;
  58. static void inittextures(void)
  59. {
  60.   IMAGE *img;
  61.   GLenum gluerr;
  62.   
  63.   glGenTextures(1,&t1id);
  64.   glBindTexture(GL_TEXTURE_2D,t1id);
  65.   if(!(img=ImageLoad("tile.rgb"))) {
  66.     fprintf(stderr,"Error reading a texture.n");
  67.     exit(-1);
  68.   }
  69.   glPixelStorei(GL_UNPACK_ALIGNMENT,4);
  70.   if((gluerr=gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img->sizeX, img->sizeY, GL_RGB,
  71.        GL_UNSIGNED_BYTE, (GLvoid *)(img->data)))) {
  72.     fprintf(stderr,"GLULib%sn",gluErrorString(gluerr));
  73.     exit(-1);
  74.   }
  75.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  76.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
  77.   
  78.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_LINEAR);
  79.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  80.   glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  81.   glGenTextures(1,&t2id);
  82.   glBindTexture(GL_TEXTURE_2D,t2id);
  83.   if(!(img=ImageLoad("bw.rgb"))) {
  84.     fprintf(stderr,"Error reading a texture.n");
  85.     exit(-1);
  86.   }
  87.   glPixelStorei(GL_UNPACK_ALIGNMENT,4);
  88.   if((gluerr=gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img->sizeX, img->sizeY, GL_RGB,
  89.        GL_UNSIGNED_BYTE, (GLvoid *)(img->data)))) {
  90.     fprintf(stderr,"GLULib%sn",gluErrorString(gluerr));
  91.     exit(-1);
  92.   }
  93.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  94.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
  95.   
  96.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_LINEAR);
  97.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  98.   glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  99. }
  100. static void drawobjs(int *l, float *f)
  101. {
  102.   int mend,j;
  103.   if(cstrip) {
  104.     float r=0.33,g=0.33,b=0.33;
  105.     for(;(*l)!=0;) {
  106.       mend=*l++;
  107.       r+=0.33;
  108.       if(r>1.0) {
  109. r=0.33;
  110. g+=0.33;
  111. if(g>1.0) {
  112.   g=0.33;
  113.   b+=0.33;
  114.   if(b>1.0)
  115.     b=0.33;
  116. }
  117.       }
  118.       glColor3f(r,g,b);
  119.       glBegin(GL_TRIANGLE_STRIP);
  120.       for(j=0;j<mend;j++) {
  121. f+=4;
  122. glTexCoord2fv(f); f+=2;
  123. glVertex3fv(f); f+=3;
  124.       }
  125.       glEnd();
  126.     }
  127.   } else
  128.     for(;(*l)!=0;) {
  129.       mend=*l++;
  130.       glBegin(GL_TRIANGLE_STRIP);
  131.       for(j=0;j<mend;j++) {
  132. glColor4fv(f); f+=4;
  133. glTexCoord2fv(f); f+=2;
  134. glVertex3fv(f); f+=3;
  135.       }
  136.       glEnd();
  137.     }
  138. }
  139. static float gettime(void)
  140. {
  141.   static clock_t told=0;
  142.   clock_t tnew,ris;
  143.   tnew=clock();
  144.   ris=tnew-told;
  145.   told=tnew;
  146.   return(ris/(float)CLOCKS_PER_SEC);
  147. }
  148. static void calcposobs(void)
  149. {
  150.   dir[0]=sin(alpha*M_PI/180.0);
  151.   dir[1]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0);
  152.   dir[2]=cos(beta*M_PI/180.0);
  153.   obs[0]+=v*dir[0];
  154.   obs[1]+=v*dir[1];
  155.   obs[2]+=v*dir[2];
  156. }
  157. /* ARGSUSED1 */
  158. static void special(int k, int x, int y)
  159. {
  160.   switch(k) {
  161.   case GLUT_KEY_LEFT:
  162.     alpha-=2.0;
  163.     break;
  164.   case GLUT_KEY_RIGHT:
  165.     alpha+=2.0;
  166.     break;
  167.   case GLUT_KEY_DOWN:
  168.     beta-=2.0;
  169.     break;
  170.   case GLUT_KEY_UP:
  171.     beta+=2.0;
  172.     break;
  173.   }
  174. }
  175. /* ARGSUSED1 */
  176. static void key(unsigned char k, int x, int y)
  177. {
  178.   switch(k) {
  179.   case 27:
  180.     exit(0);
  181.     break;
  182.     
  183.   case 'a':
  184.     v+=0.01;
  185.     break;
  186.   case 'z':
  187.     v-=0.01;
  188.     break;
  189.   case 'j':
  190.     joyactive=(!joyactive);
  191.     break;
  192.   case 'h':
  193.     help=(!help);
  194.     break;
  195.   case 'f':
  196.     fog=(!fog);
  197.     break;
  198.   case 't':
  199.     usetex=(!usetex);
  200.     break;
  201.   case 'b':
  202.     if(bfcull) {
  203.       glDisable(GL_CULL_FACE);
  204.       bfcull=0;
  205.     } else {
  206.       glEnable(GL_CULL_FACE);
  207.       bfcull=1;
  208.     }
  209.     break;
  210.   case 'm':
  211.     cstrip=(!cstrip);
  212.     break;
  213.   case 'd':
  214.     fprintf(stderr,"Deleting textures...n");
  215.     glDeleteTextures(1,&t1id);
  216.     glDeleteTextures(1,&t2id);
  217.     fprintf(stderr,"Loading textures...n");
  218.     inittextures();
  219.     fprintf(stderr,"Done.n");
  220.     break;
  221.   }
  222. }
  223. static void reshape(int w, int h) 
  224. {
  225.   WIDTH=w;
  226.   HEIGHT=h;
  227.   glMatrixMode(GL_PROJECTION);
  228.   glLoadIdentity();
  229.   gluPerspective(80.0,w/(float)h,1.0,50.0);
  230.   glMatrixMode(GL_MODELVIEW);
  231.   glLoadIdentity();
  232.   glViewport(0,0,w,h);
  233. }
  234. static void printstring(void *font, char *string)
  235. {
  236.   int len,i;
  237.   len=(int)strlen(string);
  238.   for(i=0;i<len;i++)
  239.     glutBitmapCharacter(font,string[i]);
  240. }
  241. static void printhelp(void)
  242. {
  243.   glEnable(GL_BLEND);
  244.   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  245.   glColor4f(0.0,0.0,0.0,0.5);
  246.   glRecti(40,40,600,440);
  247.   glDisable(GL_BLEND);
  248.   glColor3f(1.0,0.0,0.0);
  249.   glRasterPos2i(300,420);
  250.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Help");
  251.   glRasterPos2i(60,390);
  252.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"h - Togle Help");
  253.   glRasterPos2i(60,360);
  254.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"t - Togle Textures");
  255.   glRasterPos2i(60,330);
  256.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"f - Togle Fog");
  257.   glRasterPos2i(60,300);
  258.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"m - Togle strips");
  259.   glRasterPos2i(60,270);
  260.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"b - Togle Back face culling");
  261.   glRasterPos2i(60,240);
  262.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Arrow Keys - Rotate");
  263.   glRasterPos2i(60,210);
  264.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"a - Increase velocity");
  265.   glRasterPos2i(60,180);
  266.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"z - Decrease velocity");
  267.   glRasterPos2i(60,150);
  268.   if(joyavailable)
  269.     printstring(GLUT_BITMAP_TIMES_ROMAN_24,"j - Togle jostick control (Joystick control available)");
  270.   else
  271.     printstring(GLUT_BITMAP_TIMES_ROMAN_24,"(No Joystick control available)");
  272. }
  273. static void dojoy(void)
  274. {
  275. #ifdef _WIN32
  276.   static UINT max[2]={0,0};
  277.   static UINT min[2]={0xffffffff,0xffffffff},center[2];
  278.   MMRESULT res;
  279.   JOYINFO joy;
  280.   res=joyGetPos(JOYSTICKID1,&joy);
  281.   if(res==JOYERR_NOERROR) {
  282.     joyavailable=1;
  283.     if(max[0]<joy.wXpos)
  284.       max[0]=joy.wXpos;
  285.     if(min[0]>joy.wXpos)
  286.       min[0]=joy.wXpos;
  287.     center[0]=(max[0]+min[0])/2;
  288.     if(max[1]<joy.wYpos)
  289.       max[1]=joy.wYpos;
  290.     if(min[1]>joy.wYpos)
  291.       min[1]=joy.wYpos;
  292.     center[1]=(max[1]+min[1])/2;
  293.     if(joyactive) {
  294.       if(fabs(center[0]-(float)joy.wXpos)>0.1*(max[0]-min[0]))
  295. alpha-=2.0*(center[0]-(float)joy.wXpos)/(max[0]-min[0]);
  296.       if(fabs(center[1]-(float)joy.wYpos)>0.1*(max[1]-min[1]))
  297. beta+=2.0*(center[1]-(float)joy.wYpos)/(max[1]-min[1]);
  298.       if(joy.wButtons & JOY_BUTTON1)
  299. v+=0.01;
  300.       if(joy.wButtons & JOY_BUTTON2)
  301. v-=0.01;
  302.     }
  303.   } else
  304.     joyavailable=0;
  305. #endif
  306. }
  307. static void draw(void)
  308. {
  309.   static int count=0;
  310.   static char frbuf[80];
  311.   int i;
  312.   float fr,base,offset;
  313.   dojoy();
  314.   glEnable(GL_DEPTH_TEST);
  315.   /*
  316.     if(count & 1) {
  317.     glDepthRange(1.0,0.5);
  318.     glDepthFunc(GL_GREATER);
  319.     } else {
  320.     glDepthRange(0.0,0.5);
  321.     glDepthFunc(GL_LESS);
  322.     }
  323.     */
  324.   /*glClear(GL_COLOR_BUFFER_BIT);*/
  325.   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  326.   
  327.   if(usetex)
  328.     glEnable(GL_TEXTURE_2D);
  329.   else
  330.     glDisable(GL_TEXTURE_2D);
  331.   
  332.   if(fog)
  333.     glEnable(GL_FOG);
  334.   else
  335.     glDisable(GL_FOG);
  336.   
  337.   glShadeModel(GL_SMOOTH);
  338.   glPushMatrix();
  339.   calcposobs();
  340.   gluLookAt(obs[0],obs[1],obs[2],
  341.     obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2],
  342.     0.0,0.0,1.0);
  343.   if(dir[0]>0) {
  344.     offset=8.0;
  345.     base=obs[0]-fmod(obs[0],8.0);
  346.   } else {
  347.     offset=-8.0;
  348.     base=obs[0]+(8.0-fmod(obs[0],8.0));
  349.   }
  350.   glPushMatrix();
  351.   glTranslatef(base-offset/2.0,0.0,0.0);
  352.   for(i=0;i<NUMBLOC;i++) {
  353.     glTranslatef(offset,0.0,0.0);
  354.     glBindTexture(GL_TEXTURE_2D,t1id);
  355.     drawobjs(striplength_skin_11,stripdata_skin_11);
  356.     glBindTexture(GL_TEXTURE_2D,t2id);
  357.     drawobjs(striplength_skin_12,stripdata_skin_12);
  358.     drawobjs(striplength_skin_9,stripdata_skin_9);
  359.     drawobjs(striplength_skin_13,stripdata_skin_13);
  360.   }
  361.   glPopMatrix();
  362.   glPopMatrix();
  363.   if((count % FRAME)==0) {
  364.     fr=gettime();
  365.     sprintf(frbuf,"Frame rate: %f",FRAME/fr);
  366.   }
  367.   glDisable(GL_TEXTURE_2D);
  368.   glDisable(GL_DEPTH_TEST);
  369.   glDisable(GL_FOG);
  370.   glShadeModel(GL_FLAT);
  371.   glMatrixMode(GL_PROJECTION);
  372.   glLoadIdentity();
  373.   glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0);
  374.   glMatrixMode(GL_MODELVIEW);
  375.   glLoadIdentity();
  376.   glColor3f(1.0,0.0,0.0);
  377.   glRasterPos2i(10,10);
  378.   printstring(GLUT_BITMAP_HELVETICA_18,frbuf);
  379.   glRasterPos2i(350,470);
  380.   printstring(GLUT_BITMAP_HELVETICA_10,"Tunnel V1.3 Written by David Bucciarelli (tech.hmw@plus.it)");
  381.   if(help)
  382.     printhelp();
  383.   reshape(WIDTH,HEIGHT);
  384.   glutSwapBuffers();
  385.  
  386.   count++;
  387. }
  388. int main(int ac, char **av)
  389. {
  390.   float fogcolor[4]={0.7,0.7,0.7,1.0};
  391.   fprintf(stderr,"Tunnel V1.3nWritten by David Bucciarelli (tech.hmw@plus.it)n");
  392.   /*
  393.     #ifdef _WIN32
  394.     if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) {
  395.     fprintf(stderr,"Error setting the process class.n");
  396.     return 0;
  397.     }
  398.     if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) {
  399.     fprintf(stderr,"Error setting the process priority.n");
  400.     return 0;
  401.     }
  402.     #endif
  403.     */
  404.   glutInitWindowPosition(0,0);
  405.   glutInitWindowSize(WIDTH,HEIGHT);
  406.   glutInit(&ac,av);
  407.   glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE);
  408.   glutCreateWindow("Tunnel");
  409.   glMatrixMode(GL_PROJECTION);
  410.   glLoadIdentity();
  411.   gluPerspective(80.0,WIDTH/(float)HEIGHT,1.0,50.0);
  412.   glMatrixMode(GL_MODELVIEW);
  413.   glShadeModel(GL_SMOOTH);
  414.   glEnable(GL_DEPTH_TEST);
  415.   glEnable(GL_CULL_FACE);
  416.   glEnable(GL_TEXTURE_2D);
  417.   glEnable(GL_FOG);
  418.   glFogi(GL_FOG_MODE,GL_EXP2);
  419.   glFogfv(GL_FOG_COLOR,fogcolor);
  420.   glFogf(GL_FOG_DENSITY,0.06);
  421. #ifdef FX
  422.   glHint(GL_FOG_HINT,GL_NICEST);
  423.   /*fxMesaTextureUsePalette(1); */
  424. #endif
  425.   inittextures();
  426. #ifndef FX
  427.   glDisable(GL_TEXTURE_2D);
  428.   usetex=0;
  429. #endif
  430.   glClearColor(fogcolor[0],fogcolor[1],fogcolor[2],fogcolor[3]);
  431.   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  432.   calcposobs();
  433.   glutReshapeFunc(reshape);
  434.   glutDisplayFunc(draw);
  435.   glutKeyboardFunc(key);
  436.   glutSpecialFunc(special);
  437.   glutIdleFunc(draw);
  438.   glutMainLoop();
  439.   return 0;             /* ANSI C requires main to return int. */
  440. }