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

GIS编程

开发平台:

Visual C++

  1. /* Copyright (c) Mark J. Kilgard, 1994, 1997.  */
  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 <math.h>       /* for sqrt() */
  7. #include <GL/glut.h>
  8. #include "dino.h"
  9. typedef enum {
  10.   RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE,
  11.   LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE, DINOSAUR
  12. } displayLists;
  13. /* *INDENT-OFF* */
  14. static GLfloat body[][2] = { {0, 3}, {1, 1}, {5, 1}, {8, 4}, {10, 4}, {11, 5},
  15.   {11, 11.5}, {13, 12}, {13, 13}, {10, 13.5}, {13, 14}, {13, 15}, {11, 16},
  16.   {8, 16}, {7, 15}, {7, 13}, {8, 12}, {7, 11}, {6, 6}, {4, 3}, {3, 2},
  17.   {1, 2} };
  18. static GLfloat arm[][2] = { {8, 10}, {9, 9}, {10, 9}, {13, 8}, {14, 9}, {16, 9},
  19.   {15, 9.5}, {16, 10}, {15, 10}, {15.5, 11}, {14.5, 10}, {14, 11}, {14, 10},
  20.   {13, 9}, {11, 11}, {9, 11} };
  21. static GLfloat leg[][2] = { {8, 6}, {8, 4}, {9, 3}, {9, 2}, {8, 1}, {8, 0.5}, {9, 0},
  22.   {12, 0}, {10, 1}, {10, 2}, {12, 4}, {11, 6}, {10, 7}, {9, 7} };
  23. static GLfloat eye[][2] = { {8.75, 15}, {9, 14.7}, {9.6, 14.7}, {10.1, 15},
  24.   {9.6, 15.25}, {9, 15.25} };
  25. static GLfloat skinColor[] = {0.1, 1.0, 0.1, 1.0}, eyeColor[] = {1.0, 0.2, 0.2, 1.0};
  26. /* *INDENT-ON* */
  27. static void
  28. extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize,
  29.   GLdouble thickness, GLuint side, GLuint edge, GLuint whole)
  30. {
  31.   static GLUtriangulatorObj *tobj = NULL;
  32.   GLdouble vertex[3], dx, dy, len;
  33.   int i;
  34.   int count = (int) (dataSize / (2 * sizeof(GLfloat)));
  35.   if (tobj == NULL) {
  36.     tobj = gluNewTess();  /* create and initialize a GLU
  37.                              polygon tesselation object */
  38.     gluTessCallback(tobj, GLU_BEGIN, glBegin);
  39.     gluTessCallback(tobj, GLU_VERTEX, glVertex2fv);  /* semi-tricky */
  40.     gluTessCallback(tobj, GLU_END, glEnd);
  41.   }
  42.   glNewList(side, GL_COMPILE);
  43.   glShadeModel(GL_SMOOTH);  /* smooth minimizes seeing
  44.                                tessellation */
  45.   gluBeginPolygon(tobj);
  46.   for (i = 0; i < count; i++) {
  47.     vertex[0] = data[i][0];
  48.     vertex[1] = data[i][1];
  49.     vertex[2] = 0;
  50.     gluTessVertex(tobj, vertex, data[i]);
  51.   }
  52.   gluEndPolygon(tobj);
  53.   glEndList();
  54.   glNewList(edge, GL_COMPILE);
  55.   glShadeModel(GL_FLAT);  /* flat shade keeps angular hands
  56.                              from being "smoothed" */
  57.   glBegin(GL_QUAD_STRIP);
  58.   for (i = 0; i <= count; i++) {
  59.     /* mod function handles closing the edge */
  60.     glVertex3f(data[i % count][0], data[i % count][1], 0.0);
  61.     glVertex3f(data[i % count][0], data[i % count][1], thickness);
  62.     /* Calculate a unit normal by dividing by Euclidean
  63.        distance. We * could be lazy and use
  64.        glEnable(GL_NORMALIZE) so we could pass in * arbitrary
  65.        normals for a very slight performance hit. */
  66.     dx = data[(i + 1) % count][1] - data[i % count][1];
  67.     dy = data[i % count][0] - data[(i + 1) % count][0];
  68.     len = sqrt(dx * dx + dy * dy);
  69.     glNormal3f(dx / len, dy / len, 0.0);
  70.   }
  71.   glEnd();
  72.   glEndList();
  73.   glNewList(whole, GL_COMPILE);
  74.   glFrontFace(GL_CW);
  75.   glCallList(edge);
  76.   glNormal3f(0.0, 0.0, -1.0);  /* constant normal for side */
  77.   glCallList(side);
  78.   glPushMatrix();
  79.   glTranslatef(0.0, 0.0, thickness);
  80.   glFrontFace(GL_CCW);
  81.   glNormal3f(0.0, 0.0, 1.0);  /* opposite normal for other side */
  82.   glCallList(side);
  83.   glPopMatrix();
  84.   glEndList();
  85. }
  86. int
  87. makeDinosaur(void)
  88. {
  89.   GLfloat bodyWidth = 3.0;
  90.   extrudeSolidFromPolygon(body, sizeof(body), bodyWidth,
  91.     BODY_SIDE, BODY_EDGE, BODY_WHOLE);
  92.   extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4,
  93.     ARM_SIDE, ARM_EDGE, ARM_WHOLE);
  94.   extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2,
  95.     LEG_SIDE, LEG_EDGE, LEG_WHOLE);
  96.   extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2,
  97.     EYE_SIDE, EYE_EDGE, EYE_WHOLE);
  98.   glNewList(DINOSAUR, GL_COMPILE);
  99.   glPushMatrix();
  100.   glTranslatef(-8, -8, -bodyWidth / 2);
  101.   glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor);
  102.   glCallList(BODY_WHOLE);
  103.   glPushMatrix();
  104.   glTranslatef(0.0, 0.0, bodyWidth);
  105.   glCallList(ARM_WHOLE);
  106.   glCallList(LEG_WHOLE);
  107.   glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4);
  108.   glCallList(ARM_WHOLE);
  109.   glTranslatef(0.0, 0.0, -bodyWidth / 4);
  110.   glCallList(LEG_WHOLE);
  111.   glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1);
  112.   glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor);
  113.   glCallList(EYE_WHOLE);
  114.   glPopMatrix();
  115.   glPopMatrix();
  116.   glEndList();
  117.   return DINOSAUR;
  118. }