home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / GLUT / progs / contrib / rings.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  6.7 KB  |  275 lines

  1. /* rings.c
  2.  *
  3.  * To compile: cc -o rings rings.c -lGL -lGLU -lX11 -lglut -lXmu -lm
  4.  *
  5.  * Usage: rings
  6.  *
  7.  * Homework 4, Part 1: perspective, hierarchical coords, moving eye pos.
  8.  *
  9.  * Do a slow zoom on a bunch of rings (ala Superman III?)
  10.  *
  11.  * Philip Winston - 2/21/95
  12.  * pwinston@hmc.edu
  13.  * http://www.cs.hmc.edu/people/pwinston
  14.  *
  15.  */
  16.  
  17. #include <GL/glut.h>
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <math.h>
  22.  
  23. typedef enum {MENU_STARTOVER, MENU_ZOOM_OUT, MENU_STOP_RINGS, MENU_STOP_FADE, 
  24.               MENU_START_RINGS, MENU_START_FADE, MENU_QUIT} MenuChoices;
  25.  
  26. typedef enum {NOTALLOWED, CONE, TORUS, INNERMAT, OUTTERMAT} DisplayLists;
  27.  
  28. #define STEPS 30
  29.  
  30. int Fade = 1;   /* Start moving out */
  31.  
  32. float Axis = 0, AxisInc = (2.0 * M_PI / STEPS);
  33.  
  34. GLfloat InnerRad, OutterRad, Tilt, Trans, TransCone, Dist;
  35.  
  36.   /* mainly computes the translation amount as a function of the
  37.      tilt angle and torus radii */
  38. void myInit(void)
  39. {
  40.   float sinoftilt;
  41.  
  42.   InnerRad = 0.70;
  43.   OutterRad = 5.0;
  44.   Tilt = 15;
  45.   Dist = 10;
  46.  
  47.   sinoftilt = sin(Tilt * M_PI*2/360);
  48.  
  49.   Trans = (2*OutterRad + InnerRad) * sinoftilt + InnerRad +
  50.           ((1 - sinoftilt) * InnerRad) - (InnerRad * 1/10);
  51.  
  52.   TransCone = Trans + (OutterRad * sinoftilt + InnerRad);
  53. }
  54.  
  55.   /* I used code from the book's accnot.c as a starting point for lighting.
  56.      I have one positional light in center, then one directional */
  57. void myglInit(void)
  58. {
  59.   GLfloat light0_position[] = { 1.0, 0.2, 1.0, 0.0 };
  60.   GLfloat light1_position[] = { 0.0, 0.0, 0.0, 1.0 };
  61.   GLfloat light1_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
  62.   GLfloat light1_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  63.   GLfloat lm_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
  64.  
  65.   glEnable(GL_NORMALIZE);
  66.   glMatrixMode(GL_PROJECTION);
  67.   glLoadIdentity();
  68.   glMatrixMode(GL_MODELVIEW);
  69.   glLoadIdentity();
  70.  
  71.   glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
  72.   glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
  73.   glLightfv(GL_LIGHT1, GL_DIFFUSE,  light1_diffuse);
  74.   glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular);
  75.   glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.2);
  76.   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lm_ambient);
  77.  
  78.   glEnable(GL_LIGHTING);
  79.   glEnable(GL_LIGHT0);
  80.   glEnable(GL_LIGHT1);
  81.  
  82.   glDepthFunc(GL_LESS);
  83.   glEnable(GL_DEPTH_TEST);
  84.  
  85.   glFlush();
  86.  
  87. void myreshape(GLsizei w, GLsizei h)
  88. {
  89.   glViewport(0,0,w,h);
  90.   glFlush();
  91. }
  92.  
  93.   /* setup display lists to change material for inner/outter rings and
  94.      to draw a single torus or cone */
  95. void MakeDisplayLists(void)
  96. {
  97.   GLfloat cone_diffuse[] = { 0.0, 0.7, 0.7, 1.0 };
  98.   GLfloat mat1_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
  99.   GLfloat mat2_ambient[] = { 0.0, 0.0, 0.0, 0.0 };
  100.   GLfloat torus1_diffuse[] = { 0.7, 0.7, 0.0, 1.0 };
  101.   GLfloat torus2_diffuse[] = { 0.3, 0.0, 0.0, 1.0 };
  102.   GLfloat mat1_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  103.   GLfloat mat2_specular[] = { 0.5, 0.5, 0.5, 1.0 };
  104.  
  105.   glNewList(INNERMAT, GL_COMPILE);
  106.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat1_specular);
  107.     glMaterialf(GL_FRONT, GL_SHININESS, 50.0);
  108.     glMaterialfv(GL_FRONT, GL_DIFFUSE, torus1_diffuse);    
  109.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat1_ambient);
  110.   glEndList();
  111.  
  112.   glNewList(OUTTERMAT, GL_COMPILE);
  113.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat2_specular);
  114.     glMaterialf(GL_FRONT, GL_SHININESS, 25.0);
  115.     glMaterialfv(GL_FRONT, GL_DIFFUSE, torus2_diffuse);    
  116.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat2_ambient);
  117.   glEndList();
  118.  
  119.   glNewList(CONE, GL_COMPILE);
  120.     glMaterialfv(GL_FRONT, GL_DIFFUSE, cone_diffuse);    
  121.     glPushMatrix();
  122.       glTranslatef(0, -TransCone, 0);
  123.       glRotatef(90, 1, 0, 0);
  124.       glutSolidCone(OutterRad, 10, 8, 8);
  125.     glPopMatrix();
  126.   glEndList();
  127.  
  128.   glNewList(TORUS, GL_COMPILE);
  129.     glPushMatrix();
  130.       glRotatef(90, 1, 0, 0);
  131.       glutSolidTorus(InnerRad, OutterRad, 15, 25);
  132.     glPopMatrix();
  133.   glEndList();
  134. }
  135.   
  136.   /* Draw three rings, rotated and translate so they look cool */
  137. void DrawRings(float axis)
  138. {
  139.   GLfloat x = sin(axis), y = cos(axis);
  140.  
  141.   glPushMatrix();
  142.     glTranslatef(0, Trans, 0);
  143.     glRotatef(Tilt, x, 0, y);
  144.     glCallList(TORUS);  
  145.   glPopMatrix();
  146.  
  147.   glPushMatrix();
  148.     glRotatef(-Tilt, x, 0, y);
  149.     glCallList(TORUS);
  150.   glPopMatrix();
  151.  
  152.   glPushMatrix();
  153.     glTranslatef(0, -Trans, 0);
  154.     glRotatef(Tilt, x, 0, y);
  155.     glCallList(TORUS);
  156.   glPopMatrix();
  157. }
  158.  
  159.   /* Draw the inner thing, then glScale and draw 3 huge rings */
  160. void mydisplay(void)
  161. {
  162.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  163.  
  164.   glMatrixMode(GL_PROJECTION);
  165.   glLoadIdentity();
  166.   glFrustum(-1, 1, -1, 1, 10, 1000); 
  167.   gluLookAt(0, 0, Dist, 0, 0, 0, 0, 1, 0);
  168.  
  169.   glMatrixMode(GL_MODELVIEW);
  170.  
  171.   glCallList(INNERMAT);
  172.   DrawRings(Axis);
  173.   glCallList(CONE);
  174.  
  175.   glCallList(OUTTERMAT);
  176.   glPushMatrix();
  177.     glScalef(10, 10, 10);
  178.     DrawRings(Axis/3);
  179.   glPopMatrix();
  180.  
  181.   glutSwapBuffers();
  182.   glFlush();
  183. }
  184.  
  185.   /* rotate the axis and adjust position if nec. */
  186. void myidle(void)
  187.   Axis += AxisInc;
  188.  
  189.   if (Dist < 15 && Fade)    /* start slow */
  190.     Dist += 0.1;
  191.   else if (Dist < 800 && Fade)   /* don't go back too far */
  192.     Dist *= 1.005;  
  193.  
  194.   mydisplay();
  195. }
  196.  
  197.   /* nothing fancy */
  198. void handlemenu(int value)
  199. {
  200.   switch (value) {
  201.     case MENU_STARTOVER:
  202.       Dist = 10; Axis = 0; Fade = 1;
  203.       AxisInc = (2.0 * M_PI / STEPS);
  204.       glutChangeToMenuEntry(3, "Stop rings", MENU_STOP_RINGS);
  205.       glutChangeToMenuEntry(4, "Stop fade", MENU_STOP_FADE);
  206.       break;
  207.     case MENU_ZOOM_OUT:
  208.       Dist = 800;
  209.       break;
  210.     case MENU_STOP_RINGS:
  211.       AxisInc = 0;
  212.       glutChangeToMenuEntry(3, "Start rings", MENU_START_RINGS);
  213.       break;
  214.     case MENU_START_RINGS:
  215.       AxisInc = (2.0 * M_PI / STEPS);
  216.       glutChangeToMenuEntry(3, "Stop rings", MENU_STOP_RINGS);
  217.       break;
  218.     case MENU_STOP_FADE:
  219.       Fade = 0;
  220.       glutChangeToMenuEntry(4, "Start fade", MENU_START_FADE);
  221.       break;
  222.     case MENU_START_FADE:
  223.       Fade = 1;
  224.       glutChangeToMenuEntry(4, "Stop fade", MENU_STOP_FADE);
  225.       break;
  226.     case MENU_QUIT:
  227.       exit(0);
  228.       break;
  229.     }
  230. }
  231.  
  232. void MenuInit(void)
  233. {
  234.   glutCreateMenu(handlemenu);
  235.   glutAddMenuEntry("Start Over", MENU_STARTOVER);
  236.   glutAddMenuEntry("Zoom Out", MENU_ZOOM_OUT);
  237.   glutAddMenuEntry("Stop rings", MENU_STOP_RINGS);
  238.   glutAddMenuEntry("Stop fade", MENU_STOP_FADE);
  239.   glutAddMenuEntry("Quit", MENU_QUIT);
  240.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  241. }
  242.  
  243. void
  244. vis(int visible)
  245. {
  246.   if (visible == GLUT_VISIBLE) {
  247.       glutIdleFunc(myidle);
  248.   } else {
  249.       glutIdleFunc(NULL);
  250.   }
  251. }
  252.  
  253. int main(int argc, char** argv)
  254. {
  255.   glutInit(&argc, argv);
  256.   glutInitWindowSize(512, 512);
  257.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  258.   glutCreateWindow("rings");
  259.  
  260.   myInit();
  261.   myglInit(); 
  262.  
  263.   MakeDisplayLists();
  264.   MenuInit();
  265.  
  266.   glutReshapeFunc(myreshape);
  267.   glutDisplayFunc(mydisplay);
  268.   glutVisibilityFunc(vis);
  269.  
  270.   glutMainLoop();
  271.   return 0;             /* ANSI C requires main to return int. */
  272. }
  273.