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

GIS编程

开发平台:

Visual C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <GL/glut.h>
  4. /*
  5. ** Create a single component texture map
  6. */
  7. GLfloat *make_texture(int maxs, int maxt)
  8. {
  9.     int s, t;
  10.     static GLfloat *texture;
  11.     texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat));
  12.     for(t = 0; t < maxt; t++) {
  13. for(s = 0; s < maxs; s++) {
  14.     texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1);
  15. }
  16.     }
  17.     return texture;
  18. }
  19. GLboolean stencil = GL_TRUE;
  20. /* ARGSUSED1 */
  21. void key(unsigned char key, int x, int y)
  22. {
  23.     switch(key) {
  24.     case 't': /* toggle using stencil */
  25.       if(stencil == GL_TRUE)
  26. stencil = GL_FALSE;
  27.       else
  28. stencil = GL_TRUE;
  29.       glutPostRedisplay();
  30.       break;
  31.     case '33':
  32.       exit(0);
  33.       break;
  34.     }
  35. }
  36. enum {SPHERE = 1, CONE};
  37. enum {X, Y, Z};
  38. int startx, starty;
  39. int wid, ht;
  40. int oldwid = 0, oldht = 0;
  41. const int WINDIM = 512;
  42. const GLfloat FRUSTDIM = 110.f;
  43. const GLfloat FRUSTNEAR = 320.f;
  44. const GLfloat FRUSTFAR = 540.f;
  45. const GLfloat FRUSTDIFF = 540.f - 320.f;
  46. GLboolean drawmode = GL_FALSE;
  47. GLboolean depthmode = GL_FALSE;
  48. GLboolean rubberbandmode = GL_FALSE;
  49. GLfloat *color;
  50. GLfloat *depth;
  51. GLfloat depthbias = 0.f;
  52. GLfloat raspos[] = {0.f, 0.f, -430.f};
  53. int winWidth = 512;
  54. int winHeight = 512;
  55. GLfloat sx = 0;
  56. GLfloat sy = 0;
  57. /* Overlay Stuff */
  58. int transparent;
  59. int red;
  60. void
  61. setRasterPosXY(int x, int y)
  62. {
  63.       raspos[X] = (x - winWidth/2) * sx;
  64.       raspos[Y] = (y - winHeight/2) * sy;
  65.       glRasterPos3fv(raspos);
  66.       glutPostRedisplay();
  67. }
  68. void
  69. setRasterPosZ(int y)
  70. {
  71.       raspos[Z] = -(FRUSTNEAR + y * FRUSTDIFF/winHeight);
  72.       depthbias = (y - winHeight/2.f)/winHeight;
  73.       glRasterPos3fv(raspos);
  74.       glutPostRedisplay();
  75. }
  76. void
  77. motion(int x, int y)
  78. {
  79.   y = winHeight - y;
  80.   if(drawmode)
  81.     setRasterPosXY(x, y);
  82.   if(rubberbandmode) {
  83.     wid = x - startx;
  84.     ht = y - starty;
  85.     glutPostOverlayRedisplay();
  86.   }
  87.   if(depthmode)
  88.      setRasterPosZ(y);
  89. }
  90. /* redraw function for overlay: used to show selected region */
  91. void
  92. overlay(void)
  93. {
  94.   if(glutLayerGet(GLUT_OVERLAY_DAMAGED)) {
  95.     glClear(GL_COLOR_BUFFER_BIT);
  96.   } else {
  97.     glIndexi(transparent);
  98.     glBegin(GL_LINE_LOOP);
  99.     glVertex2i(startx, starty);
  100.     glVertex2i(startx + oldwid, starty);
  101.     glVertex2i(startx + oldwid, starty + oldht);
  102.     glVertex2i(startx, starty + oldht);
  103.     glEnd();
  104.   }
  105.   glIndexi(red);
  106.   glBegin(GL_LINE_LOOP);
  107.   glVertex2i(startx, starty);
  108.   glVertex2i(startx + wid, starty);
  109.   glVertex2i(startx + wid, starty + ht);
  110.   glVertex2i(startx, starty + ht);
  111.   glEnd();
  112.   oldwid = wid;
  113.   oldht = ht;
  114.   glFlush();
  115. }
  116. /* used to get current width and height of viewport */
  117. void
  118. reshape(int wid, int ht)
  119. {
  120.   glutUseLayer(GLUT_OVERLAY);
  121.   glMatrixMode(GL_PROJECTION);
  122.   glLoadIdentity();
  123.   gluOrtho2D(0, wid, 0, ht); /* 1 to 1 with window */
  124.   glMatrixMode(GL_MODELVIEW);
  125.   glViewport(0, 0, wid, ht);
  126.   glutUseLayer(GLUT_NORMAL);
  127.   glViewport((GLint) (-wid * .1), (GLint) (-ht * .1),
  128.     (GLsizei) (wid * 1.2), (GLsizei) (ht * 1.2));
  129.   winWidth = wid;
  130.   winHeight = ht;
  131.   sx = 2 * FRUSTDIM/(winWidth * 1.2);
  132.   sy = 2 * FRUSTDIM/(winHeight * 1.2);
  133. }
  134. void
  135. mouse(int button, int state, int x, int y)
  136. {
  137.   y = winHeight - y; /* flip y orientation */
  138.   if(state == GLUT_DOWN)
  139.     switch(button) {
  140.     case GLUT_LEFT_BUTTON: /* select an image */
  141.       startx = x;
  142.       starty = y;
  143.       wid = 0; ht = 0;
  144.       rubberbandmode = GL_TRUE;
  145.       glutShowOverlay();
  146.       break;
  147.     case GLUT_MIDDLE_BUTTON:
  148.       glutUseLayer(GLUT_NORMAL);
  149.       if(color && depth) {
  150.   drawmode = GL_TRUE;
  151.   setRasterPosXY(x, y);
  152.       }
  153.       break;
  154.     case GLUT_RIGHT_BUTTON: /* change depth */
  155.       glutUseLayer(GLUT_NORMAL);
  156.       if(color && depth) {
  157. depthmode = GL_TRUE;
  158. setRasterPosZ(y);
  159.       }
  160.       break;
  161.     }
  162.   else /* GLUT_UP */
  163.     switch(button) {
  164.     case GLUT_LEFT_BUTTON:
  165.       rubberbandmode = GL_FALSE;
  166.       glutHideOverlay();
  167.       wid = x - startx;
  168.       ht = y - starty;
  169.       if(wid < 0) {
  170. wid = -wid;
  171. startx = x;
  172.       }
  173.       if(ht < 0) {
  174. ht = -ht;
  175. starty = y;
  176.       }
  177.       color = (GLfloat *)realloc(color, wid * ht * 3 * sizeof(GLfloat));
  178.       depth = (GLfloat *)realloc(depth, wid * ht * sizeof(GLfloat));
  179.       glutUseLayer(GLUT_NORMAL);
  180.       glReadPixels(startx, starty, wid, ht, GL_RGB, GL_FLOAT, color);
  181.       glReadPixels(startx, starty, wid, ht, GL_DEPTH_COMPONENT, GL_FLOAT,
  182.    depth);
  183.       break;
  184.     case GLUT_MIDDLE_BUTTON:
  185.       drawmode = GL_FALSE;
  186.       break;
  187.     case GLUT_RIGHT_BUTTON: /* change depth */
  188.       depthmode = GL_FALSE;
  189.       break;
  190.     }
  191. }
  192. /* Called when window needs to be redrawn */
  193. void 
  194. redraw(void)
  195. {
  196.     /* material properties for objects in scene */
  197.     static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f};
  198.     glutUseLayer(GLUT_NORMAL);
  199.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
  200.     /*
  201.     ** Note: wall verticies are ordered so they are all front facing
  202.     ** this lets me do back face culling to speed things up.
  203.     */
  204.  
  205.     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat);
  206.     /* floor */
  207.     /* make the floor textured */
  208.     glEnable(GL_TEXTURE_2D);
  209.     /*
  210.     ** Since we want to turn texturing on for floor only, we have to
  211.     ** make floor a separate glBegin()/glEnd() sequence. You can't
  212.     ** turn texturing on and off between begin and end calls
  213.     */
  214.     glBegin(GL_QUADS);
  215.     glNormal3f(0.f, 1.f, 0.f);
  216.     glTexCoord2i(0, 0);
  217.     glVertex3f(-100.f, -100.f, -320.f);
  218.     glTexCoord2i(1, 0);
  219.     glVertex3f( 100.f, -100.f, -320.f);
  220.     glTexCoord2i(1, 1);
  221.     glVertex3f( 100.f, -100.f, -520.f);
  222.     glTexCoord2i(0, 1);
  223.     glVertex3f(-100.f, -100.f, -520.f);
  224.     glEnd();
  225.     glDisable(GL_TEXTURE_2D);
  226.     /* walls */
  227.     glBegin(GL_QUADS);
  228.     /* left wall */
  229.     glNormal3f(1.f, 0.f, 0.f);
  230.     glVertex3f(-100.f, -100.f, -320.f);
  231.     glVertex3f(-100.f, -100.f, -520.f);
  232.     glVertex3f(-100.f,  100.f, -520.f);
  233.     glVertex3f(-100.f,  100.f, -320.f);
  234.     /* right wall */
  235.     glNormal3f(-1.f, 0.f, 0.f);
  236.     glVertex3f( 100.f, -100.f, -320.f);
  237.     glVertex3f( 100.f,  100.f, -320.f);
  238.     glVertex3f( 100.f,  100.f, -520.f);
  239.     glVertex3f( 100.f, -100.f, -520.f);
  240.     /* ceiling */
  241.     glNormal3f(0.f, -1.f, 0.f);
  242.     glVertex3f(-100.f,  100.f, -320.f);
  243.     glVertex3f(-100.f,  100.f, -520.f);
  244.     glVertex3f( 100.f,  100.f, -520.f);
  245.     glVertex3f( 100.f,  100.f, -320.f);
  246.     /* back wall */
  247.     glNormal3f(0.f, 0.f, 1.f);
  248.     glVertex3f(-100.f, -100.f, -520.f);
  249.     glVertex3f( 100.f, -100.f, -520.f);
  250.     glVertex3f( 100.f,  100.f, -520.f);
  251.     glVertex3f(-100.f,  100.f, -520.f);
  252.     glEnd();
  253.     glPushMatrix();
  254.     glTranslatef(-40.f, -60.f, -400.f);
  255.     glScalef(2, 2, 2);
  256.     glCallList(SPHERE);
  257.     glPopMatrix();
  258.     glPushMatrix();
  259.     glTranslatef(50.f, -120.f, -400.f);
  260.     glScalef(2, 2, 2);
  261.     glCallList(CONE);
  262.     glPopMatrix();
  263.     if(stencil) {
  264.       glEnable(GL_STENCIL_TEST);
  265.       glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  266.       glStencilFunc(GL_ALWAYS, 1, 1);
  267.       glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
  268.       glPixelTransferf(GL_DEPTH_BIAS, depthbias);
  269.       glDrawPixels(wid, ht, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
  270.       glPixelTransferf(GL_DEPTH_BIAS, 0.f);
  271.       glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  272.       glStencilFunc(GL_EQUAL, 1, 1);
  273.       glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  274.       glDisable(GL_DEPTH_TEST);
  275.       glDrawPixels(wid, ht, GL_RGB, GL_FLOAT, color);
  276.       glEnable(GL_DEPTH_TEST);
  277.       glDisable(GL_STENCIL_TEST);
  278.     } else
  279.       glDrawPixels(wid, ht, GL_RGB, GL_FLOAT, color);
  280.     glutSwapBuffers();
  281. }
  282. const int TEXDIM = 256;
  283. /* Parse arguments, and set up interface between OpenGL and window system */
  284. main(int argc, char *argv[])
  285. {
  286.     GLfloat *tex;
  287.     static GLfloat lightpos[] = {50.f, 50.f, -320.f, 1.f};
  288.     static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f};
  289.     static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f};
  290.     GLUquadricObj *sphere, *cone, *base;
  291.     glutInit(&argc, argv);
  292.     glutInitWindowSize(WINDIM, WINDIM);
  293.     glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL|GLUT_DOUBLE);
  294.     (void)glutCreateWindow("compositing images with depth");
  295.     glutDisplayFunc(redraw);
  296.     glutKeyboardFunc(key);
  297.     glutMouseFunc(mouse);
  298.     glutMotionFunc(motion);
  299.     glutReshapeFunc(reshape);
  300.     /* draw a perspective scene */
  301.     glMatrixMode(GL_PROJECTION);
  302.     glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, FRUSTNEAR, FRUSTFAR); 
  303.     glMatrixMode(GL_MODELVIEW);
  304.     /* turn on features */
  305.     glEnable(GL_DEPTH_TEST);
  306.     glEnable(GL_LIGHTING);
  307.     glEnable(GL_LIGHT0);
  308.     /* place light 0 in the right place */
  309.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  310.     /* remove back faces to speed things up */
  311.     glCullFace(GL_BACK);
  312.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  313.     glNewList(SPHERE, GL_COMPILE);
  314.     /* make display lists for sphere and cone; for efficiency */
  315.     sphere = gluNewQuadric();
  316.     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat);
  317.     gluSphere(sphere, 20.f, 20, 20);
  318.     gluDeleteQuadric(sphere);
  319.     glEndList();
  320.     glNewList(CONE, GL_COMPILE);
  321.     cone = gluNewQuadric();
  322.     base = gluNewQuadric();
  323.     glRotatef(-90.f, 1.f, 0.f, 0.f);
  324.     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat);
  325.     gluQuadricOrientation(base, GLU_INSIDE);
  326.     gluDisk(base, 0., 20., 20, 1);
  327.     gluCylinder(cone, 20., 0., 60., 20, 20);
  328.     gluDeleteQuadric(cone);
  329.     gluDeleteQuadric(base);
  330.     glEndList();
  331.     /* load pattern for current 2d texture */
  332.     tex = make_texture(TEXDIM, TEXDIM);
  333.     glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex);
  334.     free(tex);
  335.     /* storage for saved image */
  336.     color = 0;
  337.     depth = 0;
  338.     
  339.     glReadBuffer(GL_FRONT);/* so glReadPixel() always get the right image */
  340.     glutInitDisplayMode(GLUT_SINGLE|GLUT_INDEX);
  341.     if(glutLayerGet(GLUT_OVERLAY_POSSIBLE)) {
  342.       glutEstablishOverlay();
  343.       glutHideOverlay();
  344.       transparent = glutLayerGet(GLUT_TRANSPARENT_INDEX);
  345.       glClearIndex(transparent);
  346.       red = (transparent + 1) % glutGet(GLUT_WINDOW_COLORMAP_SIZE);
  347.       glutSetColor(red, 1.0, 0.0, 0.0);  /* Red. */
  348.       glutOverlayDisplayFunc(overlay);
  349.     }
  350. else
  351. {
  352. printf( "Overlay support unavailable - aborting.n" );
  353. return 1;
  354. }
  355.     glutMainLoop();
  356.     return 0;
  357. }