Work on assignment 4
[opengl.git] / model.cpp
1 #include "model.hpp"
2 #include <iostream>
3 #include <assimp/Importer.hpp>
4 #include <assimp/scene.h>
5 #include <assimp/postprocess.h>
6
7 Model::Mesh::Mesh(const aiMesh *aiMesh, GLuint progId) {
8         for (int i = 0; i < aiMesh->mNumVertices; i++) {
9                 if (aiMesh->HasPositions()) {
10                         aiVector3D v = aiMesh->mVertices[i];
11                         vertices.push_back(glm::vec3(v.x, v.y, v.z));
12                 }
13                 if (aiMesh->HasNormals()) {
14                         const aiVector3D v = aiMesh->mNormals[i];
15                         normals.push_back(glm::vec3(v.x, v.y, v.z));
16                 }
17                 // check for texture coord set 0
18                 if (aiMesh->HasTextureCoords(0)) {
19                         const aiVector3D v = aiMesh->mTextureCoords[0][i];
20                         texCoords.push_back(glm::vec2(v.x, v.y));
21                 }
22         }
23
24         for (int i = 0; i < aiMesh->mNumFaces; i++) {
25                 const aiFace &face = aiMesh->mFaces[i];
26                 if(face.mNumIndices == 3) {
27                         indices.push_back(face.mIndices[0]);
28                         indices.push_back(face.mIndices[1]);
29                         indices.push_back(face.mIndices[2]);
30                 }
31         }
32         
33         glGenVertexArrays(1, &vao);
34         glBindVertexArray(vao);
35         
36         GLuint vbos[3];
37         glGenBuffers(3, vbos);
38         vertexVbo = vbos[0], normalVbo = vbos[1], indicesVbo = vbos[2];
39         
40         GLuint posLoc = glGetAttribLocation(progId, "vPosition");
41         GLuint normalLoc = glGetAttribLocation(progId, "vNormal");
42         
43         glBindBuffer(GL_ARRAY_BUFFER, vertexVbo);
44         glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
45         glEnableVertexAttribArray(posLoc);
46         glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
47         
48         glBindBuffer(GL_ARRAY_BUFFER, normalVbo);
49         glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);
50         glEnableVertexAttribArray(normalLoc);
51         glVertexAttribPointer(normalLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
52
53         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesVbo);
54         glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);
55 };
56
57 void Model::loadModel(const std::string &file) {
58         Assimp::Importer importer;
59         const aiScene *scene = importer.ReadFile(file, 
60                         aiProcess_Triangulate | aiProcess_PreTransformVertices |
61                         aiProcess_GenNormals);
62         if (!scene) {
63                 std::cerr << importer.GetErrorString() << std::endl;
64                 exit(1);
65         }
66
67         for (int i = 0; i < scene->mNumMeshes; i++) {
68                 const aiMesh *mesh = scene->mMeshes[i];
69                 meshes.push_back(Mesh(mesh, progId));
70         }
71 }
72
73 void Model::draw() {
74         for (Mesh &mesh: meshes) {
75                 glBindVertexArray(mesh.vao);
76                 glDrawElements(GL_TRIANGLES, mesh.indices.size(), GL_UNSIGNED_INT, 0);
77         }
78 }