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

GIS编程

开发平台:

Visual C++

  1. /**
  2.  * surfgrid.c - simple test of polygon offset
  3.  *
  4.  * GLUT distribution version  $Revision: 1.8 $
  5.  *
  6.  * usage:
  7.  * surfgrid [-f]
  8.  *
  9.  * options:
  10.  * -f run on full screen
  11.  *
  12.  * keys:
  13.  * p toggle polygon offset
  14.  *      F       increase polygon offset factor
  15.  *      f       decrease polygon offset factor
  16.  *      B       increase polygon offset bias
  17.  *      b       decrease polygon offset bias
  18.  * g toggle grid drawing
  19.  * s toggle smooth/flat shading
  20.  * n toggle whether to use GL evaluators or GLU nurbs
  21.  * u decr number of segments in U direction
  22.  * U incr number of segments in U direction
  23.  * v decr number of segments in V direction
  24.  * V incr number of segments in V direction
  25.  * escape quit
  26.  */
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <math.h>
  31. #include <GL/glut.h>
  32. #define W 600
  33. #define H 600
  34. float z_axis[] =
  35. {0.0, 0.0, 1.0};
  36. void
  37. norm(float v[3])
  38. {
  39.   float r;
  40.   r = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  41.   v[0] /= r;
  42.   v[1] /= r;
  43.   v[2] /= r;
  44. }
  45. void
  46. cross(float v1[3], float v2[3], float result[3])
  47. {
  48.   result[0] = v1[1] * v2[2] - v1[2] * v2[1];
  49.   result[1] = v1[2] * v2[0] - v1[0] * v2[2];
  50.   result[2] = v1[0] * v2[1] - v1[1] * v2[0];
  51. }
  52. float
  53. length(float v[3])
  54. {
  55.   float r = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  56.   return r;
  57. }
  58. static int winwidth = W, winheight = H;
  59. GLUnurbsObj *nobj;
  60. GLuint surflist, gridlist;
  61. int useglunurbs = 0;
  62. int smooth = 1;
  63. GLboolean tracking = GL_FALSE;
  64. int showgrid = 1;
  65. int showsurf = 1;
  66. int fullscreen = 0;
  67. float modelmatrix[16];
  68. float factor = 0.5;
  69. float bias = 0.002;
  70. int usegments = 4;
  71. int vsegments = 4;
  72. int spindx, spindy;
  73. int startx, starty;
  74. int curx, cury;
  75. int prevx, prevy;       /* to get good deltas using glut */
  76. void redraw(void);
  77. void createlists(void);
  78. /* Control points of the torus in Bezier form.  Can be rendered
  79.    using OpenGL evaluators. */
  80. static GLfloat torusbezierpts[] =
  81. {
  82. /* *INDENT-OFF* */
  83.    4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 3.0, 0.0, 1.0, 2.0,
  84.    3.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0, 8.0, 0.0, 0.0, 4.0,
  85.    8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 3.0, 0.0,-1.0, 2.0,
  86.    3.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0, 4.0, 0.0, 0.0, 4.0,
  87.    2.0,-2.0, 0.0, 2.0, 1.0,-1.0, 0.5, 1.0, 1.5,-1.5, 0.5, 1.0,
  88.    1.5,-1.5, 0.5, 1.0, 2.0,-2.0, 0.5, 1.0, 4.0,-4.0, 0.0, 2.0,
  89.    4.0,-4.0, 0.0, 2.0, 2.0,-2.0,-0.5, 1.0, 1.5,-1.5,-0.5, 1.0,
  90.    1.5,-1.5,-0.5, 1.0, 1.0,-1.0,-0.5, 1.0, 2.0,-2.0, 0.0, 2.0,
  91.    0.0,-2.0, 0.0, 2.0, 0.0,-1.0, 0.5, 1.0, 0.0,-1.5, 0.5, 1.0,
  92.    0.0,-1.5, 0.5, 1.0, 0.0,-2.0, 0.5, 1.0, 0.0,-4.0, 0.0, 2.0,
  93.    0.0,-4.0, 0.0, 2.0, 0.0,-2.0,-0.5, 1.0, 0.0,-1.5,-0.5, 1.0,
  94.    0.0,-1.5,-0.5, 1.0, 0.0,-1.0,-0.5, 1.0, 0.0,-2.0, 0.0, 2.0,
  95.    0.0,-2.0, 0.0, 2.0, 0.0,-1.0, 0.5, 1.0, 0.0,-1.5, 0.5, 1.0,
  96.    0.0,-1.5, 0.5, 1.0, 0.0,-2.0, 0.5, 1.0, 0.0,-4.0, 0.0, 2.0,
  97.    0.0,-4.0, 0.0, 2.0, 0.0,-2.0,-0.5, 1.0, 0.0,-1.5,-0.5, 1.0,
  98.    0.0,-1.5,-0.5, 1.0, 0.0,-1.0,-0.5, 1.0, 0.0,-2.0, 0.0, 2.0,
  99.   -2.0,-2.0, 0.0, 2.0,-1.0,-1.0, 0.5, 1.0,-1.5,-1.5, 0.5, 1.0,
  100.   -1.5,-1.5, 0.5, 1.0,-2.0,-2.0, 0.5, 1.0,-4.0,-4.0, 0.0, 2.0,
  101.   -4.0,-4.0, 0.0, 2.0,-2.0,-2.0,-0.5, 1.0,-1.5,-1.5,-0.5, 1.0,
  102.   -1.5,-1.5,-0.5, 1.0,-1.0,-1.0,-0.5, 1.0,-2.0,-2.0, 0.0, 2.0,
  103.   -4.0, 0.0, 0.0, 4.0,-2.0, 0.0, 1.0, 2.0,-3.0, 0.0, 1.0, 2.0,
  104.   -3.0, 0.0, 1.0, 2.0,-4.0, 0.0, 1.0, 2.0,-8.0, 0.0, 0.0, 4.0,
  105.   -8.0, 0.0, 0.0, 4.0,-4.0, 0.0,-1.0, 2.0,-3.0, 0.0,-1.0, 2.0,
  106.   -3.0, 0.0,-1.0, 2.0,-2.0, 0.0,-1.0, 2.0,-4.0, 0.0, 0.0, 4.0,
  107.   -4.0, 0.0, 0.0, 4.0,-2.0, 0.0, 1.0, 2.0,-3.0, 0.0, 1.0, 2.0,
  108.   -3.0, 0.0, 1.0, 2.0,-4.0, 0.0, 1.0, 2.0,-8.0, 0.0, 0.0, 4.0,
  109.   -8.0, 0.0, 0.0, 4.0,-4.0, 0.0,-1.0, 2.0,-3.0, 0.0,-1.0, 2.0,
  110.   -3.0, 0.0,-1.0, 2.0,-2.0, 0.0,-1.0, 2.0,-4.0, 0.0, 0.0, 4.0,
  111.   -2.0, 2.0, 0.0, 2.0,-1.0, 1.0, 0.5, 1.0,-1.5, 1.5, 0.5, 1.0,
  112.   -1.5, 1.5, 0.5, 1.0,-2.0, 2.0, 0.5, 1.0,-4.0, 4.0, 0.0, 2.0,
  113.   -4.0, 4.0, 0.0, 2.0,-2.0, 2.0,-0.5, 1.0,-1.5, 1.5,-0.5, 1.0,
  114.   -1.5, 1.5,-0.5, 1.0,-1.0, 1.0,-0.5, 1.0,-2.0, 2.0, 0.0, 2.0,
  115.    0.0, 2.0, 0.0, 2.0, 0.0, 1.0, 0.5, 1.0, 0.0, 1.5, 0.5, 1.0,
  116.    0.0, 1.5, 0.5, 1.0, 0.0, 2.0, 0.5, 1.0, 0.0, 4.0, 0.0, 2.0,
  117.    0.0, 4.0, 0.0, 2.0, 0.0, 2.0,-0.5, 1.0, 0.0, 1.5,-0.5, 1.0,
  118.    0.0, 1.5,-0.5, 1.0, 0.0, 1.0,-0.5, 1.0, 0.0, 2.0, 0.0, 2.0,
  119.    0.0, 2.0, 0.0, 2.0, 0.0, 1.0, 0.5, 1.0, 0.0, 1.5, 0.5, 1.0,
  120.    0.0, 1.5, 0.5, 1.0, 0.0, 2.0, 0.5, 1.0, 0.0, 4.0, 0.0, 2.0,
  121.    0.0, 4.0, 0.0, 2.0, 0.0, 2.0,-0.5, 1.0, 0.0, 1.5,-0.5, 1.0,
  122.    0.0, 1.5,-0.5, 1.0, 0.0, 1.0,-0.5, 1.0, 0.0, 2.0, 0.0, 2.0,
  123.    2.0, 2.0, 0.0, 2.0, 1.0, 1.0, 0.5, 1.0, 1.5, 1.5, 0.5, 1.0,
  124.    1.5, 1.5, 0.5, 1.0, 2.0, 2.0, 0.5, 1.0, 4.0, 4.0, 0.0, 2.0,
  125.    4.0, 4.0, 0.0, 2.0, 2.0, 2.0,-0.5, 1.0, 1.5, 1.5,-0.5, 1.0,
  126.    1.5, 1.5,-0.5, 1.0, 1.0, 1.0,-0.5, 1.0, 2.0, 2.0, 0.0, 2.0,
  127.    4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 3.0, 0.0, 1.0, 2.0,
  128.    3.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0, 8.0, 0.0, 0.0, 4.0,
  129.    8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 3.0, 0.0,-1.0, 2.0,
  130.    3.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0, 4.0, 0.0, 0.0, 4.0,
  131. /* *INDENT-ON* */
  132. };
  133. /* Control points of a torus in NURBS form.  Can be rendered using
  134.    the GLU NURBS routines. */
  135. static GLfloat torusnurbpts[] =
  136. {
  137. /* *INDENT-OFF* */
  138.    4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0,
  139.    8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0,
  140.    4.0, 0.0, 0.0, 4.0, 2.0,-2.0, 0.0, 2.0, 1.0,-1.0, 0.5, 1.0,
  141.    2.0,-2.0, 0.5, 1.0, 4.0,-4.0, 0.0, 2.0, 2.0,-2.0,-0.5, 1.0,
  142.    1.0,-1.0,-0.5, 1.0, 2.0,-2.0, 0.0, 2.0,-2.0,-2.0, 0.0, 2.0,
  143.   -1.0,-1.0, 0.5, 1.0,-2.0,-2.0, 0.5, 1.0,-4.0,-4.0, 0.0, 2.0,
  144.   -2.0,-2.0,-0.5, 1.0,-1.0,-1.0,-0.5, 1.0,-2.0,-2.0, 0.0, 2.0,
  145.   -4.0, 0.0, 0.0, 4.0,-2.0, 0.0, 1.0, 2.0,-4.0, 0.0, 1.0, 2.0,
  146.   -8.0, 0.0, 0.0, 4.0,-4.0, 0.0,-1.0, 2.0,-2.0, 0.0,-1.0, 2.0,
  147.   -4.0, 0.0, 0.0, 4.0,-2.0, 2.0, 0.0, 2.0,-1.0, 1.0, 0.5, 1.0,
  148.   -2.0, 2.0, 0.5, 1.0,-4.0, 4.0, 0.0, 2.0,-2.0, 2.0,-0.5, 1.0,
  149.   -1.0, 1.0,-0.5, 1.0,-2.0, 2.0, 0.0, 2.0, 2.0, 2.0, 0.0, 2.0,
  150.    1.0, 1.0, 0.5, 1.0, 2.0, 2.0, 0.5, 1.0, 4.0, 4.0, 0.0, 2.0,
  151.    2.0, 2.0,-0.5, 1.0, 1.0, 1.0,-0.5, 1.0, 2.0, 2.0, 0.0, 2.0,
  152.    4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0,
  153.    8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0,
  154.    4.0, 0.0, 0.0, 4.0,
  155. /* *INDENT-ON* */
  156. };
  157. void
  158. move(int x, int y)
  159. {
  160.   prevx = curx;
  161.   prevy = cury;
  162.   curx = x;
  163.   cury = y;
  164.   if (curx != startx || cury != starty) {
  165.     glutPostRedisplay();
  166.     startx = curx;
  167.     starty = cury;
  168.   }
  169. }
  170. void
  171. button(int button, int state, int x, int y)
  172. {
  173.   if (button != GLUT_LEFT_BUTTON)
  174.     return;
  175.   switch (state) {
  176.   case GLUT_DOWN:
  177.     prevx = curx = startx = x;
  178.     prevy = cury = starty = y;
  179.     spindx = 0;
  180.     spindy = 0;
  181.     tracking = GL_TRUE;
  182.     break;
  183.   case GLUT_UP:
  184.     /* 
  185.      * If user released the button while moving the mouse, keep
  186.      * spinning.
  187.      */
  188.     if (x != prevx || y != prevy) {
  189.       spindx = x - prevx;
  190.       spindy = y - prevy;
  191.     }
  192.     tracking = GL_FALSE;
  193.     break;
  194.   }
  195. }
  196. /* Maintain a square window when resizing */
  197. void
  198. reshape(int width, int height)
  199. {
  200.   int size;
  201.   size = (width < height ? width : height);
  202.   glViewport((width - size) / 2, (height - size) / 2, size, size);
  203.   glutReshapeWindow(size, size);
  204.   glutPostRedisplay();
  205. }
  206. void
  207. gridmaterials(void)
  208. {
  209.   static float front_mat_diffuse[] =
  210.   {1.0, 1.0, 0.4, 1.0};
  211.   static float front_mat_ambient[] =
  212.   {0.1, 0.1, 0.1, 1.0};
  213.   static float back_mat_diffuse[] =
  214.   {1.0, 0.0, 0.0, 1.0};
  215.   static float back_mat_ambient[] =
  216.   {0.1, 0.1, 0.1, 1.0};
  217.   glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
  218.   glMaterialfv(GL_FRONT, GL_AMBIENT, front_mat_ambient);
  219.   glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
  220.   glMaterialfv(GL_BACK, GL_AMBIENT, back_mat_ambient);
  221. }
  222. void
  223. surfacematerials(void)
  224. {
  225.   static float front_mat_diffuse[] =
  226.   {0.2, 0.7, 0.4, 1.0};
  227.   static float front_mat_ambient[] =
  228.   {0.1, 0.1, 0.1, 1.0};
  229.   static float back_mat_diffuse[] =
  230.   {1.0, 1.0, 0.2, 1.0};
  231.   static float back_mat_ambient[] =
  232.   {0.1, 0.1, 0.1, 1.0};
  233.   glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
  234.   glMaterialfv(GL_FRONT, GL_AMBIENT, front_mat_ambient);
  235.   glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
  236.   glMaterialfv(GL_BACK, GL_AMBIENT, back_mat_ambient);
  237. }
  238. void
  239. init(void)
  240. {
  241.   static float ambient[] =
  242.   {0.0, 0.0, 0.0, 1.0};
  243.   static float diffuse[] =
  244.   {1.0, 1.0, 1.0, 1.0};
  245.   static float position[] =
  246.   {90.0, 90.0, -150.0, 0.0};
  247.   static float lmodel_ambient[] =
  248.   {1.0, 1.0, 1.0, 1.0};
  249.   glMatrixMode(GL_PROJECTION);
  250.   glLoadIdentity();
  251.   gluPerspective(40.0, 1.0, 2.0, 200.0);
  252.   glMatrixMode(GL_MODELVIEW);
  253.   glLoadIdentity();
  254.   glGetFloatv(GL_MODELVIEW_MATRIX, modelmatrix);
  255.   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  256.   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  257.   glLightfv(GL_LIGHT0, GL_POSITION, position);
  258.   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  259.   glEnable(GL_LIGHTING);
  260.   glEnable(GL_LIGHT0);
  261.   glEnable(GL_DEPTH_TEST);
  262.   glEnable(GL_AUTO_NORMAL);
  263.   glFrontFace(GL_CCW);
  264.   glEnable(GL_MAP2_VERTEX_4);
  265.   glClearColor(0.25, 0.25, 0.5, 0.0);
  266. #if GL_EXT_polygon_offset
  267.   glPolygonOffsetEXT(factor, bias);
  268.   glEnable(GL_POLYGON_OFFSET_EXT);
  269. #endif
  270.   nobj = gluNewNurbsRenderer();
  271. #ifdef GLU_VERSION_1_1  /* New GLU 1.1 interface. */
  272.   gluNurbsProperty(nobj, GLU_SAMPLING_METHOD, GLU_DOMAIN_DISTANCE);
  273. #endif
  274.   surflist = glGenLists(1);
  275.   gridlist = glGenLists(1);
  276.   createlists();
  277. }
  278. void
  279. drawmesh(void)
  280. {
  281.   int i, j;
  282.   float *p;
  283.   int up2p = 4;
  284.   int uorder = 3, vorder = 3;
  285.   int nu = 4, nv = 4;
  286.   int vp2p = up2p * uorder * nu;
  287.   for (j = 0; j < nv; j++) {
  288.     for (i = 0; i < nu; i++) {
  289.       p = torusbezierpts + (j * vp2p * vorder) + (i * up2p * uorder);
  290. #if GL_EXT_polygon_offset
  291.       glPolygonOffsetEXT(factor, bias);
  292. #endif
  293.       glMap2f(GL_MAP2_VERTEX_4, 0.0, 1.0, up2p, 3, 0.0, 1.0, vp2p, 3,
  294.         (void *) p);
  295.       if (showsurf) {
  296.         surfacematerials();
  297.         glEvalMesh2(GL_FILL, 0, usegments, 0, vsegments);
  298.       }
  299.       if (showgrid) {
  300.         gridmaterials();
  301.         glEvalMesh2(GL_LINE, 0, usegments, 0, vsegments);
  302.       }
  303.     }
  304.   }
  305. }
  306. void
  307. redraw(void)
  308. {
  309.   int dx, dy;
  310.   float v[3], rot[3];
  311.   float len, ang;
  312.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  313.   glColor3f(1, 0, 0);
  314.   if (tracking) {
  315.     dx = curx - startx;
  316.     dy = cury - starty;
  317.   } else {
  318.     dx = spindx;
  319.     dy = spindy;
  320.   }
  321.   if (dx || dy) {
  322.     dy = -dy;
  323.     v[0] = dx;
  324.     v[1] = dy;
  325.     v[2] = 0;
  326.     len = length(v);
  327.     ang = -len / 600 * 360;
  328.     norm(v);
  329.     cross(v, z_axis, rot);
  330.     /* This is certainly not recommended for programs that care
  331.        about performance or numerical stability: we concatenate
  332.        the rotation onto the current modelview matrix and read
  333.        the matrix back, thus saving ourselves from writing our
  334.        own matrix manipulation routines.  */
  335.     glLoadIdentity();
  336.     glRotatef(ang, rot[0], rot[1], rot[2]);
  337.     glMultMatrixf(modelmatrix);
  338.     glGetFloatv(GL_MODELVIEW_MATRIX, modelmatrix);
  339.   }
  340.   glLoadIdentity();
  341.   glTranslatef(0.0, 0.0, -10.0);
  342.   glMultMatrixf(modelmatrix);
  343.   if (useglunurbs) {
  344.     if (showsurf)
  345.       glCallList(surflist);
  346.     if (showgrid)
  347.       glCallList(gridlist);
  348.   } else {
  349.     glMapGrid2f(usegments, 0.0, 1.0, vsegments, 0.0, 1.0);
  350.     drawmesh();
  351.   }
  352.   glutSwapBuffers();
  353. }
  354. static void
  355. usage(void)
  356. {
  357.   printf("usage: surfgrid [-f]n");
  358.   exit(-1);
  359. }
  360. /* what to do when a menu item is selected. This function also handles
  361.    keystroke events.  */
  362. void
  363. menu(int item)
  364. {
  365.   switch (item) {
  366.   case 'p':
  367. #if GL_EXT_polygon_offset
  368.     if (glIsEnabled(GL_POLYGON_OFFSET_EXT)) {
  369.       glDisable(GL_POLYGON_OFFSET_EXT);
  370.       printf("disabling polygon offsetn");
  371.     } else {
  372.       glEnable(GL_POLYGON_OFFSET_EXT);
  373.       printf("enabling polygon offsetn");
  374.     }
  375. #endif
  376.     break;
  377.   case 'F':
  378.     factor += 0.1;
  379.     printf("factor: %8.4fn", factor);
  380.     break;
  381.   case 'f':
  382.     factor -= 0.1;
  383.     printf("factor: %8.4fn", factor);
  384.     break;
  385.   case 'B':
  386.     bias += 0.0001;
  387.     printf("bias:  %8.4fn", bias);
  388.     break;
  389.   case 'b':
  390.     bias -= 0.0001;
  391.     printf("bias:  %8.4fn", bias);
  392.     break;
  393.   case 'g':
  394.     showgrid = !showgrid;
  395.     break;
  396.   case 'n':
  397.     useglunurbs = !useglunurbs;
  398.     break;
  399.   case 's':
  400.     smooth = !smooth;
  401.     if (smooth) {
  402.       glShadeModel(GL_SMOOTH);
  403.     } else {
  404.       glShadeModel(GL_FLAT);
  405.     }
  406.     break;
  407.   case 't':
  408.     showsurf = !showsurf;
  409.     break;
  410.   case 'u':
  411.     usegments = (usegments < 2 ? 1 : usegments - 1);
  412.     createlists();
  413.     break;
  414.   case 'U':
  415.     usegments++;
  416.     createlists();
  417.     break;
  418.   case 'v':
  419.     vsegments = (vsegments < 2 ? 1 : vsegments - 1);
  420.     createlists();
  421.     break;
  422.   case 'V':
  423.     vsegments++;
  424.     createlists();
  425.     break;
  426.   case '33':         /* ESC key: quit */
  427.     exit(0);
  428.     break;
  429.   }
  430.   glutPostRedisplay();
  431. }
  432. /* ARGSUSED1 */
  433. void
  434. key(unsigned char key, int x, int y)
  435. {
  436.   menu((int) key);
  437. }
  438. void
  439. animate(void)
  440. {
  441.   if (!tracking && (spindx != 0 || spindy != 0))
  442.     glutPostRedisplay();
  443. }
  444. int
  445. main(int argc, char **argv)
  446. {
  447.   int i;
  448.   glutInit(&argc, argv);  /* initialize glut, processing
  449.                              arguments */
  450.   for (i = 1; i < argc; i++) {
  451.     if (argv[i][0] == '-') {
  452.       switch (argv[i][1]) {
  453.       case 'f':
  454.         fullscreen = 1;
  455.         break;
  456.       default:
  457.         usage();
  458.         break;
  459.       }
  460.     } else {
  461.       usage();
  462.     }
  463.   }
  464.   glutInitWindowSize(winwidth, winheight);
  465.   glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
  466.   glutCreateWindow("surfgrid");
  467.   /* create a menu for the right mouse button */
  468.   glutCreateMenu(menu);
  469. #if GL_EXT_polygon_offset
  470.   glutAddMenuEntry("p: toggle polygon offset", 'p');
  471. #endif
  472.   glutAddMenuEntry("F: increase factor", 'F');
  473.   glutAddMenuEntry("f: decrease factor", 'f');
  474.   glutAddMenuEntry("B: increase bias", 'B');
  475.   glutAddMenuEntry("b: decrease bias", 'b');
  476.   glutAddMenuEntry("g: toggle grid", 'g');
  477.   glutAddMenuEntry("s: toggle smooth shading", 's');
  478.   glutAddMenuEntry("t: toggle surface", 't');
  479.   glutAddMenuEntry("n: toggle GL evalutators/GLU nurbs", 'n');
  480.   glutAddMenuEntry("u: decrement u segments", 'u');
  481.   glutAddMenuEntry("U: increment u segments", 'U');
  482.   glutAddMenuEntry("v: decrement v segments", 'v');
  483.   glutAddMenuEntry("V: increment v segments", 'V');
  484.   glutAddMenuEntry("<esc>: exit program", '33');
  485.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  486.   /* set callbacks */
  487.   glutKeyboardFunc(key);
  488.   glutDisplayFunc(redraw);
  489.   glutReshapeFunc(reshape);
  490.   glutMouseFunc(button);
  491.   glutMotionFunc(move);
  492.   glutIdleFunc(animate);
  493. #if GL_EXT_polygon_offset
  494.   if (!glutExtensionSupported("GL_EXT_polygon_offset")) {
  495.     printf("Warning: "
  496.       "GL_EXT_polygon_offset not supported on this machine... "
  497.       "trying anywayn");
  498.   }
  499. #else
  500.   printf("Warning: not compiled with GL_EXT_polygon_offset support.n");
  501. #endif
  502.   init();
  503.   glutMainLoop();
  504.   return 0;             /* ANSI C requires main to return int. */
  505. }
  506. float circleknots[] =
  507. {0.0, 0.0, 0.0, 0.25, 0.50, 0.50, 0.75, 1.0, 1.0, 1.0};
  508. void
  509. createlists(void)
  510. {
  511. #ifdef GLU_VERSION_1_1  /* New GLU 1.1 interface. */
  512.   gluNurbsProperty(nobj, GLU_U_STEP, (usegments - 1) * 4);
  513.   gluNurbsProperty(nobj, GLU_V_STEP, (vsegments - 1) * 4);
  514.   gluNurbsProperty(nobj, GLU_DISPLAY_MODE, GLU_FILL);
  515. #endif
  516.   glNewList(surflist, GL_COMPILE);
  517.   surfacematerials();
  518.   gluBeginSurface(nobj);
  519.   gluNurbsSurface(nobj, 10, circleknots, 10, circleknots,
  520.     4, 28, torusnurbpts, 3, 3, GL_MAP2_VERTEX_4);
  521.   gluEndSurface(nobj);
  522.   glEndList();
  523.   gluNurbsProperty(nobj, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
  524.   glNewList(gridlist, GL_COMPILE);
  525.   gridmaterials();
  526.   gluBeginSurface(nobj);
  527.   gluNurbsSurface(nobj, 10, circleknots, 10, circleknots,
  528.     4, 28, torusnurbpts, 3, 3, GL_MAP2_VERTEX_4);
  529.   gluEndSurface(nobj);
  530.   glEndList();
  531. }