silhouette.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:5k
- /* silhouette.c - by Tom McReynolds, SGI */
- /* Doing Silhouette Edges with stencil */
- #include <GL/glut.h>
- #include <stdlib.h>
- #include <math.h>
- enum {
- CONE = 1
- };
- /* Draw a cone */
- void
- cone(void)
- {
- glPushMatrix();
- glTranslatef(0.f, 0.f, -30.f);
- glCallList(CONE);
- glPopMatrix();
- }
- /* Draw a torus */
- void
- torus(void)
- {
- glutSolidTorus(10., 20., 20, 20);
- }
- enum {
- SIL, OBJ, SIL_AND_OBJ, TOGGLE
- };
- int rendermode = OBJ;
- void (*curobj) (void) = cone;
- void
- menu(int mode)
- {
- switch (mode) {
- case SIL:
- case OBJ:
- case SIL_AND_OBJ:
- rendermode = mode;
- break;
- case TOGGLE:
- if (curobj == cone)
- curobj = torus;
- else
- curobj = cone;
- break;
- }
- glutPostRedisplay();
- }
- int winWidth = 512;
- int winHeight = 512;
- /* used to get current width and height of viewport */
- void
- reshape(int wid, int ht)
- {
- glViewport(0, 0, wid, ht);
- winWidth = wid;
- winHeight = ht;
- glutPostRedisplay();
- }
- GLfloat viewangle;
- void
- drawsilhouette(void)
- {
- int i;
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- glEnable(GL_STENCIL_TEST);
- glStencilFunc(GL_ALWAYS, 1, 1);
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
- glDisable(GL_DEPTH_TEST); /* so the depth buffer doesn't change */
- for (i = -1; i < 2; i += 2) { /* set stencil around object */
- glViewport(i, 0, winWidth + i, winHeight);
- curobj();
- }
- for (i = -1; i < 2; i += 2) {
- glViewport(0, i, winWidth, winHeight + i);
- curobj();
- }
- /* cut out stencil where object is */
- glViewport(0, 0, winWidth, winHeight);
- glStencilFunc(GL_ALWAYS, 0, 0);
- curobj();
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glStencilFunc(GL_EQUAL, 1, 1);
- glDisable(GL_LIGHTING);
- glColor3f(1.f, 0.f, 0.f); /* draw silhouette red */
- glRotatef(-viewangle, 0.f, 1.f, 0.f);
- glRecti(-50, -50, 50, 50);
- glRotatef(viewangle, 0.f, 1.f, 0.f);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
- glDisable(GL_STENCIL_TEST);
- }
- void
- redraw(void)
- {
- /* clear stencil each time */
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- glPushMatrix();
- glRotatef(viewangle, 0.f, 1.f, 0.f);
- switch (rendermode) {
- case SIL:
- drawsilhouette();
- break;
- case SIL_AND_OBJ:
- drawsilhouette();
- curobj();
- break;
- case OBJ:
- curobj();
- break;
- }
- glPopMatrix();
- glutSwapBuffers();
- }
- /* animate scene by rotating */
- enum {
- ANIM_LEFT, ANIM_RIGHT
- };
- int animDirection = ANIM_LEFT;
- void
- anim(void)
- {
- if (animDirection == ANIM_LEFT)
- viewangle -= 1.f;
- else
- viewangle += 1.f;
- glutPostRedisplay();
- }
- /* ARGSUSED1 */
- /* special keys, like array and F keys */
- void
- special(int key, int x, int y)
- {
- switch (key) {
- case GLUT_KEY_LEFT:
- glutIdleFunc(anim);
- animDirection = ANIM_LEFT;
- break;
- case GLUT_KEY_RIGHT:
- glutIdleFunc(anim);
- animDirection = ANIM_RIGHT;
- break;
- case GLUT_KEY_UP:
- case GLUT_KEY_DOWN:
- glutIdleFunc(0);
- break;
- }
- }
- /* ARGSUSED1 */
- void
- key(unsigned char key, int x, int y)
- {
- switch (key) {
- case 'a':
- viewangle -= 10.f;
- glutPostRedisplay();
- break;
- case 's':
- viewangle += 10.f;
- glutPostRedisplay();
- break;
- case ' 33':
- exit(0);
- }
- }
- int picked_object;
- int xpos = 0, ypos = 0;
- int newxpos, newypos;
- int startx, starty;
- int
- main(int argc, char **argv)
- {
- static GLfloat lightpos[] =
- {25.f, 50.f, -50.f, 1.f};
- static GLfloat cone_mat[] =
- {0.f, .5f, 1.f, 1.f};
- GLUquadricObj *cone, *base;
- glutInit(&argc, argv);
- glutInitWindowSize(512, 512);
- glutInitDisplayMode(GLUT_STENCIL | GLUT_DEPTH | GLUT_DOUBLE);
- (void) glutCreateWindow("silhouette edges");
- glutDisplayFunc(redraw);
- glutKeyboardFunc(key);
- glutSpecialFunc(special);
- glutReshapeFunc(reshape);
- glutCreateMenu(menu);
- glutAddMenuEntry("Object", OBJ);
- glutAddMenuEntry("Silhouette Only", SIL);
- glutAddMenuEntry("Object and Silhouette", SIL_AND_OBJ);
- glutAddMenuEntry("Toggle Object", TOGGLE);
- glutAttachMenu(GLUT_RIGHT_BUTTON);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
- /* make display list for cone; for efficiency */
- glNewList(CONE, GL_COMPILE);
- cone = gluNewQuadric();
- base = gluNewQuadric();
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, cone_mat);
- gluQuadricOrientation(base, GLU_INSIDE);
- gluDisk(base, 0., 15., 32, 1);
- gluCylinder(cone, 15., 0., 60., 32, 32);
- gluDeleteQuadric(cone);
- gluDeleteQuadric(base);
- glEndList();
- glMatrixMode(GL_PROJECTION);
- glOrtho(-50., 50., -50., 50., -50., 50.);
- glMatrixMode(GL_MODELVIEW);
- glutMainLoop();
- return 0; /* ANSI C requires main to return int. */
- }