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

GIS编程

开发平台:

Visual C++

  1. /* field.c - by Tom McReynolds, SGI */
  2. /* Using the accumulation buffer for depth of field (camera focus blur). */
  3. #include <GL/glut.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. const GLdouble FRUSTDIM = 100.f;
  7. const GLdouble FRUSTNEAR = 320.f;
  8. const GLdouble FRUSTFAR = 660.f;
  9. /*
  10. ** Create a single component texture map
  11. */
  12. GLfloat *make_texture(int maxs, int maxt)
  13. {
  14.     int s, t;
  15.     static GLfloat *texture;
  16.     texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat));
  17.     for(t = 0; t < maxt; t++) {
  18.         for(s = 0; s < maxs; s++) {
  19.             texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1);
  20.         }
  21.     }
  22.     return texture;
  23. }
  24. enum {SPHERE = 1, CONE};
  25. void
  26. render(void)
  27. {
  28.     /* material properties for objects in scene */
  29.     static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f};
  30.     glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
  31.     /*
  32.     ** Note: wall verticies are ordered so they are all front facing
  33.     ** this lets me do back face culling to speed things up.
  34.     */
  35.  
  36.     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat);
  37.     /* floor */
  38.     /* make the floor textured */
  39.     glEnable(GL_TEXTURE_2D);
  40.     /*
  41.     ** Since we want to turn texturing on for floor only, we have to
  42.     ** make floor a separate glBegin()/glEnd() sequence. You can't
  43.     ** turn texturing on and off between begin and end calls
  44.     */
  45.     glBegin(GL_QUADS);
  46.     glNormal3f(0.f, 1.f, 0.f);
  47.     glTexCoord2i(0, 0);
  48.     glVertex3f(-100.f, -100.f, -320.f);
  49.     glTexCoord2i(1, 0);
  50.     glVertex3f( 100.f, -100.f, -320.f);
  51.     glTexCoord2i(1, 1);
  52.     glVertex3f( 100.f, -100.f, -640.f);
  53.     glTexCoord2i(0, 1);
  54.     glVertex3f(-100.f, -100.f, -640.f);
  55.     glEnd();
  56.     glDisable(GL_TEXTURE_2D);
  57.     /* walls */
  58.     glBegin(GL_QUADS);
  59.     /* left wall */
  60.     glNormal3f(1.f, 0.f, 0.f);
  61.     glVertex3f(-100.f, -100.f, -320.f);
  62.     glVertex3f(-100.f, -100.f, -640.f);
  63.     glVertex3f(-100.f,  100.f, -640.f);
  64.     glVertex3f(-100.f,  100.f, -320.f);
  65.     /* right wall */
  66.     glNormal3f(-1.f, 0.f, 0.f);
  67.     glVertex3f( 100.f, -100.f, -320.f);
  68.     glVertex3f( 100.f,  100.f, -320.f);
  69.     glVertex3f( 100.f,  100.f, -640.f);
  70.     glVertex3f( 100.f, -100.f, -640.f);
  71.     /* ceiling */
  72.     glNormal3f(0.f, -1.f, 0.f);
  73.     glVertex3f(-100.f,  100.f, -320.f);
  74.     glVertex3f(-100.f,  100.f, -640.f);
  75.     glVertex3f( 100.f,  100.f, -640.f);
  76.     glVertex3f( 100.f,  100.f, -320.f);
  77.     /* back wall */
  78.     glNormal3f(0.f, 0.f, 1.f);
  79.     glVertex3f(-100.f, -100.f, -640.f);
  80.     glVertex3f( 100.f, -100.f, -640.f);
  81.     glVertex3f( 100.f,  100.f, -640.f);
  82.     glVertex3f(-100.f,  100.f, -640.f);
  83.     glEnd();
  84.     glPushMatrix();
  85.     glTranslatef(-80.f, -60.f, -420.f);
  86.     glCallList(SPHERE);
  87.     glPopMatrix();
  88.     glPushMatrix();
  89.     glTranslatef(-20.f, -80.f, -600.f);
  90.     glCallList(CONE);
  91.     glPopMatrix();
  92.     if(glGetError()) /* to catch programming errors; should never happen */
  93.        printf("Oops! I screwed up my OpenGL calls somewheren");
  94.     glFlush(); /* high end machines may need this */
  95. }
  96. enum {NONE, FIELD};
  97. int rendermode = NONE;
  98. void
  99. menu(int selection)
  100. {
  101.   rendermode = selection;
  102.   glutPostRedisplay();
  103. }
  104. GLdouble focus = 420.;
  105. /* Called when window needs to be redrawn */
  106. void redraw(void)
  107. {
  108.     int i, j;
  109.     int min, max;
  110.     int count;
  111.     GLfloat scale, dx, dy;
  112.     switch(rendermode) {
  113.     case NONE:
  114.       glLoadIdentity();
  115.       glMatrixMode(GL_PROJECTION);
  116.       glLoadIdentity();
  117.       glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, FRUSTNEAR, FRUSTFAR); 
  118.       glMatrixMode(GL_MODELVIEW);
  119.       render();
  120.       break;
  121.     case FIELD:
  122.       min = -2;
  123.       max = -min + 1;
  124.       count = -2 * min + 1;
  125.       count *= count;
  126.       scale = 2.f;
  127.       glClear(GL_ACCUM_BUFFER_BIT);
  128.       for(j = min; j < max; j++) {
  129.         for(i = min; i < max; i++) {
  130.           dx = scale * i * FRUSTNEAR/focus;
  131.           dy = scale * j * FRUSTNEAR/focus;
  132.           glMatrixMode(GL_PROJECTION);
  133.           glLoadIdentity();
  134.           glFrustum(-FRUSTDIM + dx, 
  135.                     FRUSTDIM + dx, 
  136.                     -FRUSTDIM + dy, 
  137.                     FRUSTDIM + dy, 
  138.                     FRUSTNEAR,
  139.                     FRUSTFAR); 
  140.           glMatrixMode(GL_MODELVIEW);
  141.           glLoadIdentity();
  142.           glTranslatef(scale * i, scale * j, 0.f);
  143.           render();
  144.           glAccum(GL_ACCUM, 1.f/count);
  145.         }
  146.       } 
  147.       glAccum(GL_RETURN, 1.f);
  148.     break;
  149.     }
  150.     glutSwapBuffers();
  151. }
  152. /* ARGSUSED1 */
  153. void key(unsigned char key, int x, int y)
  154. {
  155.     if(key == '33')
  156.         exit(0);
  157. }
  158. const int TEXDIM = 256;
  159. /* Parse arguments, and set up interface between OpenGL and window system */
  160. int
  161. main(int argc, char *argv[])
  162. {
  163.     GLfloat *tex;
  164.     static GLfloat lightpos[] = {50.f, 50.f, -320.f, 1.f};
  165.     static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f};
  166.     static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f};
  167.     GLUquadricObj *sphere, *cone, *base;
  168.     glutInit(&argc, argv);
  169.     glutInitWindowSize(512, 512);
  170.     glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_ACCUM|GLUT_DOUBLE);
  171.     (void)glutCreateWindow("depth of field");
  172.     glutDisplayFunc(redraw);
  173.     glutKeyboardFunc(key);
  174.     glutCreateMenu(menu);
  175.     glutAddMenuEntry("Normal", NONE);
  176.     glutAddMenuEntry("Depth of Field", FIELD);
  177.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  178.     /* turn on features */
  179.     glEnable(GL_DEPTH_TEST);
  180.     glEnable(GL_LIGHTING);
  181.     glEnable(GL_LIGHT0);
  182.     /* place light 0 in the right place */
  183.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  184.     /* remove back faces to speed things up */
  185.     glCullFace(GL_BACK);
  186.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  187.     glNewList(SPHERE, GL_COMPILE);
  188.     /* make display lists for sphere and cone; for efficiency */
  189.     sphere = gluNewQuadric();
  190.     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat);
  191.     gluSphere(sphere, 20.f, 20, 20);
  192.     gluDeleteQuadric(sphere);
  193.     glEndList();
  194.     glNewList(CONE, GL_COMPILE);
  195.     cone = gluNewQuadric();
  196.     base = gluNewQuadric();
  197.     glRotatef(-90.f, 1.f, 0.f, 0.f);
  198.     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat);
  199.     gluDisk(base, 0., 20., 20, 1);
  200.     gluCylinder(cone, 20., 0., 60., 20, 20);
  201.     gluDeleteQuadric(cone);
  202.     gluDeleteQuadric(base);
  203.     glEndList();
  204.     /* load pattern for current 2d texture */
  205.     tex = make_texture(TEXDIM, TEXDIM);
  206.     glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex);
  207.     free(tex);
  208.     glutMainLoop();
  209.     return 0;             /* ANSI C requires main to return int. */
  210. }