home *** CD-ROM | disk | FTP | other *** search
/ Gambler 19 / GAMBLERCD19.BIN / UTILS / RIVA128 / Uzytki / ssystem-1.2 / SOURCE / SSYSTEM.C < prev    next >
C/C++ Source or Header  |  1998-05-02  |  16KB  |  547 lines

  1. #include <time.h>
  2. #ifndef WIN32
  3. #include <sys/times.h>
  4. #endif
  5. #include "planets.h"
  6.  
  7. #define TIMEFUNC clock()
  8. #define WIDTH 640
  9. #define HEIGHT 480
  10.  
  11. GLdouble camx=0.0, camy=0.0, camz=1.0, eyex=0.0, eyey=0.0, eyez=-1.0;
  12. GLdouble upx=0.0, upy=1.0, upz=0.0,speed=0.0,d;
  13. int frames=0,i,pause=0,linked=1,currplanet=EARTH,width=WIDTH,height=HEIGHT;
  14. int demomode=0,bench=0,help=0,fakecurrplanet=EARTH;
  15. float sec;
  16. char sbuf[80];
  17. int planorder[RINGS]={SUN,MERCURY,VENUS,EARTH,MOON,MARS,JUPITER,IO,EUROPA,
  18.     GANYMEDE,CALLISTO,SATURN,TETHYS,DIONE,RHEA,TITAN,URANUS,NEPTUNE,TRITON,
  19.     PLUTO,CHARON};
  20.  
  21. static void Reshape( int x, int y )
  22. {
  23.    width=x;
  24.    height=y;
  25.    glViewport( 0, 0, width, height );
  26.    glMatrixMode(GL_PROJECTION);
  27.    glLoadIdentity();
  28.    gluPerspective(45.0,width/(float)height,RADIUSSCALE(0.1),DISTCORRECTION(1000.0));
  29.    glMatrixMode( GL_MODELVIEW );
  30.    glLoadIdentity();
  31. }
  32.  
  33. /* Cloned from David Bucciarelli's demos */
  34. static void printstring(void *font, char *string)
  35. {
  36.   int len,i;
  37.  
  38.   len=(int)strlen(string);
  39.   for(i=0;i<len;i++)
  40.     glutBitmapCharacter(font,string[i]);
  41. }
  42.  
  43. static void OnScreenInfo()
  44. {
  45.    time_t t;
  46.    struct tm *tm;
  47.    
  48.    glDisable(GL_TEXTURE_2D);
  49.    glDisable(GL_LIGHTING);
  50.    glDisable(GL_DEPTH_TEST);
  51.    glMatrixMode(GL_PROJECTION);
  52.    glLoadIdentity();
  53.    glOrtho(0.0,(float) width,(float) height,0.0,0.0,1.0);
  54.    glMatrixMode(GL_MODELVIEW);
  55.    glLoadIdentity();
  56.    glColor3f(1.0,1.0,1.0);
  57.    glRasterPos2i(0,10);
  58.    printstring(GLUT_BITMAP_HELVETICA_10,planets[currplanet].Name);
  59.    glRasterPos2i(0,20);
  60.    t=(int) ((10093.0+days)*24.0*3600.0);
  61.    tm=gmtime(&t);
  62.    strftime(sbuf,80,"%m / %d / %Y  %X (UTC)",tm);
  63.    printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  64.    glRasterPos2i(0,30);
  65.    sprintf(sbuf,"Distance from Sun (million Km): %.2f",DISTANCE(planets[currplanet].posx,
  66.                    planets[currplanet].posy,planets[currplanet].posz)*100.0);
  67.    printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  68.    glRasterPos2i(0,height-5);
  69.    sprintf(sbuf,"Camera distance from Sun (million Km): %.2f",DISTANCE(camx,camy,camz)*100.0);
  70.    printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  71.    glRasterPos2i(0,height-15);
  72.    sprintf(sbuf,"Time factor: %.4f hours / iteration",timefactor*60.0);
  73.    printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  74.    glRasterPos2i(0,height-25);
  75.    sprintf(sbuf,"Camera speed (Km / iteration): %.2f",speed*100000000.0);
  76.    printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  77.    glRasterPos2i(width-70,height-5);
  78.    if (linked) printstring(GLUT_BITMAP_HELVETICA_10,"Linked Camera");
  79.    else printstring(GLUT_BITMAP_HELVETICA_10,"Free Camera");
  80.    if (demomode) {
  81.        glRasterPos2i(width-70,height-15);
  82.        printstring(GLUT_BITMAP_HELVETICA_10,"Demo Mode");
  83.    }
  84.    if (pause) {
  85.        glRasterPos2i(width-30,10);
  86.        printstring(GLUT_BITMAP_HELVETICA_10,"Pause");
  87.    }
  88.    if (help) {
  89.     glRasterPos2i(width/4,height/4);
  90.     sprintf(sbuf,"Home/End: Select previous/next body");
  91.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  92.     glRasterPos2i(width/4,height/4+15);
  93.     sprintf(sbuf,"t : Texture on/off");
  94.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  95.     glRasterPos2i(width/4,height/4+30);
  96.     sprintf(sbuf,"l : Lighting on/off");
  97.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  98.     glRasterPos2i(width/4,height/4+45);
  99.     sprintf(sbuf,"f : Flat/Smooth shading model");
  100.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  101.     glRasterPos2i(width/4,height/4+60);
  102.     sprintf(sbuf,"s : Stars on/off");
  103.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  104.     glRasterPos2i(width/4,height/4+75);
  105.     sprintf(sbuf,"d : Demo mode on/off");
  106.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  107.     glRasterPos2i(width/4,height/4+90);
  108.     sprintf(sbuf,"n : Place camera near current target planet");
  109.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  110.     glRasterPos2i(width/4,height/4+105);
  111.     sprintf(sbuf,"c : Toggle between free and linked to planet camera mode");
  112.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  113.     glRasterPos2i(width/4,height/4+120);
  114.     sprintf(sbuf,"p : Pause");
  115.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  116.     glRasterPos2i(width/4,height/4+135);
  117.     sprintf(sbuf,"+/- : Increase/Decrease timefactor *");
  118.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  119.     glRasterPos2i(width/4,height/4+150);
  120.     sprintf(sbuf,"Arrow keys : Camera rotation *");
  121.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  122.     glRasterPos2i(width/4,height/4+165);
  123.     sprintf(sbuf,"Page Up/Down : Increase/decrease speed *");
  124.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  125.     glRasterPos2i(width/4,height/4+195);
  126.     sprintf(sbuf,"* hold SHIFT for faster operation");
  127.     printstring(GLUT_BITMAP_HELVETICA_10,sbuf);
  128.    }
  129.    Reshape(width,height);
  130. }
  131.  
  132.  
  133. static void Idle( void )
  134. {
  135.    if (bench & (frames==1000)) {
  136.      sec=(TIMEFUNC-sec)/(float)CLOCKS_PER_SEC;
  137. #ifdef WIN32
  138.          sprintf(sbuf,"\n%.2f frames/sec\n\n",frames/sec);
  139.          MessageBox(NULL,sbuf,"Overall Performance", MB_OK);
  140. #else
  141.          printf("\n%.2f frames/sec\n\n",frames/sec);
  142. #endif
  143.          exit(2);
  144.    }   
  145.  
  146.    if (!pause) {
  147.        days+=timefactor;
  148.        UpdatePositions();
  149.    }
  150.    if (linked) {
  151.     eyex=planets[currplanet].posx-camx;
  152.      eyey=planets[currplanet].posy-camy;
  153.     eyez=planets[currplanet].posz-camz;
  154.     d=DISTANCE(eyex,eyey,eyez);
  155.     eyex/=d; eyey/=d; eyez/=d;
  156.     if (d<RADIUSSCALE(planets[currplanet].Radius*1.5)) speed*=(double)demomode;
  157.    }
  158.    camx+=eyex*speed; camy+=eyey*speed; camz+=eyez*speed;
  159.    glutPostRedisplay();
  160. }
  161.  
  162. /* Rotates (rx,ry,rz) point about the (x,y,z) axis 'angle' radians,
  163.   borrowed from Mesa */
  164. void Rotation( GLdouble angle, GLdouble x, GLdouble y, GLdouble z,
  165.                          GLdouble *rx, GLdouble *ry, GLdouble *rz)
  166. {
  167.    GLdouble mag, s, c;
  168.    GLdouble xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
  169.  
  170.    s = sin(angle);
  171.    c = cos(angle);
  172.  
  173.    mag = DISTANCE(x,y,z);
  174.  
  175.    if (mag == 0.0) return;
  176.  
  177.    x /= mag;
  178.    y /= mag;
  179.    z /= mag;
  180.  
  181.    xx = x * x;
  182.    yy = y * y;
  183.    zz = z * z;
  184.    xy = x * y;
  185.    yz = y * z;
  186.    zx = z * x;
  187.    xs = x * s;
  188.    ys = y * s;
  189.    zs = z * s;
  190.    one_c = 1.0F - c;
  191.  
  192.    x = *rx*((one_c * xx) + c);
  193.    y = *rx*((one_c * xy) - zs);
  194.    z = *rx*((one_c * zx) + ys);
  195.  
  196.    x += *ry*((one_c * xy) + zs);
  197.    y += *ry*((one_c * yy) + c);
  198.    z += *ry*((one_c * yz) - xs);
  199.  
  200.    x += *rz*((one_c * zx) - ys);
  201.    y += *rz*((one_c * yz) + xs);
  202.    z += *rz*((one_c * zz) + c);
  203.    
  204.    *rx=x; *ry=y; *rz=z;
  205. }
  206.  
  207. /* Separate function for future enhancements */
  208. static void Camera()
  209. {
  210.   gluLookAt(camx,camy,camz,
  211.           camx+eyex,camy+eyey,camz+eyez, 
  212.           upx, upy, upz);
  213. }
  214.  
  215.  
  216. static void SunHalo( void )
  217. {
  218.  static double x[4],y[4],z[4];
  219.  static double alfa,beta;
  220.  static int i;
  221.  
  222. #define SIZE RADIUSSCALE(109.0)
  223.  
  224.  x[0]=x[3]=y[0]=y[1]=SIZE;
  225.  x[1]=x[2]=y[2]=y[3]=-SIZE;
  226.  z[0]=z[1]=z[2]=z[3]=0.0;
  227.  alfa=atan2(camz,camx)-PI/2.0;
  228.  beta=atan2(camy,sqrt(camx*camx+camz*camz));
  229.  for (i=0;i<4;i++) {
  230.     Rotation(beta,1.0,0.0,0.0,&x[i],&y[i],&z[i]);
  231.      Rotation(alfa,0.0,1.0,0.0,&x[i],&y[i],&z[i]);
  232.  }     
  233.  
  234.  glEnable(GL_BLEND);
  235.  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  236.  glBegin(GL_POLYGON);
  237.  glTexCoord2f(0.0,0.0); glVertex3f(x[0],y[0],z[0]);
  238.  glTexCoord2f(0.0,1.0);  glVertex3f(x[1],y[1],z[1]); 
  239.  glTexCoord2f(1.0,1.0);  glVertex3f(x[2],y[2],z[2]); 
  240.  glTexCoord2f(1.0,0.0);  glVertex3f(x[3],y[3],z[3]); 
  241.  glEnd();
  242.  glDisable(GL_BLEND);
  243. }
  244.  
  245. static void Display( void )
  246. {
  247.    glEnable(GL_DEPTH_TEST);
  248.    glLoadIdentity();
  249.    Camera();
  250.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  251.    glDisable(GL_LIGHTING);
  252.    glDisable(GL_TEXTURE_2D);
  253.    if (drawstars) {
  254.        glPushMatrix();
  255.        glCallList(Stars);
  256.        glPopMatrix();
  257.    }
  258.    if (lighting) glEnable(GL_LIGHTING);
  259.    if (texture) glEnable(GL_TEXTURE_2D);
  260.    LightPos[0]=planets[SUN].posx;
  261.    LightPos[1]=planets[SUN].posy;
  262.    LightPos[2]=planets[SUN].posz;
  263.    glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
  264.    glMaterialfv(GL_FRONT, GL_DIFFUSE, White);
  265.    glMaterialfv(GL_FRONT, GL_EMISSION, Black);   
  266.    for (i=1;i<=RINGS;i++) {
  267.        glBindTexture(GL_TEXTURE_2D, texName[i]);
  268.     glPushMatrix();
  269.         glTranslatef(planets[i].posx,planets[i].posy,planets[i].posz);
  270.        glRotatef(-planets[i].Degrees-planets[planets[i].Sat].Degrees-90.0,1.0,0.0,0.0);
  271.        glRotatef(planets[i].DeltaRotation,0.0,0.0,1.0);
  272.        glCallList(planets[i].Sphere);
  273.        glPopMatrix();
  274.    }
  275.    glMaterialfv(GL_FRONT, GL_EMISSION, White);
  276.    glBindTexture(GL_TEXTURE_2D, texName[SUN]);
  277.    glPushMatrix();
  278.    if (texture) SunHalo(); else glCallList(planets[SUN].Sphere);
  279.    glPopMatrix();
  280.    OnScreenInfo();
  281.    glutSwapBuffers();
  282.    frames++;
  283. }
  284.  
  285.  
  286. static void Key( unsigned char key, int x, int y )
  287. {
  288.    static int m;
  289.    
  290.    m=glutGetModifiers();
  291.    switch (key) {
  292.       case 27:
  293.      sec=(TIMEFUNC-sec)/(float)CLOCKS_PER_SEC;
  294. #ifdef WIN32
  295.          sprintf(sbuf,"\n%.2f frames/sec\n\n",frames/sec);
  296.          MessageBox(NULL,sbuf,"Overall Performance", MB_OK);
  297. #else
  298.          printf("\n%.2f frames/sec\n\n",frames/sec);
  299. #endif
  300.          exit(0);
  301.          break;
  302.       case 'c': linked=!linked;
  303.               if (!linked) {
  304.                   upx=upz=0.0;
  305.                   upy=1.0;
  306.                   eyey=0.0;
  307.               }
  308.               break;
  309.       case 'p': pause=!pause;
  310.               break;
  311.       case 'f': smodel=(smodel==GL_FLAT) ? GL_SMOOTH : GL_FLAT;
  312.               glShadeModel(smodel);
  313.               break;
  314.       case 't': texture=!texture;
  315.               break;
  316.       case 's': drawstars=!drawstars;
  317.               break;
  318.       case 'n': if (currplanet==SUN) break;
  319.         d=DISTANCE(planets[currplanet].posx,
  320.                planets[currplanet].posy,planets[currplanet].posz);
  321.               camx=planets[currplanet].posx/d*
  322.                   (d-RADIUSSCALE(planets[currplanet].Radius*8.0));
  323.                 camy=planets[currplanet].posy;
  324.                 camz=planets[currplanet].posz/d*
  325.                     (d-RADIUSSCALE(planets[currplanet].Radius*8.0));
  326.                 eyex=planets[currplanet].posx-camx;
  327.                 eyey=planets[currplanet].posy-camy;
  328.                 eyez=planets[currplanet].posz-camz;
  329.                 upx=0.0; upy=1.0; upz=0.0;
  330.                 d=DISTANCE(eyex,eyey,eyez);
  331.                 eyex/=d; eyey/=d; eyez/=d;
  332.                 break;
  333.       case 'h': help=!help;
  334.               break;
  335.       case 'd': demomode=!demomode;
  336.               break;
  337.       case 'l': lighting=!lighting;
  338.               break;
  339.       case '+': if (m & GLUT_ACTIVE_SHIFT) timefactor*=1.1;
  340.               else timefactor+=1/122400.0; /* one second/iteration */
  341.         break;
  342.       case '-': if (m & GLUT_ACTIVE_SHIFT) timefactor/=1.1;
  343.               else timefactor-=1/122400.0; /* one second/iteration */
  344.         break;
  345.     }
  346.    glutPostRedisplay();
  347. }
  348.  
  349.                                                     
  350. static void Special(int k, int x, int y)
  351. {
  352.   static double rot,xx,yy,zz;
  353.   static int m;
  354.   
  355.   m=glutGetModifiers(); 
  356.   if (m & GLUT_ACTIVE_SHIFT) rot=0.05;
  357.   else rot=0.003;
  358.   switch (k) {
  359.       case GLUT_KEY_LEFT:Rotation(-rot,upx,upy,upz,&eyex,&eyey,&eyez);
  360.               break;
  361.       case GLUT_KEY_RIGHT: Rotation(rot,upx,upy,upz,&eyex,&eyey,&eyez);
  362.               break;
  363.       case GLUT_KEY_DOWN: xx=upy*eyez-upz*eyey;
  364.                   yy=-upx*eyez+upz*eyex;
  365.                   zz=upx*eyey-upy*eyex;
  366.                   Rotation(rot,xx,yy,zz,&upx,&upy,&upz);
  367.                   Rotation(rot,xx,yy,zz,&eyex,&eyey,&eyez);
  368.               break;
  369.       case GLUT_KEY_UP:   xx=upy*eyez-upz*eyey;
  370.                     yy=-upx*eyez+upz*eyex;
  371.                     zz=upx*eyey-upy*eyex;
  372.                     Rotation(-rot,xx,yy,zz,&upx,&upy,&upz);
  373.                     Rotation(-rot,xx,yy,zz,&eyex,&eyey,&eyez);
  374.               break;
  375.       case GLUT_KEY_PAGE_UP:    if (m & GLUT_ACTIVE_SHIFT) speed*=10.0;
  376.                       else speed+=0.000001;
  377.               break;
  378.       case GLUT_KEY_PAGE_DOWN:    if (m & GLUT_ACTIVE_SHIFT) speed/=10.0;
  379.                       else speed-=0.000001;
  380.                 break;
  381.       case GLUT_KEY_HOME: if (fakecurrplanet) currplanet=planorder[--fakecurrplanet];
  382.                     break;
  383.       case GLUT_KEY_END: if (fakecurrplanet<(RINGS-1)) currplanet=planorder[++fakecurrplanet];
  384.                     break;
  385.   }
  386.   if (fabs(speed)<0.000001) speed=0.0;
  387.   if (speed<-0.0001) speed=-0.0001;
  388.   if (speed>0.0001) speed=0.0001;
  389. }
  390.                                                     
  391.  
  392. static void Timer(int i)
  393. {
  394.  if (demomode) {
  395.      fakecurrplanet=rand()%(RINGS);
  396.      currplanet=planorder[fakecurrplanet];
  397.      if (currplanet!=SUN) {
  398.         d=DISTANCE(planets[currplanet].posx,
  399.                    planets[currplanet].posy,planets[currplanet].posz);
  400.               camx=planets[currplanet].posx/d*
  401.                   (d-RADIUSSCALE(planets[currplanet].Radius*8.0));
  402.             camy=planets[currplanet].posy;
  403.             camz=planets[currplanet].posz/d*
  404.                 (d-RADIUSSCALE(planets[currplanet].Radius*8.0));
  405.     }            
  406.     eyex=planets[currplanet].posx-camx;
  407.     eyey=planets[currplanet].posy-camy;
  408.     eyez=planets[currplanet].posz-camz;
  409.         upx=0.0; upy=1.0; upz=0.0;    
  410.     d=DISTANCE(eyex,eyey,eyez);
  411.         eyex/=d; eyey/=d; eyez/=d;
  412.  }
  413.  glutTimerFunc(10000,Timer,0);
  414. }
  415.  
  416.  
  417. #ifdef WIN32
  418.  
  419. void ParseCmdLineWIN32(char *s)
  420. {
  421.  int error=0;
  422.  char *endp=NULL;
  423.  char *tmp=s;
  424.  
  425.  while ((*tmp) && (!error)) {
  426.      error=0;
  427.         if (tmp[0]=='-') {
  428.                 tmp++;
  429.                 if (!strncmp(tmp,"bench",5)) {
  430.                         bench=1;
  431.                         tmp+=5;
  432.                         continue;
  433.                 }
  434.                 if (!strncmp(tmp,"slices ",7)) {
  435.                         tmp+=7;
  436.                         SLICES=strtol(tmp,&endp,10);
  437.                         tmp=endp;
  438.                         continue;
  439.                 }
  440.                 if (!strncmp(tmp,"stacks ",7)) {
  441.                         tmp+=7;
  442.                         STACKS=strtol(tmp,&endp,10);
  443.                         tmp=endp;
  444.                         continue;
  445.                 }
  446.                 error=1;
  447.         }
  448.         if (*tmp!=' ') error=1; else tmp++;
  449.  };
  450.  if (error) {
  451.         sprintf(sbuf,"ssystem [-bench] [-slices N] [-stacks N]");
  452.         MessageBox(NULL,sbuf,"ERROR: Invalid command line option",
  453.                    MB_OK | MB_ICONERROR);
  454.     exit(0);
  455.  }
  456.  
  457. }
  458.  
  459.  
  460. #else
  461.  
  462.  
  463. void ParseCmdLine(int n, char **s)
  464. {
  465.  int i=1,error=0;
  466.  char *endp=NULL;
  467.  
  468.  while ((i<n) && (!error)) {
  469.      error=0;
  470.     if (!strcmp(s[i],"-bench")) {
  471.         bench=1;
  472.         i++;
  473.         continue;
  474.     }
  475.     if (!strcmp(s[i],"-slices")) {
  476.         i++;
  477.         if (i==n) { error=1; continue; };
  478.         SLICES=strtol(s[i],&endp,10);
  479.         error=*endp;
  480.         i++;
  481.         continue;
  482.     }
  483.     if (!strcmp(s[i],"-stacks")) {
  484.         i++;
  485.         if (i==n) { error=1; continue; };
  486.         STACKS=strtol(s[i],&endp,10);
  487.         error=*endp;
  488.         i++;
  489.         continue;
  490.     }
  491.     error=1;
  492.  };
  493.  if (error) {
  494.     printf("ERROR: Invalid command line option\n");
  495.     printf("\n\tssystem [-bench] [-slices N] [-stacks N] \n\n");
  496.     exit(0);
  497.  }
  498. }
  499.  
  500. #endif
  501.  
  502. #ifdef WIN32
  503. int PASCAL
  504.  WinMain(HANDLE hInst, HANDLE hPrevInst, LPSTR lpszCmndLine,int cmdShow )
  505. #else
  506.  int main(int argc, char *argv[])
  507. #endif
  508. {
  509.  
  510. #ifdef WIN32
  511.    int argc=1;
  512.    char *argv[1];
  513.    char *s="ssystem.exe";
  514.  
  515.    argv[0]=s;
  516.    ParseCmdLineWIN32(lpszCmndLine); 
  517. #else
  518.    ParseCmdLine(argc,argv);
  519. #endif   
  520.    glutInit( &argc, argv);
  521.    glutInitWindowPosition( 0, 0 );
  522.    glutInitWindowSize(width,height);
  523.    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
  524.  
  525.    glutCreateWindow( "ssystem 1.2" );
  526.    
  527.    Init();
  528.    currplanet=EARTH;
  529.    if (bench) days=1000.0;
  530.    demomode=!bench;
  531.    UpdatePositions();
  532.    camx=planets[EARTH].posx/1.005; 
  533.    camy=planets[EARTH].posy; 
  534.    camz=planets[EARTH].posz/1.005;
  535.    speed=-0.000002;
  536.    glutKeyboardFunc( Key );
  537.    glutSpecialFunc( Special );
  538.    glutDisplayFunc( Display );
  539.    glutIdleFunc( Idle );
  540.    glutTimerFunc(10000,Timer,0);
  541.    glutReshapeFunc( Reshape );
  542.    sec=TIMEFUNC;
  543.    glutMainLoop();
  544.    return 0;
  545. }
  546.  
  547.