#include #include "debug.h" #include "algebra3.h" #include "image.h" #include "mesh.h" struct Viewport { int w, h; mat4 orientation; vec3 translate; Viewport() : w(640), h(480), orientation(identity3D()), translate(0,0,-5) {} }; Viewport view; TriangleMesh mesh; GLuint texture; void display() { // setup gl for rendering setProjection3D(view.w, view.h, 45); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // draw mesh applyMat4(translation3D(view.translate)*view.orientation); mesh.drawFlat(); // swap buffers to put what we just drew on to the screen glutSwapBuffers(); } // escape key quits, 's' takes a screenshot void keypresses(unsigned char key, int x, int y) { static int screenshots = 0; switch (key) { case 's': // saves a picture of the current screen Image::saveScreen("screenshot", screenshots++); break; case 27: // Escape key exit(0); break; } } // mouse handling functions -- lets you rotate the model around int buttonDown = -1; vec2 mousePos; void mouseclicks(int button, int state, int x, int y) { if (state==GLUT_DOWN) { buttonDown = button; } else { buttonDown = -1; } } void mousemove_passive(int x, int y) { mousePos = vec2((double)x / glutGet(GLUT_WINDOW_WIDTH),(double)y / glutGet(GLUT_WINDOW_HEIGHT)); } void mousemove(int x, int y) { vec2 newMouse = vec2((double)x / glutGet(GLUT_WINDOW_WIDTH),(double)y / glutGet(GLUT_WINDOW_HEIGHT)); vec2 diff = (newMouse - mousePos); double len = diff.length(); if (len > .001) { if (buttonDown == GLUT_LEFT_BUTTON) { vec3 axis = vec3(-diff[1]/len, -diff[0]/len, 0); view.orientation = rotation3D(axis, -180 * len)*view.orientation; } else if (buttonDown == GLUT_RIGHT_BUTTON) { view.translate += vec3(diff[0],-diff[1],0)*50; } else if (buttonDown == GLUT_MIDDLE_BUTTON) { view.translate[2] += diff[1]*50; } } mousePos = newMouse; glutPostRedisplay(); } void idle() { glutPostRedisplay(); } int main( int argc, char **argv ) { DEBUGOUT("starting with debug prints on ..."); //Initialize OpenGL glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH); //Create OpenGL Window glutInitWindowSize(view.w,view.h); // view.w and view.h currently set in default constructor of Viewport glutInitWindowPosition(0,0); glutCreateWindow("window title goes here"); //Register event handlers with OpenGL. glutDisplayFunc(display); glutKeyboardFunc(keypresses); glutPassiveMotionFunc(mousemove_passive); glutMotionFunc(mousemove); glutMouseFunc(mouseclicks); glutIdleFunc(idle); // turn on LIGHT0 (one of the 8 hardware lights provided by gl) so we get some shading { float ambient[3] = { .1f, .1f, .1f }; float diffuse[3] = { .6f, .5f, .5f }; float pos[4] = { 2, 3, -10, 0 }; glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, pos); glEnable(GL_LIGHT0); } glEnable(GL_LIGHTING); // sets what glColor calls will affect glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); // enables depth testing -- so the z buffer works glEnable(GL_DEPTH_TEST); // draw nicer lines glEnable(GL_LINE_SMOOTH); // draw both sides of our polygons glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // set the 'default' color that shows when we clear the screen glClearColor(0.0f, 0.0f, .5f, 0.0f); // it's blue string file = "cyl_textured.obj"; if (argc >= 2) file = argv[1]; DEBUGOUT("Loading mesh: " << file); if (!mesh.loadFile(file)) { cerr << "Failed to load mesh: " << file << endl; return 1; } mesh.computeVertexNormals(); mesh.centerAndScaleToOne(); string texturefile = "cylinder_tex.bmp"; if (argc >= 3) texturefile = argv[2]; DEBUGOUT("Loading texture: " << texturefile); if (!Image::loadTexture(texturefile, texture)) { cerr << "Failed to load texture: " << texturefile << endl; return 1; } //And Go! glutMainLoop(); }