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

GIS编程

开发平台:

Visual C++

  1. /* Copyright (c) Mark J. Kilgard, 1996. */
  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. #define MAX_SPHERES 50
  9. typedef struct {
  10.   GLfloat x, y, z;
  11.   int detail;
  12.   int material;
  13. } SphereInfo;
  14. /* *INDENT-OFF* */
  15. GLfloat lightPos[4] = {2.0, 4.0, 2.0, 1.0};
  16. GLfloat lightDir[4] = {-2.0, -4.0, -2.0, 1.0};
  17. GLfloat lightAmb[4] = {0.2, 0.2, 0.2, 1.0};
  18. GLfloat lightDiff[4] = {0.8, 0.8, 0.8, 1.0};
  19. GLfloat lightSpec[4] = {0.4, 0.4, 0.4, 1.0};
  20. GLfloat matColor[3][4] = {
  21.   {0.5, 0.0, 0.0, 1.0},
  22.   {0.0, 0.5, 0.0, 1.0},
  23.   {0.0, 0.0, 0.5, 1.0},
  24. };
  25. /* *INDENT-ON* */
  26. GLdouble modelMatrix[16], projMatrix[16];
  27. GLint viewport[4];
  28. int width, height;
  29. int opaque, transparent;
  30. SphereInfo sphereInfo[MAX_SPHERES];
  31. int spheres = 0;
  32. SphereInfo overlaySphere, oldOverlaySphere;
  33. void
  34. drawSphere(SphereInfo * sphere)
  35. {
  36.   glPushMatrix();
  37.   glTranslatef(sphere->x, sphere->y, sphere->z);
  38.   glMaterialfv(GL_FRONT_AND_BACK,
  39.     GL_AMBIENT_AND_DIFFUSE, matColor[sphere->material]);
  40.   glutSolidSphere(1.0, sphere->detail, sphere->detail);
  41.   glPopMatrix();
  42. }
  43. void
  44. display(void)
  45. {
  46.   int i;
  47.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  48.   for (i = 0; i < spheres; i++) {
  49.     drawSphere(&sphereInfo[i]);
  50.   }
  51.   glutSwapBuffers();
  52. }
  53. void
  54. overlayDisplay(void)
  55. {
  56.   if (glutLayerGet(GLUT_OVERLAY_DAMAGED)) {
  57.     /* If damaged, clear the overlay. */
  58.     glClear(GL_COLOR_BUFFER_BIT);
  59.   } else {
  60.     /* If not damaged, undraw last overlay sphere. */
  61.     glIndexi(transparent);
  62.     drawSphere(&oldOverlaySphere);
  63.   }
  64.   glIndexi(opaque);
  65.   drawSphere(&overlaySphere);
  66.   /* Single buffered window needs flush. */
  67.   glFlush();
  68.   /* Remember last overaly sphere position for undrawing. */
  69.   oldOverlaySphere = overlaySphere;
  70. }
  71. void
  72. reshape(int w, int h)
  73. {
  74.   width = w;
  75.   height = h;
  76.   /* Reshape both layers. */
  77.   glutUseLayer(GLUT_OVERLAY);
  78.   glViewport(0, 0, w, h);
  79.   glutUseLayer(GLUT_NORMAL);
  80.   glViewport(0, 0, w, h);
  81.   /* Read back viewport for gluUnProject. */
  82.   glGetIntegerv(GL_VIEWPORT, viewport);
  83. }
  84. void
  85. mouse(int button, int state, int x, int y)
  86. {
  87.   GLdouble objx, objy, objz;
  88.   gluUnProject(x, height - y, 0.95,
  89.     modelMatrix, projMatrix, viewport,
  90.     &objx, &objy, &objz);
  91.   overlaySphere.x = objx;
  92.   overlaySphere.y = objy;
  93.   overlaySphere.z = objz;
  94.   overlaySphere.material = button;
  95.   glutUseLayer(GLUT_OVERLAY);
  96.   glutSetColor(opaque,
  97.     2 * matColor[button][0],  /* Red. */
  98.     2 * matColor[button][1],  /* Green. */
  99.     2 * matColor[button][2]);  /* Blue. */
  100.   if (state == GLUT_UP) {
  101.     glutHideOverlay();
  102.     if (spheres < MAX_SPHERES) {
  103.       sphereInfo[spheres] = overlaySphere;
  104.       sphereInfo[spheres].detail = 25;  /* Fine tesselation. */
  105.       spheres++;
  106.     } else {
  107.       printf("oversphere: Out of spheres.n");
  108.     }
  109.     glutPostRedisplay();
  110.   } else {
  111.     overlaySphere.detail = 10;  /* Coarse tesselation. */
  112.     glutShowOverlay();
  113.     glutPostOverlayRedisplay();
  114.   }
  115. }
  116. void
  117. motion(int x, int y)
  118. {
  119.   GLdouble objx, objy, objz;
  120.   gluUnProject(x, height - y, 0.95,
  121.     modelMatrix, projMatrix, viewport,
  122.     &objx, &objy, &objz);
  123.   overlaySphere.x = objx;
  124.   overlaySphere.y = objy;
  125.   overlaySphere.z = objz;
  126.   glutPostOverlayRedisplay();
  127. }
  128. void
  129. setupMatrices(void)
  130. {
  131.   glMatrixMode(GL_PROJECTION);
  132.   gluPerspective( /* degrees field of view */ 50.0,
  133.     /* aspect ratio */ 1.0, /* Z near */ 1.0, /* Z far */ 10.0);
  134.   glMatrixMode(GL_MODELVIEW);
  135.   gluLookAt(
  136.     0.0, 0.0, 5.0,      /* eye is at (0,0,5) */
  137.     0.0, 0.0, 0.0,      /* center is at (0,0,0) */
  138.     0.0, 1.0, 0.);      /* up is in positive Y direction */
  139. }
  140. int
  141. main(int argc, char **argv)
  142. {
  143.   glutInitWindowSize(350, 350);
  144.   glutInit(&argc, argv);
  145.   glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  146.   glutCreateWindow("Overlay Sphere Positioning Demo");
  147.   glutDisplayFunc(display);
  148.   glutReshapeFunc(reshape);
  149.   glutMouseFunc(mouse);
  150.   glutMotionFunc(motion);
  151.   glEnable(GL_DEPTH_TEST);
  152.   glEnable(GL_CULL_FACE);  /* Solid spheres benefit greatly
  153.                               from back face culling. */
  154.   setupMatrices();
  155.   /* Read back matrices for use by gluUnProject. */
  156.   glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
  157.   glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
  158.   /* Set up lighting. */
  159.   glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
  160.   glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
  161.   glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
  162.   glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);
  163.   glEnable(GL_LIGHT0);
  164.   glEnable(GL_LIGHTING);
  165.   glutInitDisplayMode(GLUT_INDEX | GLUT_SINGLE);
  166.   if (glutLayerGet(GLUT_OVERLAY_POSSIBLE) == 0) {
  167.     printf("oversphere: no overlays supported; aborting.n");
  168.     exit(1);
  169.   }
  170.   glutEstablishOverlay();
  171.   glutHideOverlay();
  172.   glutOverlayDisplayFunc(overlayDisplay);
  173.   /* Find transparent and opaque index. */
  174.   transparent = glutLayerGet(GLUT_TRANSPARENT_INDEX);
  175.   opaque = (transparent + 1)
  176.     % glutGet(GLUT_WINDOW_COLORMAP_SIZE);
  177.   /* Draw overlay sphere as an outline. */
  178.   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  179.   /* Make sure overlay clears to transparent. */
  180.   glClearIndex(transparent);
  181.   /* Set up overlay matrices same as normal plane. */
  182.   setupMatrices();
  183.   glutMainLoop();
  184.   return 0;
  185. }