#include #include #include #include #include #include struct Face { int vertex1; int vertex2; int vertex3; }; struct Vector { float x; float y; float z; Vector () {} Vector (float x_, float y_, float z_) { x = x_; y = y_; z = z_; } float norm () { return sqrt(x*x + y*y + z*z); } void normalize () { float f = norm (); x /= f; y /= f; z /= f; } }; Vector operator*(float f, const Vector& a) { return Vector (a.x * f, a.y * f, a.z * f); } Vector operator*(const Vector& a, float f) { return Vector (a.x * f, a.y * f, a.z * f); } Vector operator-(const Vector& a, const Vector& b) { return Vector (a.x - b.x, a.y - b.y, a.z - b.z); } Vector operator+(const Vector& a, const Vector& b) { return Vector (a.x + b.x, a.y + b.y, a.z + b.z); } typedef Vector Vertex; class Mesh { private: typedef std::vector VertexLst; typedef std::vector FaceLst; VertexLst vertices; FaceLst faces; public: Mesh (std::istream& in) { int number_of_vertixes; in >> number_of_vertixes; std::cout << "Number_Of_Vertixes: " << number_of_vertixes << std::endl; for (int i = 0; i < number_of_vertixes; ++i) { Vertex vertex; in >> vertex.x >> vertex.y >> vertex.z; vertices.push_back(vertex); } int number_of_faces; in >> number_of_faces; for (int i = 0; i < number_of_faces; ++i) { Face face; in >> face.vertex1 >> face.vertex2 >> face.vertex3; faces.push_back (face); } std::cout << "read " << number_of_faces << " faces, " << number_of_vertixes << " vertices" << std::endl; } void display () { for (FaceLst::iterator i = faces.begin (); i != faces.end (); ++i) { std::cout << "Face: " << std::endl; std::cout << vertices[i->vertex1].x << " " << vertices[i->vertex1].y << " " << vertices[i->vertex1].z << std::endl; std::cout << vertices[i->vertex2].x << " " << vertices[i->vertex2].y << " " << vertices[i->vertex2].z << std::endl; std::cout << vertices[i->vertex3].x << " " << vertices[i->vertex3].y << " " << vertices[i->vertex3].z << std::endl; } } void draw () { for (FaceLst::iterator i = faces.begin (); i != faces.end (); ++i) { float normal_x; float normal_y; float normal_z; glEnable (GL_COLOR_MATERIAL); glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT); glColor3f (0, 0, 0); glColorMaterial (GL_FRONT_AND_BACK, GL_DIFFUSE); glColor3f (0.4, .4, 0.4); glBegin (GL_TRIANGLES); set_face_normal (*i); glVertex3f (vertices[i->vertex1].x, vertices[i->vertex1].y, vertices[i->vertex1].z); set_face_normal (*i); glVertex3f (vertices[i->vertex2].x, vertices[i->vertex2].y, vertices[i->vertex2].z); set_face_normal (*i); glVertex3f (vertices[i->vertex3].x, vertices[i->vertex3].y, vertices[i->vertex3].z); glEnd (); //draw_face_normal (*i); glDisable (GL_COLOR_MATERIAL); } } void draw_face_normal (const Face& face) { Vector normal = calc_face_normal (face); Vector pos(vertices[face.vertex1] + vertices[face.vertex2] + vertices[face.vertex3]); pos = pos * (1.0f/3.0f); glDisable (GL_LIGHTING); glColor3f (0, 1.0f, 1.0f); glBegin (GL_LINES); glVertex3f (pos.x, pos.y, pos.z); pos = pos + (0.5* normal); glVertex3f (pos.x, pos.y, pos.z); glEnd (); glEnable (GL_LIGHTING); } Vector calc_face_normal (const Face& face) { Vector u (vertices[face.vertex2].x - vertices[face.vertex1].x, vertices[face.vertex2].y - vertices[face.vertex1].y, vertices[face.vertex2].z - vertices[face.vertex1].z); Vector v (vertices[face.vertex3].x - vertices[face.vertex2].x, vertices[face.vertex3].y - vertices[face.vertex2].y, vertices[face.vertex3].z - vertices[face.vertex2].z); Vector normal (u.y*v.z - u.z*v.y, u.z*v.x - u.x*v.z, u.x*v.y - u.y*v.x); normal.normalize (); return normal; } void set_face_normal (const Face& face) { const Vector& normal = calc_face_normal (face); glNormal3f (normal.x, normal.y, normal.y); } }; class Model { private: typedef std::vector MeshLst; MeshLst meshes; public: Model (const std::string& filename) { std::ifstream in(filename.c_str()); if (!in) { std::cout << filename << ": File not found" << std::endl; exit(EXIT_FAILURE); } int number_of_meshes; in >> number_of_meshes; std::cout << "number_of_meshes: " << number_of_meshes << std::endl; for (int i = 0; i < number_of_meshes; ++i) { Mesh mesh(in); //mesh.display (); meshes.push_back(mesh); } } void draw () { for (MeshLst::iterator i = meshes.begin (); i != meshes.end (); ++i) { i->draw (); } } }; Model* the_model; GLuint model_lst; void reshape(int w, int h) { glViewport (0,0, w, h); //gluOrtho2D (-5, 5, -5, 5); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -15.6); } float x_angle = -90.0f; float y_angle = 0.0f; float z_angle = 0.0f; void display() { glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glPushMatrix (); glScalef (2, 2, 2); glTranslatef (-5,0,0); glutSolidSphere(1.0, 5, 6); glPopMatrix (); //angle += 3.0f; glPushMatrix (); //glRotatef (-90, 1.0f, 0.0f, 0.0f); glRotatef (x_angle, 1.0f, 0.0f, 0.0f); glRotatef (y_angle, 0.0f, 1.0f, 0.0f); glRotatef (z_angle, 0.0f, 0.0f, 1.0f); //glRotatef (angle, 0.0f, 0.0f, 1.0f); //glRotatef (angle/6, 0.0f, 1.0f, 1.0f); //glRotatef (angle/3, 1.0f, 0.0f, 0.0f); if (1) { glCallList (model_lst); } else { the_model->draw (); } //glutSolidSphere(5.0, 10, 10); glPopMatrix (); glutSwapBuffers (); } void keyboard (unsigned char key, int x, int y) { puts ("keyboard"); switch (key) { case 27: case 'q': exit(EXIT_SUCCESS); break; case 'd': //angle += 3.0f; display(); break; case 'a': z_angle += 5.0f; break; case 'o': z_angle -= 5.0f; break; default: break; } } void init() { GLfloat mat_specular[] = { 0.0, 0.0, 0.0, 0.0 }; GLfloat mat_shininess[] = { 0.0 }; glClearColor (1.0, 0.0, 0.0, 0.0); glShadeModel(GL_SMOOTH); glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv (GL_FRONT, GL_SHININESS, mat_shininess); GLfloat light_pos[] = {40.0f, 0.0f, 30.0f, 1.0f}; glLightfv(GL_LIGHT0, GL_POSITION, light_pos); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); model_lst = glGenLists (1); glNewList (model_lst, GL_COMPILE); the_model->draw (); glEndList (); } void mouse (int button_state, int button, int x, int y) { //std::cout << x << " " << y << " " //<< button_state << " " << button << std::endl; x_angle = x - 400; y_angle = y - 300; //display (); } void idle_func () { display (); } void mouse_motion (int x, int y) { //std::cout << "Motion: " << x << " " << y << std::endl; x_angle = x - 400; y_angle = y - 300; //display (); } int main (int argc, char** argv) { if (argc != 2) { puts ("Usage: viewer [MODELFILE]"); return EXIT_FAILURE; } else { Model* model = new Model(argv[1]); the_model = model; glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(800, 600); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(mouse); glutMotionFunc (mouse_motion); glutIdleFunc (idle_func); glutKeyboardFunc(keyboard); glutMainLoop(); delete model; return 0; } } // EOF //