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

GIS编程

开发平台:

Visual C++

  1. /* silhouette.c - by Tom McReynolds, SGI */
  2. /* Doing Silhouette Edges with stencil */
  3. #include <GL/glut.h>
  4. #include <stdlib.h>
  5. #include <math.h>
  6. enum {
  7.   CONE = 1
  8. };
  9. /* Draw a cone */
  10. void
  11. cone(void)
  12. {
  13.   glPushMatrix();
  14.   glTranslatef(0.f, 0.f, -30.f);
  15.   glCallList(CONE);
  16.   glPopMatrix();
  17. }
  18. /* Draw a torus */
  19. void
  20. torus(void)
  21. {
  22.   glutSolidTorus(10., 20., 20, 20);
  23. }
  24. enum {
  25.   SIL, OBJ, SIL_AND_OBJ, TOGGLE
  26. };
  27. int rendermode = OBJ;
  28. void (*curobj) (void) = cone;
  29. void 
  30. menu(int mode)
  31. {
  32.   switch (mode) {
  33.   case SIL:
  34.   case OBJ:
  35.   case SIL_AND_OBJ:
  36.     rendermode = mode;
  37.     break;
  38.   case TOGGLE:
  39.     if (curobj == cone)
  40.       curobj = torus;
  41.     else
  42.       curobj = cone;
  43.     break;
  44.   }
  45.   glutPostRedisplay();
  46. }
  47. int winWidth = 512;
  48. int winHeight = 512;
  49. /* used to get current width and height of viewport */
  50. void
  51. reshape(int wid, int ht)
  52. {
  53.   glViewport(0, 0, wid, ht);
  54.   winWidth = wid;
  55.   winHeight = ht;
  56.   glutPostRedisplay();
  57. }
  58. GLfloat viewangle;
  59. void
  60. drawsilhouette(void)
  61. {
  62.   int i;
  63.   glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  64.   glEnable(GL_STENCIL_TEST);
  65.   glStencilFunc(GL_ALWAYS, 1, 1);
  66.   glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
  67.   glDisable(GL_DEPTH_TEST);  /* so the depth buffer doesn't change */
  68.   for (i = -1; i < 2; i += 2) {  /* set stencil around object */
  69.     glViewport(i, 0, winWidth + i, winHeight);
  70.     curobj();
  71.   }
  72.   for (i = -1; i < 2; i += 2) {
  73.     glViewport(0, i, winWidth, winHeight + i);
  74.     curobj();
  75.   }
  76.   /* cut out stencil where object is */
  77.   glViewport(0, 0, winWidth, winHeight);
  78.   glStencilFunc(GL_ALWAYS, 0, 0);
  79.   curobj();
  80.   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  81.   glStencilFunc(GL_EQUAL, 1, 1);
  82.   glDisable(GL_LIGHTING);
  83.   glColor3f(1.f, 0.f, 0.f);  /* draw silhouette red */
  84.   glRotatef(-viewangle, 0.f, 1.f, 0.f);
  85.   glRecti(-50, -50, 50, 50);
  86.   glRotatef(viewangle, 0.f, 1.f, 0.f);
  87.   glEnable(GL_DEPTH_TEST);
  88.   glEnable(GL_LIGHTING);
  89.   glDisable(GL_STENCIL_TEST);
  90. }
  91. void
  92. redraw(void)
  93. {
  94.   /* clear stencil each time */
  95.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  96.   glPushMatrix();
  97.   glRotatef(viewangle, 0.f, 1.f, 0.f);
  98.   switch (rendermode) {
  99.   case SIL:
  100.     drawsilhouette();
  101.     break;
  102.   case SIL_AND_OBJ:
  103.     drawsilhouette();
  104.     curobj();
  105.     break;
  106.   case OBJ:
  107.     curobj();
  108.     break;
  109.   }
  110.   glPopMatrix();
  111.   glutSwapBuffers();
  112. }
  113. /* animate scene by rotating */
  114. enum {
  115.   ANIM_LEFT, ANIM_RIGHT
  116. };
  117. int animDirection = ANIM_LEFT;
  118. void 
  119. anim(void)
  120. {
  121.   if (animDirection == ANIM_LEFT)
  122.     viewangle -= 1.f;
  123.   else
  124.     viewangle += 1.f;
  125.   glutPostRedisplay();
  126. }
  127. /* ARGSUSED1 */
  128. /* special keys, like array and F keys */
  129. void 
  130. special(int key, int x, int y)
  131. {
  132.   switch (key) {
  133.   case GLUT_KEY_LEFT:
  134.     glutIdleFunc(anim);
  135.     animDirection = ANIM_LEFT;
  136.     break;
  137.   case GLUT_KEY_RIGHT:
  138.     glutIdleFunc(anim);
  139.     animDirection = ANIM_RIGHT;
  140.     break;
  141.   case GLUT_KEY_UP:
  142.   case GLUT_KEY_DOWN:
  143.     glutIdleFunc(0);
  144.     break;
  145.   }
  146. }
  147. /* ARGSUSED1 */
  148. void 
  149. key(unsigned char key, int x, int y)
  150. {
  151.   switch (key) {
  152.   case 'a':
  153.     viewangle -= 10.f;
  154.     glutPostRedisplay();
  155.     break;
  156.   case 's':
  157.     viewangle += 10.f;
  158.     glutPostRedisplay();
  159.     break;
  160.   case '33':
  161.     exit(0);
  162.   }
  163. }
  164. int picked_object;
  165. int xpos = 0, ypos = 0;
  166. int newxpos, newypos;
  167. int startx, starty;
  168. int
  169. main(int argc, char **argv)
  170. {
  171.   static GLfloat lightpos[] =
  172.   {25.f, 50.f, -50.f, 1.f};
  173.   static GLfloat cone_mat[] =
  174.   {0.f, .5f, 1.f, 1.f};
  175.   GLUquadricObj *cone, *base;
  176.   glutInit(&argc, argv);
  177.   glutInitWindowSize(512, 512);
  178.   glutInitDisplayMode(GLUT_STENCIL | GLUT_DEPTH | GLUT_DOUBLE);
  179.   (void) glutCreateWindow("silhouette edges");
  180.   glutDisplayFunc(redraw);
  181.   glutKeyboardFunc(key);
  182.   glutSpecialFunc(special);
  183.   glutReshapeFunc(reshape);
  184.   glutCreateMenu(menu);
  185.   glutAddMenuEntry("Object", OBJ);
  186.   glutAddMenuEntry("Silhouette Only", SIL);
  187.   glutAddMenuEntry("Object and Silhouette", SIL_AND_OBJ);
  188.   glutAddMenuEntry("Toggle Object", TOGGLE);
  189.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  190.   glEnable(GL_DEPTH_TEST);
  191.   glEnable(GL_CULL_FACE);
  192.   glEnable(GL_LIGHTING);
  193.   glEnable(GL_LIGHT0);
  194.   glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  195.   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  196.   /* make display list for cone; for efficiency */
  197.   glNewList(CONE, GL_COMPILE);
  198.   cone = gluNewQuadric();
  199.   base = gluNewQuadric();
  200.   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, cone_mat);
  201.   gluQuadricOrientation(base, GLU_INSIDE);
  202.   gluDisk(base, 0., 15., 32, 1);
  203.   gluCylinder(cone, 15., 0., 60., 32, 32);
  204.   gluDeleteQuadric(cone);
  205.   gluDeleteQuadric(base);
  206.   glEndList();
  207.   glMatrixMode(GL_PROJECTION);
  208.   glOrtho(-50., 50., -50., 50., -50., 50.);
  209.   glMatrixMode(GL_MODELVIEW);
  210.   glutMainLoop();
  211.   return 0;             /* ANSI C requires main to return int. */
  212. }