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

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. #ifdef _WIN32
  13. #include <windows.h>
  14. #endif
  15. #include <GL/glut.h>
  16. #if defined(GL_VERSION_1_1)
  17. /* Routines called directly. */
  18. #elif defined(GL_EXT_texture_object) && defined(GL_EXT_copy_texture) && defined(GL_EXT_subtexture)
  19. #define glBindTexture(A,B)     glBindTextureEXT(A,B)
  20. #define glGenTextures(A,B)     glGenTexturesEXT(A,B)
  21. #define glTexSubImage2D(A,B,C,D,E,F,G,H,I) glTexSubImage2DEXT(A,B,C,D,E,F,G,H,I)
  22. #else
  23. #define glBindTexture(A,B)
  24. #define glGenTextures(A,B)
  25. #define glTexSubImage2D(A,B,C,D,E,F,G,H,I)
  26. #endif
  27. static int WIDTH=640;
  28. static int HEIGHT=480;
  29. #define FRAME 50
  30. #define BASESIZE 7.5f
  31. #define SPHERE_RADIUS 0.75f
  32. #define TEX_CHECK_WIDTH 256
  33. #define TEX_CHECK_HEIGHT 256
  34. #define TEX_CHECK_SLOT_SIZE (TEX_CHECK_HEIGHT/16)
  35. #define TEX_CHECK_NUMSLOT (TEX_CHECK_HEIGHT/TEX_CHECK_SLOT_SIZE)
  36. #define TEX_REFLECT_WIDTH 256
  37. #define TEX_REFLECT_HEIGHT 256
  38. #define TEX_REFLECT_SLOT_SIZE (TEX_REFLECT_HEIGHT/16)
  39. #define TEX_REFLECT_NUMSLOT (TEX_REFLECT_HEIGHT/TEX_REFLECT_SLOT_SIZE)
  40. /* Some <math.h> files do not define M_PI... */
  41. #ifndef M_PI
  42. #define M_PI 3.14159265358979323846
  43. #endif
  44. #define EPSILON 0.0001
  45. #define clamp255(a)  ( (a)<(0.0f) ? (0.0f) : ((a)>(255.0f) ? (255.0f) : (a)) )
  46. #define fabs(x) ((x)<0.0f?-(x):(x))
  47. #define vequ(a,b) { (a)[0]=(b)[0]; (a)[1]=(b)[1]; (a)[2]=(b)[2]; }
  48. #define vsub(a,b,c) { (a)[0]=(b)[0]-(c)[0]; (a)[1]=(b)[1]-(c)[1]; (a)[2]=(b)[2]-(c)[2]; }
  49. #define dprod(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2])
  50. #define vnormalize(a,b) { 
  51.   register float m_norm; 
  52.   m_norm=sqrt((double)dprod((a),(a))); 
  53.   (a)[0] /=m_norm; 
  54.   (a)[1] /=m_norm; 
  55.   (a)[2] /=m_norm; }
  56. static GLubyte checkmap[TEX_CHECK_HEIGHT][TEX_CHECK_WIDTH][3];
  57. static GLuint checkid;
  58. static int checkmap_currentslot=0;
  59. static GLubyte reflectmap[TEX_REFLECT_HEIGHT][TEX_REFLECT_WIDTH][3];
  60. static GLuint reflectid;
  61. static int reflectmap_currentslot=0;
  62. static GLuint lightdlist;
  63. static GLuint objdlist;
  64. static float lightpos[3]={2.1,2.1,2.8};
  65. static float objpos[3]={0.0,0.0,1.0};
  66. static float sphere_pos[TEX_CHECK_HEIGHT][TEX_REFLECT_WIDTH][3];
  67. static float fogcolor[4]={0.05,0.05,0.05,1.0};
  68. static float obs[3]={7.0,0.0,2.0};
  69. static float dir[3];
  70. static float v=0.0;
  71. static float alpha=-90.0;
  72. static float beta=90.0;
  73. static int fog=1;
  74. static int bfcull=1;
  75. static int poutline=0;
  76. static int help=1;
  77. static int showcheckmap=1;
  78. static int showreflectmap=1;
  79. static int joyavailable=0;
  80. static int joyactive=0;
  81. static float gettime(void)
  82. {
  83.   static float told=0.0f;
  84.   float tnew,ris;
  85.   tnew=glutGet(GLUT_ELAPSED_TIME);
  86.   ris=tnew-told;
  87.   told=tnew;
  88.   return ris/1000.0;
  89. }
  90. static void calcposobs(void)
  91. {
  92.   dir[0]=sin(alpha*M_PI/180.0);
  93.   dir[1]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0);
  94.   dir[2]=cos(beta*M_PI/180.0);
  95.   obs[0]+=v*dir[0];
  96.   obs[1]+=v*dir[1];
  97.   obs[2]+=v*dir[2];
  98. }
  99. /* ARGSUSED1 */
  100. static void special(int k, int x, int y)
  101. {
  102.   switch(k) {
  103.   case GLUT_KEY_LEFT:
  104.     alpha-=2.0;
  105.     break;
  106.   case GLUT_KEY_RIGHT:
  107.     alpha+=2.0;
  108.     break;
  109.   case GLUT_KEY_DOWN:
  110.     beta-=2.0;
  111.     break;
  112.   case GLUT_KEY_UP:
  113.     beta+=2.0;
  114.     break;
  115.   }
  116. }
  117. /* ARGSUSED1 */
  118. static void key(unsigned char k, int x, int y)
  119. {
  120.   switch(k) {
  121.   case 27:
  122.     exit(0);
  123.     break;
  124.   case 's':
  125.     lightpos[1]-=0.1;
  126.     break;
  127.   case 'd':
  128.     lightpos[1]+=0.1;
  129.     break;
  130.   case 'e':
  131.     lightpos[0]-=0.1;
  132.     break;
  133.   case 'x':
  134.     lightpos[0]+=0.1;
  135.     break;
  136.   case 'w':
  137.     lightpos[2]-=0.1;
  138.     break;
  139.   case 'r':
  140.     lightpos[2]+=0.1;
  141.     break;
  142.   case 'j':
  143.     objpos[1]-=0.1;
  144.     break;
  145.   case 'k':
  146.     objpos[1]+=0.1;
  147.     break;
  148.   case 'i':
  149.     objpos[0]-=0.1;
  150.     break;
  151.   case 'm':
  152.     objpos[0]+=0.1;
  153.     break;
  154.   case 'u':
  155.     objpos[2]-=0.1;
  156.     break;
  157.   case 'o':
  158.     objpos[2]+=0.1;
  159.     break;
  160.   case 'a':
  161.     v+=0.005;
  162.     break;
  163.   case 'z':
  164.     v-=0.005;
  165.     break;
  166.   case 'g':
  167.     joyactive=(!joyactive);
  168.     break;
  169.   case 'h':
  170.     help=(!help);
  171.     break;
  172.   case 'f':
  173.     fog=(!fog);
  174.     break;
  175.   case '1':
  176.     showcheckmap=(!showcheckmap);
  177.     break;
  178.   case '2':
  179.     showreflectmap=(!showreflectmap);
  180.     break;
  181.   case 'b':
  182.     if(bfcull) {
  183.       glDisable(GL_CULL_FACE);
  184.       bfcull=0;
  185.     } else {
  186.       glEnable(GL_CULL_FACE);
  187.       bfcull=1;
  188.     }
  189.     break;
  190.   case 'p':
  191.     if(poutline) {
  192.       glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
  193.       poutline=0;
  194.     } else {
  195.       glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
  196.       poutline=1;
  197.     }
  198.     break;
  199.   }
  200. }
  201. static void reshape(int w, int h) 
  202. {
  203.   WIDTH=w;
  204.   HEIGHT=h;
  205.   glViewport(0,0,w,h);
  206.   glMatrixMode(GL_PROJECTION);
  207.   glLoadIdentity();
  208.   gluPerspective(45.0,w/(float)h,0.8,40.0);
  209.   glMatrixMode(GL_MODELVIEW);
  210.   glLoadIdentity();
  211. }
  212. static void printstring(void *font, char *string)
  213. {
  214.   int len,i;
  215.   len=(int)strlen(string);
  216.   for(i=0;i<len;i++)
  217.     glutBitmapCharacter(font,string[i]);
  218. }
  219. static void printhelp(void)
  220. {
  221.   glEnable(GL_BLEND);
  222.   glColor4f(0.5,0.5,0.5,0.5);
  223.   glRecti(40,40,600,440);
  224.   glDisable(GL_BLEND);
  225.   glColor3f(0.0,0.0,1.0);
  226.   glRasterPos2i(300,420);
  227.   printstring(GLUT_BITMAP_HELVETICA_18,"Help");
  228.   glRasterPos2i(60,390);
  229.   printstring(GLUT_BITMAP_HELVETICA_12,"h - Togle Help");
  230.   glRasterPos2i(60,370);
  231.   printstring(GLUT_BITMAP_HELVETICA_12,"f - Togle Fog");
  232.   glRasterPos2i(60,350);
  233.   printstring(GLUT_BITMAP_HELVETICA_12,"b - Togle Back face culling");
  234.   glRasterPos2i(60,330);
  235.   printstring(GLUT_BITMAP_HELVETICA_12,"p - Togle Wire frame");
  236.   glRasterPos2i(60,310);
  237.   printstring(GLUT_BITMAP_HELVETICA_12,"Arrow Keys - Rotate");
  238.   glRasterPos2i(60,290);
  239.   printstring(GLUT_BITMAP_HELVETICA_12,"a - Increase velocity");
  240.   glRasterPos2i(60,270);
  241.   printstring(GLUT_BITMAP_HELVETICA_12,"z - Decrease velocity");
  242.   glRasterPos2i(60,250);
  243.   if(joyavailable)
  244.     printstring(GLUT_BITMAP_HELVETICA_12,"j - Togle jostick control (Joystick control available)");
  245.   else
  246.     printstring(GLUT_BITMAP_HELVETICA_12,"(No Joystick control available)");
  247.   glRasterPos2i(60,230);
  248.   printstring(GLUT_BITMAP_HELVETICA_12,"To move the light source: s - left,  d - right,  e - far,  x - near,  w - down r - up");
  249.   glRasterPos2i(60,210);
  250.   printstring(GLUT_BITMAP_HELVETICA_12,"To move the mirror sphere: j - left,  k - right,  i - far,  m - near,  u - down o - up");
  251.   glRasterPos2i(60,190);
  252.   printstring(GLUT_BITMAP_HELVETICA_12,"1 - Togle the plane texture map window");
  253.   glRasterPos2i(60,170);
  254.   printstring(GLUT_BITMAP_HELVETICA_12,"2 - Togle the sphere texture map window");
  255. }
  256. static GLboolean seelight(float p[3],float dir[3])
  257. {
  258.   float c[3],b,a,d,t,dist[3];
  259.   vsub(c,p,objpos);
  260.   b=-dprod(c,dir);
  261.   a=dprod(c,c)-SPHERE_RADIUS*SPHERE_RADIUS;
  262.   if((d=b*b-a)<0.0 || (b<0.0 && a>0.0))
  263.     return GL_FALSE;
  264.   d=sqrt(d);
  265.   t=b-d;
  266.   if(t<EPSILON) {
  267.     t=b+d;
  268.     if(t<EPSILON)
  269.       return GL_FALSE;
  270.   }
  271.   vsub(dist,lightpos,p);
  272.   if(dprod(dist,dist)<t*t)
  273.       return GL_FALSE;
  274.   return GL_TRUE;
  275. }
  276. static int colorcheckmap(float ppos[3], float c[3])
  277. {
  278.   static float norm[3]={0.0f,0.0f,1.0f};
  279.   float ldir[3],vdir[3],h[3],dfact,kfact,r,g,b;
  280.   int x,y;
  281.   x=(int)((ppos[0]+BASESIZE/2)*(10.0f/BASESIZE));
  282.   if((x<0) || (x>10))
  283.     return GL_FALSE;
  284.   y=(int)((ppos[1]+BASESIZE/2)*(10.0f/BASESIZE));
  285.   if((y<0) || (y>10))
  286.     return GL_FALSE;
  287.   r=255.0f;
  288.   if(y & 1) {
  289.     if(x & 1)
  290.       g=255.0f;
  291.     else
  292.       g=0.0f;
  293.   } else {
  294.     if(x & 1)
  295.       g=0.0f;
  296.     else
  297.       g=255.0f;
  298.   }
  299.   b=0.0f;
  300.   vsub(ldir,lightpos,ppos);
  301.   vnormalize(ldir,ldir);
  302.   if(seelight(ppos,ldir)) {
  303.     c[0]=r*0.05f;
  304.     c[1]=g*0.05f;
  305.     c[2]=b*0.05f;
  306.     return GL_TRUE;
  307.   }
  308.   dfact=dprod(ldir,norm);
  309.   if(dfact<0.0f)
  310.     dfact=0.0f;
  311.   vsub(vdir,obs,ppos);
  312.   vnormalize(vdir,vdir);
  313.   h[0]=0.5f*(vdir[0]+ldir[0]);
  314.   h[1]=0.5f*(vdir[1]+ldir[1]);
  315.   h[2]=0.5f*(vdir[2]+ldir[2]);
  316.   kfact=dprod(h,norm);
  317.   kfact=kfact*kfact*kfact*kfact*kfact*kfact*kfact*7.0f*255.0f;
  318.   r=r*dfact+kfact;
  319.   g=g*dfact+kfact;
  320.   b=b*dfact+kfact;
  321.   
  322.   c[0]=clamp255(r);
  323.   c[1]=clamp255(g);
  324.   c[2]=clamp255(b);
  325.   return GL_TRUE;
  326. }
  327. static void updatecheckmap(int slot)
  328. {
  329.   float c[3],ppos[3];
  330.   int x,y;
  331.   glBindTexture(GL_TEXTURE_2D,checkid);
  332.   ppos[2]=0.0f;
  333.   for(y=slot*TEX_CHECK_SLOT_SIZE;y<(slot+1)*TEX_CHECK_SLOT_SIZE;y++) {
  334.     ppos[1]=(y/(float)TEX_CHECK_HEIGHT)*BASESIZE-BASESIZE/2;
  335.     for(x=0;x<TEX_CHECK_WIDTH;x++) {
  336.       ppos[0]=(x/(float)TEX_CHECK_WIDTH)*BASESIZE-BASESIZE/2;
  337.       colorcheckmap(ppos,c);
  338.       checkmap[y][x][0]=(GLubyte)c[0];
  339.       checkmap[y][x][1]=(GLubyte)c[1];
  340.       checkmap[y][x][2]=(GLubyte)c[2];
  341.     }
  342.   }
  343.   glTexSubImage2D(GL_TEXTURE_2D,0,0,slot*TEX_CHECK_SLOT_SIZE,TEX_CHECK_WIDTH,
  344.   TEX_CHECK_SLOT_SIZE,GL_RGB,GL_UNSIGNED_BYTE,
  345.   &checkmap[slot*TEX_CHECK_SLOT_SIZE][0][0]);
  346. }
  347. static void updatereflectmap(int slot)
  348. {
  349.   float rf,r,g,b,t,dfact,kfact,rdir[3];
  350.   float rcol[3],ppos[3],norm[3],ldir[3],h[3],vdir[3],planepos[3];
  351.   int x,y;
  352.   glBindTexture(GL_TEXTURE_2D,reflectid);
  353.   for(y=slot*TEX_REFLECT_SLOT_SIZE;y<(slot+1)*TEX_REFLECT_SLOT_SIZE;y++)
  354.     for(x=0;x<TEX_REFLECT_WIDTH;x++) {
  355.       ppos[0]=sphere_pos[y][x][0]+objpos[0];
  356.       ppos[1]=sphere_pos[y][x][1]+objpos[1];
  357.       ppos[2]=sphere_pos[y][x][2]+objpos[2];
  358.       vsub(norm,ppos,objpos);
  359.       vnormalize(norm,norm);
  360.       vsub(ldir,lightpos,ppos);
  361.       vnormalize(ldir,ldir);
  362.       vsub(vdir,obs,ppos);
  363.       vnormalize(vdir,vdir);
  364.       rf=2.0f*dprod(norm,vdir);
  365.       if(rf>EPSILON) {
  366. rdir[0]=rf*norm[0]-vdir[0];
  367. rdir[1]=rf*norm[1]-vdir[1];
  368. rdir[2]=rf*norm[2]-vdir[2];
  369. t=-objpos[2]/rdir[2];
  370. if(t>EPSILON) {
  371.   planepos[0]=objpos[0]+t*rdir[0];
  372.   planepos[1]=objpos[1]+t*rdir[1];
  373.   planepos[2]=0.0f;
  374.   
  375.   if(!colorcheckmap(planepos,rcol))
  376.     rcol[0]=rcol[1]=rcol[2]=0.0f;
  377. } else
  378.   rcol[0]=rcol[1]=rcol[2]=0.0f;
  379.       } else
  380. rcol[0]=rcol[1]=rcol[2]=0.0f;
  381.       dfact=0.1f*dprod(ldir,norm);
  382.       if(dfact<0.0f) {
  383. dfact=0.0f;
  384. kfact=0.0f;
  385.       } else {
  386. h[0]=0.5f*(vdir[0]+ldir[0]);
  387. h[1]=0.5f*(vdir[1]+ldir[1]);
  388. h[2]=0.5f*(vdir[2]+ldir[2]);
  389. kfact=dprod(h,norm);
  390. kfact*=kfact;
  391. kfact*=kfact;
  392. kfact*=kfact;
  393. kfact*=kfact;
  394. kfact*=10.0f;
  395.       }
  396.       r=dfact+kfact;
  397.       g=dfact+kfact;
  398.       b=dfact+kfact;
  399.       r*=255.0f;
  400.       g*=255.0f;
  401.       b*=255.0f;
  402.       r+=rcol[0];
  403.       g+=rcol[1];
  404.       b+=rcol[2];
  405.       r=clamp255(r);
  406.       g=clamp255(g);
  407.       b=clamp255(b);
  408.       reflectmap[y][x][0]=(GLubyte)r;
  409.       reflectmap[y][x][1]=(GLubyte)g;
  410.       reflectmap[y][x][2]=(GLubyte)b;
  411.     }
  412.   glTexSubImage2D(GL_TEXTURE_2D,0,0,slot*TEX_REFLECT_SLOT_SIZE,TEX_REFLECT_WIDTH,
  413.   TEX_REFLECT_SLOT_SIZE,GL_RGB,GL_UNSIGNED_BYTE,
  414.   &reflectmap[slot*TEX_REFLECT_SLOT_SIZE][0][0]);
  415. }
  416. static void drawbase(void)
  417. {
  418.   glColor3f(0.0,0.0,0.0);
  419.   glBindTexture(GL_TEXTURE_2D,checkid);
  420.   glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
  421.   glBegin(GL_QUADS);
  422.   glTexCoord2f(0.0f,0.0f);
  423.   glVertex3f(-BASESIZE/2.0f,-BASESIZE/2.0f,0.0f);
  424.   glTexCoord2f(1.0f,0.0f);
  425.   glVertex3f(BASESIZE/2.0f,-BASESIZE/2.0f,0.0f);
  426.   glTexCoord2f(1.0f,1.0f);
  427.   glVertex3f(BASESIZE/2.0f,BASESIZE/2.0f,0.0f);
  428.   glTexCoord2f(0.0f,1.0f);
  429.   glVertex3f(-BASESIZE/2.0f,BASESIZE/2.0f,0.0f);
  430.   glEnd();
  431. }
  432. static void drawobj(void)
  433. {
  434.   glColor3f(0.0,0.0,0.0);
  435.   glBindTexture(GL_TEXTURE_2D,reflectid);
  436.   glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
  437.   glPushMatrix();
  438.   glTranslatef(objpos[0],objpos[1],objpos[2]);
  439.   glCallList(objdlist);
  440.   glPopMatrix();
  441. }
  442. static void dojoy(void)
  443. {
  444. #ifdef _WIN32
  445.   static UINT max[2]={0,0};
  446.   static UINT min[2]={0xffffffff,0xffffffff},center[2];
  447.   MMRESULT res;
  448.   JOYINFO joy;
  449.   res=joyGetPos(JOYSTICKID1,&joy);
  450.   if(res==JOYERR_NOERROR) {
  451.     joyavailable=1;
  452.     if(max[0]<joy.wXpos)
  453.       max[0]=joy.wXpos;
  454.     if(min[0]>joy.wXpos)
  455.       min[0]=joy.wXpos;
  456.     center[0]=(max[0]+min[0])/2;
  457.     if(max[1]<joy.wYpos)
  458.       max[1]=joy.wYpos;
  459.     if(min[1]>joy.wYpos)
  460.       min[1]=joy.wYpos;
  461.     center[1]=(max[1]+min[1])/2;
  462.     if(joyactive) {
  463.       if(fabs(center[0]-(float)joy.wXpos)>0.1*(max[0]-min[0]))
  464. alpha-=2.5*(center[0]-(float)joy.wXpos)/(max[0]-min[0]);
  465.       if(fabs(center[1]-(float)joy.wYpos)>0.1*(max[1]-min[1]))
  466. beta+=2.5*(center[1]-(float)joy.wYpos)/(max[1]-min[1]);
  467.       if(joy.wButtons & JOY_BUTTON1)
  468. v+=0.005;
  469.       if(joy.wButtons & JOY_BUTTON2)
  470. v-=0.005;
  471.     }
  472.   } else
  473.     joyavailable=0;
  474. #endif
  475. }
  476. static void updatemaps(void)
  477. {
  478.   updatecheckmap(checkmap_currentslot);
  479.   checkmap_currentslot=(checkmap_currentslot+1) % TEX_CHECK_NUMSLOT;
  480.   updatereflectmap(reflectmap_currentslot);
  481.   reflectmap_currentslot=(reflectmap_currentslot+1) % TEX_REFLECT_NUMSLOT;
  482. }
  483. static void draw(void)
  484. {
  485.   static int count=0;
  486.   static char frbuf[80];
  487.   float fr;
  488.   dojoy();
  489.   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  490.   glEnable(GL_TEXTURE_2D);
  491.   glEnable(GL_DEPTH_TEST);
  492.   if(fog)
  493.     glEnable(GL_FOG);
  494.   else
  495.     glDisable(GL_FOG);
  496.   glPushMatrix();
  497.   calcposobs();
  498.   gluLookAt(obs[0],obs[1],obs[2],
  499.     obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2],
  500.     0.0,0.0,1.0);
  501.   drawbase();
  502.   drawobj();
  503.   glColor3f(1.0,1.0,1.0);
  504.   glDisable(GL_TEXTURE_2D);
  505.   glPushMatrix();
  506.   glTranslatef(lightpos[0],lightpos[1],lightpos[2]);
  507.   glCallList(lightdlist);
  508.   glPopMatrix();
  509.   glPopMatrix();
  510.   
  511.   if((count % FRAME)==0) {
  512.     fr=gettime();
  513.     sprintf(frbuf,"Frame rate: %f",FRAME/fr);
  514.   }
  515.   glDisable(GL_DEPTH_TEST);
  516.   glDisable(GL_FOG);
  517.   glMatrixMode(GL_PROJECTION);
  518.   glPushMatrix();
  519.   glLoadIdentity();
  520.   glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0);
  521.   glMatrixMode(GL_MODELVIEW);
  522.   glColor3f(0.0f,0.3f,1.0f);
  523.   if(showcheckmap) {
  524.     glEnable(GL_TEXTURE_2D);
  525.     glBindTexture(GL_TEXTURE_2D,checkid);
  526.     glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
  527.     glBegin(GL_QUADS);
  528.     glTexCoord2f(1.0f,0.0f);
  529.     glVertex2i(10,30);
  530.     glTexCoord2f(1.0f,1.0f);
  531.     glVertex2i(10+90,30);
  532.     glTexCoord2f(0.0f,1.0f);
  533.     glVertex2i(10+90,30+90);
  534.     glTexCoord2f(0.0f,0.0f);
  535.     glVertex2i(10,30+90);
  536.     glEnd();
  537.     glDisable(GL_TEXTURE_2D);
  538.     glBegin(GL_LINE_LOOP);
  539.     glVertex2i(10,30);
  540.     glVertex2i(10+90,30);
  541.     glVertex2i(10+90,30+90);
  542.     glVertex2i(10,30+90);
  543.     glEnd();
  544.     glRasterPos2i(105,65);
  545.     printstring(GLUT_BITMAP_HELVETICA_18,"Plane Texture Map");
  546.   }
  547.   if(showreflectmap) {
  548.     glEnable(GL_TEXTURE_2D);
  549.     glBindTexture(GL_TEXTURE_2D,reflectid);
  550.     glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
  551.     glBegin(GL_QUADS);
  552.     glTexCoord2f(1.0f,0.0f);
  553.     glVertex2i(540,30);
  554.     glTexCoord2f(1.0f,1.0f);
  555.     glVertex2i(540+90,30);
  556.     glTexCoord2f(0.0f,1.0f);
  557.     glVertex2i(540+90,30+90);
  558.     glTexCoord2f(0.0f,0.0f);
  559.     glVertex2i(540,30+90);
  560.     glEnd();
  561.     glDisable(GL_TEXTURE_2D);
  562.     glBegin(GL_LINE_LOOP);
  563.     glVertex2i(540,30);
  564.     glVertex2i(540+90,30);
  565.     glVertex2i(540+90,30+90);
  566.     glVertex2i(540,30+90);
  567.     glEnd();
  568.     glRasterPos2i(360,65);
  569.     printstring(GLUT_BITMAP_HELVETICA_18,"Sphere Texture Map");
  570.   }
  571.   glDisable(GL_TEXTURE_2D);
  572.   glRasterPos2i(10,10);
  573.   printstring(GLUT_BITMAP_HELVETICA_18,frbuf);
  574.   glRasterPos2i(360,470);
  575.   printstring(GLUT_BITMAP_HELVETICA_10,"Ray V1.0 Written by David Bucciarelli (tech.hmw@plus.it)");
  576.   if(help)
  577.     printhelp();
  578.   glMatrixMode(GL_PROJECTION);
  579.   glPopMatrix();
  580.   glMatrixMode(GL_MODELVIEW);
  581.   updatemaps();
  582.   glutSwapBuffers();
  583.   count++;
  584. }
  585. static void inittextures(void)
  586. {
  587.   int y;
  588.   glGenTextures(1,&checkid);
  589.   glBindTexture(GL_TEXTURE_2D,checkid);
  590.   for(y=0;y<TEX_CHECK_NUMSLOT;y++)
  591.     updatecheckmap(y);
  592.   glPixelStorei(GL_UNPACK_ALIGNMENT,1);
  593.   glTexImage2D(GL_TEXTURE_2D,0,3,TEX_CHECK_WIDTH,TEX_CHECK_HEIGHT,
  594.        0,GL_RGB,GL_UNSIGNED_BYTE,checkmap);
  595.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  596.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
  597.   
  598.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  599.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  600.   glGenTextures(1,&reflectid);
  601.   glBindTexture(GL_TEXTURE_2D,reflectid);
  602.   for(y=0;y<TEX_REFLECT_NUMSLOT;y++)
  603.     updatereflectmap(y);
  604.   glPixelStorei(GL_UNPACK_ALIGNMENT,1);
  605.   glTexImage2D(GL_TEXTURE_2D,0,3,TEX_REFLECT_WIDTH,TEX_REFLECT_HEIGHT,
  606.        0,GL_RGB,GL_UNSIGNED_BYTE,reflectmap);
  607.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  608.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
  609.   
  610.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  611.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  612. }
  613. static void initspherepos(void)
  614. {
  615.   float alpha,beta,sa,ca,sb,cb;
  616.   int x,y;
  617.   for(y=0;y<TEX_REFLECT_HEIGHT;y++) {
  618.     beta=M_PI-y*(M_PI/TEX_REFLECT_HEIGHT);
  619.     for(x=0;x<TEX_REFLECT_WIDTH;x++) {
  620.       alpha=-x*(2.0f*M_PI/TEX_REFLECT_WIDTH);
  621.       sa=sin(alpha);
  622.       ca=cos(alpha);
  623.       sb=sin(beta);
  624.       cb=cos(beta);
  625.       sphere_pos[y][x][0]=SPHERE_RADIUS*sa*sb;
  626.       sphere_pos[y][x][1]=SPHERE_RADIUS*ca*sb;
  627.       sphere_pos[y][x][2]=SPHERE_RADIUS*cb;
  628.     }
  629.   }
  630. }
  631. static void initdlists(void)
  632. {
  633.   GLUquadricObj *obj;
  634.   obj=gluNewQuadric();
  635.   lightdlist=glGenLists(1);
  636.   glNewList(lightdlist,GL_COMPILE);
  637.   gluQuadricDrawStyle(obj,GLU_FILL);
  638.   gluQuadricNormals(obj,GLU_NONE);
  639.   gluQuadricTexture(obj,GL_TRUE);
  640.   gluSphere(obj,0.25f,6,6);
  641.   glEndList();
  642.   objdlist=glGenLists(1);
  643.   glNewList(objdlist,GL_COMPILE);
  644.   gluQuadricDrawStyle(obj,GLU_FILL);
  645.   gluQuadricNormals(obj,GLU_NONE);
  646.   gluQuadricTexture(obj,GL_TRUE);
  647.   gluSphere(obj,SPHERE_RADIUS,16,16);
  648.   glEndList();
  649. }
  650. int main(int ac, char **av)
  651. {
  652.   fprintf(stderr,"Ray V1.0nWritten by David Bucciarelli (tech.hmw@plus.it)n");
  653.   /*
  654.     if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) {
  655.     fprintf(stderr,"Error setting the process class.n");
  656.     return 0;
  657.     }
  658.     if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) {
  659.     fprintf(stderr,"Error setting the process priority.n");
  660.     return 0;
  661.     }
  662.     */
  663.   glutInitWindowPosition(0,0);
  664.   glutInitWindowSize(WIDTH,HEIGHT);
  665.   glutInit(&ac,av);
  666.   glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE);
  667.   glutCreateWindow("Ray");
  668.   reshape(WIDTH,HEIGHT);
  669.   glShadeModel(GL_FLAT);
  670.   glEnable(GL_DEPTH_TEST);
  671.   glDepthFunc(GL_LEQUAL);
  672.   glEnable(GL_CULL_FACE);
  673.   glEnable(GL_TEXTURE_2D);
  674.   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  675.   glEnable(GL_FOG);
  676.   glFogi(GL_FOG_MODE,GL_EXP2);
  677.   glFogfv(GL_FOG_COLOR,fogcolor);
  678.   glFogf(GL_FOG_DENSITY,0.01);
  679. #ifdef FX
  680.   glHint(GL_FOG_HINT,GL_NICEST);
  681. #endif
  682.   calcposobs();
  683.   initspherepos();
  684.   inittextures();
  685.   initdlists();
  686.   glClearColor(fogcolor[0],fogcolor[1],fogcolor[2],fogcolor[3]);
  687.   glutReshapeFunc(reshape);
  688.   glutDisplayFunc(draw);
  689.   glutKeyboardFunc(key);
  690.   glutSpecialFunc(special);
  691.   glutIdleFunc(draw);
  692.   glutMainLoop();
  693.   return 0;             /* ANSI C requires main to return int. */
  694. }