/* Displays an OBJ using the glm library call from Nate Robbins's library. The object's bounding box is computed and used to set up the camera. Scott D. Anderson Fall 2006 */ #include #include #include #include #include char* filename; // the filename for the OBJ file GLMmodel* pmodel = NULL; // the model object GLfloat BoundingBox[6]; // [minx,maxx,miny,maxy,minz,maxz] void initmodel(void) { pmodel = glmReadOBJ(filename); if (!pmodel) exit(0); glmBoundingBox(pmodel,BoundingBox); printf("Bounding Box is (%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f)\n", BoundingBox[0], BoundingBox[1], BoundingBox[2], BoundingBox[3], BoundingBox[4], BoundingBox[5]); glmFacetNormals(pmodel); glmVertexNormals(pmodel, 90.0); } GLfloat Light0Ambient = 0.5; GLfloat Light0Diffuse = 0.5; GLfloat Light0Specular = 0.5; // These are the default drawing options. You can toggle these bits with // various keyboard callbacks. GLuint DrawOptions = GLM_SMOOTH | GLM_TEXTURE | GLM_MATERIAL | GLM_MATERIAL_EXTERNAL ; void display(void) { twDisplayInit(); twCamera(); glPushAttrib(GL_ALL_ATTRIB_BITS); GLfloat pos[] = { 0.0, 0.0, 1.0, 0.0 }; twGrayLight(GL_LIGHT0,pos, Light0Ambient, Light0Diffuse, Light0Specular); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); twError(); // define a default material, in case the object doesn't twTriple darkGray = {0.5, 0.5, 0.5}; twColor(darkGray,0.9,20); // draw the object glmDraw(pmodel, DrawOptions ); twError(); /* glPushMatrix(); glTranslatef(1,0,0); glmDraw(pmodel, GLM_SMOOTH | GLM_MATERIAL ); glPushMatrix(); */ glPopAttrib(); glFlush(); glutSwapBuffers(); } #define min(x,y) (x)>(y)?(y):(x) #define max(x,y) (x)>(y)?(x):(y) void adjust(unsigned char key, int x, int y) { switch (key) { case 'A': Light0Ambient = min(1,Light0Ambient+0.1); break; case 'a': Light0Ambient = max(0,Light0Ambient-0.1); break; case 'D': Light0Diffuse = min(1,Light0Diffuse+0.1); break; case 'd': Light0Diffuse = max(0,Light0Diffuse-0.1); break; case 'S': Light0Specular = min(1,Light0Specular+0.1); break; case 's': Light0Specular = max(0,Light0Specular-0.1); break; } glutPostRedisplay(); } void printlight(unsigned char key, int x, int y) { printf("light is (A,D,S)=(%3.1f,%3.1f,%3.1f)\n",Light0Ambient,Light0Diffuse,Light0Specular); } void printmodel(unsigned char key, int x, int y) { glmPrintModel(pmodel); // more than you'll ever want to know } // Toggles the various constants that determine the drawing options. We // don't check for incompatible options, because the glmDraw function does // that. void toggleOption(GLuint option, char* desc) { DrawOptions ^= option; printf("%s is now %s\n",desc, DrawOptions&option ? "on" : "off"); } void drawOption(unsigned char key, int x, int y) { if( key == '/' ) { printf("DrawOptions is 0x%x\n",DrawOptions); } else { switch(key) { case 'f': toggleOption(GLM_FLAT,"flat rendering"); break; case 'F': toggleOption(GLM_SMOOTH,"smooth rendering"); break; case 't': toggleOption(GLM_TEXTURE,"textured rendering"); break; case 'c': toggleOption(GLM_COLOR,"rendering with color"); break; case 'm': toggleOption(GLM_MATERIAL,"rendering with material"); break; case 'e': toggleOption(GLM_MATERIAL_EXTERNAL,"rendering with external material"); break; } glutPostRedisplay(); } } int main(int argc, char* argv[]) { char buf[256]; if( argc <= 1 ) { printf("What OBJ file to load? "); scanf(buf,sizeof(buf),stdin); filename = buf; } else { filename = argv[1]; } /* Ready to start doing OpenGL */ glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(500,500); glutCreateWindow(argv[0]); glutDisplayFunc(display); // It's very important that the model be initialized after OpenGL is // initialized, because if we load a texture, we need to be able to // download a texture to the graphics card and generate a texture ID, // and those requires that OpenGL be initialized. The error message // for this is pretty much absent, so you are warned! initmodel(); twBoundingBox(BoundingBox[0],BoundingBox[1], BoundingBox[2],BoundingBox[3], BoundingBox[4],BoundingBox[5]); twMainInit(); twKeyCallback('A',adjust,"Increase Ambient by 0.1"); twKeyCallback('a',adjust,"Decrease Ambient by 0.1"); twKeyCallback('D',adjust,"Increase Diffuse by 0.1"); twKeyCallback('d',adjust,"Increase Diffuse by 0.1"); twKeyCallback('S',adjust,"Increase Specular by 0.1"); twKeyCallback('s',adjust,"Increase Specular by 0.1"); twKeyCallback('p',printlight,"Print Light Settings"); twKeyCallback('P',printmodel,"Print GML OBJ model"); twKeyCallback('f',drawOption,"render with facet normals (flat)"); twKeyCallback('F',drawOption,"render with vertex normals (smooth)"); twKeyCallback('t',drawOption,"render with texture coords (toggle yes/no)"); twKeyCallback('c',drawOption,"render with colors (color material) (toggle yes/no)"); twKeyCallback('m',drawOption,"render with materials (toggle yes/no)"); twKeyCallback('e',drawOption,"use external material specs (toggle yes/no)"); twKeyCallback('/',drawOption,"show glm draw options"); glutMainLoop(); return (0); }