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

GIS编程

开发平台:

Visual C++

  1. /* gears.c */
  2. /*
  3.  * 3-D gear wheels.  This program is in the public domain.
  4.  *
  5.  * Brian Paul
  6.  */
  7. /* Conversion to GLUT by Mark J. Kilgard */
  8. #include <math.h>
  9. #include <stdlib.h>
  10. #include <GL/glut.h>
  11. #ifndef M_PI
  12. #define M_PI 3.14159265
  13. #endif
  14. /**
  15.   Draw a gear wheel.  You'll probably want to call this function when
  16.   building a display list since we do a lot of trig here.
  17.  
  18.   Input:  inner_radius - radius of hole at center
  19.           outer_radius - radius at center of teeth
  20.           width - width of gear
  21.           teeth - number of teeth
  22.           tooth_depth - depth of tooth
  23.  **/
  24. static void
  25. gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
  26.   GLint teeth, GLfloat tooth_depth)
  27. {
  28.   GLint i;
  29.   GLfloat r0, r1, r2;
  30.   GLfloat angle, da;
  31.   GLfloat u, v, len;
  32.   r0 = inner_radius;
  33.   r1 = outer_radius - tooth_depth / 2.0;
  34.   r2 = outer_radius + tooth_depth / 2.0;
  35.   da = 2.0 * M_PI / teeth / 4.0;
  36.   glShadeModel(GL_FLAT);
  37.   glNormal3f(0.0, 0.0, 1.0);
  38.   /* draw front face */
  39.   glBegin(GL_QUAD_STRIP);
  40.   for (i = 0; i <= teeth; i++) {
  41.     angle = i * 2.0 * M_PI / teeth;
  42.     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  43.     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  44.     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  45.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  46.   }
  47.   glEnd();
  48.   /* draw front sides of teeth */
  49.   glBegin(GL_QUADS);
  50.   da = 2.0 * M_PI / teeth / 4.0;
  51.   for (i = 0; i < teeth; i++) {
  52.     angle = i * 2.0 * M_PI / teeth;
  53.     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  54.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
  55.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
  56.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  57.   }
  58.   glEnd();
  59.   glNormal3f(0.0, 0.0, -1.0);
  60.   /* draw back face */
  61.   glBegin(GL_QUAD_STRIP);
  62.   for (i = 0; i <= teeth; i++) {
  63.     angle = i * 2.0 * M_PI / teeth;
  64.     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  65.     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  66.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  67.     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  68.   }
  69.   glEnd();
  70.   /* draw back sides of teeth */
  71.   glBegin(GL_QUADS);
  72.   da = 2.0 * M_PI / teeth / 4.0;
  73.   for (i = 0; i < teeth; i++) {
  74.     angle = i * 2.0 * M_PI / teeth;
  75.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  76.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
  77.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
  78.     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  79.   }
  80.   glEnd();
  81.   /* draw outward faces of teeth */
  82.   glBegin(GL_QUAD_STRIP);
  83.   for (i = 0; i < teeth; i++) {
  84.     angle = i * 2.0 * M_PI / teeth;
  85.     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  86.     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  87.     u = r2 * cos(angle + da) - r1 * cos(angle);
  88.     v = r2 * sin(angle + da) - r1 * sin(angle);
  89.     len = sqrt(u * u + v * v);
  90.     u /= len;
  91.     v /= len;
  92.     glNormal3f(v, -u, 0.0);
  93.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
  94.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
  95.     glNormal3f(cos(angle), sin(angle), 0.0);
  96.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
  97.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
  98.     u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
  99.     v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
  100.     glNormal3f(v, -u, 0.0);
  101.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  102.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  103.     glNormal3f(cos(angle), sin(angle), 0.0);
  104.   }
  105.   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
  106.   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
  107.   glEnd();
  108.   glShadeModel(GL_SMOOTH);
  109.   /* draw inside radius cylinder */
  110.   glBegin(GL_QUAD_STRIP);
  111.   for (i = 0; i <= teeth; i++) {
  112.     angle = i * 2.0 * M_PI / teeth;
  113.     glNormal3f(-cos(angle), -sin(angle), 0.0);
  114.     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  115.     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  116.   }
  117.   glEnd();
  118. }
  119. static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
  120. static GLint gear1, gear2, gear3;
  121. static GLfloat angle = 0.0;
  122. static GLuint limit;
  123. static GLuint count = 1;
  124. static void
  125. draw(void)
  126. {
  127.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  128.   glPushMatrix();
  129.   glRotatef(view_rotx, 1.0, 0.0, 0.0);
  130.   glRotatef(view_roty, 0.0, 1.0, 0.0);
  131.   glRotatef(view_rotz, 0.0, 0.0, 1.0);
  132.   glPushMatrix();
  133.   glTranslatef(-3.0, -2.0, 0.0);
  134.   glRotatef(angle, 0.0, 0.0, 1.0);
  135.   glCallList(gear1);
  136.   glPopMatrix();
  137.   glPushMatrix();
  138.   glTranslatef(3.1, -2.0, 0.0);
  139.   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
  140.   glCallList(gear2);
  141.   glPopMatrix();
  142.   glPushMatrix();
  143.   glTranslatef(-3.1, 4.2, 0.0);
  144.   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
  145.   glCallList(gear3);
  146.   glPopMatrix();
  147.   glPopMatrix();
  148.   glutSwapBuffers();
  149.   count++;
  150.   if (count == limit) {
  151.     exit(0);
  152.   }
  153. }
  154. static void
  155. idle(void)
  156. {
  157.   angle += 2.0;
  158.   glutPostRedisplay();
  159. }
  160. /* change view angle, exit upon ESC */
  161. /* ARGSUSED1 */
  162. static void
  163. key(unsigned char k, int x, int y)
  164. {
  165.   switch (k) {
  166.   case 'z':
  167.     view_rotz += 5.0;
  168.     break;
  169.   case 'Z':
  170.     view_rotz -= 5.0;
  171.     break;
  172.   case 27:  /* Escape */
  173.     exit(0);
  174.     break;
  175.   default:
  176.     return;
  177.   }
  178.   glutPostRedisplay();
  179. }
  180. /* change view angle */
  181. /* ARGSUSED1 */
  182. static void
  183. special(int k, int x, int y)
  184. {
  185.   switch (k) {
  186.   case GLUT_KEY_UP:
  187.     view_rotx += 5.0;
  188.     break;
  189.   case GLUT_KEY_DOWN:
  190.     view_rotx -= 5.0;
  191.     break;
  192.   case GLUT_KEY_LEFT:
  193.     view_roty += 5.0;
  194.     break;
  195.   case GLUT_KEY_RIGHT:
  196.     view_roty -= 5.0;
  197.     break;
  198.   default:
  199.     return;
  200.   }
  201.   glutPostRedisplay();
  202. }
  203. /* new window size or exposure */
  204. static void
  205. reshape(int width, int height)
  206. {
  207.   GLfloat h = (GLfloat) height / (GLfloat) width;
  208.   glViewport(0, 0, (GLint) width, (GLint) height);
  209.   glMatrixMode(GL_PROJECTION);
  210.   glLoadIdentity();
  211.   glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
  212.   glMatrixMode(GL_MODELVIEW);
  213.   glLoadIdentity();
  214.   glTranslatef(0.0, 0.0, -40.0);
  215. }
  216. static void
  217. init(void)
  218. {
  219.   static GLfloat pos[4] =
  220.   {5.0, 5.0, 10.0, 0.0};
  221.   static GLfloat red[4] =
  222.   {0.8, 0.1, 0.0, 1.0};
  223.   static GLfloat green[4] =
  224.   {0.0, 0.8, 0.2, 1.0};
  225.   static GLfloat blue[4] =
  226.   {0.2, 0.2, 1.0, 1.0};
  227.   glLightfv(GL_LIGHT0, GL_POSITION, pos);
  228.   glEnable(GL_CULL_FACE);
  229.   glEnable(GL_LIGHTING);
  230.   glEnable(GL_LIGHT0);
  231.   glEnable(GL_DEPTH_TEST);
  232.   /* make the gears */
  233.   gear1 = glGenLists(1);
  234.   glNewList(gear1, GL_COMPILE);
  235.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
  236.   gear(1.0, 4.0, 1.0, 20, 0.7);
  237.   glEndList();
  238.   gear2 = glGenLists(1);
  239.   glNewList(gear2, GL_COMPILE);
  240.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
  241.   gear(0.5, 2.0, 2.0, 10, 0.7);
  242.   glEndList();
  243.   gear3 = glGenLists(1);
  244.   glNewList(gear3, GL_COMPILE);
  245.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
  246.   gear(1.3, 2.0, 0.5, 10, 0.7);
  247.   glEndList();
  248.   glEnable(GL_NORMALIZE);
  249. }
  250. void 
  251. visible(int vis)
  252. {
  253.   if (vis == GLUT_VISIBLE)
  254.     glutIdleFunc(idle);
  255.   else
  256.     glutIdleFunc(NULL);
  257. }
  258. int
  259. main(int argc, char *argv[])
  260. {
  261.   glutInit(&argc, argv);
  262.   if (argc > 1) {
  263.     /* do 'n' frames then exit */
  264.     limit = atoi(argv[1]) + 1;
  265.   } else {
  266.     limit = 0;
  267.   }
  268.   glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  269.   glutCreateWindow("Gears");
  270.   init();
  271.   glutDisplayFunc(draw);
  272.   glutReshapeFunc(reshape);
  273.   glutKeyboardFunc(key);
  274.   glutSpecialFunc(special);
  275.   glutVisibilityFunc(visible);
  276.   glutMainLoop();
  277.   return 0;             /* ANSI C requires main to return int. */
  278. }