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

GIS编程

开发平台:

Visual C++

  1. /**************************************************************************
  2.  *   *
  3.  *   Copyright (C) 1988, 1989, 1990, Silicon Graphics, Inc.   *
  4.  *   *
  5.  *  These coded instructions, statements, and computer programs  contain  *
  6.  *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
  7.  *  are protected by Federal copyright law.  They  may  not be disclosed  *
  8.  *  to  third  parties  or copied or duplicated in any form, in whole or  *
  9.  *  in part, without the prior written consent of Silicon Graphics, Inc.  *
  10.  *   *
  11.  **************************************************************************/
  12. /*
  13.  *  foo $Revision: 1.4 $
  14.  */
  15. #include <assert.h>
  16. #include <math.h>
  17. #include <stdio.h>
  18. #include <stdarg.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <GL/glut.h>
  22. #include "tb.h"
  23. #include "glui.h"
  24. /* Some <math.h> files do not define M_PI... */
  25. #ifndef M_PI
  26. #define M_PI 3.14159265358979323846
  27. #endif
  28. #define UDIV 12
  29. #define VDIV 12
  30. #define WALLGRIDMAX 32
  31. #define EYEZ 3.3
  32. #define TOTALBALLS 3
  33. #define R 0
  34. #define G 1
  35. #define B 2
  36. #define X 0
  37. #define Y 1
  38. #define Z 2
  39. #define W 3
  40. int wallgrid = 8; /* sqrt of the number of quads in a wall */
  41. float fatt = 1.0;
  42. int freeze = GL_FALSE;
  43. int spin = GL_FALSE;
  44. int spinning = GL_FALSE;
  45. int objecton = GL_FALSE;
  46. int normson = GL_FALSE;
  47. int lighton[3] = {GL_TRUE, GL_TRUE, GL_TRUE};
  48. int window; /* main window id */
  49. GLboolean performance = GL_FALSE; /* performance indicator */
  50. struct {
  51.    float p[3];
  52.    float d[3];
  53.    unsigned char color[3];
  54. } balls[TOTALBALLS];
  55. float ballobj[UDIV+1][VDIV+1][4];
  56. float wallobj[WALLGRIDMAX+1][WALLGRIDMAX+1][4];
  57. float wallnorms[WALLGRIDMAX+1][WALLGRIDMAX+1][3];
  58. float wallnorm[3] = { 0.0, 0.0, -1.0 };
  59. int orx, ory;
  60. float ballscale;
  61. float ballsize;
  62. int DELTAX, DELTAY;
  63. int lflag = 0;
  64. float newpos[] = { 0.0, 0.0, 0.0, 1.0 };
  65. GLfloat light_Ka[] = { 0.3, 0.3, 0.3, 1.0 };  /* ambient */
  66. GLfloat light_Ks[] = { 0.0, 0.0, 0.0, 1.0 };  /* specular */
  67. GLfloat light0_Ka[]  = { 0.0, 0.0, 0.0, 1.0 };  /* ambient */
  68. GLfloat light0_Kd[]  = { 1.0, 0.1, 0.1, 1.0 };  /* diffuse */
  69. GLfloat light0_pos[] = { 0.0, 0.0, 0.0, 1.0 };  /* position */
  70. GLfloat light1_Ka[]  = { 0.0, 0.0, 0.0, 1.0 };  /* ambient */
  71. GLfloat light1_Kd[]  = { 0.1, 1.0, 0.1, 1.0 };  /* diffuse */
  72. GLfloat light1_pos[] = { 0.0, 0.0, 0.0, 1.0 };  /* position */
  73. GLfloat light2_Ka[]  = { 0.0, 0.0, 0.0, 1.0 };  /* ambient */
  74. GLfloat light2_Kd[]  = { 0.1, 0.1, 1.0, 1.0 };  /* diffuse */
  75. GLfloat light2_pos[] = { 0.0, 0.0, 0.0, 1.0 };  /* position */
  76. GLfloat attenuation[] = { 1.0, 3.0 };
  77. GLfloat plane_Ka[] = { 0.0, 0.0, 0.0, 1.0 };  /* ambient */
  78. GLfloat plane_Kd[] = { 0.4, 0.4, 0.4, 1.0 };  /* diffuse */
  79. GLfloat plane_Ks[] = { 1.0, 1.0, 1.0, 1.0 };  /* specular */
  80. GLfloat plane_Ke[] = { 0.0, 0.0, 0.0, 1.0 };  /* emission */
  81. GLfloat plane_Se   = 30.0;                    /* shininess */
  82. GLfloat wall_Ka[] = { 0.1, 0.1, 0.1, 1.0 };  /* ambient */
  83. GLfloat wall_Kd[] = { 0.8, 0.8, 0.8, 1.0 };  /* diffuse */
  84. GLfloat wall_Ks[] = { 1.0, 1.0, 1.0, 1.0 };  /* specular */
  85. GLfloat wall_Ke[] = { 0.0, 0.0, 0.0, 1.0 };  /* emission */
  86. GLfloat wall_Se   = 20.0;                    /* shininess */
  87. GLuint wall_material, plane_material; /* material display lists */
  88. char ofile[80];
  89. /************************************************************/
  90. /* XXX - The following is an excerpt from spin.h from spin  */
  91. /************************************************************/
  92. #define POLYGON 1
  93. #define LINES 2
  94. #define TRANSPERENT 3
  95. #define DISPLAY 4
  96. #define LMATERIAL 5
  97. #define FASTMAGIC 0x5423
  98. typedef struct fastobj {
  99.     int npoints;
  100.     int colors;
  101.     int type;
  102.     int material;
  103.     int display;
  104.     int ablend;
  105.     GLint *data;
  106. } fastobj;
  107. /*
  108.  * Wrappers to do either lines or polygons
  109.  */
  110. #define PolyOrLine() if (lflag == LINES) { 
  111. glBegin(GL_LINE_LOOP); 
  112. } else { 
  113. glBegin(GL_POLYGON); 
  114. }
  115. #define EndPolyOrLine() if (lflag == LINES) { 
  116. glEnd(); 
  117. } else { 
  118. glEnd(); 
  119. }
  120. /************************* end of spin.h excerpt *************************/
  121. fastobj *obj = NULL;
  122. /* 
  123.    general purpose text routine.  draws a string according to the
  124.    format in a stroke font at x, y after scaling it by the scale
  125.    specified.  x, y and scale are all in window-space [i.e., pixels]
  126.    with origin at the lower-left.
  127. */
  128. void 
  129. text(GLuint x, GLuint y, GLfloat scale, char* format, ...)
  130. {
  131.     va_list args;
  132.     char buffer[255], *p;
  133.     GLfloat font_scale = 119.05 + 33.33;
  134.     va_start(args, format);
  135.     vsprintf(buffer, format, args);
  136.     va_end(args);
  137.     glMatrixMode(GL_PROJECTION);
  138.     glPushMatrix();
  139.     glLoadIdentity();
  140.     gluOrtho2D(0, glutGet(GLUT_WINDOW_WIDTH), 0, glutGet(GLUT_WINDOW_HEIGHT));
  141.     glMatrixMode(GL_MODELVIEW);
  142.     glPushMatrix();
  143.     glLoadIdentity();
  144.     glPushAttrib(GL_ENABLE_BIT);
  145.     glDisable(GL_LIGHTING);
  146.     glDisable(GL_TEXTURE_2D);
  147.     glEnable(GL_DEPTH_TEST);
  148.     glEnable(GL_LINE_SMOOTH);
  149.     glEnable(GL_BLEND);
  150.     glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  151.     glTranslatef(x, y, 0.0);
  152.     glScalef(scale/font_scale, scale/font_scale, scale/font_scale);
  153.     for(p = buffer; *p; p++)
  154. glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
  155.   
  156.     glPopAttrib();
  157.     glPopMatrix();
  158.     glMatrixMode(GL_PROJECTION);
  159.     glPopMatrix();
  160.     glMatrixMode(GL_MODELVIEW);
  161. }
  162. float
  163. frand(void)
  164. {
  165.     return 2.0*(rand()/32768.0 - .5);
  166. }
  167. void
  168. resetballs(void)
  169. {
  170.     register short i;
  171.     balls[0].color[R] = 255;
  172.     balls[0].color[G] = 64;
  173.     balls[0].color[B] = 64;
  174.     balls[1].color[R] = 64;
  175.     balls[1].color[G] = 255;
  176.     balls[1].color[B] = 64;
  177.     balls[2].color[R] = 64;
  178.     balls[2].color[G] = 64;
  179.     balls[2].color[B] = 255;
  180.     for (i = 0; i < TOTALBALLS; i++) {
  181. balls[i].p[0] = 0.0;
  182. balls[i].p[1] = 0.0;
  183. balls[i].p[2] = 0.0;
  184. balls[i].d[0] = .1*frand();
  185. balls[i].d[1] = .1*frand();
  186. balls[i].d[2] = .1*frand();
  187.     }
  188. }
  189. void
  190. drawface(void)
  191. {
  192.     register int i,j;
  193.     glNormal3fv(wallnorm);
  194.     for (i=0; i < wallgrid; i++) {
  195. glBegin(GL_TRIANGLE_STRIP);
  196. for (j=0; j <= wallgrid; j++) {
  197.     glVertex3fv(wallobj[i][j]);
  198.     glVertex3fv(wallobj[i+1][j]);
  199. }
  200. glEnd();
  201.     }
  202. }
  203. void
  204. drawnorms(void)
  205. {
  206.     register int i,j;
  207.     glDisable(GL_LIGHTING);
  208.     glColor3ub(255, 255, 0);
  209.     for (i=0; i <= wallgrid; i++) {
  210. for (j=0; j <= wallgrid; j++) {
  211.     glBegin(GL_LINES);
  212.     glVertex3fv(wallobj[i][j]);
  213.     glVertex3fv(wallnorms[i][j]);
  214.     glEnd();
  215. }
  216.     }
  217.     glEnable(GL_LIGHTING);
  218. }
  219. void
  220. drawbox(void)
  221. {
  222.     glPushMatrix();
  223. /*  drawface(); */
  224.     glRotatef(90.0, 0.0, 1.0, 0.0);
  225.     drawface();
  226.     if (normson) drawnorms();
  227.     glRotatef(90.0, 0.0, 1.0, 0.0);
  228.     drawface();
  229.     if (normson) drawnorms();
  230.     glRotatef(90.0, 0.0, 1.0, 0.0);
  231. /*  drawface(); */
  232.     glRotatef(-90.0, 1.0, 0.0, 0.0);
  233.     drawface();
  234.     if (normson) drawnorms();
  235.     glRotatef(180.0, 1.0, 0.0, 0.0);
  236. /*  drawface(); */
  237.     glPopMatrix();
  238. }
  239. void
  240. drawfastobj(fastobj *obj)
  241. {
  242.     register GLint *p, *end;
  243.     register int npolys;
  244.     p = obj->data;
  245.     end = p + 8 * obj->npoints;
  246.     if(obj->colors) {
  247. npolys = obj->npoints/4;
  248. while(npolys--) {
  249.     PolyOrLine();
  250.     glColor3iv(p);
  251.     glVertex3fv((float *)p+4);
  252.     glColor3iv(p+8);
  253.     glVertex3fv((float *)p+12);
  254.     glColor3iv(p+16);
  255.     glVertex3fv((float *)p+20);
  256.     glColor3iv(p+24);
  257.     glVertex3fv((float *)p+28);
  258.     EndPolyOrLine();
  259.     p += 32;
  260. }
  261.     } else {
  262. while ( p < end) {
  263.     PolyOrLine();
  264.     glNormal3fv((float *)p);
  265.     glVertex3fv((float *)p+4);
  266.     glNormal3fv((float *)p+8);
  267.     glVertex3fv((float *)p+12);
  268.     glNormal3fv((float *)p+16);
  269.     glVertex3fv((float *)p+20);
  270.     glNormal3fv((float *)p+24);
  271.     glVertex3fv((float *)p+28);
  272.     EndPolyOrLine();
  273.     p += 32;
  274. }
  275.     }
  276. }
  277. void
  278. drawball(void)
  279. {
  280.     register int i,j;
  281.     for (i=0; i < UDIV; i++) {
  282. for (j=0; j < VDIV; j++) {
  283.     glBegin(GL_POLYGON);
  284.     glVertex4fv( ballobj[i][j] );
  285.     glVertex4fv( ballobj[i+1][j] );
  286.     glVertex4fv( ballobj[i+1][j+1] );
  287.     glVertex4fv( ballobj[i][j+1] );
  288.     glEnd();
  289. }
  290.     }
  291. }
  292. void
  293. drawimage(void)
  294. {
  295.     register short i;
  296.     static int start, end, last;
  297.     glutSetWindow(window);
  298.     if (performance)
  299. start = glutGet(GLUT_ELAPSED_TIME);
  300.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  301.     glPushMatrix();
  302.     tbMatrix();
  303.     for (i=0; i < TOTALBALLS; i++) {
  304. newpos[0] = balls[i].p[0];
  305. newpos[1] = balls[i].p[1];
  306. newpos[2] = balls[i].p[2];
  307. glLightfv(GL_LIGHT0 + i, GL_POSITION, newpos);
  308.     }
  309.     glCallList(wall_material);
  310.     glEnable(GL_LIGHTING);
  311.     drawbox();
  312.     glEnable(GL_DEPTH_TEST);
  313.     if (objecton)
  314.     {
  315. glCallList(plane_material);
  316. glPushMatrix();
  317. glScalef(1.5, 1.5, 1.5);
  318. glRotatef(180.0, 0.0, 0.0, 1.0);
  319. if (spin)
  320. {
  321.     orx += 50;
  322.     ory += 50;
  323. }
  324. glRotatef(orx/10.0, 1.0, 0.0, 0.0);
  325. glRotatef(ory/10.0, 0.0, 1.0, 0.0);
  326. drawfastobj(obj);
  327. glPopMatrix();
  328.     }
  329.     glDisable(GL_LIGHTING);
  330.     for (i=0; i < TOTALBALLS; i++) {
  331. if (lighton[i])
  332. {
  333.     glPushMatrix();
  334.     glTranslatef(balls[i].p[0],balls[i].p[1],balls[i].p[2]);
  335.     glColor3ubv(balls[i].color);
  336.     drawball();
  337.     glPopMatrix();
  338. }
  339.     }
  340.     glColor3f(1.0, 1.0, 1.0);
  341.     if (performance) {
  342.         if (end - last == 0) {
  343.     text(10, 73, 20, "unknown fps");
  344. } else {
  345.     text(10, 73, 20, "%.0f fps", 1.0 / ((end - last) / 1000.0));
  346. }
  347. last = start;
  348.     }
  349.     text(10, 43, 14, "Attenuation [%.2f]", fatt);
  350.     text(10, 13, 14, "Tesselation [%3d]", wallgrid);
  351.     glPopMatrix();
  352.     glutSwapBuffers();
  353.     if (performance)
  354. end = glutGet(GLUT_ELAPSED_TIME);
  355. }
  356. void
  357. initobjects(void)
  358. {
  359.     register float u,v,du,dv;
  360.     register short i,j;
  361.     du = 2.0*M_PI/UDIV;
  362.     dv = M_PI/VDIV;
  363.     u = 0.;
  364.     for (i=0; i <= UDIV; i++) {
  365. v = 0.;
  366. for (j=0; j <= VDIV; j++) {
  367.     ballobj[i][j][X] = ballsize*cos(u)*sin(v);
  368.     ballobj[i][j][Y] = ballsize*sin(u)*sin(v);
  369.     ballobj[i][j][Z] = ballsize*cos(v);
  370.     ballobj[i][j][W] = 1.0;
  371.     v += dv;
  372. }
  373. u += du;
  374.     }
  375.     for (i=0; i <= wallgrid; i++) {
  376. for (j=0; j <= wallgrid; j++) {
  377.     wallobj[i][j][X] = -1.0 + 2.0*i/wallgrid;
  378.     wallobj[i][j][Y] = -1.0 + 2.0*j/wallgrid;
  379.     wallobj[i][j][Z] = 1.0;
  380.     wallobj[i][j][W] = 1.0;
  381. }
  382.     }
  383.     for (i=0; i <= wallgrid; i++) {
  384. for (j=0; j <= wallgrid; j++) {
  385.     wallnorms[i][j][X] = wallobj[i][j][X] + wallnorm[X]*0.1;
  386.     wallnorms[i][j][Y] = wallobj[i][j][Y] + wallnorm[Y]*0.1;
  387.     wallnorms[i][j][Z] = wallobj[i][j][Z] + wallnorm[Z]*0.1;
  388. }
  389.     }
  390. }
  391. int MOUSEX, MOUSEY;
  392. static void
  393. mouse(int button, int state, int x, int y)
  394. {
  395.     MOUSEX = x;
  396.     MOUSEY = y;
  397.     tbMouse(button, state, x, y);
  398. }
  399. static void
  400. motion(int x, int y)
  401. {
  402.     DELTAX -= MOUSEX - x;
  403.     DELTAY += MOUSEY - y;
  404.     MOUSEX = x;
  405.     MOUSEY = y;
  406.     tbMotion(x, y);
  407. }
  408. /* ARGSUSED1 */
  409. void
  410. keyboard(unsigned char key, int x, int y)
  411. {
  412.     switch(key) {
  413.     case 27: /* ESC */
  414. exit(0);
  415. break;
  416.     case '+':
  417. wallgrid++;
  418. if (wallgrid > WALLGRIDMAX)
  419.     wallgrid = WALLGRIDMAX;
  420. initobjects();
  421. break;
  422.     case '-':
  423. wallgrid--;
  424. if (wallgrid < 1)
  425.     wallgrid = 1;
  426. initobjects();
  427. break;
  428.     }
  429. }
  430. void
  431. initialize(void)
  432. {
  433.     glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
  434.     window = glutCreateWindow("bounce");
  435.     initobjects();
  436.     srand(glutGet(GLUT_ELAPSED_TIME));
  437.     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
  438.     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light_Ka);
  439.     plane_material = glGenLists(1);
  440.     glNewList(plane_material, GL_COMPILE);
  441.     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, plane_Ka);
  442.     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, plane_Kd);
  443.     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, plane_Ks);
  444.     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, plane_Ke);
  445.     glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, plane_Se);
  446.     glEndList();
  447.     wall_material = glGenLists(1);
  448.     glNewList(wall_material, GL_COMPILE);
  449.     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, wall_Ka);
  450.     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, wall_Kd);
  451.     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, wall_Ks);
  452.     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, wall_Ke);
  453.     glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, wall_Se);
  454.     glEndList();
  455.     glLightfv(GL_LIGHT0, GL_AMBIENT, light0_Ka);
  456.     glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_Kd);
  457.     glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, attenuation[0]);
  458.     glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, attenuation[1]);
  459.     /* OpenGL's light0 has different specular properties than the rest
  460.        of the lights.... */
  461.     glLightfv(GL_LIGHT0, GL_SPECULAR, light_Ks);
  462.     glLightfv(GL_LIGHT1, GL_AMBIENT, light1_Ka);
  463.     glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_Kd);
  464.     glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, attenuation[0]);
  465.     glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, attenuation[1]);
  466.     glLightfv(GL_LIGHT2, GL_AMBIENT, light2_Ka);
  467.     glLightfv(GL_LIGHT2, GL_DIFFUSE, light2_Kd);
  468.     glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, attenuation[0]);
  469.     glLightf(GL_LIGHT2, GL_LINEAR_ATTENUATION, attenuation[1]);
  470.     glutMotionFunc(motion);
  471.     glutMouseFunc(mouse);
  472.     glutKeyboardFunc(keyboard);
  473. }
  474. void
  475. calcball(void)
  476. {
  477.     register short i,j;
  478.     for (j=0; j < TOTALBALLS; j++) {
  479. for (i=0; i < 3; i++) {
  480.     balls[j].p[i] += balls[j].d[i];
  481.     if (fabs(balls[j].p[i]) > ballscale) {
  482. balls[j].p[i] = (balls[j].p[i] > 0.0) ?
  483. ballscale : -ballscale;
  484. balls[j].d[i] = -balls[j].d[i];
  485.     }
  486. }
  487.     }
  488. }
  489. static void menu(int value);
  490. static void idle(void);
  491. static void
  492. make_menu(void)
  493. {
  494.     static int main_menu = 0;
  495.     if (main_menu)
  496. glutDestroyMenu(main_menu);
  497.     main_menu = glutCreateMenu(menu);
  498.     glutAddMenuEntry("bounce", 0);
  499.     glutAddMenuEntry("", 0);
  500.     if (lighton[0])
  501. glutAddMenuEntry("red light off", 1);
  502.     else
  503. glutAddMenuEntry("red light on", 1);
  504.     if (lighton[1])
  505. glutAddMenuEntry("green light off", 2);
  506.     else
  507. glutAddMenuEntry("green light on", 2);
  508.     if (lighton[2])
  509. glutAddMenuEntry("blue light off", 3);
  510.     else
  511. glutAddMenuEntry("blue light on", 3);
  512.     if (freeze)
  513. glutAddMenuEntry("unfreeze lights", 4);
  514.     else
  515. glutAddMenuEntry("freeze lights", 4);
  516.     if (normson)
  517. glutAddMenuEntry("normals off", 7);
  518.     else
  519. glutAddMenuEntry("normals on", 7);
  520.     if (performance)
  521. glutAddMenuEntry("frame rate off", 8);
  522.     else
  523. glutAddMenuEntry("frame rate on", 8);
  524.     if (obj)
  525.     {
  526. if (objecton)
  527.     glutAddMenuEntry("object off", 5);
  528. else
  529.     glutAddMenuEntry("object on", 5);
  530. if (spin)
  531.     glutAddMenuEntry("object spin off", 6);
  532. else
  533.     glutAddMenuEntry("object spin on", 6);
  534.     }
  535.     glutAddMenuEntry("", 0);
  536.     glutAddMenuEntry("exit", 9);
  537.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  538. }
  539. static void
  540. menu(int value)
  541. {
  542.     switch(value) {
  543.     case 1:
  544. if ((lighton[0] = !lighton[0]))
  545.     glEnable(GL_LIGHT0);
  546. else
  547.     glDisable(GL_LIGHT0);
  548. break;
  549.     case 2:
  550. if ((lighton[1] = !lighton[1]))
  551.     glEnable(GL_LIGHT1);
  552. else
  553.     glDisable(GL_LIGHT1);
  554. break;
  555.     case 3:
  556. if ((lighton[2] = !lighton[2]))
  557.     glEnable(GL_LIGHT2);
  558. else
  559.     glDisable(GL_LIGHT2);
  560. break;
  561.     case 4:
  562. freeze =  !freeze;
  563.         if (!freeze || spinning) {
  564.   glutIdleFunc(idle);
  565.         } else {
  566.   glutIdleFunc(NULL);
  567.         }
  568. break;
  569.     case 5:
  570. if (obj)
  571.     objecton =  !objecton;
  572. else
  573.     exit(1);
  574. break;
  575.     case 6:
  576. spin =  !spin;
  577. break;
  578.     case 7:
  579.         normson = !normson;
  580.         break;
  581.     case 8:
  582. performance = !performance;
  583. break;
  584.     case 9:
  585. exit(0);
  586. break;
  587.     }
  588.     glutPostWindowRedisplay(window);
  589.     make_menu();
  590. }
  591. /**********************************************************/
  592. /* XXX - The following is a clone of fastobj.c from spin  */
  593. /**********************************************************/
  594. fastobj*
  595. readfastobj(char *name)
  596. {
  597.     FILE *inf;
  598.     fastobj *obj;
  599.     int i;
  600.     int nlongs;
  601.     int magic;
  602.     GLint *ip;
  603.     char filename[512];
  604.     inf = fopen(name,"r");
  605.     if(!inf) {
  606.    sprintf(filename,"%s",name);
  607. inf = fopen(filename,"r");
  608. if(!inf) {
  609.     fprintf(stderr,"readfast: can't open input file %sn",name);
  610.     exit(1);
  611. }
  612.     }
  613.     fread(&magic,sizeof(int),1,inf);
  614.     if(magic != FASTMAGIC) {
  615. fprintf(stderr,"readfast: bad magic in object filen");
  616. fclose(inf);
  617. exit(1);
  618.     }
  619.     obj = (fastobj *)malloc(sizeof(fastobj));
  620.     fread(&obj->npoints,sizeof(int),1,inf);
  621.     fread(&obj->colors,sizeof(int),1,inf);
  622.     /*
  623.      * Insure that the data is quad-word aligned and begins on a page
  624.      * boundary.  This shields us from the performance loss which occurs 
  625.      * whenever we try to fetch data which straddles a page boundary  (the OS
  626.      * has to map in the next virtual page and re-start the DMA transfer).
  627.      */
  628.     nlongs = 8 * obj->npoints;
  629.     obj->data = (GLint *) malloc(nlongs*sizeof(int) + 4096);
  630.     obj->data = (GLint *) (((int)(obj->data)) + 0xfff);
  631.     obj->data = (GLint *) (((int)(obj->data)) & 0xfffff000);
  632.     /* XXX Careful, sizeof(GLint) could change from implementation
  633.        to implementation making this file format implementation
  634.        dependent. -mjk */
  635.     for (i = 0, ip = obj->data;  i < nlongs/4;  i++, ip += 4)
  636. fread(ip, 3 * sizeof(GLint), 1, inf);
  637.     fclose(inf);
  638.     return obj;
  639. }
  640. /*
  641.  * objmaxpoint
  642.  *
  643.  * find the vertex farthest from the origin,
  644.  * so we can set the near and far clipping planes tightly.
  645.  */
  646. #define MAXVERT(v) if ( (len = sqrt( (*(v))  *  (*(v))  +        
  647. (*(v+1)) * (*(v+1)) +        
  648. (*(v+2)) * (*(v+2)) )) > max)  
  649. max = len;
  650. float
  651. objmaxpoint(obj)
  652. fastobj *obj;
  653. {
  654.     register float *p, *end;
  655.     register int npolys;
  656.     register float len;
  657.     register float max = 0.0;
  658.     p = (float *) (obj->data);
  659.     if (obj->colors) {
  660. npolys = obj->npoints/4;
  661. while(npolys--) {
  662.     MAXVERT(p+4);
  663.     MAXVERT(p+12);
  664.     MAXVERT(p+20);
  665.     MAXVERT(p+28);
  666.     p += 32;
  667. }
  668.     } else {
  669. end = p + 8 * obj->npoints;
  670. while ( p < end) {
  671.     MAXVERT(p+4);
  672.     MAXVERT(p+12);
  673.     MAXVERT(p+20);
  674.     MAXVERT(p+28);
  675.     p += 32;
  676. }
  677.     }
  678.     return max;
  679. }
  680. static void
  681. idle(void)
  682. {
  683.     assert(!freeze || spinning);
  684.     if (!freeze) {
  685.         calcball();
  686.     }
  687.     if (spinning) {
  688.         tbStepAnimation();
  689.     }
  690.     glutPostWindowRedisplay(window);
  691. }
  692. /* When not visible, stop animating.  Restart when visible again. */
  693. static void 
  694. visible(int vis)
  695. {
  696.   if (vis == GLUT_VISIBLE) {
  697.     if (!freeze || spinning)
  698.       glutIdleFunc(idle);
  699.   } else {
  700.     if (!freeze || spinning)
  701.       glutIdleFunc(NULL);
  702.   }
  703. }
  704. static void
  705. reshape(int width, int height)
  706. {
  707.     glViewport(0, 0, width, height);
  708.     glMatrixMode(GL_PROJECTION);
  709.     glLoadIdentity();
  710.     gluPerspective(60.0, (float)width/height, EYEZ-2.0, EYEZ+2.0);
  711.     glMatrixMode(GL_MODELVIEW);
  712.     glLoadIdentity();
  713.     glTranslatef(0.0, 0.25, -EYEZ);
  714.     tbReshape(width, height);
  715.     gluiReshape(width, height);
  716. }
  717. void
  718. update_fatt(float value)
  719. {
  720.     fatt = 5 * value;
  721.     glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, fatt);
  722.     glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, fatt);
  723.     glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, fatt);
  724.     glutPostWindowRedisplay(window);
  725. }
  726. void
  727. update_grid(float value)
  728. {
  729.     wallgrid = WALLGRIDMAX*value;
  730.     if (wallgrid < 1)
  731. wallgrid = 1;
  732.     initobjects();
  733.     glutPostWindowRedisplay(window);
  734. }
  735. void
  736. spinChange(int state)
  737. {
  738.   spinning = state;
  739.   if (spinning || !freeze) {
  740.     glutIdleFunc(idle);
  741.   } else {
  742.     glutIdleFunc(NULL);
  743.   }
  744. }
  745. int
  746. main(int argc, char **argv)
  747. {
  748.     glutInitWindowSize(512, 512);
  749.     glutInitWindowPosition(64, 64);
  750.     glutInit(&argc, argv);
  751.     if (argc > 1)
  752.     {
  753. int i;
  754. for (i=0; argv[1][i] != '/' && argv[1][i] != ''; i++);
  755. if (argv[1][i] != '/')
  756. {
  757.     strcpy(ofile, "/usr/demos/data/models/");
  758.     strcat(ofile, argv[1]);
  759. }
  760. else
  761.     strcpy(ofile, argv[1]);
  762. if (obj = readfastobj(ofile))
  763.     objecton = GL_TRUE;
  764.     }
  765.     ballsize = .04;
  766.     ballscale = 1.0 - ballsize;
  767.     initialize();
  768.     make_menu();
  769.     resetballs();
  770.     /* Use local lights for the box */
  771.     glEnable(GL_LIGHT0);
  772.     glEnable(GL_LIGHT1);
  773.     glEnable(GL_LIGHT2);
  774.     make_menu();
  775.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  776.     glutDisplayFunc(drawimage);
  777.     glutReshapeFunc(reshape);
  778.     glutVisibilityFunc(visible);
  779.     gluiHorizontalSlider(window, 130, -10, -10, 20,
  780.  (float)wallgrid/WALLGRIDMAX, update_grid);
  781.     gluiHorizontalSlider(window, 130, -40, -10, 20, fatt/5.0, update_fatt);
  782.     tbInit(GLUT_LEFT_BUTTON);
  783.     tbAnimate(1);
  784.     tbAnimateFunc(spinChange);
  785.     glutMainLoop();
  786.     return 0;             /* ANSI C requires main to return int. */
  787. }