/* An open box, using material and lighting. This is interesting because, depending on the angle of view, we will see either the "front" or "back" of different polygons, defining front as the counter-clockwise winding rule. We'd like the lighting to look "right," so we'll use two-sided lighting and two-sided material. With two lights, that can be turned on/off independently. This demo thanks to Zsuzsa Moricz, class of 2006 Written by Scott D. Anderson scott.anderson@acm.org Fall 2005 */ #include #include void DrawQuadBothSides( twTriple vertexArray[], twTriple frontNormal, int a, int b, int c, int d) { glBegin(GL_QUADS); // frontwards glNormal3fv(frontNormal); glVertex3fv(vertexArray[a]); glVertex3fv(vertexArray[b]); glVertex3fv(vertexArray[c]); glVertex3fv(vertexArray[d]); // backwards glNormal3f(-frontNormal[0], -frontNormal[1], -frontNormal[2]); glVertex3fv(vertexArray[d]); glVertex3fv(vertexArray[c]); glVertex3fv(vertexArray[b]); glVertex3fv(vertexArray[a]); glEnd(); } /* This box is a unit box, much like glutSolidCube, except that the vertices are 0/1, not -1/+1. It uses whatever material you have specified, like glutSolidCube(). If you want something different, you'll have to scale it. */ void OpenBox() { GLfloat corners[][3] = {{ 0, 0, 0 }, // 0 lower left back { 1, 0, 0 }, // 1 lower right back { 1, 1, 0 }, // 2 upper right back { 0, 1, 0 }, // 3 upper left back { 0, 0, 1 }, // 4 lower left front { 1, 0, 1 }, // 5 lower right front { 1, 1, 1 }, // 6 upper right front { 0, 1, 1 }}; // 7 upper left front GLfloat normals[][3] = {{ +1, 0, 0 }, // 0 right { -1, 0, 0 }, // 1 left { 0, +1, 0 }, // 2 up { 0, -1, 0 }, // 3 down { 0, 0, +1 }, // 4 towards { 0, 0, -1 }}; // 5 away DrawQuadBothSides( corners, normals[0], 1, 2, 6, 5); // right DrawQuadBothSides( corners, normals[1], 0, 4, 7, 3); // left DrawQuadBothSides( corners, normals[2], 0, 4, 5, 1); // bottom DrawQuadBothSides( corners, normals[3], 4, 5, 6, 7); // front DrawQuadBothSides( corners, normals[4], 3, 2, 1, 0); // back } bool Light0 = true; bool Light1 = true; void display(void) { twDisplayInit(); twCamera(); glEnable(GL_LIGHTING); glEnable(GL_CULL_FACE); // only draw front faces twAmbient(0.1); // turn down ambient to make the // lighting effects more obvious GLfloat light0[] = { 0, 2, 0, 1 }; twGrayLight(GL_LIGHT0, light0, 0.1, 0.6, 0.7); if(Light0) glEnable(GL_LIGHT0); else glDisable(GL_LIGHT0); GLfloat light1[] = { 0, 2, 1, 0 }; twGrayLight(GL_LIGHT1, light1, 0.1, 0.6, 0.8); if(Light1) glEnable(GL_LIGHT1); else glDisable(GL_LIGHT1); twTriple boxColor = {238/255.0, 197/255.0, 145/255.0}; twColor(boxColor,0.4,10); OpenBox(); glFlush(); glutSwapBuffers(); // necessary for animation } void lightToggle(unsigned char k, int x, int y) { switch(k) { case '1': Light0 = !Light0; break; case '2': Light1 = !Light1; break; } glutPostRedisplay(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); twInitWindowSize(650,650); glutCreateWindow(argv[0]); twBoundingBox(-1,2,-1,2,-1,2); twMainInit(); twKeyCallback('1', lightToggle, "Toggle first light"); twKeyCallback('2', lightToggle, "Toggle second light"); glutDisplayFunc(display); glutMainLoop(); return 0; }