home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / demos / gears.c < prev    next >
C/C++ Source or Header  |  2000-01-07  |  9KB  |  372 lines

  1. /* $Id: gears.c,v 1.2 1999/10/21 16:39:06 brianp Exp $ */
  2.  
  3. /*
  4.  * 3-D gear wheels.  This program is in the public domain.
  5.  *
  6.  * Command line options:
  7.  *    -info      print GL implementation information
  8.  *
  9.  *
  10.  * Brian Paul
  11.  */
  12.  
  13. /* Conversion to GLUT by Mark J. Kilgard */
  14.  
  15. /*
  16.  * $Log: gears.c,v $
  17.  * Revision 1.2  1999/10/21 16:39:06  brianp
  18.  * added -info command line option
  19.  *
  20.  * Revision 1.1.1.1  1999/08/19 00:55:40  jtg
  21.  * Imported sources
  22.  *
  23.  * Revision 3.2  1999/06/03 17:07:36  brianp
  24.  * an extra quad was being drawn in front and back faces
  25.  *
  26.  * Revision 3.1  1998/11/03 02:49:10  brianp
  27.  * added fps output
  28.  *
  29.  * Revision 3.0  1998/02/14 18:42:29  brianp
  30.  * initial rev
  31.  *
  32.  */
  33.  
  34.  
  35. #include <math.h>
  36. #include <stdlib.h>
  37. #include <stdio.h>
  38. #include <string.h>
  39. #include <GL/glut.h>
  40.  
  41. #ifndef M_PI
  42. #define M_PI 3.14159265
  43. #endif
  44.  
  45. static GLint T0 = 0;
  46. static GLint Frames = 0;
  47.  
  48.  
  49. /**
  50.  
  51.   Draw a gear wheel.  You'll probably want to call this function when
  52.   building a display list since we do a lot of trig here.
  53.  
  54.   Input:  inner_radius - radius of hole at center
  55.           outer_radius - radius at center of teeth
  56.           width - width of gear
  57.           teeth - number of teeth
  58.           tooth_depth - depth of tooth
  59.  
  60.  **/
  61.  
  62. static void
  63. gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
  64.   GLint teeth, GLfloat tooth_depth)
  65. {
  66.   GLint i;
  67.   GLfloat r0, r1, r2;
  68.   GLfloat angle, da;
  69.   GLfloat u, v, len;
  70.  
  71.   r0 = inner_radius;
  72.   r1 = outer_radius - tooth_depth / 2.0;
  73.   r2 = outer_radius + tooth_depth / 2.0;
  74.  
  75.   da = 2.0 * M_PI / teeth / 4.0;
  76.  
  77.   glShadeModel(GL_FLAT);
  78.  
  79.   glNormal3f(0.0, 0.0, 1.0);
  80.  
  81.   /* draw front face */
  82.   glBegin(GL_QUAD_STRIP);
  83.   for (i = 0; i <= teeth; i++) {
  84.     angle = i * 2.0 * M_PI / teeth;
  85.     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  86.     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  87.     if (i < teeth) {
  88.       glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  89.       glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  90.     }
  91.   }
  92.   glEnd();
  93.  
  94.   /* draw front sides of teeth */
  95.   glBegin(GL_QUADS);
  96.   da = 2.0 * M_PI / teeth / 4.0;
  97.   for (i = 0; i < teeth; i++) {
  98.     angle = i * 2.0 * M_PI / teeth;
  99.  
  100.     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  101.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
  102.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
  103.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  104.   }
  105.   glEnd();
  106.  
  107.   glNormal3f(0.0, 0.0, -1.0);
  108.  
  109.   /* draw back face */
  110.   glBegin(GL_QUAD_STRIP);
  111.   for (i = 0; i <= teeth; i++) {
  112.     angle = i * 2.0 * M_PI / teeth;
  113.     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  114.     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  115.     if (i < teeth) {
  116.       glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  117.       glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  118.     }
  119.   }
  120.   glEnd();
  121.  
  122.   /* draw back sides of teeth */
  123.   glBegin(GL_QUADS);
  124.   da = 2.0 * M_PI / teeth / 4.0;
  125.   for (i = 0; i < teeth; i++) {
  126.     angle = i * 2.0 * M_PI / teeth;
  127.  
  128.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  129.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
  130.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
  131.     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  132.   }
  133.   glEnd();
  134.  
  135.   /* draw outward faces of teeth */
  136.   glBegin(GL_QUAD_STRIP);
  137.   for (i = 0; i < teeth; i++) {
  138.     angle = i * 2.0 * M_PI / teeth;
  139.  
  140.     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  141.     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  142.     u = r2 * cos(angle + da) - r1 * cos(angle);
  143.     v = r2 * sin(angle + da) - r1 * sin(angle);
  144.     len = sqrt(u * u + v * v);
  145.     u /= len;
  146.     v /= len;
  147.     glNormal3f(v, -u, 0.0);
  148.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
  149.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
  150.     glNormal3f(cos(angle), sin(angle), 0.0);
  151.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
  152.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
  153.     u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
  154.     v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
  155.     glNormal3f(v, -u, 0.0);
  156.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  157.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  158.     glNormal3f(cos(angle), sin(angle), 0.0);
  159.   }
  160.  
  161.   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
  162.   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
  163.  
  164.   glEnd();
  165.  
  166.   glShadeModel(GL_SMOOTH);
  167.  
  168.   /* draw inside radius cylinder */
  169.   glBegin(GL_QUAD_STRIP);
  170.   for (i = 0; i <= teeth; i++) {
  171.     angle = i * 2.0 * M_PI / teeth;
  172.     glNormal3f(-cos(angle), -sin(angle), 0.0);
  173.     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  174.     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  175.   }
  176.   glEnd();
  177.  
  178. }
  179.  
  180. static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
  181. static GLint gear1, gear2, gear3;
  182. static GLfloat angle = 0.0;
  183.  
  184. static void
  185. draw(void)
  186. {
  187.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  188.  
  189.   glPushMatrix();
  190.   glRotatef(view_rotx, 1.0, 0.0, 0.0);
  191.   glRotatef(view_roty, 0.0, 1.0, 0.0);
  192.   glRotatef(view_rotz, 0.0, 0.0, 1.0);
  193.  
  194.   glPushMatrix();
  195.   glTranslatef(-3.0, -2.0, 0.0);
  196.   glRotatef(angle, 0.0, 0.0, 1.0);
  197.   glCallList(gear1);
  198.   glPopMatrix();
  199.  
  200.   glPushMatrix();
  201.   glTranslatef(3.1, -2.0, 0.0);
  202.   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
  203.   glCallList(gear2);
  204.   glPopMatrix();
  205.  
  206.   glPushMatrix();
  207.   glTranslatef(-3.1, 4.2, 0.0);
  208.   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
  209.   glCallList(gear3);
  210.   glPopMatrix();
  211.  
  212.   glPopMatrix();
  213.  
  214.   glutSwapBuffers();
  215.  
  216.   Frames++;
  217.   {
  218.      GLint t = glutGet(GLUT_ELAPSED_TIME);
  219.      if (t - T0 >= 5000) {
  220.         GLfloat seconds = (t - T0) / 1000.0;
  221.         GLfloat fps = Frames / seconds;
  222.         printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
  223.         T0 = t;
  224.         Frames = 0;
  225.      }
  226.   }
  227. }
  228.  
  229.  
  230. static void
  231. idle(void)
  232. {
  233.   angle += 2.0;
  234.   glutPostRedisplay();
  235. }
  236.  
  237. /* change view angle, exit upon ESC */
  238. /* ARGSUSED1 */
  239. static void
  240. key(unsigned char k, int x, int y)
  241. {
  242.   switch (k) {
  243.   case 'z':
  244.     view_rotz += 5.0;
  245.     break;
  246.   case 'Z':
  247.     view_rotz -= 5.0;
  248.     break;
  249.   case 27:  /* Escape */
  250.     exit(0);
  251.     break;
  252.   default:
  253.     return;
  254.   }
  255.   glutPostRedisplay();
  256. }
  257.  
  258. /* change view angle */
  259. /* ARGSUSED1 */
  260. static void
  261. special(int k, int x, int y)
  262. {
  263.   switch (k) {
  264.   case GLUT_KEY_UP:
  265.     view_rotx += 5.0;
  266.     break;
  267.   case GLUT_KEY_DOWN:
  268.     view_rotx -= 5.0;
  269.     break;
  270.   case GLUT_KEY_LEFT:
  271.     view_roty += 5.0;
  272.     break;
  273.   case GLUT_KEY_RIGHT:
  274.     view_roty -= 5.0;
  275.     break;
  276.   default:
  277.     return;
  278.   }
  279.   glutPostRedisplay();
  280. }
  281.  
  282. /* new window size or exposure */
  283. static void
  284. reshape(int width, int height)
  285. {
  286.   GLfloat h = (GLfloat) height / (GLfloat) width;
  287.  
  288.   glViewport(0, 0, (GLint) width, (GLint) height);
  289.   glMatrixMode(GL_PROJECTION);
  290.   glLoadIdentity();
  291.   glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
  292.   glMatrixMode(GL_MODELVIEW);
  293.   glLoadIdentity();
  294.   glTranslatef(0.0, 0.0, -40.0);
  295. }
  296.  
  297. static void
  298. init(int argc, char *argv[])
  299. {
  300.   static GLfloat pos[4] =
  301.   {5.0, 5.0, 10.0, 0.0};
  302.   static GLfloat red[4] =
  303.   {0.8, 0.1, 0.0, 1.0};
  304.   static GLfloat green[4] =
  305.   {0.0, 0.8, 0.2, 1.0};
  306.   static GLfloat blue[4] =
  307.   {0.2, 0.2, 1.0, 1.0};
  308.  
  309.   glLightfv(GL_LIGHT0, GL_POSITION, pos);
  310.   glEnable(GL_CULL_FACE);
  311.   glEnable(GL_LIGHTING);
  312.   glEnable(GL_LIGHT0);
  313.   glEnable(GL_DEPTH_TEST);
  314.  
  315.   /* make the gears */
  316.   gear1 = glGenLists(1);
  317.   glNewList(gear1, GL_COMPILE);
  318.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
  319.   gear(1.0, 4.0, 1.0, 20, 0.7);
  320.   glEndList();
  321.  
  322.   gear2 = glGenLists(1);
  323.   glNewList(gear2, GL_COMPILE);
  324.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
  325.   gear(0.5, 2.0, 2.0, 10, 0.7);
  326.   glEndList();
  327.  
  328.   gear3 = glGenLists(1);
  329.   glNewList(gear3, GL_COMPILE);
  330.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
  331.   gear(1.3, 2.0, 0.5, 10, 0.7);
  332.   glEndList();
  333.  
  334.   glEnable(GL_NORMALIZE);
  335.  
  336.   if (argc > 1 && strcmp(argv[1], "-info")==0) {
  337.      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
  338.      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
  339.      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
  340.      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
  341.   }
  342. }
  343.  
  344. void 
  345. visible(int vis)
  346. {
  347.   if (vis == GLUT_VISIBLE)
  348.     glutIdleFunc(idle);
  349.   else
  350.     glutIdleFunc(NULL);
  351. }
  352.  
  353. int main(int argc, char *argv[])
  354. {
  355.   glutInit(&argc, argv);
  356.   glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  357.  
  358.   glutInitWindowPosition(0, 0);
  359.   glutInitWindowSize(300, 300);
  360.   glutCreateWindow("Gears");
  361.   init(argc, argv);
  362.  
  363.   glutDisplayFunc(draw);
  364.   glutReshapeFunc(reshape);
  365.   glutKeyboardFunc(key);
  366.   glutSpecialFunc(special);
  367.   glutVisibilityFunc(visible);
  368.  
  369.   glutMainLoop();
  370.   return 0;             /* ANSI C requires main to return int. */
  371. }
  372.