/* Demonstrates constructing a scene using library objects. The scene is not intended to be beautiful, just functional. Written by Scott D. Anderson scott.anderson@acm.org Fall 2006 */ #include #include // for exit() #include #include #include #include const float maxbyte = 255.0; // maximum value of an unsigned byte void endTable() { // Gowun's table on either side. The top is six units in radius, so we // shrink by a factor of 6. twTriple surfaceColor = { 188/maxbyte, 143/maxbyte, 143/maxbyte }; // RosyBrown twTriple barColor = { 0.8, 0.8, 0.8 }; // 80% gray glPushMatrix(); glScalef(0.16,0.08,0.16); // 1/6th scale, but shorter gkim1DrawTable(surfaceColor, barColor, barColor, surfaceColor); glPopMatrix(); } /* This function draws Al Capone. The object is rescaled so that it is 2 units high (and proportional in depth and width). The function arranges for the origin to be at the middle of the bottom of the bounding box, so that Al goes from 0-2 on the Y axis, and +/- 0.92 on the x (so almost 2 units wide) and +/- 0.38 on the Z (so about 3/4th of a unit deep). The function reads the file and draws the object the first time it is called; later calls skip reading the file and just draw. This allows us to package everything up into just one function, which is convenient. It means that the first time the function is called it will be quite long, but we'd have to pay that price sometime anyhow. */ void drawAlCapone(bool printBB) { // The following variable must be declared static, so that it doesn't // get reset to NULL every time the function is called, since this is // how we avoid reloading the OBJ file every single time. static GLMmodel* AlCapone = NULL; // the model object const char* obj_filename = "al.obj"; // lives in $TWHOMEDIR/objects if(NULL==AlCapone) { AlCapone = glmReadOBJ(twPathname(obj_filename,true)); if (!AlCapone) { fprintf(stderr,"error reading OBJ file %s\n",obj_filename); return; } // Since Al is taller than he is wide or deep, we know that he'll be 2 // unit high after unitizing, with origin at the center. glmUnitize(AlCapone); // It makes sense to delay printing the BB until after we've // rescaled the object. if(printBB) { GLfloat BoundingBox[6]; // [minx,maxx,miny,maxy,minz,maxz] glmBoundingBox(AlCapone,BoundingBox); printf("Bounding Box is (%f,%f,%f,%f,%f,%f)\n", BoundingBox[0], BoundingBox[1], BoundingBox[2], BoundingBox[3], BoundingBox[4], BoundingBox[5]); } // Finish initialization glmFacetNormals(AlCapone); glmVertexNormals(AlCapone, 90.0); } // Now the actual drawing code, which is always executed glPushMatrix(); glTranslatef(0,1,0); // up to the middle of Al glmDraw(AlCapone, GLM_SMOOTH | GLM_MATERIAL); glPopMatrix(); } void display(void) { twDisplayInit(); twCamera(); // Remember that the origin is in the left lower back corner of the "room" twTriple floorColor = { 112/maxbyte, 128/maxbyte, 144/maxbyte }; // slate gray twColor(floorColor,0,0); twGround(); // draw walls in Antique White twTriple wallColor = { 250/maxbyte, 235/maxbyte, 215/maxbyte }; twColor(wallColor,0,0); twSky(); // Mala's Couch centered in the back. We'll make it 6 feet wide. // Origin is undocumented; seems to be in the center of the main cube, // which is painful glPushMatrix(); glTranslatef(7.5,1.25,0.5); twTriple couchColor = {105/maxbyte, 139/maxbyte, 105/maxbyte}; // Dark Sea Green 4 twTriple pipingColor = {193/maxbyte, 255/maxbyte, 193/maxbyte}; // Dark Sea Green 1 msarkarCouch(1,couchColor,pipingColor); glPopMatrix(); glPushMatrix(); glTranslatef(1,0,1.5); // to the left of the couch (as we face it) endTable(); glPopMatrix(); glPushMatrix(); glTranslatef(12,0,1.5); // to the right of the couch (as we face it) endTable(); glPopMatrix(); // Al Capone. Because Al uses material and lighting, we have to // enable lighting for this part. We'll have directional light from // above GLfloat pos[] = { 0.0, 0.0, 1.0, 0.0 }; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); twGrayLight(GL_LIGHT0,pos,0.9,0.9,0.9); glPushMatrix(); glTranslatef(2,0,7); // on the left, in front glRotatef(45,0,1,0); // facing upstage left glScalef(3,3,3); // let's make him 6 feet tall. drawAlCapone(true); glPopMatrix(); glFlush(); glutSwapBuffers(); // necessary for animation } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); twInitWindowSize(500,500); glutCreateWindow(argv[0]); glutDisplayFunc(display); twBoundingBox(0,15,0,8,0,15); // 15x15 room. origin at left bottom front glLineWidth(2); twMainInit(); glutMainLoop(); return 0; }