#include #include #include #include #include #include using namespace std; enum VAO_IDs {OFF, NumVAOs}; enum Buffer_IDs {vertexBuffer, indexBuffer, NumBuffers}; enum Attrib_IDs {vPosition, vColor, vNormal}; GLuint VAOs[NumVAOs]; GLuint Buffers[NumBuffers]; const GLuint NumVertices = 6; struct vertexT{ vec3 point; vec3 color; vec3 normal; }; vector vertices; vector indices; ShaderInfo shaders[] = { { GL_VERTEX_SHADER, "off.vert" }, { GL_FRAGMENT_SHADER, "triangles.frag"}, { GL_NONE, NULL} }; void DoErrorReport(string header ) { GLenum err = GL_NO_ERROR; bool firstPass = true; while ((err = glGetError()) != GL_NO_ERROR) { if(firstPass) { cout << header << endl; firstPass = false; } cout << "Got error " << err << ": " ; cout << gluErrorString(err) << endl; } } void DoNormal(GLushort p1, GLushort p2, GLushort p3){ vec3 a,b, n; a = normalize(vertices[p2].point - vertices[p1].point); b = normalize(vertices[p3].point - vertices[p1].point); n = cross(a,b); vertices[p1].normal += n; vertices[p2].normal += n; vertices[p3].normal += n; return; } GLfloat Min(GLfloat a, GLfloat b) { if (a < b) { return a; } else { return b; } } GLfloat Max(GLfloat a, GLfloat b) { if (a > b) { return a; } else { return b; } } void MinMax(GLfloat & min, GLfloat & max, vec3 point) { int i; for(i=0;i<3;i++) { min = Min(min, point[i]); max = Max(max, point[i]); } return; } void LoadOff( string fileName){ ifstream offFile; int vertexCount; int i,j; GLfloat min, max; GLfloat scale; vec3 translate; int count; GLshort p1, p2, p3; vertexT vertex; offFile.open(fileName.c_str()); if (not offFile) { cerr << "Failed ot open " << fileName << endl; exit(-1); } offFile >> vertexCount; vertex.color[0] = 1; for(i=0;i> vertex.point; if (i == 0) { min = vertex.point.x; max = vertex.point.x; } MinMax(min, max, vertex.point); vertices.push_back(vertex); } // start reading the polygons offFile >> count; while (offFile) { // read in the first three indicies for the polygon offFile >> p1 >> p2 >> p3; // and add them in indices.push_back(p1); indices.push_back(p2); indices.push_back(p3); DoNormal(p1, p2, p3); // for all other indicies in the polygon for(i=3; i < count; i++) { // read in the next point. p2 = p3; offFile >> p3; // add the new triangle to the list of triangles. indices.push_back(p1); indices.push_back(p2); indices.push_back(p3); DoNormal(p1, p2, p3); } offFile >> count; } offFile.close(); // normalize the normals // translate = vec3(min, min, min); scale = (max-min)/2.0; for(i=0;i< vertices.size();i++) { vertices[i].normal = normalize(vertices[i].normal); vertices[i].point =(vertices[i].point-translate )/scale - vec3(1,1,1); } return; } void setup() { GLuint program; glClearColor(1.0, 1.0, 1.0, 1.0); LoadOff("lizard.off"); program = LoadShaders(shaders); glUseProgram(program); glGenVertexArrays(NumVAOs, VAOs); glBindVertexArray(VAOs[OFF]); glGenBuffers(NumBuffers, Buffers); // set up the index vbo glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Buffers[indexBuffer]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLuint), indices.data(), GL_STATIC_DRAW); // set up the vertex vbo glBindBuffer(GL_ARRAY_BUFFER, Buffers[vertexBuffer]); glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vertexT), vertices.data(), GL_STATIC_DRAW); GLsizei stride = sizeof(vertexT); // attributes for the vertices glVertexAttribPointer(vPosition, 3, GL_FLOAT, GL_FALSE, stride , BUFFER_OFFSET(offsetof(vertexT, point))); glEnableVertexAttribArray(vPosition); glVertexAttribPointer(vColor, 3, GL_FLOAT, GL_FALSE, stride , BUFFER_OFFSET(offsetof(vertexT, color))); glEnableVertexAttribArray(vColor); glVertexAttribPointer(vNormal, 3, GL_FLOAT, GL_FALSE, stride , BUFFER_OFFSET(offsetof(vertexT, normal))); glEnableVertexAttribArray(vNormal); DoErrorReport("End of Setup"); return; } void display(){ glClear(GL_COLOR_BUFFER_BIT); glBindVertexArray(VAOs[OFF]); glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, NULL); glFlush(); DoErrorReport("End of Display"); return; } void keypress(unsigned char key, int x, int y) { switch(key) { case 'q': exit(0); } glutPostRedisplay(); return; } int main(int argc, char * argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutInitWindowSize(512, 512); glutInitContextVersion(3,0); glutInitContextProfile(GLUT_CORE_PROFILE); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutKeyboardFunc(keypress); glewExperimental = GL_TRUE; if (glewInit()) { cerr << "Unable to initialize glew, exiting " << endl; exit (-1); } setup(); glutMainLoop(); return 0; }