lightlab.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:8k
- /* Copyright (c) Mark J. Kilgard, 1994. */
- /* This program is freely distributable without licensing fees
- and is provided without guarantee or warrantee expressed or
- implied. This program is -not- in the public domain. */
- #include <stdlib.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <GL/glut.h>
- enum {
- BRASS, RED_PLASTIC, EMERALD, SLATE
- } MaterialType;
- enum {
- TORUS_MATERIAL = 1, TEAPOT_MATERIAL = 2, ICO_MATERIAL = 3
- } MaterialDisplayList;
- enum {
- LIGHT_OFF, LIGHT_RED, LIGHT_WHITE, LIGHT_GREEN
- } LightValues;
- GLfloat red_light[] =
- {1.0, 0.0, 0.0, 1.0}, green_light[] =
- {0.0, 1.0, 0.0, 1.0}, white_light[] =
- {1.0, 1.0, 1.0, 1.0};
- GLfloat left_light_position[] =
- {-1.0, 0.0, 1.0, 0.0}, right_light_position[] =
- {1.0, 0.0, 1.0, 0.0};
- GLfloat brass_ambient[] =
- {0.33, 0.22, 0.03, 1.0}, brass_diffuse[] =
- {0.78, 0.57, 0.11, 1.0}, brass_specular[] =
- {0.99, 0.91, 0.81, 1.0}, brass_shininess = 27.8;
- GLfloat red_plastic_ambient[] =
- {0.0, 0.0, 0.0}, red_plastic_diffuse[] =
- {0.5, 0.0, 0.0}, red_plastic_specular[] =
- {0.7, 0.6, 0.6}, red_plastic_shininess = 32.0;
- GLfloat emerald_ambient[] =
- {0.0215, 0.1745, 0.0215}, emerald_diffuse[] =
- {0.07568, 0.61424, 0.07568}, emerald_specular[] =
- {0.633, 0.727811, 0.633}, emerald_shininess = 76.8;
- GLfloat slate_ambient[] =
- {0.02, 0.02, 0.02}, slate_diffuse[] =
- {0.02, 0.01, 0.01}, slate_specular[] =
- {0.4, 0.4, 0.4}, slate_shininess = .78125;
- int shade_model = GL_SMOOTH;
- char *left_light, *right_light;
- char *ico_material, *teapot_material, *torus_material;
- void
- output(GLfloat x, GLfloat y, char *format,...)
- {
- va_list args;
- char buffer[200], *p;
- va_start(args, format);
- vsprintf(buffer, format, args);
- va_end(args);
- glPushMatrix();
- glTranslatef(x, y, 0);
- for (p = buffer; *p; p++)
- glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
- glPopMatrix();
- }
- void
- display(void)
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glScalef(1.3, 1.3, 1.3);
- glRotatef(20.0, 1.0, 0.0, 0.0);
- glPushMatrix();
- glTranslatef(-0.65, 0.7, 0.0);
- glRotatef(90.0, 1.0, 0.0, 0.0);
- glCallList(TORUS_MATERIAL);
- glutSolidTorus(0.275, 0.85, 10, 15);
- glPopMatrix();
- glPushMatrix();
- glTranslatef(-0.75, -0.8, 0.0);
- glCallList(TEAPOT_MATERIAL);
- glutSolidTeapot(0.7);
- glPopMatrix();
- glPushMatrix();
- glTranslatef(1.0, 0.0, -1.0);
- glCallList(ICO_MATERIAL);
- glutSolidIcosahedron();
- glPopMatrix();
- glPopMatrix();
- glPushAttrib(GL_ENABLE_BIT);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_LIGHTING);
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- gluOrtho2D(0, 3000, 0, 3000);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- output(80, 2800, "Torus: %s", torus_material);
- output(80, 2650, "Icosahedron: %s", ico_material);
- output(80, 2500, "Teapot: %s", teapot_material);
- output(80, 250, "Left light: %s", left_light);
- output(1700, 250, "Right light: %s", right_light);
- output(850, 100, "Shade model: %s",
- shade_model == GL_SMOOTH ? "smooth" : "flat");
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glPopAttrib();
- glutSwapBuffers();
- }
- void
- light_select(GLenum which, int value, char **label)
- {
- glEnable(which);
- switch (value) {
- case LIGHT_OFF:
- *label = "off";
- glDisable(which);
- break;
- case LIGHT_RED:
- *label = "red";
- glLightfv(which, GL_DIFFUSE, red_light);
- break;
- case LIGHT_WHITE:
- *label = "white";
- glLightfv(which, GL_DIFFUSE, white_light);
- break;
- case LIGHT_GREEN:
- *label = "green";
- glLightfv(which, GL_DIFFUSE, green_light);
- break;
- }
- glutPostRedisplay();
- }
- void
- left_light_select(int value)
- {
- light_select(GL_LIGHT0, value, &left_light);
- }
- void
- right_light_select(int value)
- {
- light_select(GL_LIGHT1, value, &right_light);
- }
- void
- material(int dlist, GLfloat * ambient, GLfloat * diffuse,
- GLfloat * specular, GLfloat shininess)
- {
- glNewList(dlist, GL_COMPILE);
- glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
- glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
- glMaterialf(GL_FRONT, GL_SHININESS, shininess);
- glEndList();
- }
- char *
- material_select(int object, int value)
- {
- glutPostRedisplay();
- switch (value) {
- case BRASS:
- material(object, brass_ambient,
- brass_diffuse, brass_specular, brass_shininess);
- return "brass";
- case RED_PLASTIC:
- material(object, red_plastic_ambient, red_plastic_diffuse,
- red_plastic_specular, red_plastic_shininess);
- return "red plastic";
- case EMERALD:
- material(object, emerald_ambient, emerald_diffuse,
- emerald_specular, emerald_shininess);
- return "emerald";
- case SLATE:
- material(object, slate_ambient, slate_diffuse,
- slate_specular, slate_shininess);
- return "slate";
- }
- return NULL; /* avoid bogus warning! */
- }
- void
- torus_select(int value)
- {
- torus_material = material_select(TORUS_MATERIAL, value);
- }
- void
- teapot_select(int value)
- {
- teapot_material = material_select(TEAPOT_MATERIAL, value);
- }
- void
- ico_select(int value)
- {
- ico_material = material_select(ICO_MATERIAL, value);
- }
- void
- main_menu_select(int value)
- {
- if (value == 666)
- exit(0);
- glShadeModel(shade_model = value);
- glutPostRedisplay();
- }
- int
- main(int argc, char **argv)
- {
- int left_light_m, right_light_m, torus_m, teapot_m, ico_m;
- glutInitWindowSize(400, 400);
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
- glutCreateWindow("Lighting Laboratory");
- glutDisplayFunc(display);
- #define LIGHT_MENU_ENTRIES()
- glutAddMenuEntry("Disable", LIGHT_OFF);
- glutAddMenuEntry("Red", LIGHT_RED);
- glutAddMenuEntry("White", LIGHT_WHITE);
- glutAddMenuEntry("Green", LIGHT_GREEN);
- #define MATERIAL_MENU_ENTRIES()
- glutAddMenuEntry("Brass", BRASS);
- glutAddMenuEntry("Red plastic", RED_PLASTIC);
- glutAddMenuEntry("Emerald", EMERALD);
- glutAddMenuEntry("Slate", SLATE);
- left_light_m = glutCreateMenu(left_light_select);
- LIGHT_MENU_ENTRIES();
- right_light_m = glutCreateMenu(right_light_select);
- LIGHT_MENU_ENTRIES();
- torus_m = glutCreateMenu(torus_select);
- MATERIAL_MENU_ENTRIES();
- teapot_m = glutCreateMenu(teapot_select);
- MATERIAL_MENU_ENTRIES();
- ico_m = glutCreateMenu(ico_select);
- MATERIAL_MENU_ENTRIES();
- glutCreateMenu(main_menu_select);
- glutAddMenuEntry("Smooth shading", GL_SMOOTH);
- glutAddMenuEntry("Flat shading", GL_FLAT);
- glutAddSubMenu("Left light", left_light_m);
- glutAddSubMenu("Right light", right_light_m);
- glutAddSubMenu("Torus", torus_m);
- glutAddSubMenu("Teapot", teapot_m);
- glutAddSubMenu("Icosahedron", ico_m);
- glutAddMenuEntry("Quit", 666);
- glutAttachMenu(GLUT_RIGHT_BUTTON);
- glLightfv(GL_LIGHT0, GL_POSITION, left_light_position);
- glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
- glLightfv(GL_LIGHT1, GL_POSITION, right_light_position);
- glLightfv(GL_LIGHT1, GL_SPECULAR, white_light);
- left_light_select(LIGHT_RED);
- right_light_select(LIGHT_GREEN);
- torus_select(RED_PLASTIC);
- teapot_select(BRASS);
- ico_select(EMERALD);
- glEnable(GL_LIGHTING);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_NORMALIZE);
- glLineWidth(1.0);
- glMatrixMode(GL_PROJECTION);
- gluPerspective( /* degrees field of view */ 50.0,
- /* aspect ratio */ 1.0, /* Z near */ 1.0, /* Z far */ 10.0);
- glMatrixMode(GL_MODELVIEW);
- gluLookAt(0.0, 0.0, 5.0, /* eye is at (0,0,5) */
- 0.0, 0.0, 0.0, /* center is at (0,0,0) */
- 0.0, 1.0, 0.); /* up is in positive Y direction */
- glTranslatef(0.0, 0.0, -1.0);
- glutMainLoop();
- return 0; /* ANSI C requires main to return int. */
- }