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

GIS编程

开发平台:

Visual C++

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