#include #include // function prototypes void display(void); void reshape(int width, int height); void keyboard(unsigned char key, int x, int y); void init(void); void printHelp(); void printStatus(); float clamp(float f); // global variable -- yuck // you should create different arrays for diffuse // and specular -- this is only so that // they can be easily indexed for change float mat[]={0.5f, 0.0f, 0.0f, 1.0f, 0.2f, 0.2f, 0.2f, 1.0f}; float matHighlights=1.0f; unsigned int twoSided = GL_FALSE; unsigned int local = GL_TRUE; enum{DIFFUSE, SPECULAR, HIGHLIGHTS}; enum{RED,GREEN,BLUE, ALL}; static int matType=DIFFUSE; static int color=RED; int main(int argc, char **argv) { // set up window glutInitWindowSize(400, 400); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("Materials Lab"); // register callback functions glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); // print instructions printHelp(); printStatus(); // initalize opengl parameters init(); // loop until something happens glutMainLoop(); return 0; } void init() { // initialize viewing system glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, 1.0, 10.0, 100.0); glMatrixMode(GL_MODELVIEW); // initialize background color to black glClearColor(0.0,0.0,0.0,0.0); // enable depth buffering glEnable(GL_DEPTH_TEST); // shading model is smooth glEnable(GL_SMOOTH); // normalize normals glEnable(GL_NORMALIZE); // cull backfacing polygons glCullFace(GL_BACK); glEnable(GL_CULL_FACE); // initialize light GLfloat lightPosition[] = {30.0f, 50.0f, 30.0f}; // set light position glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); // this will make it a // positional light GLfloat whiteLight[] = {1.0f, 1.0f, 1.0f, 1.0f}; // set the light color to white glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteLight); // for diffuse glLightfv(GL_LIGHT0, GL_SPECULAR, whiteLight); // and specular // enable lighting and the light we defined glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } void reshape(int width, int height) { if (width< height) glViewport(0,0,width, width); else glViewport(0,0,height,height); } void display() { // clear the buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // initialize modelview matrix glLoadIdentity(); //move teapot into scene glTranslatef(0.0f, 0.0f, -50.0f); // set material proprties // we can set different properties for front and back faces // but we are only going to see front faces anyway glMaterialfv(GL_FRONT, GL_DIFFUSE, mat); glMaterialfv(GL_FRONT, GL_SPECULAR, &mat[4]); glMaterialf(GL_FRONT, GL_SHININESS, matHighlights); // choose lighting model glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, local); // local viewer used for specular lighting //draw teapot glPushMatrix(); glRotatef(180,0,0,1); // fix glut winding problems glScalef(-1, -1, -1); // fix glut winding problems glutSolidTeapot(10.0); glPopMatrix(); // draw to screen glutSwapBuffers(); } void keyboard(unsigned char key, int x, int y) { int sign=1; switch (key) { case 'd': case 'D': cout << "Setting diffuse properties." << endl; matType = DIFFUSE; break; case 's': case 'S': cout << "Setting specular properties." << endl; matType = SPECULAR; break; case 'h': case 'H': cout << "Setting highlight properties." << endl; matType = HIGHLIGHTS; break; case 'r': case 'R': cout << "Setting red." << endl; color = RED; break; case 'g': case 'G': cout << "Setting green." << endl; color = GREEN; break; case 'b': case 'B': cout << "Setting blue." << endl; color = BLUE; break; case 'a': case 'A': cout << "Setting all colors." << endl; color = ALL; break; case '-': sign = -1; case '+': if (matType == HIGHLIGHTS) { matHighlights += sign * 2.0f; if (matHighlights < 1) matHighlights = 1; } else { for (int i=0; i<3; i++) if (color == i || color == ALL) mat[matType*4+i] = clamp(mat[matType*4+i]+sign*.02); } break; case 'l': case 'L': local = 1 - local; break; case '2': twoSided= 1 - twoSided; break; case '?': printStatus(); default: break; } glutPostRedisplay(); } void printHelp() { cout << "Type + (increase) or - (decrease) to change the current property/color value." << endl; cout << "Type ? for current property/color values." << endl; cout << "Type r (red), g (green), b (blue), or a (alla) to reset color(s) to change." << endl; cout << "Type d (diffuse), s (specular), h (shininess) to reset property to change." << endl; } void printStatus() { cout << "Diffuse: " << mat[0] << " " << mat[1] << " " << mat[2] << endl; cout << "Specular: " << mat[4] << " " << mat[5] << " " << mat[6] << endl; cout << "Shininess: " << matHighlights << endl; } float clamp(float f) { if (f<0) f=0; if (f>1) f=1; return f; }