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

GIS编程

开发平台:

Visual C++

  1. /* Copyright (c) Mark J. Kilgard, 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. /* editgrid demonstrates how a simple 2nd order grid mesh or a more
  6.    complex 4th order grid mesh can rendered with OpenGL evaluators.
  7.    The control points for either grid can be interactively moved in 2D
  8.    by selecting and moving with the left mouse button.  Antialising can
  9.    also be enabled from the pop-up menu. */
  10. /* Compile: cc -o editgrid editgrid.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <GL/glut.h>
  14. int antialiasing = 0;
  15. int gridSize = 20;
  16. GLuint selectedPoint = (GLuint) ~0;
  17. int winWidth, winHeight;
  18. GLuint selectBuffer[64];
  19. GLdouble modelMatrix[16], projMatrix[16];
  20. GLint viewport[4];
  21. /* Simple 2nd order initial grid.  4 points (2 by 2). */
  22. GLfloat grid2x2[2][2][3] =
  23. {
  24.   {
  25.     {-2.0, -2.0, 0.0},
  26.     {2.0, -2.0, 0.0}},
  27.   {
  28.     {-2.0, 2.0, 0.0},
  29.     {2.0, 2.0, 0.0}}
  30. };
  31. /* More complex 4nd order initial grid.  16 points (4 by 4). */
  32. GLfloat grid4x4[4][4][3] =
  33. {
  34.   {
  35.     {-2.0, -2.0, 0.0},
  36.     {-0.5, -2.0, 0.0},
  37.     {0.5, -2.0, 0.0},
  38.     {2.0, -2.0, 0.0}},
  39.   {
  40.     {-2.0, -0.5, 0.0},
  41.     {-0.5, -0.5, 0.0},
  42.     {0.5, -0.5, 0.0},
  43.     {2.0, -0.5, 0.0}},
  44.   {
  45.     {-2.0, 0.5, 0.0},
  46.     {-0.5, 0.5, 0.0},
  47.     {0.5, 0.5, 0.0},
  48.     {2.0, 0.5, 0.0}},
  49.   {
  50.     {-2.0, 2.0, 0.0},
  51.     {-0.5, 2.0, 0.0},
  52.     {0.5, 2.0, 0.0},
  53.     {2.0, 2.0, 0.0}}
  54. };
  55. GLfloat *grid = &grid4x4[0][0][0];
  56. int uSize = 4;
  57. int vSize = 4;
  58. void
  59. setupMesh(void)
  60. {
  61.   glEnable(GL_MAP2_VERTEX_3);
  62.   glMapGrid2f(gridSize, 0.0, 1.0, gridSize, 0.0, 1.0);
  63. }
  64. void
  65. evaluateGrid(void)
  66. {
  67.   glColor3f(1.0, 1.0, 1.0);
  68.   glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, uSize, 0, 1, uSize * 3, vSize, grid);
  69.   glEvalMesh2(GL_LINE, 0, gridSize, 0, gridSize);
  70. }
  71. void
  72. drawControlPoints(void)
  73. {
  74.   int i;
  75.   glColor3f(1.0, 1.0, 0.0);
  76.   glPointSize(5.0);
  77.   glBegin(GL_POINTS);
  78.   for (i = 0; i < uSize * vSize; i++) {
  79.     glVertex3fv(&grid[i * 3]);
  80.   }
  81.   glEnd();
  82. }
  83. void
  84. selectControlPoints(void)
  85. {
  86.   int i;
  87.   for (i = 0; i < uSize * vSize; i++) {
  88.     glLoadName(i);
  89.     glBegin(GL_POINTS);
  90.     glVertex3fv(&grid[i * 3]);
  91.     glEnd();
  92.   }
  93. }
  94. void
  95. display(void)
  96. {
  97.   glClear(GL_COLOR_BUFFER_BIT);
  98.   evaluateGrid();
  99.   drawControlPoints();
  100.   glutSwapBuffers();
  101. }
  102. void
  103. ortho(void)
  104. {
  105.   if (winWidth <= winHeight)
  106.     glOrtho(-4.0, 4.0, -4.0 * (GLfloat) winHeight / (GLfloat) winWidth,
  107.       4.0 * (GLfloat) winHeight / (GLfloat) winWidth, -4.0, 4.0);
  108.   else
  109.     glOrtho(-4.0 * (GLfloat) winWidth / (GLfloat) winHeight,
  110.       4.0 * (GLfloat) winWidth / (GLfloat) winHeight, -4.0, 4.0, -4.0, 4.0);
  111. }
  112. GLuint
  113. pick(int x, int y)
  114. {
  115.   int hits;
  116.   (void) glRenderMode(GL_SELECT);
  117.   glInitNames();
  118.   glPushName(~0);
  119.   glMatrixMode(GL_PROJECTION);
  120.   glPushMatrix();
  121.   glLoadIdentity();
  122.   gluPickMatrix(x, winHeight - y, 8.0, 8.0, viewport);
  123.   ortho();
  124.   glMatrixMode(GL_MODELVIEW);
  125.   selectControlPoints();
  126.   glMatrixMode(GL_PROJECTION);
  127.   glPopMatrix();
  128.   glMatrixMode(GL_MODELVIEW);
  129.   hits = glRenderMode(GL_RENDER);
  130.   if (hits) {
  131. #ifdef DEBUG
  132.     {
  133.       unsigned int i;
  134.       GLint names;
  135.       GLuint *ptr;
  136.       printf("hits = %dn", hits);
  137.       ptr = (GLuint *) selectBuffer;
  138.       for (i = 0; i < hits; i++) {  /* for each hit  */
  139.         int j;
  140.         names = *ptr;
  141.         printf("number of names for hit = %dn", *ptr);
  142.         ptr++;
  143.         printf("  z1 is %g;", (float) *ptr / 0xffffffff);
  144.         ptr++;
  145.         printf("  z2 is %gn", (float) *ptr / 0xffffffff);
  146.         ptr++;
  147.         printf(" the name is ");
  148.         for (j = 0; j < names; j++) {  /* For each name. */
  149.           printf("%d ", *ptr);
  150.           ptr++;
  151.         }
  152.         printf("n");
  153.       }
  154.     }
  155. #endif
  156.     return selectBuffer[3];
  157.   } else {
  158.     return ~0;
  159.   }
  160. }
  161. void
  162. reshape(int w, int h)
  163. {
  164.   glViewport(0, 0, w, h);
  165.   winWidth = w;
  166.   winHeight = h;
  167.   glMatrixMode(GL_PROJECTION);
  168.   glLoadIdentity();
  169.   ortho();
  170.   glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
  171.   glMatrixMode(GL_MODELVIEW);
  172.   glLoadIdentity();
  173.   glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
  174.   viewport[0] = 0;
  175.   viewport[1] = 0;
  176.   viewport[2] = winWidth;
  177.   viewport[3] = winHeight;
  178. }
  179. void
  180. mouse(int button, int state, int x, int y)
  181. {
  182.   if (button == GLUT_LEFT_BUTTON) {
  183.     if (state == GLUT_DOWN) {
  184.       selectedPoint = pick(x, y);
  185.     } else {
  186.       selectedPoint = -1;
  187.     }
  188.   }
  189. }
  190. void
  191. motion(int x, int y)
  192. {
  193.   GLdouble objx, objy, objz;
  194.   if (selectedPoint != ~0) {
  195.     gluUnProject(x, winHeight - y, 0.95,
  196.       modelMatrix, projMatrix, viewport,
  197.       &objx, &objy, &objz);
  198.     grid[selectedPoint * 3 + 0] = objx;
  199.     grid[selectedPoint * 3 + 1] = objy;
  200.     glutPostRedisplay();
  201.   }
  202. }
  203. /* ARGSUSED1 */
  204. static void
  205. keyboard(unsigned char key, int x, int y)
  206. {
  207.   switch (key) {
  208.   case 27:
  209.     exit(0);
  210.   }
  211. }
  212. enum {
  213.   M_2ND_ORDER_GRID, M_4TH_ORDER_GRID, M_INCREASE_GRID, M_DECREASE_GRID, M_TOGGLE_ANTIALIASING, M_QUIT
  214. };
  215. void
  216. menu(int value)
  217. {
  218.   switch (value) {
  219.   case M_2ND_ORDER_GRID:
  220.     grid = &grid2x2[0][0][0];
  221.     uSize = 2;
  222.     vSize = 2;
  223.     setupMesh();
  224.     break;
  225.   case M_4TH_ORDER_GRID:
  226.     grid = &grid4x4[0][0][0];
  227.     uSize = 4;
  228.     vSize = 4;
  229.     setupMesh();
  230.     break;
  231.   case M_INCREASE_GRID:
  232.     gridSize += 2;
  233.     setupMesh();
  234.     break;
  235.   case M_DECREASE_GRID:
  236.     gridSize -= 2;
  237.     if (gridSize < 2) {
  238.       gridSize = 2;
  239.     }
  240.     setupMesh();
  241.     break;
  242.   case M_TOGGLE_ANTIALIASING:
  243.     if (antialiasing) {
  244.       antialiasing = 0;
  245.       glDisable(GL_BLEND);
  246.       glDisable(GL_LINE_SMOOTH);
  247.       glDisable(GL_POINT_SMOOTH);
  248.     } else {
  249.       antialiasing = 1;
  250.       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  251.       glEnable(GL_BLEND);
  252.       glEnable(GL_LINE_SMOOTH);
  253.       glEnable(GL_POINT_SMOOTH);
  254.     }
  255.     break;
  256.   case M_QUIT:
  257.     exit(0);
  258.     break;
  259.   }
  260.   glutPostRedisplay();
  261. }
  262. int
  263. main(int argc, char **argv)
  264. {
  265.   glutInit(&argc, argv);
  266.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  267.   glutCreateWindow("editgrid");
  268.   glutReshapeFunc(reshape);
  269.   glutDisplayFunc(display);
  270.   glutMouseFunc(mouse);
  271.   glutKeyboardFunc(keyboard);
  272.   glutMotionFunc(motion);
  273.   glutCreateMenu(menu);
  274.   glutAddMenuEntry("2nd order grid", M_2ND_ORDER_GRID);
  275.   glutAddMenuEntry("4nd order grid", M_4TH_ORDER_GRID);
  276.   glutAddMenuEntry("Increase grid sizing by 2", M_INCREASE_GRID);
  277.   glutAddMenuEntry("Decrease grid sizing by 2", M_DECREASE_GRID);
  278.   glutAddMenuEntry("Toggle antialiasing", M_TOGGLE_ANTIALIASING);
  279.   glutAddMenuEntry("Quit", M_QUIT);
  280.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  281.   glSelectBuffer(sizeof(selectBuffer), selectBuffer);
  282.   setupMesh();
  283.   glutMainLoop();
  284.   return 0;             /* ANSI C requires main to return int. */
  285. }