highlight.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:17k
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <GL/glut.h>
- #include "texture.h"
- /* Some <math.h> files do not define M_PI... */
- #ifndef M_PI
- #define M_PI 3.14159265358979323846
- #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);
- }
- #ifndef FALSE
- enum {FALSE, TRUE};
- #endif
- enum {X, Y, Z, W};
- enum {OBJ_ANGLE, LIGHT_ANGLE, OBJ_TRANSLATE};
- enum {SURF_TEX, HIGHLIGHT_TEX};
- /* window dimensions */
- int winWidth = 512;
- int winHeight = 512;
- int active;
- int dblbuf = TRUE;
- int highlight = TRUE;
- int gouraud = FALSE;
- int texmap = FALSE;
- int notex = FALSE; /* don't texture gouraud */
- int object = 2;
- int maxobject = 2;
- GLfloat lightangle[2] = {0.f, 0.f};
- GLfloat objangle[2] = {0.f, 0.f};
- GLfloat objpos[2] = {0.f, 0.f};
- GLfloat color[4] = {1.f, 1.f, 1.f, 1.f};
- GLfloat zero[4] = {0.f, 0.f, 0.f, 1.f};
- GLfloat one[4] = {1.f, 1.f, 1.f, 1.f};
- int texdim = 128;
- GLfloat *lighttex = 0;
- GLfloat lightpos[4] = {0.f, 0.f, 1.f, 0.f};
- GLboolean lightchanged[2] = {GL_TRUE, GL_TRUE};
- enum {UPDATE_OGL, UPDATE_TEX};
- /* draw a highly tesselated sphere with a specular highlight */
- void
- makeHighlight(int shinyness)
- {
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glPushMatrix(); /* starts as modelview */
- glLoadIdentity();
- glTranslatef(0.f, 0.f, -texdim/2.f);
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glOrtho(-texdim/2., texdim/2., -texdim/2., texdim/2., 0., texdim/2.);
- glPushAttrib(GL_LIGHTING_BIT|GL_VIEWPORT_BIT);
- glViewport(0, 0, texdim, texdim);
- glEnable(GL_LIGHTING);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, zero);
- glLightfv(GL_LIGHT0, GL_POSITION, lightpos); /* light direction */
- /* XXX TODO, range check an report errors */
- glMateriali(GL_FRONT, GL_SHININESS, shinyness); /* cosine power */
- glMaterialfv(GL_FRONT, GL_AMBIENT, zero);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, zero);
- glMaterialfv(GL_FRONT, GL_SPECULAR, color);
- glDisable(GL_TEXTURE_2D);
- glCallList(1);
- glEnable(GL_TEXTURE_2D);
- glPopAttrib();
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- glReadPixels(0, 0, texdim, texdim, GL_RGB, GL_FLOAT, lighttex);
- glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texdim, texdim, 0, GL_RGB,
- GL_FLOAT, lighttex);
- }
- void
- reshape(int wid, int ht)
- {
- winWidth = wid;
- winHeight = ht;
- glViewport(0, 0, wid, ht);
- }
- void
- motion(int x, int y)
- {
- switch(active)
- {
- case OBJ_ANGLE:
- objangle[X] = (x - winWidth/2) * 360./winWidth;
- objangle[Y] = (y - winHeight/2) * 360./winHeight;
- glutPostRedisplay();
- break;
- case LIGHT_ANGLE:
- lightangle[X] = (x - winWidth/2) * 2 * M_PI/winWidth;
- lightangle[Y] = (winHeight/2 - y) * 2 * M_PI/winHeight;
- lightpos[Y] = sin(lightangle[Y]);
- lightpos[X] = cos(lightangle[Y]) * sin(lightangle[X]);
- lightpos[Z] = cos(lightangle[Y]) * cos(lightangle[X]);
- lightpos[W] = 0.;
- lightchanged[UPDATE_OGL] = GL_TRUE;
- lightchanged[UPDATE_TEX] = GL_TRUE;
- glutPostRedisplay();
- break;
- case OBJ_TRANSLATE:
- objpos[X] = (x - winWidth/2) * 100./winWidth;
- objpos[Y] = (winHeight/2 - y) * 100./winHeight;
- 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 */
- active = OBJ_ANGLE;
- motion(x, y);
- break;
- case GLUT_MIDDLE_BUTTON:
- active = LIGHT_ANGLE;
- motion(x, y);
- break;
- case GLUT_RIGHT_BUTTON: /* move the polygon */
- active = OBJ_TRANSLATE;
- motion(x, y);
- break;
- }
- }
- /* draw the object unlit without surface texture */
- void redraw_white(void)
- {
- glPushMatrix(); /* assuming modelview */
- glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
- glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
- glRotatef(objangle[Y], 1.f, 0.f, 0.f);
-
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
-
- glDisable(GL_LIGHTING);
- glDisable(GL_TEXTURE_2D);
- /* draw the specular highlight */
-
- glCallList(object);
- glEnable(GL_TEXTURE_2D);
- glPopMatrix(); /* assuming modelview */
- CHECK_ERROR("OpenGL Error in redraw_tex()");
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- /* just draw textured highlight */
- void redraw_tex_highlight(void)
- {
- if(lightchanged[UPDATE_TEX])
- {
- makeHighlight(128);
- lightchanged[UPDATE_TEX] = GL_FALSE;
- }
- glPushMatrix(); /* assuming modelview */
- glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
- glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
- glRotatef(objangle[Y], 1.f, 0.f, 0.f);
-
- glClearColor(.1f, .1f, .1f, 1.f);
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glClearColor(0.f, 0.f, 0.f, 1.f);
-
- /* draw the specular highlight */
- glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX);
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
-
- glCallList(object);
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- glPopMatrix(); /* assuming modelview */
- CHECK_ERROR("OpenGL Error in redraw_tex()");
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- /* just draw opengl highlight */
- void redraw_gouraud_highlight(void)
- {
- if(lightchanged[UPDATE_OGL])
- {
- glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
- lightchanged[UPDATE_OGL] = GL_FALSE;
- }
- glPushAttrib(GL_LIGHTING);
- glPushMatrix(); /* assuming modelview */
- glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
- glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
- glRotatef(objangle[Y], 1.f, 0.f, 0.f);
-
- glClearColor(.1f, .1f, .1f, 1.f);
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glClearColor(0.f, 0.f, 0.f, 1.f);
-
- /* draw the specular highlight */
- glEnable(GL_LIGHTING);
- glDisable(GL_TEXTURE_2D);
- glMaterialfv(GL_FRONT, GL_SPECULAR, color); /* turn on ogl highlights */
- glMaterialfv(GL_FRONT, GL_DIFFUSE, zero); /* turn off ogl diffuse */
- glMaterialfv(GL_FRONT, GL_AMBIENT, zero); /* turn off ogl diffuse */
- /* draw the specular highlight */
- glCallList(object);
- glEnable(GL_TEXTURE_2D);
- glPopMatrix(); /* assuming modelview */
- glPopAttrib();
- CHECK_ERROR("OpenGL Error in redraw_tex()");
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- /* show highlight texture map */
- void redraw_map(void)
- {
- if(lightchanged[UPDATE_TEX])
- {
- makeHighlight(128);
- lightchanged[UPDATE_TEX] = GL_FALSE;
- }
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX);
- glDisable(GL_LIGHTING);
- 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();
- glEnable(GL_LIGHTING);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- CHECK_ERROR("OpenGL Error in redraw_map()");
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- /* multipass, use texture to make highlight */
- void redraw_tex(void)
- {
- if(lightchanged[UPDATE_TEX])
- {
- makeHighlight(128);
- lightchanged[UPDATE_TEX] = GL_FALSE;
- }
- if(lightchanged[UPDATE_OGL])
- {
- glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
- lightchanged[UPDATE_OGL] = GL_FALSE;
- }
- glPushMatrix(); /* assuming modelview */
- glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
- glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
- glRotatef(objangle[Y], 1.f, 0.f, 0.f);
-
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
-
- /* draw the diffuse portion of the light */
- glEnable(GL_LIGHTING);
- glBindTexture(GL_TEXTURE_2D, SURF_TEX);
- if(notex)
- glDisable(GL_TEXTURE_2D);
- glCallList(object);
- if(notex)
- glEnable(GL_TEXTURE_2D);
- glDisable(GL_LIGHTING);
- /* draw the specular highlight */
- glEnable(GL_BLEND);
- glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX);
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glDepthFunc(GL_LEQUAL);
-
- glCallList(object);
- glDepthFunc(GL_LESS);
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- glDisable(GL_BLEND);
- glPopMatrix(); /* assuming modelview */
- CHECK_ERROR("OpenGL Error in redraw_tex()");
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- /* multipass; use opengl to make highlight */
- void redraw_phong(void)
- {
- if(lightchanged[UPDATE_OGL])
- {
- glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
- lightchanged[UPDATE_OGL] = GL_FALSE;
- }
- glPushAttrib(GL_LIGHTING);
- glPushMatrix(); /* assuming modelview */
- glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
- glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
- glRotatef(objangle[Y], 1.f, 0.f, 0.f);
-
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
-
- /* draw the diffuse portion of the light */
- glEnable(GL_LIGHTING);
- glBindTexture(GL_TEXTURE_2D, SURF_TEX);
- if(notex)
- glDisable(GL_TEXTURE_2D);
- glCallList(object);
- if(notex)
- glEnable(GL_TEXTURE_2D);
- /* turn off texturing so phong highlight color is pure */
- glDisable(GL_TEXTURE_2D);
- glMaterialfv(GL_FRONT, GL_SPECULAR, color); /* turn on ogl highlights */
- glMaterialfv(GL_FRONT, GL_DIFFUSE, zero); /* turn off ogl diffuse */
- glMaterialfv(GL_FRONT, GL_AMBIENT, zero); /* turn off ogl diffuse */
- /* draw the specular highlight */
- glEnable(GL_BLEND);
- glDepthFunc(GL_LEQUAL);
-
- glCallList(object);
- glEnable(GL_TEXTURE_2D);
- glDepthFunc(GL_LESS);
- glDisable(GL_BLEND);
- glPopMatrix(); /* assuming modelview */
- glPopAttrib();
- CHECK_ERROR("OpenGL Error in redraw_tex()");
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- /* Use OpenGL lighting to get highlight */
- void redraw_original(void)
- {
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
-
- glPushMatrix(); /* assuming modelview */
- glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
- glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
- glRotatef(objangle[Y], 1.f, 0.f, 0.f);
-
- if(lightchanged[UPDATE_OGL])
- {
- glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
- lightchanged[UPDATE_OGL] = GL_FALSE;
- }
- glEnable(GL_LIGHTING);
- glBindTexture(GL_TEXTURE_2D, SURF_TEX);
- glMaterialfv(GL_FRONT, GL_SPECULAR, color); /* turn on ogl highlights */
- if(notex)
- glDisable(GL_TEXTURE_2D);
- glCallList(object);
- if(notex)
- glEnable(GL_TEXTURE_2D);
- glMaterialfv(GL_FRONT, GL_SPECULAR, zero);
- glDisable(GL_LIGHTING);
- glPopMatrix(); /* assuming modelview */
- CHECK_ERROR("OpenGL Error in redraw()");
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- /* Draw with no highlight */
- void redraw_diffuse(void)
- {
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
-
- glPushMatrix(); /* assuming modelview */
- glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
- glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
- glRotatef(objangle[Y], 1.f, 0.f, 0.f);
-
- if(lightchanged[UPDATE_OGL])
- {
- glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
- lightchanged[UPDATE_OGL] = GL_FALSE;
- }
- /* draw the diffuse portion of the light */
- glEnable(GL_LIGHTING);
- glBindTexture(GL_TEXTURE_2D, SURF_TEX);
- glCallList(object);
- glDisable(GL_LIGHTING);
- glPopMatrix(); /* assuming modelview */
- CHECK_ERROR("OpenGL Error in redraw()");
- if(dblbuf)
- glutSwapBuffers();
- else
- glFlush();
- }
- /* ARGSUSED1 */
- void key(unsigned char key, int x, int y)
- {
- switch(key)
- {
- case 'u': /* unmodified highlight */
- printf("Use unmodified gouraud highlightn");
- glutDisplayFunc(redraw_original);
- glutPostRedisplay();
- break;
- case 'd':
- printf("Draw diffuse onlyn");
- glutDisplayFunc(redraw_diffuse);
- glutPostRedisplay();
- break;
- case 'g': /* separate gouraud shaded highlight */
- printf("Use separate gouraud shaded highlightn");
- glutDisplayFunc(redraw_phong);
- glutPostRedisplay();
- break;
- case 't': /* separate textured highlight */
- printf("Use separate texture highlightn");
- glutDisplayFunc(redraw_tex);
- glutPostRedisplay();
- break;
- case 'o':
- /* toggle object type */
- object++;
- if(object > maxobject)
- object = 2;
- glutPostRedisplay();
- break;
- case 'm':
- /* show highlight texture map */
- printf("Show highlight texture mapn");
- glutDisplayFunc(redraw_map);
- glutPostRedisplay();
- break;
- case 'n':
- if(notex)
- notex = FALSE;
- else
- notex = TRUE;
- glutPostRedisplay();
- break;
- case 'h':
- printf("Show textured phong highlightn");
- glutDisplayFunc(redraw_tex_highlight);
- glutPostRedisplay();
- break;
- case 'p':
- printf("Show gouraud-shaded phong highlightn");
- glutDisplayFunc(redraw_gouraud_highlight);
- glutPostRedisplay();
- break;
- case 'w':
- printf("Show white objectn");
- glutDisplayFunc(redraw_white);
- glutPostRedisplay();
- break;
- case ' 33':
- exit(0);
- break;
- default:
- fprintf(stderr, "Keyboard commands:nn"
- "u - (unmodified opengl lighting)n"
- "d - diffuse onlyn"
- "g - multipass gouraud highlightn"
- "t - multipass texture highlightn"
- "o - toggle objectn"
- "m - show highlight texture mapn"
- "n - toggle surface texturingn"
- "h - show textured phong highlightn"
- "p - show gouraud-shaded phong highlightn"
- "w - show unlit white objectn");
- break;
- }
- }
- main(int argc, char *argv[])
- {
- GLuint *tex;
- int texwid, texht, texcomps;
- GLUquadricObj *quadric;
- glutInitWindowSize(winWidth, winHeight);
- glutInit(&argc, argv);
- 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_original);
- glutReshapeFunc(reshape);
- glutMouseFunc(mouse);
- glutMotionFunc(motion);
- glutKeyboardFunc(key);
- /* draw a perspective scene */
- glMatrixMode(GL_PROJECTION);
- glFrustum(-100., 100., -100., 100., 300., 600.);
- glMatrixMode(GL_MODELVIEW);
- /* look at scene from (0, 0, 450) */
- gluLookAt(0., 0., 450., 0., 0., 0., 0., 1., 0.);
- /* turn on features */
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
-
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- glMateriali(GL_FRONT, GL_SHININESS, 128); /* cosine power */
- /* remove back faces to speed things up */
- glCullFace(GL_BACK);
- glBlendFunc(GL_ONE, GL_ONE);
- lightchanged[UPDATE_TEX] = GL_TRUE;
- lightchanged[UPDATE_OGL] = GL_TRUE;
- /* load pattern for current 2d texture */
- tex = read_texture("../data/wood.rgb", &texwid, &texht, &texcomps);
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, texwid, texht, GL_RGBA,
- GL_UNSIGNED_BYTE, tex);
- free(tex);
- CHECK_ERROR("end of main");
- lighttex = (GLfloat *)malloc(texdim * texdim * sizeof(GL_FLOAT) * 3);
- /* XXX TODO use display list to avoid retesselating */
- glNewList(1, GL_COMPILE);
- glutSolidSphere((GLdouble)texdim/2., 50, 50);
- glEndList();
- glNewList(2, GL_COMPILE);
- glutSolidTeapot(70.);
- glEndList();
- quadric = gluNewQuadric();
- gluQuadricTexture(quadric, GL_TRUE);
- glNewList(3, GL_COMPILE);
- gluSphere(quadric, 70., 20, 20);
- glEndList();
- gluDeleteQuadric(quadric);
- maxobject = 3;
- glutMainLoop();
- return 0;
- }