/* 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 #include #include #include 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((GLenum)(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. */ }