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

GIS编程

开发平台:

Visual C++

  1. /* reflect.c */
  2. /**
  3.  * Demo of a reflective, texture-mapped surface with OpenGL.
  4.  * Brian Paul  (brianp@ssec.wisc.edu)  August 14, 1995
  5.  *
  6.  * Hardware texture mapping is highly recommended!
  7.  *
  8.  * The basic steps are:
  9.  *    1. Render the reflective object (a polygon) from the normal viewpoint,
  10.  *       setting the stencil planes = 1.
  11.  *    2. Render the scene from a special viewpoint:  the viewpoint which
  12.  *       is on the opposite side of the reflective plane.  Only draw where
  13.  *       stencil = 1.  This draws the objects in the reflective surface.
  14.  *    3. Render the scene from the original viewpoint.  This draws the
  15.  *       objects in the normal fashion.  Use blending when drawing
  16.  *       the reflective, textured surface.
  17.  *
  18.  * This is a very crude demo.  It could be much better.
  19.  */
  20. /*
  21.  * Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
  22.  *
  23.  * August 1996 - A few optimizations by Brian
  24.  */
  25. /* Conversion to GLUT by Mark J. Kilgard */
  26. #define USE_ZBUFFER
  27. /* OK, without hardware support this is overkill. */
  28. #define USE_TEXTURE
  29. #include <math.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <GL/glut.h>
  33. #include "image.h"
  34. #define DEG2RAD (3.14159/180.0)
  35. #define TABLE_TEXTURE "brick.rgb"
  36. #define MAX_OBJECTS 2
  37. static GLint table_list;
  38. static GLint objects_list[MAX_OBJECTS];
  39. static GLfloat xrot, yrot;
  40. static GLfloat spin;
  41. static void 
  42. make_table(void)
  43. {
  44.   static GLfloat table_mat[] =
  45.   {1.0, 1.0, 1.0, 0.6};
  46.   static GLfloat gray[] =
  47.   {0.4, 0.4, 0.4, 1.0};
  48.   table_list = glGenLists(1);
  49.   glNewList(table_list, GL_COMPILE);
  50.   /* load table's texture */
  51.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat);
  52. /*   glMaterialfv( GL_FRONT, GL_EMISSION, gray ); */
  53.   glMaterialfv(GL_FRONT, GL_DIFFUSE, table_mat);
  54.   glMaterialfv(GL_FRONT, GL_AMBIENT, gray);
  55.   /* draw textured square for the table */
  56.   glPushMatrix();
  57.   glScalef(4.0, 4.0, 4.0);
  58.   glBegin(GL_POLYGON);
  59.   glNormal3f(0.0, 1.0, 0.0);
  60.   glTexCoord2f(0.0, 0.0);
  61.   glVertex3f(-1.0, 0.0, 1.0);
  62.   glTexCoord2f(1.0, 0.0);
  63.   glVertex3f(1.0, 0.0, 1.0);
  64.   glTexCoord2f(1.0, 1.0);
  65.   glVertex3f(1.0, 0.0, -1.0);
  66.   glTexCoord2f(0.0, 1.0);
  67.   glVertex3f(-1.0, 0.0, -1.0);
  68.   glEnd();
  69.   glPopMatrix();
  70.   glDisable(GL_TEXTURE_2D);
  71.   glEndList();
  72. }
  73. static void 
  74. make_objects(void)
  75. {
  76.   GLUquadricObj *q;
  77.   static GLfloat cyan[] =
  78.   {0.0, 1.0, 1.0, 1.0};
  79.   static GLfloat green[] =
  80.   {0.2, 1.0, 0.2, 1.0};
  81.   static GLfloat black[] =
  82.   {0.0, 0.0, 0.0, 0.0};
  83.   q = gluNewQuadric();
  84.   gluQuadricDrawStyle(q, GLU_FILL);
  85.   gluQuadricNormals(q, GLU_SMOOTH);
  86.   objects_list[0] = glGenLists(1);
  87.   glNewList(objects_list[0], GL_COMPILE);
  88.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan);
  89.   glMaterialfv(GL_FRONT, GL_EMISSION, black);
  90.   gluCylinder(q, 0.5, 0.5, 1.0, 15, 10);
  91.   glEndList();
  92.   objects_list[1] = glGenLists(1);
  93.   glNewList(objects_list[1], GL_COMPILE);
  94.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
  95.   glMaterialfv(GL_FRONT, GL_EMISSION, black);
  96.   gluCylinder(q, 1.5, 0.0, 2.5, 15, 10);
  97.   glEndList();
  98. }
  99. static GLfloat light_pos[] =
  100. {0.0, 20.0, 0.0, 1.0};
  101. static void 
  102. init(void)
  103. {
  104.   RGBImageRec *image;
  105.   make_table();
  106.   make_objects();
  107.   /* Setup texture */
  108. #ifdef USE_TEXTURE
  109.   image = RGBImageLoad(TABLE_TEXTURE);
  110.   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY,
  111.     GL_RGB, GL_UNSIGNED_BYTE, image->data);
  112.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  113.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  114.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  115.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  116. #endif
  117.   xrot = 30.0;
  118.   yrot = 50.0;
  119.   spin = 0.0;
  120. #ifndef USE_ZBUFFER
  121.   glEnable(GL_CULL_FACE);
  122. #endif
  123.   glShadeModel(GL_FLAT);
  124.   glEnable(GL_LIGHT0);
  125.   glEnable(GL_LIGHTING);
  126.   glClearColor(0.5, 0.5, 0.5, 1.0);
  127.   glEnable(GL_NORMALIZE);
  128. }
  129. static void 
  130. reshape(int w, int h)
  131. {
  132.   GLfloat aspect = (float) w / (float) h;
  133.   glViewport(0, 0, w, h);
  134.   glMatrixMode(GL_PROJECTION);
  135.   glLoadIdentity();
  136.   glFrustum(-aspect, aspect, -1.0, 1.0, 4.0, 300.0);
  137.   glMatrixMode(GL_MODELVIEW);
  138.   glLoadIdentity();
  139. }
  140. /* ARGSUSED */
  141. static void 
  142. draw_objects(GLfloat eyex, GLfloat eyey, GLfloat eyez)
  143. {
  144. #ifndef USE_ZBUFFER
  145.   if (eyex < 0.5) {
  146. #endif
  147.     glPushMatrix();
  148.     glTranslatef(1.0, 1.5, 0.0);
  149.     glRotatef(spin, 1.0, 0.5, 0.0);
  150.     glRotatef(0.5 * spin, 0.0, 0.5, 1.0);
  151.     glCallList(objects_list[0]);
  152.     glPopMatrix();
  153.     glPushMatrix();
  154.     glTranslatef(-1.0, 0.85 + 3.0 * fabs(cos(0.01 * spin)), 0.0);
  155.     glRotatef(0.5 * spin, 0.0, 0.5, 1.0);
  156.     glRotatef(spin, 1.0, 0.5, 0.0);
  157.     glScalef(0.5, 0.5, 0.5);
  158.     glCallList(objects_list[1]);
  159.     glPopMatrix();
  160. #ifndef USE_ZBUFFER
  161.   } else {
  162.     glPushMatrix();
  163.     glTranslatef(-1.0, 0.85 + 3.0 * fabs(cos(0.01 * spin)), 0.0);
  164.     glRotatef(0.5 * spin, 0.0, 0.5, 1.0);
  165.     glRotatef(spin, 1.0, 0.5, 0.0);
  166.     glScalef(0.5, 0.5, 0.5);
  167.     glCallList(objects_list[1]);
  168.     glPopMatrix();
  169.     glPushMatrix();
  170.     glTranslatef(1.0, 1.5, 0.0);
  171.     glRotatef(spin, 1.0, 0.5, 0.0);
  172.     glRotatef(0.5 * spin, 0.0, 0.5, 1.0);
  173.     glCallList(objects_list[0]);
  174.     glPopMatrix();
  175.   }
  176. #endif
  177. }
  178. static void 
  179. draw_table(void)
  180. {
  181.   glCallList(table_list);
  182. }
  183. static void 
  184. draw_scene(void)
  185. {
  186.   GLfloat dist = 20.0;
  187.   GLfloat eyex, eyey, eyez;
  188.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  189.   eyex = dist * cos(yrot * DEG2RAD) * cos(xrot * DEG2RAD);
  190.   eyez = dist * sin(yrot * DEG2RAD) * cos(xrot * DEG2RAD);
  191.   eyey = dist * sin(xrot * DEG2RAD);
  192.   /* view from top */
  193.   glPushMatrix();
  194.   gluLookAt(eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
  195.   glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  196.   /* draw table into stencil planes */
  197.   glEnable(GL_STENCIL_TEST);
  198. #ifdef USE_ZBUFFER
  199.   glDisable(GL_DEPTH_TEST);
  200. #endif
  201.   glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
  202.   glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
  203.   glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  204.   draw_table();
  205.   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  206. #ifdef USE_ZBUFFER
  207.   glEnable(GL_DEPTH_TEST);
  208. #endif
  209.   /* render view from below (reflected viewport) */
  210.   /* only draw where stencil==1 */
  211.   if (eyey > 0.0) {
  212.     glPushMatrix();
  213.     glStencilFunc(GL_EQUAL, 1, 0xffffffff);  /* draw if ==1 */
  214.     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  215.     glScalef(1.0, -1.0, 1.0);
  216.     /* Reposition light in reflected space. */
  217.     glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  218.     draw_objects(eyex, eyey, eyez);
  219.     glPopMatrix();
  220.     /* Restore light's original unreflected position. */
  221.     glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  222.   }
  223.   glDisable(GL_STENCIL_TEST);
  224.   glEnable(GL_BLEND);
  225.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  226. #ifdef USE_TEXTURE
  227.   glEnable(GL_TEXTURE_2D);
  228. #endif
  229.   draw_table();
  230.   glDisable(GL_TEXTURE_2D);
  231.   glDisable(GL_BLEND);
  232.   /* view from top */
  233.   glPushMatrix();
  234.   draw_objects(eyex, eyey, eyez);
  235.   glPopMatrix();
  236.   glPopMatrix();
  237.   glutSwapBuffers();
  238. }
  239. /* ARGSUSED1 */
  240. void 
  241. key(unsigned char key, int x, int y)
  242. {
  243.   switch (key) {
  244.   case 27:
  245.     exit(0);
  246.     break;
  247.   }
  248. }
  249. /* ARGSUSED1 */
  250. void
  251. special(int key, int x, int y)
  252. {
  253.   switch(key) {
  254.   case GLUT_KEY_UP:
  255.     xrot += 3.0;
  256. #ifndef USE_ZBUFFER
  257.     if (xrot > 180)
  258.       xrot = 180;
  259. #endif
  260.     break;
  261.   case GLUT_KEY_DOWN:
  262.     xrot -= 3.0;
  263. #ifndef USE_ZBUFFER
  264.     if (xrot < 0)
  265.       xrot = 0;
  266. #endif
  267.     break;
  268.   case GLUT_KEY_LEFT:
  269.     yrot += 3.0;
  270.     break;
  271.   case GLUT_KEY_RIGHT:
  272.     yrot -= 3.0;
  273.     break;
  274.   default:
  275.     return;
  276.   }
  277.   glutPostRedisplay();
  278. }
  279. static void 
  280. idle(void)
  281. {
  282.   spin += 2.0;
  283.   yrot += 3.0;
  284.   glutPostRedisplay();
  285. }
  286. void 
  287. visible(int vis)
  288. {
  289.   if (vis == GLUT_VISIBLE)
  290.     glutIdleFunc(idle);
  291.   else
  292.     glutIdleFunc(NULL);
  293. }
  294. int
  295. main(int argc, char *argv[])
  296. {
  297.   glutInitWindowSize(400, 300);
  298.   glutInit(&argc, argv);
  299.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB
  300. #ifdef USE_ZBUFFER
  301.     | GLUT_DEPTH
  302. #endif
  303.     | GLUT_STENCIL);
  304.   
  305.   glutCreateWindow("reflect");
  306.   glutReshapeFunc(reshape);
  307.   glutDisplayFunc(draw_scene);
  308.   glutKeyboardFunc(key);
  309.   glutSpecialFunc(special);
  310.   glutVisibilityFunc(visible);
  311.   init();
  312.   glutMainLoop();
  313.   return 0;             /* ANSI C requires main to return int. */
  314. }