Work on assignment 4
[opengl.git] / model.cpp
diff --git a/model.cpp b/model.cpp
new file mode 100644 (file)
index 0000000..29e3d8a
--- /dev/null
+++ b/model.cpp
@@ -0,0 +1,78 @@
+#include "model.hpp"
+#include <iostream>
+#include <assimp/Importer.hpp>
+#include <assimp/scene.h>
+#include <assimp/postprocess.h>
+
+Model::Mesh::Mesh(const aiMesh *aiMesh, GLuint progId) {
+       for (int i = 0; i < aiMesh->mNumVertices; i++) {
+               if (aiMesh->HasPositions()) {
+                       aiVector3D v = aiMesh->mVertices[i];
+                       vertices.push_back(glm::vec3(v.x, v.y, v.z));
+               }
+               if (aiMesh->HasNormals()) {
+                       const aiVector3D v = aiMesh->mNormals[i];
+                       normals.push_back(glm::vec3(v.x, v.y, v.z));
+               }
+               // check for texture coord set 0
+               if (aiMesh->HasTextureCoords(0)) {
+                       const aiVector3D v = aiMesh->mTextureCoords[0][i];
+                       texCoords.push_back(glm::vec2(v.x, v.y));
+               }
+       }
+
+       for (int i = 0; i < aiMesh->mNumFaces; i++) {
+               const aiFace &face = aiMesh->mFaces[i];
+               if(face.mNumIndices == 3) {
+                       indices.push_back(face.mIndices[0]);
+                       indices.push_back(face.mIndices[1]);
+                       indices.push_back(face.mIndices[2]);
+               }
+       }
+       
+       glGenVertexArrays(1, &vao);
+       glBindVertexArray(vao);
+       
+       GLuint vbos[3];
+       glGenBuffers(3, vbos);
+       vertexVbo = vbos[0], normalVbo = vbos[1], indicesVbo = vbos[2];
+       
+       GLuint posLoc = glGetAttribLocation(progId, "vPosition");
+       GLuint normalLoc = glGetAttribLocation(progId, "vNormal");
+       
+       glBindBuffer(GL_ARRAY_BUFFER, vertexVbo);
+       glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
+       glEnableVertexAttribArray(posLoc);
+       glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
+       
+       glBindBuffer(GL_ARRAY_BUFFER, normalVbo);
+       glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);
+       glEnableVertexAttribArray(normalLoc);
+       glVertexAttribPointer(normalLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
+
+       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesVbo);
+       glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);
+};
+
+void Model::loadModel(const std::string &file) {
+       Assimp::Importer importer;
+       const aiScene *scene = importer.ReadFile(file, 
+                       aiProcess_Triangulate | aiProcess_PreTransformVertices |
+                       aiProcess_GenNormals);
+       if (!scene) {
+               std::cerr << importer.GetErrorString() << std::endl;
+               exit(1);
+       }
+
+       for (int i = 0; i < scene->mNumMeshes; i++) {
+               const aiMesh *mesh = scene->mMeshes[i];
+               meshes.push_back(Mesh(mesh, progId));
+       }
+}
+
+void Model::draw() {
+       for (Mesh &mesh: meshes) {
+               glBindVertexArray(mesh.vao);
+               glDrawElements(GL_TRIANGLES, mesh.indices.size(), GL_UNSIGNED_INT, 0);
+       }
+}