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

GIS编程

开发平台:

Visual C++

  1. /* Copyright (c) Mark J. Kilgard, 1994. */
  2. /* This program is freely distributable without licensing fees 
  3.    and is provided without guarantee or warrantee expressed or 
  4.    implied. This program is -not- in the public domain. */
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #ifndef _WIN32
  8. #include <unistd.h>
  9. #else
  10. #include <process.h>  /* for getpid */
  11. #define random rand
  12. #define srandom srand
  13. #endif
  14. #include <math.h>
  15. #include <GL/glut.h>
  16. /* Some <math.h> files do not define M_PI... */
  17. #ifndef M_PI
  18. #define M_PI 3.14159265358979323846
  19. #endif
  20. #ifndef M_PI_2
  21. #define M_PI_2 1.57079632679489661923
  22. #endif
  23. GLboolean moving = GL_FALSE;
  24. #define MAX_PLANES 15
  25. struct {
  26.   float speed;          /* zero speed means not flying */
  27.   GLfloat red, green, blue;
  28.   float theta;
  29.   float x, y, z, angle;
  30. } planes[MAX_PLANES];
  31. #define v3f glVertex3f  /* v3f was the short IRIS GL name for
  32.                            glVertex3f */
  33. void
  34. draw(void)
  35. {
  36.   GLfloat red, green, blue;
  37.   int i;
  38.   glClear(GL_DEPTH_BUFFER_BIT);
  39.   /* paint black to blue smooth shaded polygon for background */
  40.   glDisable(GL_DEPTH_TEST);
  41.   glShadeModel(GL_SMOOTH);
  42.   glBegin(GL_POLYGON);
  43.   glColor3f(0.0, 0.0, 0.0);
  44.   v3f(-20, 20, -19);
  45.   v3f(20, 20, -19);
  46.   glColor3f(0.0, 0.0, 1.0);
  47.   v3f(20, -20, -19);
  48.   v3f(-20, -20, -19);
  49.   glEnd();
  50.   /* paint planes */
  51.   glEnable(GL_DEPTH_TEST);
  52.   glShadeModel(GL_FLAT);
  53.   for (i = 0; i < MAX_PLANES; i++)
  54.     if (planes[i].speed != 0.0) {
  55.       glPushMatrix();
  56.       glTranslatef(planes[i].x, planes[i].y, planes[i].z);
  57.       glRotatef(290.0, 1.0, 0.0, 0.0);
  58.       glRotatef(planes[i].angle, 0.0, 0.0, 1.0);
  59.       glScalef(1.0 / 3.0, 1.0 / 4.0, 1.0 / 4.0);
  60.       glTranslatef(0.0, -4.0, -1.5);
  61.       glBegin(GL_TRIANGLE_STRIP);
  62.       /* left wing */
  63.       v3f(-7.0, 0.0, 2.0);
  64.       v3f(-1.0, 0.0, 3.0);
  65.       glColor3f(red = planes[i].red, green = planes[i].green,
  66.         blue = planes[i].blue);
  67.       v3f(-1.0, 7.0, 3.0);
  68.       /* left side */
  69.       glColor3f(0.6 * red, 0.6 * green, 0.6 * blue);
  70.       v3f(0.0, 0.0, 0.0);
  71.       v3f(0.0, 8.0, 0.0);
  72.       /* right side */
  73.       v3f(1.0, 0.0, 3.0);
  74.       v3f(1.0, 7.0, 3.0);
  75.       /* final tip of right wing */
  76.       glColor3f(red, green, blue);
  77.       v3f(7.0, 0.0, 2.0);
  78.       glEnd();
  79.       glPopMatrix();
  80.     }
  81.   glutSwapBuffers();
  82. }
  83. void
  84. tick_per_plane(int i)
  85. {
  86.   float theta = planes[i].theta += planes[i].speed;
  87.   planes[i].z = -9 + 4 * cos(theta);
  88.   planes[i].x = 4 * sin(2 * theta);
  89.   planes[i].y = sin(theta / 3.4) * 3;
  90.   planes[i].angle = ((atan(2.0) + M_PI_2) * sin(theta) - M_PI_2) * 180 / M_PI;
  91.   if (planes[i].speed < 0.0)
  92.     planes[i].angle += 180;
  93. }
  94. void
  95. add_plane(void)
  96. {
  97.   int i;
  98.   for (i = 0; i < MAX_PLANES; i++)
  99.     if (planes[i].speed == 0) {
  100. #define SET_COLOR(r,g,b) 
  101. planes[i].red=r; planes[i].green=g; planes[i].blue=b;
  102.       switch (random() % 6) {
  103.       case 0:
  104.         SET_COLOR(1.0, 0.0, 0.0);  /* red */
  105.         break;
  106.       case 1:
  107.         SET_COLOR(1.0, 1.0, 1.0);  /* white */
  108.         break;
  109.       case 2:
  110.         SET_COLOR(0.0, 1.0, 0.0);  /* green */
  111.         break;
  112.       case 3:
  113.         SET_COLOR(1.0, 0.0, 1.0);  /* magenta */
  114.         break;
  115.       case 4:
  116.         SET_COLOR(1.0, 1.0, 0.0);  /* yellow */
  117.         break;
  118.       case 5:
  119.         SET_COLOR(0.0, 1.0, 1.0);  /* cyan */
  120.         break;
  121.       }
  122.       planes[i].speed = ((float) (random() % 20)) * 0.001 + 0.02;
  123.       if (random() & 0x1)
  124.         planes[i].speed *= -1;
  125.       planes[i].theta = ((float) (random() % 257)) * 0.1111;
  126.       tick_per_plane(i);
  127.       if (!moving)
  128.         glutPostRedisplay();
  129.       return;
  130.     }
  131. }
  132. void
  133. remove_plane(void)
  134. {
  135.   int i;
  136.   for (i = MAX_PLANES - 1; i >= 0; i--)
  137.     if (planes[i].speed != 0) {
  138.       planes[i].speed = 0;
  139.       if (!moving)
  140.         glutPostRedisplay();
  141.       return;
  142.     }
  143. }
  144. void
  145. tick(void)
  146. {
  147.   int i;
  148.   for (i = 0; i < MAX_PLANES; i++)
  149.     if (planes[i].speed != 0.0)
  150.       tick_per_plane(i);
  151. }
  152. void
  153. animate(void)
  154. {
  155.   tick();
  156.   glutPostRedisplay();
  157. }
  158. void
  159. visible(int state)
  160. {
  161.   if (state == GLUT_VISIBLE) {
  162.     if (moving)
  163.       glutIdleFunc(animate);
  164.   } else {
  165.     if (moving)
  166.       glutIdleFunc(NULL);
  167.   }
  168. }
  169. /* ARGSUSED1 */
  170. void
  171. keyboard(unsigned char ch, int x, int y)
  172. {
  173.   switch (ch) {
  174.   case ' ':
  175.     if (!moving) {
  176.       tick();
  177.       glutPostRedisplay();
  178.     }
  179.     break;
  180.   case 27:             /* ESC */
  181.     exit(0);
  182.     break;
  183.   }
  184. }
  185. #define ADD_PLANE 1
  186. #define REMOVE_PLANE 2
  187. #define MOTION_ON 3
  188. #define MOTION_OFF 4
  189. #define QUIT 5
  190. void
  191. menu(int item)
  192. {
  193.   switch (item) {
  194.   case ADD_PLANE:
  195.     add_plane();
  196.     break;
  197.   case REMOVE_PLANE:
  198.     remove_plane();
  199.     break;
  200.   case MOTION_ON:
  201.     moving = GL_TRUE;
  202.     glutChangeToMenuEntry(3, "Motion off", MOTION_OFF);
  203.     glutIdleFunc(animate);
  204.     break;
  205.   case MOTION_OFF:
  206.     moving = GL_FALSE;
  207.     glutChangeToMenuEntry(3, "Motion", MOTION_ON);
  208.     glutIdleFunc(NULL);
  209.     break;
  210.   case QUIT:
  211.     exit(0);
  212.     break;
  213.   }
  214. }
  215. int
  216. main(int argc, char *argv[])
  217. {
  218.   glutInit(&argc, argv);
  219.   /* use multisampling if available */
  220.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
  221.   glutCreateWindow("glutplane");
  222.   glutDisplayFunc(draw);
  223.   glutKeyboardFunc(keyboard);
  224.   glutVisibilityFunc(visible);
  225.   glutCreateMenu(menu);
  226.   glutAddMenuEntry("Add plane", ADD_PLANE);
  227.   glutAddMenuEntry("Remove plane", REMOVE_PLANE);
  228.   glutAddMenuEntry("Motion", MOTION_ON);
  229.   glutAddMenuEntry("Quit", QUIT);
  230.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  231.   /* setup OpenGL state */
  232.   glClearDepth(1.0);
  233.   glClearColor(0.0, 0.0, 0.0, 0.0);
  234.   glMatrixMode(GL_PROJECTION);
  235.   glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 20);
  236.   glMatrixMode(GL_MODELVIEW);
  237.   /* add three initial random planes */
  238.   srandom(getpid());
  239.   add_plane();
  240.   add_plane();
  241.   add_plane();
  242.   /* start event processing */
  243.   glutMainLoop();
  244.   return 0;             /* ANSI C requires main to return int. */
  245. }