/* Chloe Fan Creative Scene Piano and Bench in room Final: Moved piano Added other furniture Added plants Added extras (vase, artwork) Created left wall Animations 11.30: Extended room Added door Removed right wall for easy viewing */ #include #include #include "cfan2.cpp" #include #include #include GLuint textureIDs[7]; GLfloat doorRotationLeft = 0; GLfloat doorRotationRight = 0; GLfloat benchX = 0; GLfloat spiralRotation = 0; twTriple wallColor = {0.85,0.97,0.72}; void init() { glGenTextures(7,textureIDs); twLoadTexture(textureIDs[0],"wood.ppm"); twLoadTexture(textureIDs[1],"dawnsmcr.ppm"); twLoadTexture(textureIDs[2],"sand.ppm"); twLoadTexture(textureIDs[3],"sheetmusic.ppm"); twLoadTexture(textureIDs[4],"dpch.ppm"); twLoadTexture(textureIDs[5],"pianorose.ppm"); twLoadTexture(textureIDs[6],"bwrose.ppm"); } void texinit() { glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // light would shine on floor glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } void drawPalm(bool printBB) { static GLMmodel* Palm = NULL; const char* obj_filename = "palm.obj"; if(NULL==Palm) { Palm = glmReadOBJ(twPathname(obj_filename,true)); if (!Palm) { fprintf(stderr,"error reading OBJ file %s\n",obj_filename); return; } glmUnitize(Palm); if(printBB) { GLfloat BoundingBox[6]; glmBoundingBox(Palm,BoundingBox); printf("Bounding Box is (%f,%f,%f,%f,%f,%f)\n", BoundingBox[0], BoundingBox[1], BoundingBox[2], BoundingBox[3], BoundingBox[4], BoundingBox[5]); } glmFacetNormals(Palm); glmVertexNormals(Palm, 90.0); } glPushMatrix(); glmDraw(Palm, GLM_SMOOTH | GLM_MATERIAL); glPopMatrix(); } void drawPlant(bool printBB) { static GLMmodel* Plant = NULL; const char* obj_filename = "palmPotted.obj"; if(NULL==Plant) { Plant = glmReadOBJ(twPathname(obj_filename,true)); if (!Plant) { fprintf(stderr,"error reading OBJ file %s\n",obj_filename); return; } glmUnitize(Plant); if(printBB) { GLfloat BoundingBox[6]; glmBoundingBox(Plant,BoundingBox); printf("Bounding Box is (%f,%f,%f,%f,%f,%f)\n", BoundingBox[0], BoundingBox[1], BoundingBox[2], BoundingBox[3], BoundingBox[4], BoundingBox[5]); } glmFacetNormals(Plant); glmVertexNormals(Plant, 90.0); } glPushMatrix(); glmDraw(Plant, GLM_SMOOTH | GLM_MATERIAL); glPopMatrix(); } void display(void) { twDisplayInit(); twCamera(); glPushAttrib(GL_ALL_ATTRIB_BITS); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glEnable(GL_NORMALIZE); glEnable(GL_LIGHTING); twAmbient(0); // turn down ambient to make lights more obvious GLfloat light0pos[] = {0,10,0,0}; // directional light twGrayLight(GL_LIGHT0, light0pos, 0.1,0.8,1); glEnable(GL_LIGHT0); GLfloat light1pos[] = {-16,12,-20,1}; // point light twGrayLight(GL_LIGHT1, light1pos, 0,0.5,1); glEnable(GL_LIGHT1); // 2nd light too bright for dawn /* GLfloat light2pos[] = {15,5,20,1}; twGrayLight(GL_LIGHT2, light2pos, 0,0.5,1); glEnable(GL_LIGHT2);*/ // floor glPushMatrix(); glBindTexture(GL_TEXTURE_2D, textureIDs[0]); glTranslatef(0,-5.5,0); glBegin(GL_POLYGON); { /*twTriple floorColor = {0.85,0.6,0.4}; twColor(floorColor,0,0);*/ twTriple u = {0,1,0}; glNormal3fv(u); glTexCoord2f(0,1); glVertex3f(-30,0,30); // front left glTexCoord2f(1,1); glVertex3f(40,0,30); // front right glTexCoord2f(1,0); glVertex3f(40,0,-30); // back right glTexCoord2f(0,0); glVertex3f(-30,0,-30); // back left } glEnd(); glPopMatrix(); // left wall w/sunset glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);//unaffected by light glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glBindTexture(GL_TEXTURE_2D, textureIDs[1]); glPushMatrix(); glEnable(GL_CULL_FACE); glBegin(GL_POLYGON); { glTexCoord2f(0,1); glVertex3f(-40,-5.5,30); // bottom front glTexCoord2f(1,1); glVertex3f(-40,-5.5,-30); // bottom back glTexCoord2f(1,0); glVertex3f(-40,20,-30); // top back glTexCoord2f(0,0); glVertex3f(-40,20,30); // top front } glEnd(); glDisable(GL_CULL_FACE); glPopMatrix(); // sand outside glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);//unaffected by light glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glBindTexture(GL_TEXTURE_2D, textureIDs[2]); glPushMatrix(); glBegin(GL_POLYGON); { glTexCoord2f(0,1); glVertex3f(-40,-5.5,30); glTexCoord2f(1,1); glVertex3f(-30,-5.5,30); glTexCoord2f(1,0); glVertex3f(-30,-5.5,-30); glTexCoord2f(0,0); glVertex3f(-40,-5.5,-30); } glEnd(); glPopMatrix(); // sheet music glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);//affected by light glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glBindTexture(GL_TEXTURE_2D, textureIDs[3]); glPushMatrix(); glTranslatef(-20,0,-20); glRotatef(30,0,1,0); glBegin(GL_POLYGON); { glTexCoord2f(0,1); glVertex3f(-2,3,2); glTexCoord2f(1,1); glVertex3f(2,3,2); glTexCoord2f(1,0); glVertex3f(2,6,1.5); glTexCoord2f(0,0); glVertex3f(-2,6,1.5); } glEnd(); glPopMatrix(); // art 1 coastal harmony glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);//unaffected by light glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glBindTexture(GL_TEXTURE_2D, textureIDs[4]); glPushMatrix(); glBegin(GL_POLYGON); { glTexCoord2f(0,1); glVertex3f(-5,5,-29.9); glTexCoord2f(1,1); glVertex3f(10,5,-29.9); glTexCoord2f(1,0); glVertex3f(10,13,-29.9); glTexCoord2f(0,0); glVertex3f(-5,13,-29.9); } glEnd(); glPopMatrix(); // art 2 piano rose glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);//unaffected by light glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glBindTexture(GL_TEXTURE_2D, textureIDs[5]); glPushMatrix(); glBegin(GL_POLYGON); { glTexCoord2f(0,1); glVertex3f(39.9,5,-5); glTexCoord2f(1,1); glVertex3f(39.9,5,5); glTexCoord2f(1,0); glVertex3f(39.9,12,5); glTexCoord2f(0,0); glVertex3f(39.9,12,-5); } glEnd(); glPopMatrix(); // art 3 bw rose glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);//unaffected by light glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glBindTexture(GL_TEXTURE_2D, textureIDs[6]); glPushMatrix(); glEnable(GL_CULL_FACE); // so that it won't block initial scene glBegin(GL_POLYGON); { glTexCoord2f(0,1); glVertex3f(5,5,29.9); glTexCoord2f(1,1); glVertex3f(-5,5,29.9); glTexCoord2f(1,0); glVertex3f(-5,12,29.9); glTexCoord2f(0,0); glVertex3f(5,12,29.9); } glEnd(); glDisable(GL_CULL_FACE); glPopMatrix(); glDisable(GL_TEXTURE_2D); // so that the rest of scene shows up // left inside wall, will look like window wall // horizontal stripes glPushMatrix(); glBegin(GL_POLYGON); { twColor(wallColor,0,0); twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,19.5,30); glVertex3f(-30,19.5,-30); glVertex3f(-30,20,-30); glVertex3f(-30,20,30); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,14.5,30); glVertex3f(-30,14.5,20); glVertex3f(-30,15,20); glVertex3f(-30,15,30); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,14.5,0); glVertex3f(-30,14.5,-30); glVertex3f(-30,15,-30); glVertex3f(-30,15,0); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,9.5,30); glVertex3f(-30,9.5,20); glVertex3f(-30,10,20); glVertex3f(-30,10,30); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,9.5,0); glVertex3f(-30,9.5,-30); glVertex3f(-30,10,-30); glVertex3f(-30,10,-0); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,4.5,30); glVertex3f(-30,4.5,20); glVertex3f(-30,5,20); glVertex3f(-30,5,30); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,4.5,0); glVertex3f(-30,4.5,-30); glVertex3f(-30,5,-30); glVertex3f(-30,5,0); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,-0.5,30); glVertex3f(-30,-0.5,20); glVertex3f(-30,0,20); glVertex3f(-30,0,30); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,-0.5,0); glVertex3f(-30,-0.5,-30); glVertex3f(-30,0,-30); glVertex3f(-30,0,0); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,-5.5,30); glVertex3f(-30,-5.5,20); glVertex3f(-30,-5,20); glVertex3f(-30,-5,30); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,-5.5,0); glVertex3f(-30,-5.5,-30); glVertex3f(-30,-5,-30); glVertex3f(-30,-5,0); } glEnd(); // vertical stripes glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,-5.5,30); glVertex3f(-30,-5.5,29.5); glVertex3f(-30,20,29.5); glVertex3f(-30,20,30); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,-5.5,20.5); glVertex3f(-30,-5.5,20); glVertex3f(-30,20,20); glVertex3f(-30,20,20.5); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,15,10.25); glVertex3f(-30,15,9.75); glVertex3f(-30,20,9.75); glVertex3f(-30,20,10.25); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,-5.5,0); glVertex3f(-30,-5.5,-0.5); glVertex3f(-30,20,-0.5); glVertex3f(-30,20,0); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,-5.5,-9.75); glVertex3f(-30,-5.5,-10.25); glVertex3f(-30,20,-10.25); glVertex3f(-30,20,-9.75); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,-5.5,-19.75); glVertex3f(-30,-5.5,-20.25); glVertex3f(-30,20,-20.25); glVertex3f(-30,20,-19.75); } glEnd(); glBegin(GL_POLYGON); { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(-30,-5.5,-29.5); glVertex3f(-30,-5.5,-30); glVertex3f(-30,20,-30); glVertex3f(-30,20,-29.5); } glEnd(); glPopMatrix(); // left door glPushMatrix(); glTranslatef(-30,-5.5,20); glRotatef(doorRotationLeft,0,1,0); glBegin(GL_POLYGON); // left panel { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(0,0,0); glVertex3f(0,0,-0.5); glVertex3f(0,20.5,-0.5); glVertex3f(0,20.5,0); } glEnd(); glBegin(GL_POLYGON); // right panel { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(0,0,-9.5); glVertex3f(0,0,-10); glVertex3f(0,20.5,-10); glVertex3f(0,20.5,-9.5); } glEnd(); glBegin(GL_POLYGON); // bottom panel { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(0,0,0); glVertex3f(0,0,-10); glVertex3f(0,0.5,-10); glVertex3f(0,0.5,0); } glEnd(); glBegin(GL_POLYGON); // top panel { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(0,20,0); glVertex3f(0,20,-10); glVertex3f(0,20.5,-10); glVertex3f(0,20.5,0); } glEnd(); glPopMatrix(); // right door glPushMatrix(); glTranslatef(-30,-5.5,0); glRotatef(doorRotationRight,0,1,0); glBegin(GL_POLYGON); // left panel { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(0,0,10); glVertex3f(0,0,9.5); glVertex3f(0,20.5,9.5); glVertex3f(0,20.5,10); } glEnd(); glBegin(GL_POLYGON); // right panel { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(0,0,0.5); glVertex3f(0,0,0); glVertex3f(0,20.5,0); glVertex3f(0,20.5,0.5); } glEnd(); glBegin(GL_POLYGON); // bottom panel { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(0,0,10); glVertex3f(0,0,0); glVertex3f(0,0.5,0); glVertex3f(0,0.5,10); } glEnd(); glBegin(GL_POLYGON); // top panel { twTriple u = {1,0,0}; glNormal3fv(u); glVertex3f(0,20,10); glVertex3f(0,20,0); glVertex3f(0,20.5,0); glVertex3f(0,20.5,10); } glEnd(); glPopMatrix(); // back wall glPushMatrix(); glEnable(GL_CULL_FACE); glBegin(GL_POLYGON); { twColor(wallColor,0,0); twTriple u = {0,0,1}; glNormal3fv(u); glVertex3f(-30,-5.5,-30); // LL glVertex3f(40,-5.5,-30); // LR glVertex3f(40,20,-30); // UR glVertex3f(-30,20,-30); // UL } glEnd(); glPopMatrix(); // right wall glPushMatrix(); glBegin(GL_POLYGON); { twTriple u = {-1,0,0}; glNormal3fv(u); glVertex3f(40,-5.5,-30); // LL glVertex3f(40,-5.5,30); // LR glVertex3f(40,20,30); // UR glVertex3f(40,20,-30); // UL } glEnd(); glPopMatrix(); // front wall glPushMatrix(); glBegin(GL_POLYGON); { twTriple u = {0,0,-1}; glNormal3fv(u); glVertex3f(40,-5.5,30); // LR glVertex3f(-30,-5.5,30); // LL glVertex3f(-30,20,30); // UL glVertex3f(40,20,30); // UR } glEnd(); glPopMatrix(); glDisable(GL_CULL_FACE); glPushMatrix(); GLfloat matAmb[] = {0, 0, 0, 1}; GLfloat matDiff[] = {0.1, 0.1, 0.1, 0.1}; GLfloat matSpec[] = {1, 1, 1, 1}; GLfloat matEmis[] = {0, 0, 0, 0}; GLfloat matShi = 20; glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb); glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff); glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec); glMaterialfv(GL_FRONT, GL_EMISSION, matEmis); glMaterialf(GL_FRONT, GL_SHININESS, matShi); // move to corner glTranslatef(-20,0,-20); glRotatef(30,0,1,0); // draw piano cfan2Piano(); // move to bench location glTranslatef(0,-2.5,8.5); glTranslatef(benchX,0,benchX); // to move bench glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb); glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff); glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec); glMaterialfv(GL_FRONT, GL_EMISSION, matEmis); glMaterialf(GL_FRONT, GL_SHININESS, matShi); // draw bench in color of piano cfan2Bench(); glPopMatrix(); // ===STUDENT CONTRIBUTIONS=== // palm glPushMatrix(); glTranslatef(-35,5,25); glScalef(10,10,10); drawPalm(false); glTranslatef(0,0,-4.5); drawPalm(false); glPopMatrix(); //plant glPushMatrix(); glTranslatef(36,-1.5,20); glScalef(5,5,5); drawPlant(false); glPopMatrix(); // ceiling lamp glPushMatrix(); glTranslatef(0,15,0); glScalef(0.3,0.5,0.3); twTriple lightColor = {1,0.71,0}; // gold color twTriple bulbColor = {1,1,1}; msarkarCeilingLight(5,lightColor,bulbColor ); glPopMatrix(); // couch glPushMatrix(); glTranslatef(39,-2,0); glRotatef(-90,0,1,0); twTriple colorA = {1,0.97,0.9}; twTriple colorB = {1,0.93,0.76}; msarkarCouch(2,colorA,colorB); glPopMatrix(); // end tables glPushMatrix(); glTranslatef(36,-6,10); glScalef(0.75,0.5,0.75); zkabayadTable(false); glTranslatef(0,0,-26); zkabayadTable(false); glPopMatrix(); // vase glPushMatrix(); twTriple vaseColor = {0.31,0.64,0.79}; twTriple bottomColor = {0.19,0.42,0.52}; twTriple rimColor = {0.67,0.78,1}; twTriple flowerColor1 = {1,0.95,0.67}; twTriple flowerColor2 = {1,0.83,0}; glTranslatef(36,0.25,-7.5); msarkarVase(2,vaseColor,bottomColor,rimColor,flowerColor1,flowerColor2); glPopMatrix(); // spiral glPushMatrix(); twTriple color = {0.83,0.83,0.83}; glTranslatef(-35,5,10); glRotatef(spiralRotation,0,1,0); zmoriczSpiral(color,3,10); glPopMatrix(); glPopAttrib(); glFlush(); glutSwapBuffers(); } bool OpeningLeft = false; // if left door is active bool LeftOpen = false; // if left door is opening bool OpeningRight = false; // if right door is active bool RightOpen = false; // if right door is opening bool IsSliding = false; // if bench is in action bool Sliding = false; // if bench is sliding out bool Rotating = false; // if spiral is rotating // idle callback for door void openLeft() { if(doorRotationLeft == 0 || doorRotationLeft == -90) { LeftOpen = !LeftOpen; // switch rotation direction if(doorRotationLeft == 0) doorRotationLeft--; // then inc/dec as needed if(doorRotationLeft == -90) doorRotationLeft++; } if(LeftOpen) doorRotationLeft--; else doorRotationLeft++; glutPostRedisplay(); } void openRight() { if(doorRotationRight == 0 || doorRotationRight == 90) { RightOpen = !RightOpen; // switch rotation direction if(doorRotationRight == 0) doorRotationRight++; // then inc/dec as needed if(doorRotationRight == 90) doorRotationRight--; } if(RightOpen) doorRotationRight++; else doorRotationRight--; glutPostRedisplay(); } void slideBench() { // if in home position or full slide position if (benchX == 0 || benchX == 3) { Sliding = !Sliding; // switch sliding direction if(benchX == 0) // if in home position benchX+=0.5;// move out; x value increases, z value increases if(benchX == 3) benchX-=0.5; } if(Sliding) benchX++; //increase if in action of sliding out else benchX--; glutPostRedisplay(); } void rotateSpiral() { spiralRotation+=10; // it's already rotating, so keep on rotating glutPostRedisplay(); } void keys(unsigned char k, int, int) { switch (k) { case '0': // reset animations doorRotationLeft = 0; OpeningLeft = false; LeftOpen = false; doorRotationRight = 0; OpeningRight = false; RightOpen = false; Sliding = false; Rotating = false; spiralRotation = 0; break; case '1': // open/stop left door OpeningLeft = !OpeningLeft; if(OpeningLeft) glutIdleFunc(openLeft); else glutIdleFunc(NULL); break; case '2': //open/stop right door OpeningRight = !OpeningRight; if(OpeningRight) glutIdleFunc(openRight); else glutIdleFunc(NULL); break; case '3': // slide in/out piano chair IsSliding = !IsSliding; if(IsSliding) glutIdleFunc(slideBench); else glutIdleFunc(NULL); break; case '4': // rotate spiral outside Rotating = !Rotating; // turn rotating on or off if(Rotating) glutIdleFunc(rotateSpiral); else glutIdleFunc(NULL); break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); twInitWindowSize(500,500); glutCreateWindow(argv[0]); init(); texinit(); glutDisplayFunc(display); // twBoundingBox(-12,12,-5.5,9,-9,10); // wrapped twBoundingBox(-40, 40, -5.5, 20, -30, 30); // room size twMainInit(); twKeyCallback('0',keys,"Reset animations"); twKeyCallback('1',keys,"Open left door"); twKeyCallback('2',keys,"Open right door"); twKeyCallback('3',keys,"Slide piano chair"); twKeyCallback('4',keys,"Rotate outside spiral"); glutMainLoop(); return 0; }