Added d/D keys to change viewing distance, 'a' to toggle animation
[mesa.git] / progs / demos / gears.c
index 8d99a8d317fd19a853fa2de7c289ea7a68977830..7abbd3670bd4def368ad2f36718c6ade46aaf72d 100644 (file)
@@ -1,33 +1,22 @@
-/* $Id: gears.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
-
 /*
  * 3-D gear wheels.  This program is in the public domain.
  *
+ * Command line options:
+ *    -info      print GL implementation information
+ *    -exit      automatically exit after 30 seconds
+ *
+ *
  * Brian Paul
  */
 
 /* Conversion to GLUT by Mark J. Kilgard */
 
-/*
- * $Log: gears.c,v $
- * Revision 1.1  1999/08/19 00:55:40  jtg
- * Initial revision
- *
- * Revision 3.2  1999/06/03 17:07:36  brianp
- * an extra quad was being drawn in front and back faces
- *
- * Revision 3.1  1998/11/03 02:49:10  brianp
- * added fps output
- *
- * Revision 3.0  1998/02/14 18:42:29  brianp
- * initial rev
- *
- */
 
 
 #include <math.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <GL/glut.h>
 
 #ifndef M_PI
 
 static GLint T0 = 0;
 static GLint Frames = 0;
+static GLint autoexit = 0;
+static GLint win = 0;
+static GLboolean Visible = GL_TRUE;
+static GLboolean Animate = GL_TRUE;
+static GLfloat viewDist = 40.0;
 
 
 /**
@@ -173,48 +167,65 @@ static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
 static GLint gear1, gear2, gear3;
 static GLfloat angle = 0.0;
 
+static void
+cleanup(void)
+{
+   glDeleteLists(gear1, 1);
+   glDeleteLists(gear2, 1);
+   glDeleteLists(gear3, 1);
+   glutDestroyWindow(win);
+}
+
 static void
 draw(void)
 {
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
   glPushMatrix();
-  glRotatef(view_rotx, 1.0, 0.0, 0.0);
-  glRotatef(view_roty, 0.0, 1.0, 0.0);
-  glRotatef(view_rotz, 0.0, 0.0, 1.0);
 
-  glPushMatrix();
-  glTranslatef(-3.0, -2.0, 0.0);
-  glRotatef(angle, 0.0, 0.0, 1.0);
-  glCallList(gear1);
-  glPopMatrix();
+    glTranslatef(0.0, 0.0, -viewDist);
 
-  glPushMatrix();
-  glTranslatef(3.1, -2.0, 0.0);
-  glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
-  glCallList(gear2);
-  glPopMatrix();
+    glRotatef(view_rotx, 1.0, 0.0, 0.0);
+    glRotatef(view_roty, 0.0, 1.0, 0.0);
+    glRotatef(view_rotz, 0.0, 0.0, 1.0);
 
-  glPushMatrix();
-  glTranslatef(-3.1, 4.2, 0.0);
-  glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
-  glCallList(gear3);
-  glPopMatrix();
+    glPushMatrix();
+      glTranslatef(-3.0, -2.0, 0.0);
+      glRotatef(angle, 0.0, 0.0, 1.0);
+      glCallList(gear1);
+    glPopMatrix();
+
+    glPushMatrix();
+      glTranslatef(3.1, -2.0, 0.0);
+      glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
+      glCallList(gear2);
+    glPopMatrix();
+
+    glPushMatrix();
+      glTranslatef(-3.1, 4.2, 0.0);
+      glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
+      glCallList(gear3);
+    glPopMatrix();
 
   glPopMatrix();
 
   glutSwapBuffers();
 
   Frames++;
+
   {
-     GLint t = glutGet(GLUT_ELAPSED_TIME);
-     if (t - T0 >= 5000) {
-        GLfloat seconds = (t - T0) / 1000.0;
-        GLfloat fps = Frames / seconds;
-        printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
-        T0 = t;
-        Frames = 0;
-     }
+    GLint t = glutGet(GLUT_ELAPSED_TIME);
+    if (t - T0 >= 5000) {
+      GLfloat seconds = (t - T0) / 1000.0;
+      GLfloat fps = Frames / seconds;
+      printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps);
+      T0 = t;
+      Frames = 0;
+      if ((t >= 999.0 * autoexit) && (autoexit)) {
+        cleanup();
+        exit(0);
+      }
+    }
   }
 }
 
@@ -222,10 +233,28 @@ draw(void)
 static void
 idle(void)
 {
-  angle += 2.0;
+  static double t0 = -1.;
+  double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
+  if (t0 < 0.0)
+    t0 = t;
+  dt = t - t0;
+  t0 = t;
+
+  angle += 70.0 * dt;  /* 70 degrees per second */
+  angle = fmod(angle, 360.0); /* prevents eventual overflow */
+
   glutPostRedisplay();
 }
 
+static void
+update_idle_func(void)
+{
+  if (Visible && Animate)
+    glutIdleFunc(idle);
+  else
+    glutIdleFunc(NULL);
+}
+
 /* change view angle, exit upon ESC */
 /* ARGSUSED1 */
 static void
@@ -238,7 +267,18 @@ key(unsigned char k, int x, int y)
   case 'Z':
     view_rotz -= 5.0;
     break;
+  case 'd':
+     viewDist += 1.0;
+     break;
+  case 'D':
+     viewDist -= 1.0;
+     break;
+  case 'a':
+     Animate = !Animate;
+     update_idle_func();
+     break;
   case 27:  /* Escape */
+    cleanup();
     exit(0);
     break;
   default:
@@ -282,21 +322,16 @@ reshape(int width, int height)
   glLoadIdentity();
   glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
   glMatrixMode(GL_MODELVIEW);
-  glLoadIdentity();
-  glTranslatef(0.0, 0.0, -40.0);
 }
 
 static void
-init(void)
+init(int argc, char *argv[])
 {
-  static GLfloat pos[4] =
-  {5.0, 5.0, 10.0, 0.0};
-  static GLfloat red[4] =
-  {0.8, 0.1, 0.0, 1.0};
-  static GLfloat green[4] =
-  {0.0, 0.8, 0.2, 1.0};
-  static GLfloat blue[4] =
-  {0.2, 0.2, 1.0, 1.0};
+  static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0};
+  static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0};
+  static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0};
+  static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0};
+  GLint i;
 
   glLightfv(GL_LIGHT0, GL_POSITION, pos);
   glEnable(GL_CULL_FACE);
@@ -324,15 +359,27 @@ init(void)
   glEndList();
 
   glEnable(GL_NORMALIZE);
+
+  for ( i=1; i<argc; i++ ) {
+    if (strcmp(argv[i], "-info")==0) {
+      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
+      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
+      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
+      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
+    }
+    else if ( strcmp(argv[i], "-exit")==0) {
+      autoexit = 30;
+      printf("Auto Exit after %i seconds.\n", autoexit );
+    }
+  }
 }
 
-void 
+
+static void 
 visible(int vis)
 {
-  if (vis == GLUT_VISIBLE)
-    glutIdleFunc(idle);
-  else
-    glutIdleFunc(NULL);
+   Visible = vis;
+   update_idle_func();
 }
 
 int main(int argc, char *argv[])
@@ -342,14 +389,15 @@ int main(int argc, char *argv[])
 
   glutInitWindowPosition(0, 0);
   glutInitWindowSize(300, 300);
-  glutCreateWindow("Gears");
-  init();
+  win = glutCreateWindow("Gears");
+  init(argc, argv);
 
   glutDisplayFunc(draw);
   glutReshapeFunc(reshape);
   glutKeyboardFunc(key);
   glutSpecialFunc(special);
   glutVisibilityFunc(visible);
+  update_idle_func();
 
   glutMainLoop();
   return 0;             /* ANSI C requires main to return int. */