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

GIS编程

开发平台:

Visual C++

  1. /* This program demonstrates how to use the stencil buffer to visualize
  2. ** the depth complexity of a scene.
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <GL/glut.h>
  7. /* show contents of stencil buffer */
  8. int winwid = 512;
  9. int winht = 512;
  10. GLubyte *stencil = 0; /* so realloc works the first time */
  11. void resize(int wid, int ht)
  12. {
  13.     winwid = wid;
  14.     winht = ht;
  15.     stencil = (GLubyte *)realloc((void*)stencil,
  16.                                  winwid * winht * sizeof(GLubyte));
  17.     glViewport(0, 0, wid, ht);
  18. }
  19. /* ARGSUSED1 */
  20. void key(unsigned char key, int x, int y)
  21. {
  22.     if(key == '33')
  23.         exit(0);
  24. }
  25. int rotate = 0;
  26. GLfloat udangle = 0.f;
  27. GLfloat lrangle = 0.f;
  28. void motion(int x, int y)
  29. {
  30.     if(rotate)
  31.     {
  32.         udangle = (y - winht/2) * 360./winht;
  33.         lrangle = (x - winwid/2) * 360./winwid;
  34.     }
  35.     glutPostRedisplay();
  36. }
  37. void mouse(int button, int state, int x, int y)
  38. {
  39.     if(state == GLUT_DOWN)
  40.     switch(button)
  41.     {
  42.     case GLUT_LEFT_BUTTON: /* rotate the scene up and down */
  43.     case GLUT_MIDDLE_BUTTON: /* rotate the scene left and right */
  44.         rotate = 1;
  45.         motion(x, y);
  46.         break;
  47.     }
  48.     else
  49.         rotate = 0; /* overkill; cover right button too */
  50. }
  51. /* read back stencil buffer, store in memory, draw back colorized */
  52. void showstencil(void)
  53. {
  54.     glReadPixels(0, 0, winwid, winht, GL_STENCIL_INDEX, 
  55.                  GL_UNSIGNED_BYTE, stencil);
  56.     glRasterPos2i(-1, -1);
  57.     glDrawPixels(winwid, winht, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, stencil);
  58. }
  59. int showdepth = 0;
  60. int depthtest = 1;
  61. /* Called when window needs to be redrawn */
  62. void redraw(void)
  63. {
  64.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
  65.     glEnable(GL_STENCIL_TEST);
  66.     if(depthtest)
  67.         glEnable(GL_DEPTH_TEST);
  68.     glPushMatrix();
  69.     glRotatef(lrangle, 0.f, 1.f, 0.f);
  70.     glRotatef(udangle, 1.f, 0.f, 0.f);
  71.     glCallList(1); /* draw scene */
  72.     glPopMatrix();
  73.     glDisable(GL_STENCIL_TEST);
  74.     glFlush(); /* high end machines may need this */
  75.     if(depthtest)
  76.         glDisable(GL_DEPTH_TEST);
  77.     if(showdepth)
  78.         showstencil();
  79.     if(glGetError()) /* to catch programming errors; should never happen */
  80.        printf("Oops! I screwed up my OpenGL calls somewheren");
  81.     glutSwapBuffers();
  82. }
  83. /* menu entries mapped to actions */
  84. enum {RENDER, SHOW_STENCIL, DEPTH_TEST};
  85. void menu(int choice)
  86. {
  87.     switch(choice)
  88.     {
  89.     case RENDER:
  90.         showdepth = 0;
  91.         break;
  92.     case SHOW_STENCIL:
  93.         showdepth = 1;
  94.         break;
  95.     case DEPTH_TEST:
  96.         depthtest = !depthtest;
  97.         if(depthtest)
  98.             /* show how many pixels were discarded by depth test */
  99.             glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
  100.         else
  101.             /* show how many pixels were written to frame buffer */
  102.             glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
  103.         break;
  104.     }
  105.     glutPostRedisplay();
  106. }
  107. typedef struct {
  108.     GLfloat r;
  109.     GLfloat g;
  110.     GLfloat b;
  111. } Color;
  112.  
  113. /* color map to indicate different depth complexities */
  114. Color map[] = {
  115.     {0.f, 0.f, 0.f,},
  116.     {0.f, .25f, 0.f,},
  117.     {0.f, .5f, 0.f,},
  118.     {0.f, .75f, 0.f,},
  119.     {0.f, 1.f, 0.f,},
  120.     {.25f, 1.f, 0.f,},
  121.     {.5f, 1.f, 0.f,},
  122.     {.75f, 1.f, 0.f,},
  123.     {1.f, 1.f, 0.f,},
  124.     {1.f, .75f, 0.f,},
  125.     {1.f, .5f, 0.f,},
  126.     {1.f, .25f, 0.f,},
  127.     {1.f, .0f, 0.f,},
  128.     {1.f, .0f, 0.f,},
  129.     {1.f, .0f, 0.f,},
  130.     {1.f, .0f, 0.f,}
  131. };
  132. /* mapsize should be a power of two */
  133. #define mapsize 16
  134. GLfloat lightpos[4] = {.5f, .5f, -1.f, 1.f};
  135. main(int argc, char *argv[])
  136. {
  137.     GLfloat rmap[mapsize], gmap[mapsize], bmap[mapsize];
  138.     int i;
  139.     glutInit(&argc, argv);
  140.     glutInitWindowSize(winwid, winht);
  141.     glutInitDisplayMode(GLUT_RGBA|GLUT_STENCIL|GLUT_DOUBLE|GLUT_DEPTH);
  142.     (void)glutCreateWindow("visualizing depth complexity");
  143.     glutDisplayFunc(redraw);
  144.     glutKeyboardFunc(key);
  145.     glutReshapeFunc(resize);
  146.     glutMouseFunc(mouse);
  147.     glutMotionFunc(motion);
  148.     glutCreateMenu(menu);
  149.     glutAddMenuEntry("Draw Scene", RENDER);
  150.     glutAddMenuEntry("Show Stencil", SHOW_STENCIL);
  151.     glutAddMenuEntry("Toggle Depth Test", DEPTH_TEST);
  152.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  153.     glStencilFunc(GL_ALWAYS, ~0, ~0);
  154.     glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
  155.     /* draw an interesting scene */
  156.     glNewList(1, GL_COMPILE);
  157.     /* center */
  158.     glPushMatrix();
  159.     glScalef(.2f, .2f, .2f);
  160.     glutSolidTetrahedron();
  161.     glPopMatrix();
  162.     /* right */
  163.     glTranslatef(.4f, 0.f, 0.f);
  164.     glutSolidSphere(.25, 8, 8);
  165.     /* left */
  166.     glTranslatef(-.8f, 0.f, 0.f);
  167.     glutSolidSphere(.25, 8, 8);
  168.     /* bottom */
  169.     glTranslatef(.4f, -.4f, 0.f);
  170.     glutSolidSphere(.25, 8, 8);
  171.     /* top */
  172.     glTranslatef(0.f, .8f, 0.f);
  173.     glutSolidSphere(.25, 8, 8);
  174.     /* lefttop */
  175.     glTranslatef(-.5f, .1f, 0.f);
  176.     glutSolidCube(.3);
  177.     /* righttop */
  178.     glTranslatef(1.f, 0.f, 0.f);
  179.     glutSolidCube(.3);
  180.     /* rightbot */
  181.     glTranslatef(0.f, -1.f, 0.f);
  182.     glutSolidCube(.3);
  183.     /* rightbot */
  184.     glTranslatef(-1.f, 0.f, 0.f);
  185.     glutSolidCube(.3);
  186.     glEndList();
  187.     /* color ramp to show increasing complexity */
  188.     /* black shading to green to yellow to red */
  189.     for(i = 0; i < mapsize; i++)
  190.     {
  191.         rmap[i] = map[i].r;
  192.         gmap[i] = map[i].g;
  193.         bmap[i] = map[i].b;
  194.     }
  195.     glPixelMapfv(GL_PIXEL_MAP_I_TO_R, mapsize, rmap);
  196.     glPixelMapfv(GL_PIXEL_MAP_I_TO_G, mapsize, gmap);
  197.     glPixelMapfv(GL_PIXEL_MAP_I_TO_B, mapsize, bmap);
  198.     glEnable(GL_LIGHTING);
  199.     glEnable(GL_LIGHT0);
  200.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  201.     glutMainLoop();
  202.     return 0;
  203. }