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

GIS编程

开发平台:

Visual C++

  1. #include <GL/glut.h>
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include "texture.h"
  5. #include <stdlib.h>
  6. #ifndef __sgi
  7. /* Most math.h's do not define float versions of the math functions. */
  8. #define sqrtf(x) (float)sqrt((x))
  9. #endif
  10. #if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2)
  11. #define glBindTexture glBindTextureEXT
  12. #endif
  13. #define CHECK_ERROR(str)                                           
  14. {                                                                  
  15.     GLenum error;                                                  
  16.     if(error = glGetError())                                       
  17.        printf("GL Error: %s (%s)n", gluErrorString(error), str);  
  18. }
  19. /* display lists */
  20. enum {SPHERE = 1, CONE, LIGHT, DISK, FLOOR, BACK, LEFT, RIGHT, CEIL};
  21. /* texture objects */
  22. enum {DEFAULT, LIGHTMAP, SURFMAP}; 
  23. enum {NONE, LIGHT_XY, LIGHT_Z, LIGHT_INTENS};
  24. #ifndef TRUE
  25. enum {FALSE, TRUE};
  26. #endif
  27. enum {X, Y, Z, W};
  28. enum {R, G, B, A};
  29. GLfloat staticlightpos[] = {50.f, 70.f, -10.f, 1.f};
  30. GLfloat lightpos[] = {50.f, 70.f, -10.f, 1.f};
  31. GLfloat intensity = 1.f;
  32. GLfloat nearScale = .49f, farScale = .0001f;
  33. int dblbuf = TRUE;
  34. int action = NONE;
  35. int winWidth = 512;
  36. int winHeight = 512;
  37. int curtess = 1; /* current tessellation level */
  38. int lasttess = 1; /* last set tessellation level */
  39. void
  40. reshape(int wid, int ht)
  41. {
  42.     winWidth = wid;
  43.     winHeight = ht;
  44.     glViewport(0, 0, wid, ht);
  45. }
  46. void
  47. motion(int x, int y)
  48. {
  49.     switch(action)
  50.     {
  51.     case LIGHT_XY:
  52. lightpos[X] = (x - winWidth/2) * 200.f/winWidth;
  53. lightpos[Y] = (winHeight/2 - y) * 200.f/winHeight;
  54. glutPostRedisplay();
  55. break;
  56.     case LIGHT_Z:
  57. lightpos[Z] = (winHeight/2 - y) * 200.f/winWidth;
  58. glutPostRedisplay();
  59. break;
  60.     case LIGHT_INTENS:
  61. intensity = x/(GLfloat)winWidth;
  62. glutPostRedisplay();
  63. break;
  64.     }
  65. }
  66. void
  67. mouse(int button, int state, int x, int y)
  68. {
  69.     if(state == GLUT_DOWN)
  70. switch(button)
  71. {
  72. case GLUT_LEFT_BUTTON: /* move the light */
  73.     action = LIGHT_XY;
  74.     motion(x, y);
  75.     break;
  76. case GLUT_MIDDLE_BUTTON:
  77.     action = LIGHT_INTENS;
  78.     motion(x, y);
  79.     break;
  80. case GLUT_RIGHT_BUTTON: /* move the polygon */
  81.     action = LIGHT_Z;
  82.     motion(x, y);
  83.     break;
  84. }
  85. }
  86. /*
  87. ** Create a single component texture map
  88. */
  89. GLfloat *make_texture(int maxs, int maxt)
  90. {
  91.     int s, t;
  92.     GLfloat *texture;
  93.     texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat));
  94.     for(t = 0; t < maxt; t++) {
  95. for(s = 0; s < maxs; s++) {
  96.     texture[s + maxs * t] = ((s >> 3) & 0x1) ^ ((t >> 3) & 0x1);
  97. }
  98.     }
  99.     return texture;
  100. }
  101. /* make tesselated surface for display list dlist */
  102. /* normal tells you surface position and orientation */
  103. /* count = tesselation count */
  104. void
  105. tess_surface(GLuint dlist, int count)
  106. {
  107.     int i, j;
  108.     GLfloat x0, y0, z0;
  109.     GLfloat over[3], up[3]; /* axes */
  110.     int Sindex, Tindex; /* active texture axes */
  111.     glNewList(dlist, GL_COMPILE);
  112.     glBegin(GL_QUADS);
  113.     switch(dlist)
  114.     {
  115.     case FLOOR:
  116. glNormal3f( 0.f,  1.f, 0.f);
  117. x0 = -100.f; y0 = -100.f; z0 = 100.f;
  118. over[X] = 1.f/count; over[Y] = 0.f; over[Z] = 0.f;
  119. up[X] = 0.f; up[Y] = 0.f; up[Z] = -1.f/count;
  120. Sindex = X; Tindex = Z;
  121. break;
  122.     case CEIL:
  123. glNormal3f( 0.f, -1.f, 0.f);
  124. x0 = -100.f; y0 = 100.f; z0 = 100.f;
  125. over[X] = 0.f; over[Y] = 0.f; over[Z] = -1.f/count;
  126. up[X] = 1.f/count; up[Y] = 0.f; up[Z] = 0.f;
  127. Sindex = X; Tindex = Z;
  128. break;
  129.     case LEFT:
  130. glNormal3f( 1.f,  0.f, 0.f);
  131. x0 = -100.f; y0 = -100.f; z0 = 100.f;
  132. over[X] = 0.f; over[Y] = 0.f; over[Z] = -1.f/count; 
  133. up[X] = 0.f; up[Y] = 1.f/count; up[Z] = 0.f;
  134. Sindex = Z; Tindex = Y;
  135. break;
  136.     case RIGHT:
  137. glNormal3f(-1.f,  0.f, 0.f);
  138. x0 =  100.f; y0 = -100.f; z0 = 100.f;
  139. over[X] = 0.f; over[Y] = 1.f/count; over[Z] = 0.f;
  140. up[X] = 0.f; up[Y] = 0.f; up[Z] = -1.f/count; 
  141. Sindex = Z; Tindex = Y;
  142. break;
  143.     case BACK:
  144. glNormal3f( 0.f,  0.f, 1.f);
  145. x0 = -100.f; y0 = -100.f; z0 = -100.f;
  146. over[X] = 1.f/count; over[Y] = 0.f; over[Z] = 0.f;
  147. up[X] = 0.f; up[Y] = 1.f/count; up[Z] = 0.f;
  148. Sindex = X; Tindex = Y;
  149. break;
  150.     default:
  151. fprintf(stderr, "tess_surface(): bad display list argument %dn",
  152. dlist);
  153. glEnd();
  154. glEndList();
  155. return;
  156.     }
  157.     for(j = 0; j < count; j++)
  158. for(i = 0; i < count; i++)
  159. {
  160.     glTexCoord2f(i * over[Sindex], j * up[Tindex]);
  161.     glVertex3f(x0 + i * 200 * over[X] + j * 200 * up[X],
  162.        y0 + i * 200 * over[Y] + j * 200 * up[Y],
  163.        z0 + i * 200 * over[Z] + j * 200 * up[Z]);
  164.     glTexCoord2f((i + 1) * over[Sindex], j * up[Tindex]);
  165.     glVertex3f(x0 + (i + 1) * 200 * over[X] + j * 200 * up[X],
  166.        y0 + (i + 1) * 200 * over[Y] + j * 200 * up[Y],
  167.        z0 + (i + 1) * 200 * over[Z] + j * 200 * up[Z]);
  168.     glTexCoord2f((i + 1) * over[Sindex], (j + 1) * up[Tindex]);
  169.     glVertex3f(x0 + (i + 1) * 200 * over[X] + (j + 1) * 200 * up[X],
  170.        y0 + (i + 1) * 200 * over[Y] + (j + 1) * 200 * up[Y],
  171.        z0 + (i + 1) * 200 * over[Z] + (j + 1) * 200 * up[Z]);
  172.     glTexCoord2f(i * over[Sindex], (j + 1) * up[Tindex]);
  173.     glVertex3f(x0 + i * 200 * over[X] + (j + 1) * 200 * up[X],
  174.        y0 + i * 200 * over[Y] + (j + 1) * 200 * up[Y],
  175.        z0 + i * 200 * over[Z] + (j + 1) * 200 * up[Z]);
  176. }
  177.     glEnd();
  178.     glEndList();
  179. }
  180. static GLfloat zero[] = {0.f, 0.f, 0.f, 1.f};
  181. static GLfloat one[] = {1.f, 1.f, 1.f, 1.f};
  182. static GLfloat diff[] = {.25f, .25f, .25f, .25f};
  183. /* create a lightmap simulating a local light with attenuation */
  184. void
  185. make_lightmap(GLenum light, int dim)
  186. {
  187.     GLfloat quadratic, linear, constant;
  188.     GLfloat diffuse[4], ambient[4]; /* light color */
  189.     GLfloat *texture;
  190.     GLfloat dist, scale, edge;
  191.     int size;
  192.     int i, j;
  193.     glPushAttrib(GL_TEXTURE_BIT);
  194.     /* get from light to simplify api */
  195.     glGetLightfv(light, GL_QUADRATIC_ATTENUATION, &quadratic);
  196.     glGetLightfv(light, GL_LINEAR_ATTENUATION, &linear);
  197.     glGetLightfv(light, GL_CONSTANT_ATTENUATION, &constant);
  198.     glGetLightfv(light, GL_AMBIENT, ambient);
  199.     glGetLightfv(light, GL_DIFFUSE, diffuse);
  200.     size = dim + 2;
  201.     texture = (GLfloat *)malloc(sizeof(GLfloat) * 3 * size * size);
  202.     dist = dim/2; /* 1 in from border */
  203.     edge = 1.f/(constant + linear * dist + quadratic * dist * dist);
  204.     for(j = 0; j < size; j++)
  205. for(i = 0; i < size; i++)
  206. {
  207.     dist = sqrtf((float)((size/2.f - i) * (size/2.f - i) +
  208.  (size/2.f - j) * (size/2.f - j)));
  209.     scale = 1.f/(constant + linear * dist + quadratic * dist * dist);
  210.     if(dist >= dim/2)
  211.     {
  212. texture[3 * (i + size * j) + 0] = 
  213.     diffuse[R] * edge + ambient[R];
  214. texture[3 * (i + size * j) + 1] = 
  215.     diffuse[G] * edge + ambient[G];
  216. texture[3 * (i + size * j) + 2] = 
  217.     diffuse[B] * edge + ambient[B];
  218.     }
  219.     else
  220.     {
  221. texture[3 * (i + size * j) + 0] = 
  222.     diffuse[R] * scale + ambient[R];
  223. texture[3 * (i + size * j) + 1] = 
  224.     diffuse[G] * scale + ambient[G];
  225. texture[3 * (i + size * j) + 2] = 
  226.     diffuse[B] * scale + ambient[B];
  227.     }
  228. }
  229.     glBindTexture(GL_TEXTURE_2D, LIGHTMAP);
  230.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  231.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  232.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  233.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 
  234.  size, size, 1, GL_RGB, GL_FLOAT, texture);
  235.     free(texture);
  236.     glPopAttrib();
  237. }
  238. /* draw a highly tesselated disk with local light */
  239. void
  240. draw_lightmap(int dim, int dist)
  241. {
  242.     GLUquadricObj *qobj;
  243.     GLfloat *texture;
  244.     GLfloat light[4] = {0.f, 0.f, 1.f, 1.f};
  245.     texture = (GLfloat *)malloc(sizeof(GLfloat) * 3 * dim * dim);
  246.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  247.     glPushMatrix(); /* starts as modelview */
  248.     glLoadIdentity();
  249.     glTranslatef(0.f, 0.f, -dist);
  250.     glMatrixMode(GL_PROJECTION);
  251.     glPushMatrix();
  252.     glLoadIdentity();
  253.     glOrtho(-dim/2., dim/2., -dim/2., dim/2., 0., (double)dist);
  254.     glPushAttrib(GL_LIGHTING_BIT|GL_VIEWPORT_BIT);
  255.     glViewport(0, 0, dim, dim);
  256.     glEnable(GL_LIGHTING);
  257.     light[Z] = dist;
  258.     glLightfv(GL_LIGHT0, GL_POSITION, light); /* light position */
  259.     /* XXX TODO, range check an report errors */
  260.     glDisable(GL_TEXTURE_2D);
  261.     qobj = gluNewQuadric();
  262.     gluDisk(qobj, 0., dim/2. * sqrt(2.), dim/4, dim/4);
  263.     gluDeleteQuadric(qobj);
  264.     glEnable(GL_TEXTURE_2D);
  265.     glPopAttrib();
  266.     glPopMatrix();
  267.     glMatrixMode(GL_MODELVIEW);
  268.     glPopMatrix();
  269.     glReadPixels(0, 0, dim, dim, GL_RGB, GL_FLOAT, texture);
  270.     glBindTexture(GL_TEXTURE_2D, LIGHTMAP);
  271.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  272.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dim, dim, 0, GL_RGB,
  273.  GL_FLOAT, texture);
  274.     free(texture);
  275. }
  276. int texdim = 256;
  277. /* draw the lightmap texture */
  278. void redraw_lightmap(void)
  279. {
  280.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  281.     glPushAttrib(GL_LIGHTING_BIT|GL_TEXTURE_BIT);
  282.     /* assume GL_MODELVIEW */
  283.     glPushMatrix();
  284.     glLoadIdentity();
  285.     glMatrixMode(GL_PROJECTION);
  286.     glPushMatrix();
  287.     glLoadIdentity();
  288.     glEnable(GL_TEXTURE_2D);
  289.     glBindTexture(GL_TEXTURE_2D, LIGHTMAP);
  290.     glDisable(GL_LIGHTING);
  291.     glColor3f(1.f, 1.f, 1.f);
  292.     glBegin(GL_QUADS);
  293.     glTexCoord2i(0, 0);
  294.     glVertex2i(-1, -1);
  295.     glTexCoord2i(1, 0);
  296.     glVertex2i(1, -1);
  297.     glTexCoord2i(1, 1);
  298.     glVertex2i(1,  1);
  299.     glTexCoord2i(0, 1);
  300.     glVertex2i(-1,  1);
  301.     glEnd();
  302.     glPopMatrix();
  303.     glMatrixMode(GL_MODELVIEW);
  304.     glPopMatrix();
  305.     glPopAttrib();
  306.     CHECK_ERROR("OpenGL Error in redraw_map()");
  307.     if(dblbuf)
  308. glutSwapBuffers(); 
  309.     else
  310. glFlush(); 
  311. }
  312. /* draw the lightmap texture */
  313. void redraw_combomap(void)
  314. {
  315.     GLfloat scale;
  316.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  317.     glPushAttrib(GL_LIGHTING_BIT|GL_TEXTURE_BIT|GL_COLOR_BUFFER_BIT|
  318.  GL_DEPTH_BUFFER_BIT);
  319.     /* assume GL_MODELVIEW */
  320.     glPushMatrix();
  321.     glLoadIdentity();
  322.     glMatrixMode(GL_PROJECTION);
  323.     glPushMatrix();
  324.     glLoadIdentity();
  325.     glEnable(GL_TEXTURE_2D);
  326.     glDisable(GL_LIGHTING);
  327.     glBindTexture(GL_TEXTURE_2D, SURFMAP);
  328.     glColor3f(intensity, intensity, intensity);
  329.     glBegin(GL_QUADS);
  330.     glTexCoord2i(0, 0);
  331.     glVertex2i(-1, -1);
  332.     glTexCoord2i(5, 0);
  333.     glVertex2i(1, -1);
  334.     glTexCoord2i(5, 5);
  335.     glVertex2i(1,  1);
  336.     glTexCoord2i(0, 5);
  337.     glVertex2i(-1,  1);
  338.     glEnd();
  339.     glEnable(GL_BLEND);
  340.     glDepthFunc(GL_LEQUAL);
  341.     glBlendFunc(GL_ZERO, GL_SRC_COLOR);
  342.     glBindTexture(GL_TEXTURE_2D, LIGHTMAP);
  343.     glMatrixMode(GL_TEXTURE);
  344.     glPushMatrix();
  345.     glTranslatef(.5f, .5f, 0.f);
  346.     scale = .25f + (lightpos[Z] + 100.f) * 3.75f/200.f;
  347.     glScalef(scale, scale, 0.f);
  348.     glTranslatef(-.5f, -.5f, 0.f);
  349.     glTranslatef(-lightpos[X]/200.f, -lightpos[Y]/200.f, 0.f);
  350.     glColor3f(1.f, 1.f, 1.f);
  351.     glBegin(GL_QUADS);
  352.     glTexCoord2i(0, 0);
  353.     glVertex2i(-1, -1);
  354.     glTexCoord2i(1, 0);
  355.     glVertex2i(1, -1);
  356.     glTexCoord2i(1, 1);
  357.     glVertex2i(1,  1);
  358.     glTexCoord2i(0, 1);
  359.     glVertex2i(-1,  1);
  360.     glEnd();
  361.     /* GL_TEXTURE */
  362.     glPopMatrix();
  363.     glMatrixMode(GL_PROJECTION);
  364.     glPopMatrix();
  365.     glMatrixMode(GL_MODELVIEW);
  366.     glPopMatrix();
  367.     glPopAttrib();
  368.     CHECK_ERROR("OpenGL Error in redraw_combomap()");
  369.     if(dblbuf)
  370. glutSwapBuffers(); 
  371.     else
  372. glFlush(); 
  373. }
  374. /* draw the openGL scene with lighting off */
  375. void render_scene(int tess)
  376. {
  377.     /* material properties for objects in scene */
  378.     /* update tessellation if it changed */
  379.     if(tess != lasttess)
  380.     {
  381. tess_surface(FLOOR, tess);
  382. tess_surface(CEIL,  tess);
  383. tess_surface(LEFT,  tess);
  384. tess_surface(RIGHT, tess);
  385. tess_surface(BACK,  tess);
  386. lasttess = tess;
  387.     }
  388.     glPushAttrib(GL_LIGHTING_BIT|GL_TEXTURE_BIT);
  389.     /* floor */
  390.     glColor3f(.5f, .35f, .35f); /* reddish */
  391.     glEnable(GL_TEXTURE_2D);
  392.     glCallList(FLOOR);
  393.     glDisable(GL_TEXTURE_2D);
  394.     /* ceiling */
  395.     glColor3f(.35f, .5f, .35f); /* greenish */
  396.     glCallList(CEIL);
  397.     /* right wall */
  398.     glColor3f(.35f, .35f, .5f); /* bluish */
  399.     glCallList(RIGHT);
  400.     /* left wall */
  401.     glCallList(LEFT);
  402.     /* back wall */
  403.     glCallList(BACK);
  404.     /* draw the sphere */
  405.     
  406.     glCallList(SPHERE);
  407.     /* draw the cone */
  408.     glCallList(CONE);
  409.     /* draw the light */
  410.     glPushMatrix();
  411.     glTranslatef(lightpos[X], lightpos[Y], lightpos[Z]);
  412.     glCallList(LIGHT);
  413.     glPopMatrix();
  414.     glPopAttrib();
  415.     CHECK_ERROR("OpenGL Error in render_unlit()");
  416. }
  417. void
  418. redraw_opengl(void)
  419. {
  420.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  421.     glPushAttrib(GL_LIGHTING_BIT);
  422.     glEnable(GL_LIGHTING);
  423.     glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
  424.     glEnable(GL_COLOR_MATERIAL);
  425.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos); /* opengl lit */ 
  426.     render_scene(curtess);
  427.     glPopAttrib();
  428.     if(dblbuf)
  429. glutSwapBuffers(); 
  430.     else
  431. glFlush(); 
  432. }
  433. void
  434. redraw_unlit(void)
  435. {
  436.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  437.     glPushAttrib(GL_LIGHTING_BIT);
  438.     glDisable(GL_LIGHTING);
  439.     render_scene(1);
  440.     glPopAttrib();
  441.     if(dblbuf)
  442. glutSwapBuffers(); 
  443.     else
  444. glFlush(); 
  445. }
  446. /* draw the scene white, modulated by lightmap */
  447. /* unlit, uncolored simulated by lighting */
  448. /* texgen overrides texture coords */
  449. void render_white(void)
  450. {
  451.     GLfloat scale;
  452.     /* texgen used to override texure coords */
  453.     static GLfloat XZs[] = {1/200.f, 0.f, 0.f, .5f};
  454.     static GLfloat XZt[] = {0.f, 0.f, 1/200.f, .5f};
  455.     static GLfloat YZs[]  = {0.f, 0.f, 1/200.f, .5f};
  456.     static GLfloat YZt[]  = {0.f, 1/200.f, 0.f, .5f};
  457.     static GLfloat XYs[]  = {1/200.f, 0.f, 0.f, .5f};
  458.     static GLfloat XYt[]  = {0.f, 1/200.f, 0.f, .5f};
  459.     /* material properties for objects in scene */
  460.     glPushAttrib(GL_LIGHTING_BIT|GL_TEXTURE_BIT);
  461.     glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  462.     glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  463.     glEnable(GL_LIGHTING);
  464.     /* simulate unlit, color = white */
  465.     glLightfv(GL_LIGHT0, GL_AMBIENT, diff);
  466.     glMaterialfv(GL_FRONT, GL_DIFFUSE, zero);
  467.     glColorMaterial(GL_FRONT, GL_AMBIENT);
  468.     glEnable(GL_COLOR_MATERIAL);
  469.     glEnable(GL_TEXTURE_2D);
  470.     glBindTexture(GL_TEXTURE_2D, LIGHTMAP);
  471.     
  472.     glEnable(GL_TEXTURE_GEN_S);
  473.     glEnable(GL_TEXTURE_GEN_T);
  474.     glMatrixMode(GL_TEXTURE);
  475.     glPushMatrix();
  476.     glTexGenfv(GL_S, GL_OBJECT_PLANE, XZs);
  477.     glTexGenfv(GL_T, GL_OBJECT_PLANE, XZt);
  478.     glLoadIdentity();
  479.     glTranslatef(.5f, .5f, 0.f);
  480.     scale = nearScale - (nearScale - farScale)/200.f * (100.f + lightpos[Y]);
  481.     glScalef(scale, scale, 1.f);
  482.     glTranslatef(-.5f, -.5f, 0.f);
  483.     glTranslatef(-lightpos[X]/200.f, -lightpos[Z]/200.f, 0.f);
  484.     /* add intensity (colorchange) */
  485.     scale = lightpos[Y] + 100;
  486.     scale /= 200.f;
  487.     scale *= scale;
  488.     scale = 1.f/(1.f + scale);
  489.     scale = 1.f;
  490.     glColor3f(scale, scale, scale);
  491.     /* floor */
  492.     glCallList(FLOOR);
  493.     glLoadIdentity();
  494.     glTranslatef(.5f, .5f, 0.f);
  495.     scale = nearScale - (nearScale - farScale)/200.f * (100.f - lightpos[Y]);
  496.     glScalef(scale, scale, 1.f);
  497.     glTranslatef(-.5f, -.5f, 0.f);
  498.     glTranslatef(-lightpos[X]/200.f, -lightpos[Z]/200.f, 0.f);
  499.     scale = 100 - lightpos[Y];
  500.     scale /= 100.f;
  501.     scale *= scale;
  502.     scale = 1.f/(1.f + scale);
  503.     scale = 1.f;
  504.     glColor3f(scale, scale, scale);
  505.     /* ceiling */
  506.      glCallList(CEIL);
  507.     glTexGenfv(GL_S, GL_OBJECT_PLANE, YZs);
  508.     glTexGenfv(GL_T, GL_OBJECT_PLANE, YZt);
  509.     glLoadIdentity();
  510.     glTranslatef(.5f, .5f, 0.f);
  511.     scale = nearScale - (nearScale - farScale)/200.f * (100.f - lightpos[X]);
  512.     glScalef(scale, scale, 1.f);
  513.     glTranslatef(-.5f, -.5f, 0.f);
  514.     glTranslatef(-lightpos[Z]/200.f, -lightpos[Y]/200.f, 0.f);
  515.     scale = 100 - lightpos[X];
  516.     scale /= 100.f;
  517.     scale *= scale;
  518.     scale = 1.f/(1.f + scale);
  519.     scale = 1.f;
  520.     glColor3f(scale, scale, scale);
  521.     /* right wall */
  522.     glCallList(RIGHT);
  523.     glLoadIdentity();
  524.     glTranslatef(.5f, .5f, 0.f);
  525.     scale = nearScale - (nearScale - farScale)/200.f * (100.f + lightpos[X]);
  526.     glScalef(scale, scale, 1.f);
  527.     glTranslatef(-.5f, -.5f, 0.f);
  528.     glTranslatef(-lightpos[Z]/200.f, -lightpos[Y]/200.f, 0.f);
  529.     scale = lightpos[X] + 100;
  530.     scale /= 100.f;
  531.     scale *= scale;
  532.     scale = 1.f/(1.f + scale);
  533.     scale = 1.f;
  534.     glColor3f(scale, scale, scale);
  535.     /* left wall */
  536.     glCallList(LEFT);
  537.     glTexGenfv(GL_S, GL_OBJECT_PLANE, XYs);
  538.     glTexGenfv(GL_T, GL_OBJECT_PLANE, XYt);
  539.     glLoadIdentity();
  540.     glTranslatef(.5f, .5f, 0.f);
  541.     scale = nearScale - (nearScale - farScale)/200.f * (100.f + lightpos[Z]);
  542.     glScalef(scale, scale, 1.f);
  543.     glTranslatef(-.5f, -.5f, 0.f);
  544.     glTranslatef(-lightpos[X]/200.f, -lightpos[Y]/200.f, 0.f);
  545.     scale = lightpos[Z] + 100;
  546.     scale /= 100.f;
  547.     scale *= scale;
  548.     scale = 1.f/(1.f + scale);
  549.     scale = 1.f;
  550.     glColor3f(scale, scale, scale);
  551.     /* back wall */
  552.     glCallList(BACK);
  553.     /* done with texture matrix */
  554.     glPopMatrix();
  555.     glMatrixMode(GL_MODELVIEW);
  556.     /* no contribution to highly tesselated objects */
  557.     glMaterialfv(GL_FRONT, GL_AMBIENT, zero);
  558.     glLightfv(GL_LIGHT0, GL_AMBIENT, zero);
  559.     /* draw the sphere */
  560.     
  561.     glCallList(SPHERE);
  562.     /* draw the cone */
  563.     glCallList(CONE);
  564.     glPopAttrib();
  565.     CHECK_ERROR("OpenGL Error in render_white()");
  566. }
  567. void
  568. redraw_white(void)
  569. {
  570.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  571.     render_white();
  572.     if(dblbuf)
  573. glutSwapBuffers(); 
  574.     else
  575. glFlush(); 
  576. }
  577. void
  578. redraw_lightmapped(void)
  579. {
  580.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  581.     glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_LIGHTING_BIT);
  582.     glDisable(GL_LIGHTING);
  583.     render_scene(1);
  584.     glEnable(GL_LIGHTING);
  585.     glEnable(GL_BLEND);
  586.     glBlendFunc(GL_ZERO, GL_SRC_COLOR);
  587.     glDepthFunc(GL_LEQUAL);
  588.     render_white();
  589.     glPopAttrib();
  590.     if(dblbuf)
  591. glutSwapBuffers(); 
  592.     else
  593. glFlush(); 
  594. }
  595. void
  596. redraw_maponly(void)
  597. {
  598.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  599.     glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_LIGHTING_BIT);
  600.     glDisable(GL_LIGHTING);
  601.     render_scene(1);
  602.     glEnable(GL_LIGHTING);
  603.     glEnable(GL_BLEND);
  604.     glBlendFunc(GL_ZERO, GL_SRC_COLOR);
  605.     glDepthFunc(GL_LEQUAL);
  606.     render_white();
  607.     glBlendFunc(GL_ONE, GL_ONE);
  608.     glDisable(GL_LIGHTING); /* add in unlit scene again */
  609.     render_scene(1);
  610.     
  611.     glPopAttrib();
  612.     if(dblbuf)
  613. glutSwapBuffers(); 
  614.     else
  615. glFlush(); 
  616. }
  617. void
  618. redraw_complete(void)
  619. {
  620.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  621.     glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_LIGHTING_BIT);
  622.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos); /* opengl lit */ 
  623.     glDisable(GL_LIGHTING);
  624.     render_scene(1);
  625.     glEnable(GL_LIGHTING);
  626.     glEnable(GL_BLEND);
  627.     glBlendFunc(GL_ZERO, GL_SRC_COLOR);
  628.     glDepthFunc(GL_LEQUAL);
  629.     render_white();
  630.     glBlendFunc(GL_ONE, GL_ONE);
  631.     glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
  632.     glEnable(GL_COLOR_MATERIAL);
  633.     render_scene(1);
  634.     glPopAttrib();
  635.     if(dblbuf)
  636. glutSwapBuffers(); 
  637.     else
  638. glFlush(); 
  639. }
  640. /* ARGSUSED1 */
  641. void key(unsigned char key, int x, int y)
  642. {
  643.     switch(key)
  644.     {
  645.     case 'l': /* show lightmap */
  646. glutDisplayFunc(redraw_lightmap);
  647. glutPostRedisplay();
  648. break;
  649.     case 'w': /* show white scene modulated by lightmap */
  650. glutDisplayFunc(redraw_white);
  651. glutPostRedisplay();
  652. break;
  653.     case 'm': /* unlit scene modified by lightmap */
  654. glutDisplayFunc(redraw_lightmapped);
  655. glutPostRedisplay();
  656. break;
  657.     case 'u': /* draw scene without lighting */
  658. glutDisplayFunc(redraw_unlit);
  659. glutPostRedisplay();
  660. break;
  661.     case 'o': /* draw scene lit using OpenGL */
  662. glutDisplayFunc(redraw_opengl);
  663. glutPostRedisplay();
  664. break;
  665.     case 'a': /* show scene lit with OpenGL and lightmaps */
  666. glutDisplayFunc(redraw_complete);
  667. glutPostRedisplay();
  668. break;
  669.     case 'p': /* show scene lit with pure lightmaps */
  670. glutDisplayFunc(redraw_maponly);
  671. glutPostRedisplay();
  672. break;
  673.     case 'x': /* surface texture with lightmap combined */
  674. glutDisplayFunc(redraw_combomap);
  675. glutPostRedisplay();
  676. break;
  677.     case 'T': /* surface texture with lightmap combined */
  678. curtess++;
  679. glutPostRedisplay();
  680. break;
  681.     case 't': /* surface texture with lightmap combined */
  682. curtess--;
  683. if(curtess < 1)
  684.     curtess = 1;
  685. glutPostRedisplay();
  686. break;
  687.     case '1': /* surface texture with lightmap combined */
  688. curtess = 1;
  689. glutPostRedisplay();
  690. break;
  691.     case 'y':
  692. farScale -= .0001f;
  693. if(farScale < .0001f)
  694.     farScale = .0001f;
  695. printf("farScale = %.4fn", farScale);
  696. glutPostRedisplay();
  697. break;
  698.     case 'Y':
  699. farScale += .0001f;
  700. printf("farScale = %.4fn", farScale);
  701. glutPostRedisplay();
  702. break;
  703.     case 'z':
  704. nearScale -= .01f;
  705. if(nearScale < .01f)
  706.     nearScale = .01f;
  707. printf("nearScale = %.2fn", nearScale);
  708. glutPostRedisplay();
  709. break;
  710.     case 'Z':
  711. nearScale += .01f;
  712. printf("nearScale = %.2fn", nearScale);
  713. glutPostRedisplay();
  714. break;
  715.     case '33':
  716. exit(0);
  717. break;
  718.     case '?':
  719.     case 'h':
  720.     default:
  721. fprintf(stderr, 
  722. "Keyboard Commandsn"
  723. "l - draw lightmapn"
  724. "w - draw white scene modulated by lightmapn"
  725. "m - draw unlit scene modified by lightmapn"
  726. "u - draw unlit scenen"
  727. "o - draw scene lit by OpenGLn"
  728. "a - draw scene lit by OpenGL (tess = 1) + lightmapsn"
  729. "p - draw scene lit only by lightmapsn"
  730. "x - interactive lightmap on brick walln"
  731. "T - increase surface tessellationn"
  732. "t - decrease surface tessellationn"
  733. "1 - set tessellation to onen"
  734. "y - decrease far scale for lightmapsn"
  735. "Y - increase far scale for lightmapsn"
  736. "z - decrease near scale for lightmapsn"
  737. "Z - increase near scale for lightmapsn");
  738. break;
  739.     }
  740.     glutPostRedisplay();
  741. }
  742. main(int argc, char *argv[])
  743. {
  744.     GLfloat *tex;
  745.     GLUquadricObj *qobj;
  746.     glutInit(&argc, argv);
  747.     glutInitWindowSize(winWidth, winHeight);
  748.     if(argc > 1)
  749.     {
  750. char *args = argv[1];
  751. int done = FALSE;
  752. while(!done)
  753. {
  754.     switch(*args)
  755.     {
  756.     case 's': /* single buffer */
  757. printf("Single Bufferedn");
  758. dblbuf = FALSE;
  759. break;
  760.     case '-': /* do nothing */
  761. break;
  762.     case 0:
  763. done = TRUE;
  764. break;
  765.     }
  766.     args++;
  767. }
  768.     }
  769.     if(dblbuf)
  770. glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  771.     else
  772. glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH);
  773.     (void)glutCreateWindow("example program");
  774.     glutDisplayFunc(redraw_opengl);
  775.     glutKeyboardFunc(key);
  776.     glutMouseFunc(mouse);
  777.     glutMotionFunc(motion);
  778.     glutReshapeFunc(reshape);
  779.     /* draw a perspective scene */
  780.     glMatrixMode(GL_PROJECTION);
  781.     glFrustum(-100., 100., -100., 100., 300., 501.); 
  782.     glMatrixMode(GL_MODELVIEW);
  783.     /* look at scene from (0, 0, 400) */
  784.     gluLookAt(0., 0., 400., 0., 0., 0., 0., 1., 0.);
  785.     /* turn on features */
  786.     glEnable(GL_DEPTH_TEST);
  787.     glEnable(GL_LIGHT0);
  788.     glLightfv(GL_LIGHT0, GL_POSITION, staticlightpos);
  789.     /* remove back faces to speed things up */
  790.     glCullFace(GL_BACK);
  791.     /* make a display list containing a sphere */
  792.     glNewList(SPHERE, GL_COMPILE);
  793.     {
  794. glPushMatrix();
  795. glTranslatef(0.f, -80.f, -80.f);
  796. qobj = gluNewQuadric();
  797. gluQuadricTexture(qobj, GL_TRUE);
  798. glColor3f(.5f, .25f, 0.f);
  799. gluSphere(qobj, 20.f, 20, 20);
  800. gluDeleteQuadric(qobj);
  801. glPopMatrix();
  802.     }
  803.     glEndList();
  804.     /* make a display list containing a sphere */
  805.     glNewList(LIGHT, GL_COMPILE);
  806.     {
  807. qobj = gluNewQuadric();
  808. glColor3f(1.f, 1.f, 1.f);
  809. glPushAttrib(GL_LIGHTING_BIT);
  810. glDisable(GL_LIGHTING);
  811. gluSphere(qobj, 3.f, 20, 20);
  812. glPopAttrib();
  813. gluDeleteQuadric(qobj);
  814.     }
  815.     glEndList();
  816.     /* create a display list containing a cone */
  817.     glNewList(CONE, GL_COMPILE);
  818.     {
  819. glPushMatrix();
  820. glTranslatef(-60.f, -100.f, -5.f);
  821. qobj = gluNewQuadric();
  822. gluQuadricTexture(qobj, GL_TRUE);
  823. glRotatef(-90.f, 1.f, 0.f, 0.f);
  824. glColor3f(0.f, .25f, .5f);
  825. gluCylinder(qobj, 20., 0., 60., 20, 20);
  826. gluDeleteQuadric(qobj);
  827. qobj = gluNewQuadric();
  828. gluQuadricOrientation(qobj, GLU_INSIDE);
  829. gluDisk(qobj, 0., 20., 20, 1);
  830. gluDeleteQuadric(qobj);
  831. glPopMatrix();
  832.     }
  833.     glEndList();
  834.     /* load pattern for current 2d texture */
  835.     tex = make_texture(128, 128);
  836.     /* makes texturing faster, and looks better than GL_LINEAR */
  837.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  838.     glTexImage2D(GL_TEXTURE_2D, 0, 1, 128, 128, 0, GL_RED, GL_FLOAT, tex);
  839.     free(tex);
  840.     {
  841. GLuint *surftex;
  842. int texwid, texht, texcomps;
  843. surftex = read_texture("../data/brick.rgb", &texwid, &texht, &texcomps);
  844. glBindTexture(GL_TEXTURE_2D, SURFMAP);
  845. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  846. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texwid, texht, 0, GL_RGBA,
  847.      GL_UNSIGNED_BYTE, surftex);
  848.     }
  849.     glBindTexture(GL_TEXTURE_2D, DEFAULT);
  850.     tess_surface(FLOOR, 1);
  851.     tess_surface(CEIL, 1);
  852.     tess_surface(LEFT, 1);
  853.     tess_surface(RIGHT, 1);
  854.     tess_surface(BACK, 1);
  855.     /* 1/80 intensity at edges */
  856.     glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 100.f/(texdim * texdim/4));
  857.     /* 1/2 intensity at edges */
  858.     glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 1.f/texdim/2);
  859.     glLightfv(GL_LIGHT1, GL_DIFFUSE, one);
  860.     make_lightmap(GL_LIGHT1, 128);
  861.     key('?', 0, 0);
  862.     CHECK_ERROR("end of main");
  863.     glutMainLoop();
  864.     return 0;
  865. }