JModel::JModel(string path){ modelMatrix = glm::mat4(5.0f); normalMatrix = glm::transpose(glm::inverse(modelMatrix)); LoadObj(shapes, materials, path.c_str()); // Make VBO int m = 0; for (m = 0; m < shapes.size(); m++){ data.push_back(VertexBufferObject()); int j = 0; int k = 0; int i = 0; for (i = 0; i < shapes[m].mesh.positions.size(); ){ Vertex vert; vert.p.x = shapes[m].mesh.positions[i++]; vert.p.y = shapes[m].mesh.positions[i++]; vert.p.z = shapes[m].mesh.positions[i++]; vert.n.x = shapes[m].mesh.normals[j++]; vert.n.y = shapes[m].mesh.normals[j++]; vert.n.z = shapes[m].mesh.normals[j++]; vert.u.x = shapes[m].mesh.texcoords[k++]; vert.u.y = shapes[m].mesh.texcoords[k++]; data[m].verts.push_back(vert); } data[m].texture = Engine::GetTexture(materials[shapes[m].mesh.material_ids[0]].diffuse_texname); // printf("Texture Loaded: %s, %d\n", "roof.jpg", data[m].texture); printf("Texture Loaded: %s, %d\n", materials[shapes[m].mesh.material_ids[0]].diffuse_texname.c_str(), data[m].texture); glGenVertexArrays(1, &data[m].vao); glBindVertexArray(data[m].vao); glEnableVertexAttribArray(0); glGenBuffers(1, &data[m].vbo); glBindBuffer(GL_ARRAY_BUFFER, data[m].vbo); glBufferData(GL_ARRAY_BUFFER, data[m].verts.size() * sizeof(Vertex), &data[m].verts[0].p.x, GL_STATIC_DRAW); glGenBuffers(1, &data[m].ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data[m].ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, shapes[m].mesh.indices.size() * sizeof(unsigned int), &shapes[m].mesh.indices[0], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, data[m].vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data[m].ibo); glBindVertexArray(0); } printf("Model Created!\n"); }
bool Mesh::load(const std::string& path, NormalType nt) { std::vector<tinyobj::material_t> materials; std::vector<tinyobj::shape_t> shapes; std::string err; LoadObj(shapes, materials, err, path.c_str()); if (shapes.empty()) return false; if (shapes[0].mesh.indices.empty()) return false; if (shapes[0].mesh.normals.empty()) nt = FLAT; bool hasTexCoord = !shapes[0].mesh.texcoords.empty(); std::vector<std::vector<int>> facesForVertex(shapes[0].mesh.positions.size() / 3); std::vector<std::vector<int>> numInFaceForVertex(shapes[0].mesh.positions.size() / 3); for (size_t i = 0; i < shapes[0].mesh.indices.size() / 3; ++i) { Vertex a, b, c; float *tmp; tmp = &shapes[0].mesh.positions[shapes[0].mesh.indices[i * 3] * 3]; a.position = glm::vec3(tmp[0], tmp[1], tmp[2]); tmp = &shapes[0].mesh.positions[shapes[0].mesh.indices[i * 3 + 1] * 3]; b.position = glm::vec3(tmp[0], tmp[1], tmp[2]); tmp = &shapes[0].mesh.positions[shapes[0].mesh.indices[i * 3 + 2] * 3]; c.position = glm::vec3(tmp[0], tmp[1], tmp[2]); if (nt != FLAT) { tmp = &shapes[0].mesh.normals[shapes[0].mesh.indices[i * 3] * 3]; a.normal = glm::normalize(glm::vec3(tmp[0], tmp[1], tmp[2])); tmp = &shapes[0].mesh.normals[shapes[0].mesh.indices[i * 3 + 1] * 3]; b.normal = glm::normalize(glm::vec3(tmp[0], tmp[1], tmp[2])); tmp = &shapes[0].mesh.normals[shapes[0].mesh.indices[i * 3 + 2] * 3]; c.normal = glm::normalize(glm::vec3(tmp[0], tmp[1], tmp[2])); } if (hasTexCoord) { tmp = &shapes[0].mesh.texcoords[shapes[0].mesh.indices[i * 3] * 2]; a.texCoord = glm::vec2(tmp[0], tmp[1]); tmp = &shapes[0].mesh.texcoords[shapes[0].mesh.indices[i * 3 + 1] * 2]; b.texCoord = glm::vec2(tmp[0], tmp[1]); tmp = &shapes[0].mesh.texcoords[shapes[0].mesh.indices[i * 3 + 2] * 2]; c.texCoord = glm::vec2(tmp[0], tmp[1]); } m_triangles.push_back(new Triangle(a, b, c, *m_material, hasTexCoord, nt != FLAT)); if (nt == CONSISTENT) { facesForVertex[shapes[0].mesh.indices[i * 3]].push_back(i); facesForVertex[shapes[0].mesh.indices[i * 3 + 1]].push_back(i); facesForVertex[shapes[0].mesh.indices[i * 3 + 2]].push_back(i); numInFaceForVertex[shapes[0].mesh.indices[i * 3]].push_back(0); numInFaceForVertex[shapes[0].mesh.indices[i * 3 + 1]].push_back(1); numInFaceForVertex[shapes[0].mesh.indices[i * 3 + 2]].push_back(2); } } if (nt == CONSISTENT) { for (int i = 0; i < facesForVertex.size(); ++i) { float *tmp = &shapes[0].mesh.normals[i * 3]; glm::vec3 vertNormal(tmp[0], tmp[1], tmp[2]); vertNormal = glm::normalize(vertNormal); float minCos = 2.0f; for (int facenum : facesForVertex[i]) { float curCos = glm::dot(vertNormal, m_triangles[facenum]->getFaceNormal()); if (curCos < minCos) minCos = curCos; } for (int j = 0; j < facesForVertex[i].size(); ++j) { int faceNum = facesForVertex[i][j]; int vertNum = numInFaceForVertex[i][j]; Vertex v = m_triangles[faceNum]->getVertex(vertNum); v.alpha = glm::acos(minCos) * (1.0f + 0.03632f * (1 - minCos) * (1 - minCos)); m_triangles[faceNum]->setVertex(vertNum, v); } } for (auto& t:m_triangles) { t->commitTransformations(); } } return true; }