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

GIS编程

开发平台:

Visual C++

  1. /* isosurf.c */
  2. /* Mesa 2.0 version
  3.    Display an isosurface of 3-D wind speed volume.  Use arrow keys to
  4.    rotate, S toggles smooth shading, L toggles lighting
  5.    Brian Paul */
  6. /* Conversion to GLUT and OpenGL 1.1 by Mark J. Kilgard */
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <math.h>
  11. #include <GL/glut.h>
  12. #ifndef GL_VERSION_1_1
  13. /* OpenGL 1.1 not supported so emulate OpenGL 1.1
  14.    vertex arrays with the EXT_vertex_array extension. */
  15. #define GL_VERTEX_ARRAY GL_VERTEX_ARRAY_EXT
  16. #define GL_NORMAL_ARRAY GL_NORMAL_ARRAY_EXT
  17. #define glDrawArrays(a,b,c) glDrawArraysEXT(a,b,c)
  18. #define glVertexPointer(a,b,c,d) glVertexPointerEXT(a,b,c,numverts,d)
  19. #define glNormalPointer(a,b,c) glNormalPointerEXT(a,b,numverts,c)
  20. #endif
  21. GLboolean speed_test = GL_FALSE;
  22. GLboolean use_vertex_arrays = GL_FALSE;
  23. GLboolean doubleBuffer = GL_TRUE;
  24. GLboolean smooth = GL_TRUE;
  25. GLboolean lighting = GL_TRUE;
  26. #define MAXVERTS 10000
  27. static GLfloat verts[MAXVERTS][3];
  28. static GLfloat norms[MAXVERTS][3];
  29. static GLint numverts;
  30. static GLfloat xrot;
  31. static GLfloat yrot;
  32. static void 
  33. read_surface(char *filename)
  34. {
  35.   FILE *f;
  36.   f = fopen(filename, "r");
  37.   if (!f) {
  38.     printf("couldn't read %sn", filename);
  39.     exit(1);
  40.   }
  41.   numverts = 0;
  42.   while (!feof(f) && numverts < MAXVERTS) {
  43.     fscanf(f, "%f %f %f  %f %f %f",
  44.       &verts[numverts][0], &verts[numverts][1], &verts[numverts][2],
  45.       &norms[numverts][0], &norms[numverts][1], &norms[numverts][2]);
  46.     numverts++;
  47.   }
  48.   numverts--;
  49.   printf("%d vertices, %d trianglesn", numverts, numverts - 2);
  50.   fclose(f);
  51. }
  52. static void 
  53. draw_surface(void)
  54. {
  55.   int i;
  56. #if defined(GL_EXT_vertex_array) || defined(GL_VERSION_1_1)
  57.   if (use_vertex_arrays) {
  58.     glDrawArrays(GL_TRIANGLE_STRIP, 0, numverts);
  59.   } else {
  60. #endif
  61.     glBegin(GL_TRIANGLE_STRIP);
  62.     for (i = 0; i < numverts; i++) {
  63.       glNormal3fv(norms[i]);
  64.       glVertex3fv(verts[i]);
  65.     }
  66.     glEnd();
  67. #if defined(GL_EXT_vertex_array) || defined(GL_VERSION_1_1)
  68.   }
  69. #endif
  70. }
  71. static void 
  72. draw1(void)
  73. {
  74.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  75.   glPushMatrix();
  76.   glRotatef(yrot, 0.0, 1.0, 0.0);
  77.   glRotatef(xrot, 1.0, 0.0, 0.0);
  78.   draw_surface();
  79.   glPopMatrix();
  80.   if (doubleBuffer) {
  81.     glutSwapBuffers();
  82.   } else {
  83.     glFlush();
  84.   }
  85. }
  86. static void 
  87. draw(void)
  88. {
  89.   if (speed_test) {
  90.     for (xrot = 0.0; xrot <= 360.0; xrot += 10.0) {
  91.       draw1();
  92.     }
  93.     exit(0);
  94.   } else {
  95.     draw1();
  96.   }
  97. }
  98. static void 
  99. InitMaterials(void)
  100. {
  101.   static float ambient[] =
  102.   {0.1, 0.1, 0.1, 1.0};
  103.   static float diffuse[] =
  104.   {0.5, 1.0, 1.0, 1.0};
  105.   static float position0[] =
  106.   {0.0, 0.0, 20.0, 0.0};
  107.   static float position1[] =
  108.   {0.0, 0.0, -20.0, 0.0};
  109.   static float front_mat_shininess[] =
  110.   {60.0};
  111.   static float front_mat_specular[] =
  112.   {0.2, 0.2, 0.2, 1.0};
  113.   static float front_mat_diffuse[] =
  114.   {0.5, 0.28, 0.38, 1.0};
  115.   static float lmodel_ambient[] =
  116.   {1.0, 1.0, 1.0, 1.0};
  117.   static float lmodel_twoside[] =
  118.   {GL_FALSE};
  119.   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  120.   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  121.   glLightfv(GL_LIGHT0, GL_POSITION, position0);
  122.   glEnable(GL_LIGHT0);
  123.   glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
  124.   glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
  125.   glLightfv(GL_LIGHT1, GL_POSITION, position1);
  126.   glEnable(GL_LIGHT1);
  127.   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  128.   glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
  129.   glEnable(GL_LIGHTING);
  130.   glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
  131.   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
  132.   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
  133. }
  134. static void 
  135. Init(void)
  136. {
  137.   glClearColor(0.0, 0.0, 0.0, 0.0);
  138.   glShadeModel(GL_SMOOTH);
  139.   glEnable(GL_DEPTH_TEST);
  140.   InitMaterials();
  141.   glMatrixMode(GL_PROJECTION);
  142.   glLoadIdentity();
  143.   glFrustum(-1.0, 1.0, -1.0, 1.0, 5, 25);
  144.   glMatrixMode(GL_MODELVIEW);
  145.   glLoadIdentity();
  146.   glTranslatef(0.0, 0.0, -6.0);
  147. #if defined(GL_EXT_vertex_array) || defined(GL_VERSION_1_1)
  148.   if (use_vertex_arrays) {
  149.     glVertexPointer(3, GL_FLOAT, 0, verts);
  150.     glNormalPointer(GL_FLOAT, 0, norms);
  151.     glEnable(GL_VERTEX_ARRAY);
  152.     glEnable(GL_NORMAL_ARRAY);
  153.   }
  154. #endif
  155. }
  156. /* ARGSUSED1 */
  157. static void 
  158. Key(unsigned char key, int x, int y)
  159. {
  160.   switch (key) {
  161.   case 27:  /* Escape */
  162.     exit(0);
  163.     break;
  164.   case 'S':
  165.   case 's':
  166.     smooth = !smooth;
  167.     if (smooth) {
  168.       glShadeModel(GL_SMOOTH);
  169.     } else {
  170.       glShadeModel(GL_FLAT);
  171.     }
  172.     break;
  173.   case 'L':
  174.   case 'l':
  175.     lighting = !lighting;
  176.     if (lighting) {
  177.       glEnable(GL_LIGHTING);
  178.     } else {
  179.       glDisable(GL_LIGHTING);
  180.     }
  181.     break;
  182.   default:
  183.     return;
  184.   }
  185.   glutPostRedisplay();
  186. }
  187. /* ARGSUSED1 */
  188. static void 
  189. Special(int key, int x, int y)
  190. {
  191.   switch (key) {
  192.   case GLUT_KEY_LEFT:
  193.     yrot -= 15.0;
  194.     break;
  195.   case GLUT_KEY_RIGHT:
  196.     yrot += 15.0;
  197.     break;
  198.   case GLUT_KEY_UP:
  199.     xrot += 15.0;
  200.     break;
  201.   case GLUT_KEY_DOWN:
  202.     xrot -= 15.0;
  203.     break;
  204.   default:
  205.     return;
  206.   }
  207.   glutPostRedisplay();
  208. }
  209. static GLboolean
  210. Args(int argc, char **argv)
  211. {
  212.   GLint i;
  213.   for (i = 1; i < argc; i++) {
  214.     if (strcmp(argv[i], "-sb") == 0) {
  215.       doubleBuffer = GL_FALSE;
  216.     } else if (strcmp(argv[i], "-db") == 0) {
  217.       doubleBuffer = GL_TRUE;
  218.     } else if (strcmp(argv[i], "-speed") == 0) {
  219.       speed_test = GL_TRUE;
  220.       doubleBuffer = GL_TRUE;
  221.     } else if (strcmp(argv[i], "-va") == 0) {
  222.       use_vertex_arrays = GL_TRUE;
  223.     } else {
  224.       printf("%s (Bad option).n", argv[i]);
  225.       return GL_FALSE;
  226.     }
  227.   }
  228.   return GL_TRUE;
  229. }
  230. int
  231. supportsOneDotOne(void)
  232. {
  233.   const GLubyte *version;
  234.   int major, minor;
  235.   version = glGetString(GL_VERSION);
  236.   if (sscanf(version, "%d.%d", &major, &minor) == 2)
  237.     return major > 1 || minor >= 1;
  238.   return 0;  /* OpenGL version string malformed! */
  239. }
  240. int 
  241. main(int argc, char **argv)
  242. {
  243.   int type;
  244.   glutInitWindowSize(400, 400);
  245.   glutInit(&argc, argv);
  246.   read_surface("isosurf.dat");
  247.   if (Args(argc, argv) == GL_FALSE) {
  248.     exit(1);
  249.   }
  250.   type = GLUT_DEPTH;
  251.   type |= GLUT_RGB;
  252.   type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  253.   glutInitDisplayMode(type);
  254.   glutCreateWindow("Isosurface");
  255.   /* Make sure server supports the vertex array extension */
  256.   if (glutExtensionSupported("GL_EXT_vertex_array")) {
  257.     use_vertex_arrays = GL_FALSE;
  258.   }
  259.   if (supportsOneDotOne()) {
  260.     /* Always use vertex arrays if OpenGL 1.1 is supported! */
  261.     use_vertex_arrays = GL_TRUE;
  262.   }
  263.   Init();
  264.   glutDisplayFunc(draw);
  265.   glutKeyboardFunc(Key);
  266.   glutSpecialFunc(Special);
  267.   glutMainLoop();
  268.   return 0;             /* ANSI C requires main to return int. */
  269. }