lightmap.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:26k
- #include <GL/glut.h>
- #include <math.h>
- #include <stdio.h>
- #include "texture.h"
- #include <stdlib.h>
- #ifndef __sgi
- /* Most math.h's do not define float versions of the math functions. */
- #define sqrtf(x) (float)sqrt((x))
- #endif
- #if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2)
- #define glBindTexture glBindTextureEXT
- #endif
- #define CHECK_ERROR(str)
- {
- GLenum error;
- if(error = glGetError())
- printf("GL Error: %s (%s)n", gluErrorString(error), str);
- }
- /* display lists */
- enum {SPHERE = 1, CONE, LIGHT, DISK, FLOOR, BACK, LEFT, RIGHT, CEIL};
- /* texture objects */
- enum {DEFAULT, LIGHTMAP, SURFMAP};
- enum {NONE, LIGHT_XY, LIGHT_Z, LIGHT_INTENS};
- #ifndef TRUE
- enum {FALSE, TRUE};
- #endif
- enum {X, Y, Z, W};
- enum {R, G, B, A};
- GLfloat staticlightpos[] = {50.f, 70.f, -10.f, 1.f};
- GLfloat lightpos[] = {50.f, 70.f, -10.f, 1.f};
- GLfloat intensity = 1.f;
- GLfloat nearScale = .49f, farScale = .0001f;
- int dblbuf = TRUE;
- int action = NONE;
- int winWidth = 512;
- int winHeight = 512;
- int curtess = 1; /* current tessellation level */
- int lasttess = 1; /* last set tessellation level */
- void
- reshape(int wid, int ht)
- {
- winWidth = wid;
- winHeight = ht;
- glViewport(0, 0, wid, ht);
- }
- void
- motion(int x, int y)
- {
- switch(action)
- {
- case LIGHT_XY:
- lightpos[X] = (x - winWidth/2) * 200.f/winWidth;
- lightpos[Y] = (winHeight/2 - y) * 200.f/winHeight;
- glutPostRedisplay();
- break;
- case LIGHT_Z:
- lightpos[Z] = (winHeight/2 - y) * 200.f/winWidth;
- glutPostRedisplay();
- break;
- case LIGHT_INTENS:
- intensity = x/(GLfloat)winWidth;
- glutPostRedisplay();
- break;
- }
- }
- void
- mouse(int button, int state, int x, int y)
- {
- if(state == GLUT_DOWN)
- switch(button)
- {
- case GLUT_LEFT_BUTTON: /* move the light */
- action = LIGHT_XY;
- motion(x, y);
- break;
- case GLUT_MIDDLE_BUTTON:
- action = LIGHT_INTENS;
- motion(x, y);
- break;
- case GLUT_RIGHT_BUTTON: /* move the polygon */
- action = LIGHT_Z;
- motion(x, y);
- break;
- }
- }
- /*
- ** Create a single component texture map
- */
- GLfloat *make_texture(int maxs, int maxt)
- {
- int s, t;
- GLfloat *texture;
- texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat));
- for(t = 0; t < maxt; t++) {
- for(s = 0; s < maxs; s++) {
- texture[s + maxs * t] = ((s >> 3) & 0x1) ^ ((t >> 3) & 0x1);
- }
- }
- return texture;
- }
- /* make tesselated surface for display list dlist */
- /* normal tells you surface position and orientation */
- /* count = tesselation count */
- void
- tess_surface(GLuint dlist, int count)
- {
- int i, j;
- GLfloat x0, y0, z0;
- GLfloat over[3], up[3]; /* axes */
- int Sindex, Tindex; /* active texture axes */
- glNewList(dlist, GL_COMPILE);
- glBegin(GL_QUADS);
- switch(dlist)
- {
- case FLOOR:
- glNormal3f( 0.f, 1.f, 0.f);
- x0 = -100.f; y0 = -100.f; z0 = 100.f;
- over[X] = 1.f/count; over[Y] = 0.f; over[Z] = 0.f;
- up[X] = 0.f; up[Y] = 0.f; up[Z] = -1.f/count;
- Sindex = X; Tindex = Z;
- break;
- case CEIL:
- glNormal3f( 0.f, -1.f, 0.f);
- x0 = -100.f; y0 = 100.f; z0 = 100.f;
- over[X] = 0.f; over[Y] = 0.f; over[Z] = -1.f/count;
- up[X] = 1.f/count; up[Y] = 0.f; up[Z] = 0.f;
- Sindex = X; Tindex = Z;
- break;
- case LEFT:
- glNormal3f( 1.f, 0.f, 0.f);
- x0 = -100.f; y0 = -100.f; z0 = 100.f;
- over[X] = 0.f; over[Y] = 0.f; over[Z] = -1.f/count;
- up[X] = 0.f; up[Y] = 1.f/count; up[Z] = 0.f;
- Sindex = Z; Tindex = Y;
- break;
- case RIGHT:
- glNormal3f(-1.f, 0.f, 0.f);
- x0 = 100.f; y0 = -100.f; z0 = 100.f;
- over[X] = 0.f; over[Y] = 1.f/count; over[Z] = 0.f;
- up[X] = 0.f; up[Y] = 0.f; up[Z] = -1.f/count;
- Sindex = Z; Tindex = Y;
- break;
- case BACK:
- glNormal3f( 0.f, 0.f, 1.f);
- x0 = -100.f; y0 = -100.f; z0 = -100.f;
- over[X] = 1.f/count; over[Y] = 0.f; over[Z] = 0.f;
- up[X] = 0.f; up[Y] = 1.f/count; up[Z] = 0.f;
- Sindex = X; Tindex = Y;
- break;
- default:
- fprintf(stderr, "tess_surface(): bad display list argument %dn",
- dlist);
- glEnd();
- glEndList();
- return;
- }
- for(j = 0; j < count; j++)
- for(i = 0; i < count; i++)
- {
- glTexCoord2f(i * over[Sindex], j * up[Tindex]);
- glVertex3f(x0 + i * 200 * over[X] + j * 200 * up[X],
- y0 + i * 200 * over[Y] + j * 200 * up[Y],
- z0 + i * 200 * over[Z] + j * 200 * up[Z]);
- glTexCoord2f((i + 1) * over[Sindex], j * up[Tindex]);
- glVertex3f(x0 + (i + 1) * 200 * over[X] + j * 200 * up[X],
- y0 + (i + 1) * 200 * over[Y] + j * 200 * up[Y],
- z0 + (i + 1) * 200 * over[Z] + j * 200 * up[Z]);
- glTexCoord2f((i + 1) * over[Sindex], (j + 1) * up[Tindex]);
- glVertex3f(x0 + (i + 1) * 200 * over[X] + (j + 1) * 200 * up[X],
- y0 + (i + 1) * 200 * over[Y] + (j + 1) * 200 * up[Y],
- z0 + (i + 1) * 200 * over[Z] + (j + 1) * 200 * up[Z]);
- glTexCoord2f(i * over[Sindex], (j + 1) * up[Tindex]);
- glVertex3f(x0 + i * 200 * over[X] + (j + 1) * 200 * up[X],
- y0 + i * 200 * over[Y] + (j + 1) * 200 * up[Y],
- z0 + i * 200 * over[Z] + (j + 1) * 200 * up[Z]);
- }
- glEnd();
- glEndList();
- }
- static GLfloat zero[] = {0.f, 0.f, 0.f, 1.f};
- static GLfloat one[] = {1.f, 1.f, 1.f, 1.f};
- static GLfloat diff[] = {.25f, .25f, .25f, .25f};
- /* create a lightmap simulating a local light with attenuation */
- void
- make_lightmap(GLenum light, int dim)
- {
- GLfloat quadratic, linear, constant;
- GLfloat diffuse[4], ambient[4]; /* light color */
- GLfloat *texture;
- GLfloat dist, scale, edge;
- int size;
- int i, j;
- glPushAttrib(GL_TEXTURE_BIT);
- /* get from light to simplify api */
- glGetLightfv(light, GL_QUADRATIC_ATTENUATION, &quadratic);
- glGetLightfv(light, GL_LINEAR_ATTENUATION, &linear);
- glGetLightfv(light, GL_CONSTANT_ATTENUATION, &constant);
- glGetLightfv(light, GL_AMBIENT, ambient);
- glGetLightfv(light, GL_DIFFUSE, diffuse);
- size = dim + 2;
- texture = (GLfloat *)malloc(sizeof(GLfloat) * 3 * size * size);
- dist = dim/2; /* 1 in from border */
- edge = 1.f/(constant + linear * dist + quadratic * dist * dist);
- for(j = 0; j < size; j++)
- for(i = 0; i < size; i++)
- {
- dist = sqrtf((float)((size/2.f - i) * (size/2.f - i) +
- (size/2.f - j) * (size/2.f - j)));
- scale = 1.f/(constant + linear * dist + quadratic * dist * dist);
- if(dist >= dim/2)
- {
- texture[3 * (i + size * j) + 0] =
- diffuse[R] * edge + ambient[R];
- texture[3 * (i + size * j) + 1] =
- diffuse[G] * edge + ambient[G];
- texture[3 * (i + size * j) + 2] =
- diffuse[B] * edge + ambient[B];
- }
- else
- {
- texture[3 * (i + size * j) + 0] =
- diffuse[R] * scale + ambient[R];
- texture[3 * (i + size * j) + 1] =
- diffuse[G] * scale + ambient[G];
- texture[3 * (i + size * j) + 2] =
- diffuse[B] * scale + ambient[B];
- }
- }
- glBindTexture(GL_TEXTURE_2D, LIGHTMAP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
- size, size, 1, GL_RGB, GL_FLOAT, texture);
- free(texture);
- glPopAttrib();
- }
- /* draw a highly tesselated disk with local light */
- void
- draw_lightmap(int dim, int dist)
- {
- GLUquadricObj *qobj;
- GLfloat *texture;
- GLfloat light[4] = {0.f, 0.f, 1.f, 1.f};
- texture = (GLfloat *)malloc(sizeof(GLfloat) * 3 * dim * dim);
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glPushMatrix(); /* starts as modelview */
- glLoadIdentity();
- glTranslatef(0.f, 0.f, -dist);
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glOrtho(-dim/2., dim/2., -dim/2., dim/2., 0., (double)dist);
- glPushAttrib(GL_LIGHTING_BIT|GL_VIEWPORT_BIT);
- glViewport(0, 0, dim, dim);
- glEnable(GL_LIGHTING);
- light[Z] = dist;
- glLightfv(GL_LIGHT0, GL_POSITION, light); /* light position */
- /* XXX TODO, range check an report errors */
- glDisable(GL_TEXTURE_2D);
- qobj = gluNewQuadric();
- gluDisk(qobj, 0., dim/2. * sqrt(2.), dim/4, dim/4);
- gluDeleteQuadric(qobj);
- glEnable(GL_TEXTURE_2D);
- glPopAttrib();
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- glReadPixels(0, 0, dim, dim, GL_RGB, GL_FLOAT, texture);
- glBindTexture(GL_TEXTURE_2D, LIGHTMAP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dim, dim, 0, GL_RGB,
- GL_FLOAT, texture);
- free(texture);
- }
- int texdim = 256;
- /* draw the lightmap texture */
- void redraw_lightmap(void)
- {
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glPushAttrib(GL_LIGHTING_BIT|GL_TEXTURE_BIT);
- /* assume GL_MODELVIEW */
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, LIGHTMAP);
- glDisable(GL_LIGHTING);
- glColor3f(1.f, 1.f, 1.f);
- glBegin(GL_QUADS);
- glTexCoord2i(0, 0);
- glVertex2i(-1, -1);
- glTexCoord2i(1, 0);
- glVertex2i(1, -1);
- glTexCoord2i(1, 1);
- glVertex2i(1, 1);
- glTexCoord2i(0, 1);
- glVertex2i(-1, 1);
- glEnd();
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- glPopAttrib();
- CHECK_ERROR("OpenGL Error in redraw_map()");
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- /* draw the lightmap texture */
- void redraw_combomap(void)
- {
- GLfloat scale;
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glPushAttrib(GL_LIGHTING_BIT|GL_TEXTURE_BIT|GL_COLOR_BUFFER_BIT|
- GL_DEPTH_BUFFER_BIT);
- /* assume GL_MODELVIEW */
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glEnable(GL_TEXTURE_2D);
- glDisable(GL_LIGHTING);
- glBindTexture(GL_TEXTURE_2D, SURFMAP);
- glColor3f(intensity, intensity, intensity);
- glBegin(GL_QUADS);
- glTexCoord2i(0, 0);
- glVertex2i(-1, -1);
- glTexCoord2i(5, 0);
- glVertex2i(1, -1);
- glTexCoord2i(5, 5);
- glVertex2i(1, 1);
- glTexCoord2i(0, 5);
- glVertex2i(-1, 1);
- glEnd();
- glEnable(GL_BLEND);
- glDepthFunc(GL_LEQUAL);
- glBlendFunc(GL_ZERO, GL_SRC_COLOR);
- glBindTexture(GL_TEXTURE_2D, LIGHTMAP);
- glMatrixMode(GL_TEXTURE);
- glPushMatrix();
- glTranslatef(.5f, .5f, 0.f);
- scale = .25f + (lightpos[Z] + 100.f) * 3.75f/200.f;
- glScalef(scale, scale, 0.f);
- glTranslatef(-.5f, -.5f, 0.f);
- glTranslatef(-lightpos[X]/200.f, -lightpos[Y]/200.f, 0.f);
- glColor3f(1.f, 1.f, 1.f);
- glBegin(GL_QUADS);
- glTexCoord2i(0, 0);
- glVertex2i(-1, -1);
- glTexCoord2i(1, 0);
- glVertex2i(1, -1);
- glTexCoord2i(1, 1);
- glVertex2i(1, 1);
- glTexCoord2i(0, 1);
- glVertex2i(-1, 1);
- glEnd();
- /* GL_TEXTURE */
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- glPopAttrib();
- CHECK_ERROR("OpenGL Error in redraw_combomap()");
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- /* draw the openGL scene with lighting off */
- void render_scene(int tess)
- {
- /* material properties for objects in scene */
- /* update tessellation if it changed */
- if(tess != lasttess)
- {
- tess_surface(FLOOR, tess);
- tess_surface(CEIL, tess);
- tess_surface(LEFT, tess);
- tess_surface(RIGHT, tess);
- tess_surface(BACK, tess);
- lasttess = tess;
- }
- glPushAttrib(GL_LIGHTING_BIT|GL_TEXTURE_BIT);
- /* floor */
- glColor3f(.5f, .35f, .35f); /* reddish */
- glEnable(GL_TEXTURE_2D);
- glCallList(FLOOR);
- glDisable(GL_TEXTURE_2D);
- /* ceiling */
- glColor3f(.35f, .5f, .35f); /* greenish */
- glCallList(CEIL);
- /* right wall */
- glColor3f(.35f, .35f, .5f); /* bluish */
- glCallList(RIGHT);
- /* left wall */
- glCallList(LEFT);
- /* back wall */
- glCallList(BACK);
- /* draw the sphere */
-
- glCallList(SPHERE);
- /* draw the cone */
- glCallList(CONE);
- /* draw the light */
- glPushMatrix();
- glTranslatef(lightpos[X], lightpos[Y], lightpos[Z]);
- glCallList(LIGHT);
- glPopMatrix();
- glPopAttrib();
- CHECK_ERROR("OpenGL Error in render_unlit()");
- }
- void
- redraw_opengl(void)
- {
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glPushAttrib(GL_LIGHTING_BIT);
- glEnable(GL_LIGHTING);
- glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
- glEnable(GL_COLOR_MATERIAL);
- glLightfv(GL_LIGHT0, GL_POSITION, lightpos); /* opengl lit */
- render_scene(curtess);
- glPopAttrib();
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- void
- redraw_unlit(void)
- {
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glPushAttrib(GL_LIGHTING_BIT);
- glDisable(GL_LIGHTING);
- render_scene(1);
- glPopAttrib();
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- /* draw the scene white, modulated by lightmap */
- /* unlit, uncolored simulated by lighting */
- /* texgen overrides texture coords */
- void render_white(void)
- {
- GLfloat scale;
- /* texgen used to override texure coords */
- static GLfloat XZs[] = {1/200.f, 0.f, 0.f, .5f};
- static GLfloat XZt[] = {0.f, 0.f, 1/200.f, .5f};
- static GLfloat YZs[] = {0.f, 0.f, 1/200.f, .5f};
- static GLfloat YZt[] = {0.f, 1/200.f, 0.f, .5f};
- static GLfloat XYs[] = {1/200.f, 0.f, 0.f, .5f};
- static GLfloat XYt[] = {0.f, 1/200.f, 0.f, .5f};
- /* material properties for objects in scene */
- glPushAttrib(GL_LIGHTING_BIT|GL_TEXTURE_BIT);
- glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glEnable(GL_LIGHTING);
- /* simulate unlit, color = white */
- glLightfv(GL_LIGHT0, GL_AMBIENT, diff);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, zero);
- glColorMaterial(GL_FRONT, GL_AMBIENT);
- glEnable(GL_COLOR_MATERIAL);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, LIGHTMAP);
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glMatrixMode(GL_TEXTURE);
- glPushMatrix();
- glTexGenfv(GL_S, GL_OBJECT_PLANE, XZs);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, XZt);
- glLoadIdentity();
- glTranslatef(.5f, .5f, 0.f);
- scale = nearScale - (nearScale - farScale)/200.f * (100.f + lightpos[Y]);
- glScalef(scale, scale, 1.f);
- glTranslatef(-.5f, -.5f, 0.f);
- glTranslatef(-lightpos[X]/200.f, -lightpos[Z]/200.f, 0.f);
- /* add intensity (colorchange) */
- scale = lightpos[Y] + 100;
- scale /= 200.f;
- scale *= scale;
- scale = 1.f/(1.f + scale);
- scale = 1.f;
- glColor3f(scale, scale, scale);
- /* floor */
- glCallList(FLOOR);
- glLoadIdentity();
- glTranslatef(.5f, .5f, 0.f);
- scale = nearScale - (nearScale - farScale)/200.f * (100.f - lightpos[Y]);
- glScalef(scale, scale, 1.f);
- glTranslatef(-.5f, -.5f, 0.f);
- glTranslatef(-lightpos[X]/200.f, -lightpos[Z]/200.f, 0.f);
- scale = 100 - lightpos[Y];
- scale /= 100.f;
- scale *= scale;
- scale = 1.f/(1.f + scale);
- scale = 1.f;
- glColor3f(scale, scale, scale);
- /* ceiling */
- glCallList(CEIL);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, YZs);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, YZt);
- glLoadIdentity();
- glTranslatef(.5f, .5f, 0.f);
- scale = nearScale - (nearScale - farScale)/200.f * (100.f - lightpos[X]);
- glScalef(scale, scale, 1.f);
- glTranslatef(-.5f, -.5f, 0.f);
- glTranslatef(-lightpos[Z]/200.f, -lightpos[Y]/200.f, 0.f);
- scale = 100 - lightpos[X];
- scale /= 100.f;
- scale *= scale;
- scale = 1.f/(1.f + scale);
- scale = 1.f;
- glColor3f(scale, scale, scale);
- /* right wall */
- glCallList(RIGHT);
- glLoadIdentity();
- glTranslatef(.5f, .5f, 0.f);
- scale = nearScale - (nearScale - farScale)/200.f * (100.f + lightpos[X]);
- glScalef(scale, scale, 1.f);
- glTranslatef(-.5f, -.5f, 0.f);
- glTranslatef(-lightpos[Z]/200.f, -lightpos[Y]/200.f, 0.f);
- scale = lightpos[X] + 100;
- scale /= 100.f;
- scale *= scale;
- scale = 1.f/(1.f + scale);
- scale = 1.f;
- glColor3f(scale, scale, scale);
- /* left wall */
- glCallList(LEFT);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, XYs);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, XYt);
- glLoadIdentity();
- glTranslatef(.5f, .5f, 0.f);
- scale = nearScale - (nearScale - farScale)/200.f * (100.f + lightpos[Z]);
- glScalef(scale, scale, 1.f);
- glTranslatef(-.5f, -.5f, 0.f);
- glTranslatef(-lightpos[X]/200.f, -lightpos[Y]/200.f, 0.f);
- scale = lightpos[Z] + 100;
- scale /= 100.f;
- scale *= scale;
- scale = 1.f/(1.f + scale);
- scale = 1.f;
- glColor3f(scale, scale, scale);
- /* back wall */
- glCallList(BACK);
- /* done with texture matrix */
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- /* no contribution to highly tesselated objects */
- glMaterialfv(GL_FRONT, GL_AMBIENT, zero);
- glLightfv(GL_LIGHT0, GL_AMBIENT, zero);
- /* draw the sphere */
-
- glCallList(SPHERE);
- /* draw the cone */
- glCallList(CONE);
- glPopAttrib();
- CHECK_ERROR("OpenGL Error in render_white()");
- }
- void
- redraw_white(void)
- {
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- render_white();
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- void
- redraw_lightmapped(void)
- {
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_LIGHTING_BIT);
- glDisable(GL_LIGHTING);
- render_scene(1);
- glEnable(GL_LIGHTING);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ZERO, GL_SRC_COLOR);
- glDepthFunc(GL_LEQUAL);
- render_white();
- glPopAttrib();
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- void
- redraw_maponly(void)
- {
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_LIGHTING_BIT);
- glDisable(GL_LIGHTING);
- render_scene(1);
- glEnable(GL_LIGHTING);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ZERO, GL_SRC_COLOR);
- glDepthFunc(GL_LEQUAL);
- render_white();
- glBlendFunc(GL_ONE, GL_ONE);
- glDisable(GL_LIGHTING); /* add in unlit scene again */
- render_scene(1);
-
- glPopAttrib();
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- void
- redraw_complete(void)
- {
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_LIGHTING_BIT);
- glLightfv(GL_LIGHT0, GL_POSITION, lightpos); /* opengl lit */
- glDisable(GL_LIGHTING);
- render_scene(1);
- glEnable(GL_LIGHTING);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ZERO, GL_SRC_COLOR);
- glDepthFunc(GL_LEQUAL);
- render_white();
- glBlendFunc(GL_ONE, GL_ONE);
- glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
- glEnable(GL_COLOR_MATERIAL);
- render_scene(1);
- glPopAttrib();
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- /* ARGSUSED1 */
- void key(unsigned char key, int x, int y)
- {
- switch(key)
- {
- case 'l': /* show lightmap */
- glutDisplayFunc(redraw_lightmap);
- glutPostRedisplay();
- break;
- case 'w': /* show white scene modulated by lightmap */
- glutDisplayFunc(redraw_white);
- glutPostRedisplay();
- break;
- case 'm': /* unlit scene modified by lightmap */
- glutDisplayFunc(redraw_lightmapped);
- glutPostRedisplay();
- break;
- case 'u': /* draw scene without lighting */
- glutDisplayFunc(redraw_unlit);
- glutPostRedisplay();
- break;
- case 'o': /* draw scene lit using OpenGL */
- glutDisplayFunc(redraw_opengl);
- glutPostRedisplay();
- break;
- case 'a': /* show scene lit with OpenGL and lightmaps */
- glutDisplayFunc(redraw_complete);
- glutPostRedisplay();
- break;
- case 'p': /* show scene lit with pure lightmaps */
- glutDisplayFunc(redraw_maponly);
- glutPostRedisplay();
- break;
- case 'x': /* surface texture with lightmap combined */
- glutDisplayFunc(redraw_combomap);
- glutPostRedisplay();
- break;
- case 'T': /* surface texture with lightmap combined */
- curtess++;
- glutPostRedisplay();
- break;
- case 't': /* surface texture with lightmap combined */
- curtess--;
- if(curtess < 1)
- curtess = 1;
- glutPostRedisplay();
- break;
- case '1': /* surface texture with lightmap combined */
- curtess = 1;
- glutPostRedisplay();
- break;
- case 'y':
- farScale -= .0001f;
- if(farScale < .0001f)
- farScale = .0001f;
- printf("farScale = %.4fn", farScale);
- glutPostRedisplay();
- break;
- case 'Y':
- farScale += .0001f;
- printf("farScale = %.4fn", farScale);
- glutPostRedisplay();
- break;
- case 'z':
- nearScale -= .01f;
- if(nearScale < .01f)
- nearScale = .01f;
- printf("nearScale = %.2fn", nearScale);
- glutPostRedisplay();
- break;
- case 'Z':
- nearScale += .01f;
- printf("nearScale = %.2fn", nearScale);
- glutPostRedisplay();
- break;
- case ' 33':
- exit(0);
- break;
- case '?':
- case 'h':
- default:
- fprintf(stderr,
- "Keyboard Commandsn"
- "l - draw lightmapn"
- "w - draw white scene modulated by lightmapn"
- "m - draw unlit scene modified by lightmapn"
- "u - draw unlit scenen"
- "o - draw scene lit by OpenGLn"
- "a - draw scene lit by OpenGL (tess = 1) + lightmapsn"
- "p - draw scene lit only by lightmapsn"
- "x - interactive lightmap on brick walln"
- "T - increase surface tessellationn"
- "t - decrease surface tessellationn"
- "1 - set tessellation to onen"
- "y - decrease far scale for lightmapsn"
- "Y - increase far scale for lightmapsn"
- "z - decrease near scale for lightmapsn"
- "Z - increase near scale for lightmapsn");
- break;
- }
- glutPostRedisplay();
- }
- main(int argc, char *argv[])
- {
- GLfloat *tex;
- GLUquadricObj *qobj;
- glutInit(&argc, argv);
- glutInitWindowSize(winWidth, winHeight);
- if(argc > 1)
- {
- char *args = argv[1];
- int done = FALSE;
- while(!done)
- {
- switch(*args)
- {
- case 's': /* single buffer */
- printf("Single Bufferedn");
- dblbuf = FALSE;
- break;
- case '-': /* do nothing */
- break;
- case 0:
- done = TRUE;
- break;
- }
- args++;
- }
- }
- if(dblbuf)
- glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
- else
- glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH);
- (void)glutCreateWindow("example program");
- glutDisplayFunc(redraw_opengl);
- glutKeyboardFunc(key);
- glutMouseFunc(mouse);
- glutMotionFunc(motion);
- glutReshapeFunc(reshape);
- /* draw a perspective scene */
- glMatrixMode(GL_PROJECTION);
- glFrustum(-100., 100., -100., 100., 300., 501.);
- glMatrixMode(GL_MODELVIEW);
- /* look at scene from (0, 0, 400) */
- gluLookAt(0., 0., 400., 0., 0., 0., 0., 1., 0.);
- /* turn on features */
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHT0);
- glLightfv(GL_LIGHT0, GL_POSITION, staticlightpos);
- /* remove back faces to speed things up */
- glCullFace(GL_BACK);
- /* make a display list containing a sphere */
- glNewList(SPHERE, GL_COMPILE);
- {
- glPushMatrix();
- glTranslatef(0.f, -80.f, -80.f);
- qobj = gluNewQuadric();
- gluQuadricTexture(qobj, GL_TRUE);
- glColor3f(.5f, .25f, 0.f);
- gluSphere(qobj, 20.f, 20, 20);
- gluDeleteQuadric(qobj);
- glPopMatrix();
- }
- glEndList();
- /* make a display list containing a sphere */
- glNewList(LIGHT, GL_COMPILE);
- {
- qobj = gluNewQuadric();
- glColor3f(1.f, 1.f, 1.f);
- glPushAttrib(GL_LIGHTING_BIT);
- glDisable(GL_LIGHTING);
- gluSphere(qobj, 3.f, 20, 20);
- glPopAttrib();
- gluDeleteQuadric(qobj);
- }
- glEndList();
- /* create a display list containing a cone */
- glNewList(CONE, GL_COMPILE);
- {
- glPushMatrix();
- glTranslatef(-60.f, -100.f, -5.f);
- qobj = gluNewQuadric();
- gluQuadricTexture(qobj, GL_TRUE);
- glRotatef(-90.f, 1.f, 0.f, 0.f);
- glColor3f(0.f, .25f, .5f);
- gluCylinder(qobj, 20., 0., 60., 20, 20);
- gluDeleteQuadric(qobj);
- qobj = gluNewQuadric();
- gluQuadricOrientation(qobj, GLU_INSIDE);
- gluDisk(qobj, 0., 20., 20, 1);
- gluDeleteQuadric(qobj);
- glPopMatrix();
- }
- glEndList();
- /* load pattern for current 2d texture */
- tex = make_texture(128, 128);
- /* makes texturing faster, and looks better than GL_LINEAR */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, 1, 128, 128, 0, GL_RED, GL_FLOAT, tex);
- free(tex);
- {
- GLuint *surftex;
- int texwid, texht, texcomps;
- surftex = read_texture("../data/brick.rgb", &texwid, &texht, &texcomps);
- glBindTexture(GL_TEXTURE_2D, SURFMAP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texwid, texht, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, surftex);
- }
- glBindTexture(GL_TEXTURE_2D, DEFAULT);
- tess_surface(FLOOR, 1);
- tess_surface(CEIL, 1);
- tess_surface(LEFT, 1);
- tess_surface(RIGHT, 1);
- tess_surface(BACK, 1);
- /* 1/80 intensity at edges */
- glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 100.f/(texdim * texdim/4));
- /* 1/2 intensity at edges */
- glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 1.f/texdim/2);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, one);
- make_lightmap(GL_LIGHT1, 128);
- key('?', 0, 0);
- CHECK_ERROR("end of main");
- glutMainLoop();
- return 0;
- }