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

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. #include <GL/glut.h>
  8. /* Uses EXT_polygon_offset extension if available to better
  9.    render the fold outlines. */
  10. #if GL_EXT_polygon_offset
  11. int polygon_offset;
  12. #endif
  13. enum {
  14.   FLAT,                 /* completely flat sheet of paper */
  15.   FLAP1,                /* left flap being folded in */
  16.   FLAP2,                /* right flap being folded int */
  17.   CENTER2,              /* right side folded up at center */
  18.   WING2,                /* right wing folded down */
  19.   CENTER1,              /* left side folded up at center */
  20.   WING1,                /* left wing folded down */
  21.   FOLDED                /* fully folded paper airplane */
  22. } States;
  23. int motion = 1;
  24. int spinning = 1;
  25. int state = FLAT;
  26. int click = 0;
  27. int delay = 0;
  28. int direction;
  29. float flap1_angle = 0;
  30. float flap2_angle = 0;
  31. float center1_angle = 0;
  32. float center2_angle = 0;
  33. float wing1_angle = 0;
  34. float wing2_angle = 0;
  35. /**
  36. These correspond to the polygons for the paper sections:
  37.   +----------+----------+
  38.   |         /|         |
  39.   |  2     / |     3   |
  40.   |       /  |         |
  41.   +------/   |   ------+
  42.   |     /|   |   |     |
  43.   | 1  / |   |   |  4  |
  44.   |   /  |   |   |     |
  45.   |  /   |   |   |     |
  46.   | /    | 5 | 6 |     |
  47.   |/     |   |   |     |
  48.   +      |   |   |      +
  49.   |  7   |   |   |  8   |
  50.   |      |   |   |      |
  51.   |      |   |   |      |
  52.   |      |   |   |      |
  53.   |      |   |   |      |
  54.   |      |   |   |      |
  55.   |      |   |   |      |
  56.   +------+---+---+------+
  57. */
  58. typedef GLfloat Point[2];
  59. Point poly1[] =
  60. {
  61.   {-1, 0},
  62.   {-1 / 3.0, 2 / 3.0},
  63.   {-1, 2 / 3.0}
  64. };
  65. Point poly2[] =
  66. {
  67.   {-1, 1},
  68.   {-1, 2 / 3.0},
  69.   {-1 / 3.0, 2 / 3.0},
  70.   {0, 1}
  71. };
  72. Point poly3[] =
  73. {
  74.   {0, 1},
  75.   {1, 1},
  76.   {1, 2 / 3.0},
  77.   {1 / 3.0, 2 / 3.0}
  78. };
  79. Point poly4[] =
  80. {
  81.   {1 / 3.0, 2 / 3.0},
  82.   {1, 2 / 3.0},
  83.   {1, 0}
  84. };
  85. Point poly5[] =
  86. {
  87.   {-1 / 3.0, 2 / 3.0},
  88.   {0, 1},
  89.   {0, -1.5},
  90.   {-1 / 3.0, -1.5}
  91. };
  92. Point poly6[] =
  93. {
  94.   {0, 1},
  95.   {1 / 3.0, 2 / 3.0},
  96.   {1 / 3.0, -1.5},
  97.   {0, -1.5}
  98. };
  99. Point poly7[] =
  100. {
  101.   {-1, 0},
  102.   {-1 / 3.0, 2 / 3.0},
  103.   {-1 / 3.0, -1.5},
  104.   {-1, -1.5}
  105. };
  106. Point poly8[] =
  107. {
  108.   {1, 0},
  109.   {1 / 3.0, 2 / 3.0},
  110.   {1 / 3.0, -1.5},
  111.   {1, -1.5}
  112. };
  113. void
  114. polydlist(int dlist, int num, Point points[])
  115. {
  116.   int i;
  117.   glNewList(dlist, GL_COMPILE);
  118.   glBegin(GL_POLYGON);
  119.   for (i = 0; i < num; i++) {
  120.     glVertex2fv(&points[i][0]);
  121.   }
  122.   glEnd();
  123.   glEndList();
  124. }
  125. void
  126. idle(void)
  127. {
  128.   if (spinning)
  129.     click++;
  130.   switch (state) {
  131.   case FLAT:
  132.     delay++;
  133.     if (delay >= 80) {
  134.       delay = 0;
  135.       state = FLAP1;
  136.       glutSetWindowTitle("origami (folding)");
  137.       direction = 1;
  138.     }
  139.     break;
  140.   case FLAP1:
  141.     flap1_angle += 2 * direction;
  142.     if (flap1_angle >= 180) {
  143.       state = FLAP2;
  144.     } else if (flap1_angle <= 0) {
  145.       state = FLAT;
  146.     }
  147.     break;
  148.   case FLAP2:
  149.     flap2_angle += 2 * direction;
  150.     if (flap2_angle >= 180) {
  151.       state = CENTER2;
  152.     } else if (flap2_angle <= 0) {
  153.       state = FLAP1;
  154.     }
  155.     break;
  156.   case CENTER2:
  157.     center2_angle += 2 * direction;
  158.     if (center2_angle >= 84) {
  159.       state = WING2;
  160.     } else if (center2_angle <= 0) {
  161.       state = FLAP2;
  162.     }
  163.     break;
  164.   case WING2:
  165.     wing2_angle += 2 * direction;
  166.     if (wing2_angle >= 84) {
  167.       state = CENTER1;
  168.     } else if (wing2_angle <= 0) {
  169.       state = CENTER2;
  170.     }
  171.     break;
  172.   case CENTER1:
  173.     center1_angle += 2 * direction;
  174.     if (center1_angle >= 84) {
  175.       state = WING1;
  176.     } else if (center1_angle <= 0) {
  177.       state = WING2;
  178.     }
  179.     break;
  180.   case WING1:
  181.     wing1_angle += 2 * direction;
  182.     if (wing1_angle >= 84) {
  183.       state = FOLDED;
  184.     } else if (wing1_angle <= 0) {
  185.       state = CENTER1;
  186.     }
  187.     break;
  188.   case FOLDED:
  189.     delay++;
  190.     if (delay >= 80) {
  191.       delay = 0;
  192.       glutSetWindowTitle("origami (unfolding)");
  193.       direction = -1;
  194.       state = WING1;
  195.     }
  196.     break;
  197.   }
  198.   glutPostRedisplay();
  199. }
  200. void
  201. draw_folded_plane(void)
  202. {
  203.   /* *INDENT-OFF* */
  204.   glPushMatrix();
  205.     glRotatef(click, 0, 0, 1);
  206.     glRotatef(click / 5.0, 0, 1, 0);
  207.     glTranslatef(0, .25, 0);
  208.     glPushMatrix();
  209.       glRotatef(center1_angle, 0, 1, 0);
  210.       glPushMatrix();
  211.         glTranslatef(-.5, .5, 0);
  212.         glRotatef(flap1_angle, 1, 1, 0);
  213.         glTranslatef(.5, -.5, 0);
  214.         glCallList(2);
  215.       glPopMatrix();
  216.       glCallList(5);
  217.       glPushMatrix();
  218.         glTranslatef(-1 / 3.0, 0, 0);
  219.         glRotatef(-wing1_angle, 0, 1, 0);
  220.         glTranslatef(1 / 3.0, 0, 0);
  221.         glCallList(7);
  222.         glPushMatrix();
  223.           glTranslatef(-.5, .5, 0);
  224.           glRotatef(flap1_angle, 1, 1, 0);
  225.           glTranslatef(.5, -.5, 0);
  226.           glCallList(1);
  227.         glPopMatrix();
  228.       glPopMatrix();
  229.     glPopMatrix();
  230.     glPushMatrix();
  231.       glRotatef(-center2_angle, 0, 1, 0);
  232.       glPushMatrix();
  233.         glTranslatef(.5, .5, 0);
  234.         glRotatef(-flap2_angle, -1, 1, 0);
  235.         glTranslatef(-.5, -.5, 0);
  236.         glCallList(3);
  237.       glPopMatrix();
  238.       glCallList(6);
  239.       glPushMatrix();
  240.         glTranslatef(1 / 3.0, 0, 0);
  241.         glRotatef(wing2_angle, 0, 1, 0);
  242.         glTranslatef(-1 / 3.0, 0, 0);
  243.         glCallList(8);
  244.         glPushMatrix();
  245.           glTranslatef(.5, .5, 0);
  246.           glRotatef(-flap2_angle, -1, 1, 0);
  247.           glTranslatef(-.5, -.5, 0);
  248.           glCallList(4);
  249.         glPopMatrix();
  250.       glPopMatrix();
  251.     glPopMatrix();
  252.   glPopMatrix();
  253.   /* *INDENT-ON* */
  254. }
  255. void
  256. display(void)
  257. {
  258.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  259.   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  260.   glColor3ub(67, 205, 128);
  261. #if GL_EXT_polygon_offset
  262.   if (polygon_offset) {
  263.     glPolygonOffsetEXT(0.5, 0.0);
  264.     glEnable(GL_POLYGON_OFFSET_EXT);
  265.   }
  266. #endif
  267.   draw_folded_plane();
  268.   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  269.   glColor3ub(255, 255, 255);
  270. #if GL_EXT_polygon_offset
  271.   if (polygon_offset) {
  272.     glPolygonOffsetEXT(0.0, 0.0);
  273.     /* XXX a bug in the unpatched IRIX 5.3 OpenGL posts
  274.        GL_INVALID_ENUM when GL_POLYGON_OFFSET_EXT is disabled;
  275.        please ignore it. */
  276.     glDisable(GL_POLYGON_OFFSET_EXT);
  277.   } else {
  278.     glPushMatrix();
  279.     glTranslatef(0, 0, .05);
  280.   }
  281. #else
  282.   glPushMatrix();
  283.   glTranslatef(0, 0, .05);
  284. #endif
  285.   draw_folded_plane();
  286. #if GL_EXT_polygon_offset
  287.   if (!polygon_offset) {
  288.     glPopMatrix();
  289.   }
  290. #else
  291.   glPopMatrix();
  292. #endif
  293.   glutSwapBuffers();
  294. }
  295. void
  296. visible(int state)
  297. {
  298.   if (state == GLUT_VISIBLE) {
  299.     if (motion)
  300.       glutIdleFunc(idle);
  301.   } else {
  302.     glutIdleFunc(NULL);
  303.   }
  304. }
  305. void
  306. menu(int value)
  307. {
  308.   switch (value) {
  309.   case 1:
  310.     direction = -direction;
  311.     if (direction > 0) {
  312.       glutSetWindowTitle("origami (folding)");
  313.     } else {
  314.       glutSetWindowTitle("origami (unfolding)");
  315.     }
  316.     break;
  317.   case 2:
  318.     motion = 1 - motion;
  319.     if (motion) {
  320.       glutIdleFunc(idle);
  321.     } else {
  322.       glutIdleFunc(NULL);
  323.     }
  324.     break;
  325.   case 3:
  326.     spinning = 1 - spinning;
  327.     break;
  328.   case 666:
  329.     exit(0);
  330.   }
  331. }
  332. int
  333. main(int argc, char **argv)
  334. {
  335.   glutInit(&argc, argv);
  336.   glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  337.   glutCreateWindow("origami");
  338.   glutDisplayFunc(display);
  339.   glutVisibilityFunc(visible);
  340.   glClearColor(.488, .617, .75, 1.0);
  341.   glMatrixMode(GL_PROJECTION);
  342.   gluPerspective(40.0, 1.0, 0.1, 10.0);
  343.   glMatrixMode(GL_MODELVIEW);
  344.   gluLookAt(0, 0, 5.5,
  345.     0, 0, 0,
  346.     0, 1, 0);
  347.   glEnable(GL_DEPTH_TEST);
  348.   glDepthFunc(GL_LEQUAL);
  349.   glLineWidth(2.0);
  350.   polydlist(1, sizeof(poly1) / sizeof(Point), poly1);
  351.   polydlist(2, sizeof(poly2) / sizeof(Point), poly2);
  352.   polydlist(3, sizeof(poly3) / sizeof(Point), poly3);
  353.   polydlist(4, sizeof(poly4) / sizeof(Point), poly4);
  354.   polydlist(5, sizeof(poly5) / sizeof(Point), poly5);
  355.   polydlist(6, sizeof(poly6) / sizeof(Point), poly6);
  356.   polydlist(7, sizeof(poly7) / sizeof(Point), poly7);
  357.   polydlist(8, sizeof(poly8) / sizeof(Point), poly8);
  358.   glutCreateMenu(menu);
  359.   glutAddMenuEntry("Reverse direction", 1);
  360.   glutAddMenuEntry("Toggle motion", 2);
  361.   glutAddMenuEntry("Toggle spinning", 3);
  362.   glutAddMenuEntry("Quit", 666);
  363.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  364. #if GL_EXT_polygon_offset
  365.   polygon_offset = glutExtensionSupported("GL_EXT_polygon_offset");
  366. #endif
  367.   glutMainLoop();
  368.   return 0;             /* ANSI C requires main to return int. */
  369. }