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

GIS编程

开发平台:

Visual C++

  1. /* Copyright (c) Mark J. Kilgard, 1994. */
  2. /**
  3.  * (c) Copyright 1993, Silicon Graphics, Inc.
  4.  * ALL RIGHTS RESERVED 
  5.  * Permission to use, copy, modify, and distribute this software for 
  6.  * any purpose and without fee is hereby granted, provided that the above
  7.  * copyright notice appear in all copies and that both the copyright notice
  8.  * and this permission notice appear in supporting documentation, and that 
  9.  * the name of Silicon Graphics, Inc. not be used in advertising
  10.  * or publicity pertaining to distribution of the software without specific,
  11.  * written prior permission. 
  12.  *
  13.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  14.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  15.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  16.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  17.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  18.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  19.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  20.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  21.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  22.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  23.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  24.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  25.  * 
  26.  * US Government Users Restricted Rights 
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  29.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  30.  * clause at DFARS 252.227-7013 and/or in similar or successor
  31.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  32.  * Unpublished-- rights reserved under the copyright laws of the
  33.  * United States.  Contractor/manufacturer is Silicon Graphics,
  34.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  35.  *
  36.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  37.  */
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <math.h>
  41. #include <string.h>
  42. #include <time.h>
  43. #include <GL/glut.h>
  44. #define MAXOBJS 10000
  45. #define MAXSELECT 100
  46. #define MAXFEED 300
  47. #define SOLID 1
  48. #define LINE 2
  49. #define POINT 3
  50. GLint windW = 300, windH = 300;
  51. GLuint selectBuf[MAXSELECT];
  52. GLfloat feedBuf[MAXFEED];
  53. GLint vp[4];
  54. float zRotation = 90.0;
  55. float zoom = 1.0;
  56. GLint objectCount;
  57. GLint numObjects;
  58. struct object {
  59.   float v1[2];
  60.   float v2[2];
  61.   float v3[2];
  62.   float color[3];
  63. } objects[MAXOBJS];
  64. GLenum linePoly = GL_FALSE;
  65. static void
  66. InitObjects(GLint num)
  67. {
  68.   GLint i;
  69.   float x, y;
  70.   if (num > MAXOBJS) {
  71.     num = MAXOBJS;
  72.   }
  73.   if (num < 1) {
  74.     num = 1;
  75.   }
  76.   objectCount = num;
  77.   srand((unsigned int) time(NULL));
  78.   for (i = 0; i < num; i++) {
  79.     x = (rand() % 300) - 150;
  80.     y = (rand() % 300) - 150;
  81.     objects[i].v1[0] = x + (rand() % 50) - 25;
  82.     objects[i].v2[0] = x + (rand() % 50) - 25;
  83.     objects[i].v3[0] = x + (rand() % 50) - 25;
  84.     objects[i].v1[1] = y + (rand() % 50) - 25;
  85.     objects[i].v2[1] = y + (rand() % 50) - 25;
  86.     objects[i].v3[1] = y + (rand() % 50) - 25;
  87.     objects[i].color[0] = ((rand() % 100) + 50) / 150.0;
  88.     objects[i].color[1] = ((rand() % 100) + 50) / 150.0;
  89.     objects[i].color[2] = ((rand() % 100) + 50) / 150.0;
  90.   }
  91. }
  92. static void
  93. Init(void)
  94. {
  95.   numObjects = 10;
  96.   InitObjects(numObjects);
  97. }
  98. static void
  99. Reshape(int width, int height)
  100. {
  101.   windW = width;
  102.   windH = height;
  103.   glViewport(0, 0, windW, windH);
  104.   glGetIntegerv(GL_VIEWPORT, vp);
  105. }
  106. static void
  107. Render(GLenum mode)
  108. {
  109.   GLint i;
  110.   for (i = 0; i < objectCount; i++) {
  111.     if (mode == GL_SELECT) {
  112.       glLoadName(i);
  113.     }
  114.     glColor3fv(objects[i].color);
  115.     glBegin(GL_POLYGON);
  116.     glVertex2fv(objects[i].v1);
  117.     glVertex2fv(objects[i].v2);
  118.     glVertex2fv(objects[i].v3);
  119.     glEnd();
  120.   }
  121. }
  122. static GLint
  123. DoSelect(GLint x, GLint y)
  124. {
  125.   GLint hits;
  126.   glSelectBuffer(MAXSELECT, selectBuf);
  127.   glRenderMode(GL_SELECT);
  128.   glInitNames();
  129.   glPushName(~0);
  130.   glPushMatrix();
  131.   glMatrixMode(GL_PROJECTION);
  132.   glLoadIdentity();
  133.   gluPickMatrix(x, windH - y, 4, 4, vp);
  134.   gluOrtho2D(-175, 175, -175, 175);
  135.   glMatrixMode(GL_MODELVIEW);
  136.   glClearColor(0.0, 0.0, 0.0, 0.0);
  137.   glClear(GL_COLOR_BUFFER_BIT);
  138.   glScalef(zoom, zoom, zoom);
  139.   glRotatef(zRotation, 0, 0, 1);
  140.   Render(GL_SELECT);
  141.   glPopMatrix();
  142.   hits = glRenderMode(GL_RENDER);
  143.   if (hits <= 0) {
  144.     return -1;
  145.   }
  146.   return selectBuf[(hits - 1) * 4 + 3];
  147. }
  148. static void
  149. RecolorTri(GLint h)
  150. {
  151.   objects[h].color[0] = ((rand() % 100) + 50) / 150.0;
  152.   objects[h].color[1] = ((rand() % 100) + 50) / 150.0;
  153.   objects[h].color[2] = ((rand() % 100) + 50) / 150.0;
  154. }
  155. static void
  156. DeleteTri(GLint h)
  157. {
  158.   objects[h] = objects[objectCount - 1];
  159.   objectCount--;
  160. }
  161. static void
  162. GrowTri(GLint h)
  163. {
  164.   float v[2];
  165.   float *oldV;
  166.   GLint i;
  167.   v[0] = objects[h].v1[0] + objects[h].v2[0] + objects[h].v3[0];
  168.   v[1] = objects[h].v1[1] + objects[h].v2[1] + objects[h].v3[1];
  169.   v[0] /= 3;
  170.   v[1] /= 3;
  171.   for (i = 0; i < 3; i++) {
  172.     switch (i) {
  173.     case 0:
  174.       oldV = objects[h].v1;
  175.       break;
  176.     case 1:
  177.       oldV = objects[h].v2;
  178.       break;
  179.     case 2:
  180.       oldV = objects[h].v3;
  181.       break;
  182.     }
  183.     oldV[0] = 1.5 * (oldV[0] - v[0]) + v[0];
  184.     oldV[1] = 1.5 * (oldV[1] - v[1]) + v[1];
  185.   }
  186. }
  187. static void
  188. Mouse(int button, int state, int mouseX, int mouseY)
  189. {
  190.   GLint hit;
  191.   if (state == GLUT_DOWN) {
  192.     hit = DoSelect((GLint) mouseX, (GLint) mouseY);
  193.     if (hit != -1) {
  194.       if (button == GLUT_LEFT_BUTTON) {
  195.         RecolorTri(hit);
  196.       } else if (button == GLUT_MIDDLE_BUTTON) {
  197.         GrowTri(hit);
  198.       } else if (button == GLUT_RIGHT_BUTTON) {
  199.         DeleteTri(hit);
  200.       }
  201.       glutPostRedisplay();
  202.     }
  203.   }
  204. }
  205. static void
  206. Draw(void)
  207. {
  208.   glPushMatrix();
  209.   glMatrixMode(GL_PROJECTION);
  210.   glLoadIdentity();
  211.   gluOrtho2D(-175, 175, -175, 175);
  212.   glMatrixMode(GL_MODELVIEW);
  213.   glClearColor(0.0, 0.0, 0.0, 0.0);
  214.   glClear(GL_COLOR_BUFFER_BIT);
  215.   glScalef(zoom, zoom, zoom);
  216.   glRotatef(zRotation, 0, 0, 1);
  217.   Render(GL_RENDER);
  218.   glPopMatrix();
  219.   glutSwapBuffers();
  220. }
  221. static void
  222. DumpFeedbackVert(GLint * i, GLint n)
  223. {
  224.   GLint index;
  225.   index = *i;
  226.   if (index + 7 > n) {
  227.     *i = n;
  228.     printf("  ???n");
  229.     return;
  230.   }
  231.   printf("  (%g %g %g), color = (%4.2f %4.2f %4.2f)n",
  232.     feedBuf[index],
  233.     feedBuf[index + 1],
  234.     feedBuf[index + 2],
  235.     feedBuf[index + 3],
  236.     feedBuf[index + 4],
  237.     feedBuf[index + 5]);
  238.   index += 7;
  239.   *i = index;
  240. }
  241. static void
  242. DrawFeedback(GLint n)
  243. {
  244.   GLint i;
  245.   GLint verts;
  246.   printf("Feedback results (%d floats):n", n);
  247.   for (i = 0; i < n; i++) {
  248.     switch ((GLint) feedBuf[i]) {
  249.     case GL_POLYGON_TOKEN:
  250.       printf("Polygon");
  251.       i++;
  252.       if (i < n) {
  253.         verts = (GLint) feedBuf[i];
  254.         i++;
  255.         printf(": %d vertices", verts);
  256.       } else {
  257.         verts = 0;
  258.       }
  259.       printf("n");
  260.       while (verts) {
  261.         DumpFeedbackVert(&i, n);
  262.         verts--;
  263.       }
  264.       i--;
  265.       break;
  266.     case GL_LINE_TOKEN:
  267.       printf("Line:n");
  268.       i++;
  269.       DumpFeedbackVert(&i, n);
  270.       DumpFeedbackVert(&i, n);
  271.       i--;
  272.       break;
  273.     case GL_LINE_RESET_TOKEN:
  274.       printf("Line Reset:n");
  275.       i++;
  276.       DumpFeedbackVert(&i, n);
  277.       DumpFeedbackVert(&i, n);
  278.       i--;
  279.       break;
  280.     default:
  281.       printf("%9.2fn", feedBuf[i]);
  282.       break;
  283.     }
  284.   }
  285.   if (i == MAXFEED) {
  286.     printf("...n");
  287.   }
  288.   printf("n");
  289. }
  290. static void
  291. DoFeedback(void)
  292. {
  293.   GLint x;
  294.   glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf);
  295.   (void) glRenderMode(GL_FEEDBACK);
  296.   glPushMatrix();
  297.   glMatrixMode(GL_PROJECTION);
  298.   glLoadIdentity();
  299.   gluOrtho2D(-175, 175, -175, 175);
  300.   glMatrixMode(GL_MODELVIEW);
  301.   glClearColor(0.0, 0.0, 0.0, 0.0);
  302.   glClear(GL_COLOR_BUFFER_BIT);
  303.   glScalef(zoom, zoom, zoom);
  304.   glRotatef(zRotation, 0, 0, 1);
  305.   Render(GL_FEEDBACK);
  306.   glPopMatrix();
  307.   x = glRenderMode(GL_RENDER);
  308.   if (x == -1) {
  309.     x = MAXFEED;
  310.   }
  311.   DrawFeedback((GLint) x);
  312. }
  313. /* ARGSUSED1 */
  314. static void
  315. Key(unsigned char key, int x, int y)
  316. {
  317.   switch (key) {
  318.   case 'z':
  319.     zoom /= 0.75;
  320.     glutPostRedisplay();
  321.     break;
  322.   case 'Z':
  323.     zoom *= 0.75;
  324.     glutPostRedisplay();
  325.     break;
  326.   case 'f':
  327.     DoFeedback();
  328.     glutPostRedisplay();
  329.     break;
  330.   case 'l':
  331.     linePoly = !linePoly;
  332.     if (linePoly) {
  333.       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  334.     } else {
  335.       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  336.     }
  337.     glutPostRedisplay();
  338.     break;
  339.   case 27:
  340.     exit(0);
  341.   }
  342. }
  343. /* ARGSUSED1 */
  344. static void
  345. SpecialKey(int key, int x, int y)
  346. {
  347.   switch (key) {
  348.   case GLUT_KEY_LEFT:
  349.     zRotation += 0.5;
  350.     glutPostRedisplay();
  351.     break;
  352.   case GLUT_KEY_RIGHT:
  353.     zRotation -= 0.5;
  354.     glutPostRedisplay();
  355.     break;
  356.   }
  357. }
  358. int
  359. main(int argc, char **argv)
  360. {
  361.   glutInit(&argc, argv);
  362.   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  363.   glutCreateWindow("Select Test");
  364.   Init();
  365.   glutReshapeFunc(Reshape);
  366.   glutKeyboardFunc(Key);
  367.   glutSpecialFunc(SpecialKey);
  368.   glutMouseFunc(Mouse);
  369.   glutDisplayFunc(Draw);
  370.   glutMainLoop();
  371.   return 0;             /* ANSI C requires main to return int. */
  372. }