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

GIS编程

开发平台:

Visual C++

  1. /* pony.c */
  2. /* 
  3.  * By Brian Paul,  written July 31, 1997  for Mark.
  4.  */
  5. #include <GL/glut.h>
  6. #include <assert.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <math.h>
  10. #include "readtex.h"
  11. /* Some <math.h> files do not define M_PI... */
  12. #ifndef M_PI
  13. #define M_PI 3.14159265358979323846
  14. #endif
  15. /************************ Pony-specific code *********************************/
  16. static float BodyDepth = 0.216;
  17. static GLfloat BodyVerts[][2] =
  18. {
  19.   {-0.993334, 0.344444},
  20.   {-0.72, 0.462964},
  21.   {-0.58, -0.411113},
  22.   {-0.406667, -0.692593},
  23.   {0.733334, -0.633334},
  24.   {0.846666, -0.225926},
  25.   {0.873335, -0.55926},
  26.   {0.879998, -0.988888},
  27.   {0.933332, -0.974074},
  28.   {0.953334, -0.537037},
  29.   {0.906667, -0.0777776},
  30.   {0.806666, 0.0333334},
  31.   {-0.26, 0.0111111},
  32.   {-0.406667, 0.27037},
  33.   {-0.54, 0.781481},
  34.   {-0.673333, 1.00371},
  35.   {-0.653332, 0.803704},
  36.   {-1.05333, 0.44815}
  37. };
  38. static float LegDepth = 0.144;
  39. static float FrontLegPos[3] =
  40. {-0.36, -0.324, 0.108};
  41. static GLfloat FrontLegVerts[][2] =
  42. {
  43.   {-0.23, -0.113481},
  44.   {-0.123333, -0.528296},
  45.   {-0.0926752, -0.728103},
  46.   {-0.0766667, -1.232},
  47.   {0.0233333, -1.232},
  48.   {0.0433332, -0.743111},
  49.   {0.0366667, -0.424593},
  50.   {0.0699998, -0.157926},
  51.   {0.116667, 0.049482},
  52.   {-0.0166667, 0.197629},
  53.   {-0.196667, 0.13837}
  54. };
  55. static float BackLegPos[3] =
  56. {0.684, -0.324, 0.108};
  57. static GLfloat BackLegVerts[][2] =
  58. {
  59.   {-0.24, -0.195556},
  60.   {-0.0933332, -0.41037},
  61.   {-0.04, -0.684445},
  62.   {-0.113333, -1.26222},
  63.   {0, -1.26222},
  64.   {0.1, -0.677037},
  65.   {0.213333, -0.121482},
  66.   {0.153333, 0.108148},
  67.   {-0.0533333, 0.211853},
  68.   {-0.26, 0.063702}
  69. };
  70. static float ManeDepth = 0.288;
  71. static GLfloat ManeVerts[][2] =
  72. {
  73.   {-0.512667, 0.578519},
  74.   {-0.419333, 0.267407},
  75.   {-0.299333, -0.00666719},
  76.   {-0.239333, -0.0140724},
  77.   {-0.226, 0.0896296},
  78.   {-0.319333, 0.422963},
  79.   {-0.532667, 0.741481}
  80. };
  81. static float EyePos[3] =
  82. {-0.702, 0.648, 0.1116};
  83. static float EyeSize = 0.025;
  84. /* Display lists */
  85. static GLuint Body = 0, FrontLeg = 0, BackLeg = 0, Mane = 0;
  86. /* Generate an extruded, capped part from a 2-D polyline. */
  87. static void 
  88. ExtrudePart(int n, GLfloat v[][2], float depth)
  89. {
  90.   static GLUtriangulatorObj *tobj = NULL;
  91.   int i;
  92.   float z0 = 0.5 * depth;
  93.   float z1 = -0.5 * depth;
  94.   GLdouble vertex[3];
  95.   if (tobj == NULL) {
  96.     tobj = gluNewTess();  /* create and initialize a GLU polygon * *
  97.                              tesselation object */
  98.     gluTessCallback(tobj, GLU_BEGIN, glBegin);
  99.     gluTessCallback(tobj, GLU_VERTEX, glVertex2fv);  /* semi-tricky */
  100.     gluTessCallback(tobj, GLU_END, glEnd);
  101.   }
  102.   /* +Z face */
  103.   glPushMatrix();
  104.   glTranslatef(0.0, 0.0, z0);
  105.   glNormal3f(0.0, 0.0, 1.0);
  106.   gluBeginPolygon(tobj);
  107.   for (i = 0; i < n; i++) {
  108.     vertex[0] = v[i][0];
  109.     vertex[1] = v[i][1];
  110.     vertex[2] = 0.0;
  111.     gluTessVertex(tobj, vertex, v[i]);
  112.   }
  113.   gluEndPolygon(tobj);
  114.   glPopMatrix();
  115.   /* -Z face */
  116.   glFrontFace(GL_CW);
  117.   glPushMatrix();
  118.   glTranslatef(0.0, 0.0, z1);
  119.   glNormal3f(0.0, 0.0, -1.0);
  120.   gluBeginPolygon(tobj);
  121.   for (i = 0; i < n; i++) {
  122.     vertex[0] = v[i][0];
  123.     vertex[1] = v[i][1];
  124.     vertex[2] = z1;
  125.     gluTessVertex(tobj, vertex, v[i]);
  126.   }
  127.   gluEndPolygon(tobj);
  128.   glPopMatrix();
  129.   glFrontFace(GL_CCW);
  130.   /* edge polygons */
  131.   glBegin(GL_TRIANGLE_STRIP);
  132.   for (i = 0; i <= n; i++) {
  133.     float x = v[i % n][0];
  134.     float y = v[i % n][1];
  135.     float dx = v[(i + 1) % n][0] - x;
  136.     float dy = v[(i + 1) % n][1] - y;
  137.     glVertex3f(x, y, z0);
  138.     glVertex3f(x, y, z1);
  139.     glNormal3f(dy, -dx, 0.0);
  140.   }
  141.   glEnd();
  142. }
  143. /* 
  144.  * Build the four display lists which make up the pony.
  145.  */
  146. static void 
  147. MakePony(void)
  148. {
  149.   static GLfloat blue[4] =
  150.   {0.1, 0.1, 1.0, 1.0};
  151.   static GLfloat black[4] =
  152.   {0.0, 0.0, 0.0, 1.0};
  153.   static GLfloat pink[4] =
  154.   {1.0, 0.5, 0.5, 1.0};
  155.   Body = glGenLists(1);
  156.   glNewList(Body, GL_COMPILE);
  157.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
  158.   ExtrudePart(sizeof(BodyVerts) / sizeof(GLfloat) / 2, BodyVerts, BodyDepth);
  159.   /* eyes */
  160.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, black);
  161.   glNormal3f(0.0, 0.0, 1.0);
  162.   glBegin(GL_POLYGON);
  163.   glVertex3f(EyePos[0] - EyeSize, EyePos[1] - EyeSize, EyePos[2]);
  164.   glVertex3f(EyePos[0] + EyeSize, EyePos[1] - EyeSize, EyePos[2]);
  165.   glVertex3f(EyePos[0] + EyeSize, EyePos[1] + EyeSize, EyePos[2]);
  166.   glVertex3f(EyePos[0] - EyeSize, EyePos[1] + EyeSize, EyePos[2]);
  167.   glEnd();
  168.   glNormal3f(0.0, 0.0, -1.0);
  169.   glBegin(GL_POLYGON);
  170.   glVertex3f(EyePos[0] - EyeSize, EyePos[1] + EyeSize, -EyePos[2]);
  171.   glVertex3f(EyePos[0] + EyeSize, EyePos[1] + EyeSize, -EyePos[2]);
  172.   glVertex3f(EyePos[0] + EyeSize, EyePos[1] - EyeSize, -EyePos[2]);
  173.   glVertex3f(EyePos[0] - EyeSize, EyePos[1] - EyeSize, -EyePos[2]);
  174.   glEnd();
  175.   glEndList();
  176.   Mane = glGenLists(1);
  177.   glNewList(Mane, GL_COMPILE);
  178.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, pink);
  179.   ExtrudePart(sizeof(ManeVerts) / sizeof(GLfloat) / 2, ManeVerts, ManeDepth);
  180.   glEndList();
  181.   FrontLeg = glGenLists(1);
  182.   glNewList(FrontLeg, GL_COMPILE);
  183.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
  184.   ExtrudePart(sizeof(FrontLegVerts) / sizeof(GLfloat) / 2,
  185.     FrontLegVerts, LegDepth);
  186.   glEndList();
  187.   BackLeg = glGenLists(1);
  188.   glNewList(BackLeg, GL_COMPILE);
  189.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
  190.   ExtrudePart(sizeof(BackLegVerts) / sizeof(GLfloat) / 2,
  191.     BackLegVerts, LegDepth);
  192.   glEndList();
  193. }
  194. /* 
  195.  * Draw the pony.  legAngle should be in [-15,15] or so.
  196.  * The pony display lists will be constructed the first time this is called.
  197.  */
  198. static void 
  199. DrawPony(float legAngle)
  200. {
  201.   if (!Body) {
  202.     MakePony();
  203.   }
  204.   assert(Body);
  205.   /* BODY */
  206.   glCallList(Body);
  207.   /* MANE */
  208.   glCallList(Mane);
  209.   /* FRONT +Z LEG */
  210.   glPushMatrix();
  211.   glTranslatef(FrontLegPos[0], FrontLegPos[1], FrontLegPos[2]);
  212.   glRotatef(legAngle, 0.0, 0.0, 1.0);
  213.   glCallList(FrontLeg);
  214.   glPopMatrix();
  215.   /* FRONT -Z LEG */
  216.   glPushMatrix();
  217.   glTranslatef(FrontLegPos[0], FrontLegPos[1], -FrontLegPos[2]);
  218.   glRotatef(-legAngle, 0.0, 0.0, 1.0);
  219.   glCallList(FrontLeg);
  220.   glPopMatrix();
  221.   /* BACK +Z LEG */
  222.   glPushMatrix();
  223.   glTranslatef(BackLegPos[0], BackLegPos[1], BackLegPos[2]);
  224.   glRotatef(-legAngle, 0.0, 0.0, 1.0);
  225.   glCallList(BackLeg);
  226.   glPopMatrix();
  227.   /* BACK -Z LEG */
  228.   glPushMatrix();
  229.   glTranslatef(BackLegPos[0], BackLegPos[1], -BackLegPos[2]);
  230.   glRotatef(legAngle, 0.0, 0.0, 1.0);
  231.   glCallList(BackLeg);
  232.   glPopMatrix();
  233. }
  234. /************************* end of pony code **********************************/
  235. static float Speed = 2.0;
  236. static float LegAngleStep = 0.75;
  237. static float LegMaxAngle = 15.0;
  238. static float LegAngle = 0.0, LegDeltaAngle = 0.5;
  239. static float WalkAngle = -90.0, DeltaWalkAngle = 0.225;
  240. static float WalkRadius = 4.0;
  241. static float Xrot = 0, Yrot = 30.0;
  242. static GLboolean AnimFlag = GL_TRUE;
  243. static void 
  244. Idle(void)
  245. {
  246.     /* update animation vars */
  247.     LegAngle += LegDeltaAngle * Speed;
  248.     if (LegAngle > LegMaxAngle) {
  249.       LegDeltaAngle = -LegAngleStep;
  250.     } else if (LegAngle < -LegMaxAngle) {
  251.       LegDeltaAngle = LegAngleStep;
  252.     }
  253.     WalkAngle += DeltaWalkAngle * Speed;
  254.     glutPostRedisplay();
  255. }
  256. static void 
  257. DrawGround(void)
  258. {
  259.   static GLuint ground = 0;
  260.   if (ground == 0) {
  261.     const int rows = 20, columns = 20;
  262.     float sizeA = 1.25, sizeB = 0.2;
  263.     float x, z;
  264.     int i, j;
  265.     GLfloat mat[2][4] =
  266.     {
  267.       {0.0, 0.6, 0.0, 1.0},
  268.       {0.1, 0.8, 0.1, 1.0}
  269.     };
  270.     ground = glGenLists(1);
  271.     glNewList(ground, GL_COMPILE);
  272.     glNormal3f(0.0, 1.0, 0.0);
  273.     x = -(columns * (sizeA + sizeB)) / 4;
  274.     for (i = 0; i <= rows; i++) {
  275.       float size = (i & 1) ? sizeA : sizeB;
  276.       z = -(rows * (sizeA + sizeB)) / 4;
  277.       glBegin(GL_QUAD_STRIP);
  278.       for (j = 0; j <= columns; j++) {
  279.         /* glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat[(i+j)%2]); */
  280.         glColor4fv(mat[(i + j) % 2]);
  281.         glVertex3f(x + size, 0.0, z);
  282.         glVertex3f(x, 0.0, z);
  283.         if (j & 1)
  284.           z += sizeA;
  285.         else
  286.           z += sizeB;
  287.       }
  288.       glEnd();
  289.       x += size;
  290.     }
  291.     glEndList();
  292.   }
  293.   glCallList(ground);
  294. }
  295. static void 
  296. DrawLogo(void)
  297. {
  298.   glEnable(GL_TEXTURE_2D);
  299.   glShadeModel(GL_SMOOTH);
  300.   glBegin(GL_POLYGON);
  301.   glColor3f(1, 0, 0);
  302.   glTexCoord2f(0, 0);
  303.   glVertex2f(-1.0, -0.5);
  304.   glColor3f(0, 1, 0);
  305.   glTexCoord2f(1, 0);
  306.   glVertex2f(1.0, -0.5);
  307.   glColor3f(0, 0, 1);
  308.   glTexCoord2f(1, 1);
  309.   glVertex2f(1.0, 0.5);
  310.   glColor3f(1, 1, 0);
  311.   glTexCoord2f(0, 1);
  312.   glVertex2f(-1.0, 0.5);
  313.   glEnd();
  314.   glDisable(GL_TEXTURE_2D);
  315.   glShadeModel(GL_FLAT);
  316. }
  317. static void 
  318. Display(void)
  319. {
  320.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  321.   /* viewing */
  322.   glPushMatrix();
  323.   glRotatef(Xrot, 1.0, 0.0, 0.0);
  324.   glRotatef(Yrot, 0.0, 1.0, 0.0);
  325.   /* ground */
  326.   glDisable(GL_LIGHTING);
  327.   glPushMatrix();
  328.   glTranslatef(0.0, -1.6, 0.0);
  329.   DrawGround();
  330.   glPopMatrix();
  331.   /* logo */
  332.   glPushMatrix();
  333.   glScalef(2.5, 2.5, 2.5);
  334.   DrawLogo();
  335.   glPopMatrix();
  336.   /* pony */
  337.   {
  338.     float xPos, zPos;
  339.     xPos = WalkRadius * cos(WalkAngle * M_PI / 180.0);
  340.     zPos = WalkRadius * sin(WalkAngle * M_PI / 180.0);
  341.     glEnable(GL_LIGHTING);
  342.     glPushMatrix();
  343.     glTranslatef(xPos, 0.0, zPos);
  344.     glRotatef(-WalkAngle + 90.0, 0.0, 1.0, 0.0);
  345.     DrawPony(LegAngle);
  346.     glPopMatrix();
  347.   }
  348.   glPopMatrix();
  349.   glutSwapBuffers();
  350. }
  351. static void 
  352. Reshape(int width, int height)
  353. {
  354.   float ar;
  355.   glViewport(0, 0, width, height);
  356.   glMatrixMode(GL_PROJECTION);
  357.   glLoadIdentity();
  358.   ar = (float) width / (float) height;
  359.   glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
  360.   glMatrixMode(GL_MODELVIEW);
  361.   glLoadIdentity();
  362.   glTranslatef(0.0, 0.0, -23.0 / 2.5);
  363. }
  364. /* ARGSUSED1 */
  365. static void 
  366. Key(unsigned char key, int x, int y)
  367. {
  368.   switch (key) {
  369.   case 27:
  370.     exit(0);
  371.     break;
  372.   case ' ':
  373.     AnimFlag = !AnimFlag;
  374.     if (AnimFlag) {
  375.       glutIdleFunc(Idle);
  376.     } else {
  377.       glutIdleFunc(NULL);
  378.     }
  379.     break;
  380.   }
  381.   glutPostRedisplay();
  382. }
  383. /* ARGSUSED1 */
  384. static void 
  385. SpecialKey(int key, int x, int y)
  386. {
  387.   float step = 2.0;
  388.   switch (key) {
  389.   case GLUT_KEY_UP:
  390.     Xrot += step;
  391.     break;
  392.   case GLUT_KEY_DOWN:
  393.     Xrot -= step;
  394.     break;
  395.   case GLUT_KEY_LEFT:
  396.     Yrot -= step;
  397.     break;
  398.   case GLUT_KEY_RIGHT:
  399.     Yrot += step;
  400.     break;
  401.   }
  402.   glutPostRedisplay();
  403. }
  404. static void 
  405. Init(void)
  406. {
  407.   GLfloat lightPos[4] =
  408.   {1.0, 10.0, 10.0, 0.0};
  409.   glClearColor(0.5, 0.8, 0.99, 1.0);
  410.   glEnable(GL_DEPTH_TEST);
  411.   glEnable(GL_NORMALIZE);
  412.   glEnable(GL_LIGHTING);
  413.   glEnable(GL_LIGHT0);
  414.   glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
  415.   glShadeModel(GL_FLAT);
  416.   LoadRGBMipmaps("logo.bw", 1);
  417. }
  418. static void
  419. vis(int visible)
  420. {
  421.   if (visible == GLUT_VISIBLE) {
  422.     if (AnimFlag)
  423.       glutIdleFunc(Idle);
  424.   } else {
  425.     if (AnimFlag)
  426.       glutIdleFunc(NULL);
  427.   }
  428. }
  429. int 
  430. main(int argc, char *argv[])
  431. {
  432.   glutInit(&argc, argv);
  433.   glutInitWindowSize(640, 480);
  434.   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  435.   glutCreateWindow("Blue Pony");
  436.   Init();
  437.   glutReshapeFunc(Reshape);
  438.   glutKeyboardFunc(Key);
  439.   glutSpecialFunc(SpecialKey);
  440.   glutDisplayFunc(Display);
  441.   glutVisibilityFunc(vis);
  442.   glutMainLoop();
  443.   return 0;             /* ANSI C requires main to return int. */
  444. }