Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void loadModel(const std::string& fileName) {
- tinyobj::attrib_t attrib;
- std::vector<tinyobj::shape_t> shapes;
- std::vector<tinyobj::material_t> materials;
- std::string err;
- std::string baseDir = getBaseDir(fileName);
- if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &err, fileName.c_str(), baseDir.c_str())) {
- throw std::runtime_error(err);
- }
- auto textureStart = textureIndex; // first free slot in texture array
- uint32_t indexCount = 0; // the number of indices to be drawn in one bundle
- auto indexStart = static_cast<uint32_t>(indices.size()); // index offset for drawing
- int currentMat = 0; // the current OBJ material being used in face loop
- for (const auto& mat : materials) {
- // loads a texture and adds it to the global array. also increments textureIndex.
- // note: if you are loading multiple textures per material (i.e. diffuse + normal textures),
- // you'll need to track this better than just a single index variable. Also, this
- // method here does not account for materials with no textures, it's work in progress.
- loadTexture(baseDir + mat.diffuse_texname, textureIndex);
- }
- std::unordered_map<Vertex, uint32_t> uniqueVertices = {};
- for (size_t shape = 0; shape < shapes.size(); shape++) {
- size_t index_offset = 0;
- for (size_t face = 0; face < shapes[shape].mesh.num_face_vertices.size(); face++) {
- // check if the material of this face is different than previous
- auto thisMat = shapes[shape].mesh.material_ids[face];
- if (thisMat != currentMat) {
- // save the index data for this sub-object bundle for drawing later
- // what is saved is the indexCount: the number of indices to be drawn
- // in one draw call, as well as the indexStart: the offset into the
- // main indices array. the last parameter is the index into the
- // global texture array. this index is passed to the fragment shader.
- recordIndexInfo(indexCount, indexStart, textureStart + currentMat);
- currentMat = thisMat;
- indexCount = 0;
- indexStart = static_cast<uint32_t>(indices.size());
- }
- int faceVerts = shapes[shape].mesh.num_face_vertices[face];
- for (size_t vert = 0; vert < faceVerts; vert++) {
- tinyobj::index_t idx = shapes[shape].mesh.indices[index_offset + vert];
- tinyobj::real_t vx = attrib.vertices[3*idx.vertex_index+0];
- tinyobj::real_t vy = attrib.vertices[3*idx.vertex_index+1];
- tinyobj::real_t vz = attrib.vertices[3*idx.vertex_index+2];
- tinyobj::real_t nx = attrib.normals[3*idx.normal_index+0];
- tinyobj::real_t ny = attrib.normals[3*idx.normal_index+1];
- tinyobj::real_t nz = attrib.normals[3*idx.normal_index+2];
- tinyobj::real_t tx = attrib.texcoords[2*idx.texcoord_index+0];
- tinyobj::real_t ty = 1.0f - attrib.texcoords[2*idx.texcoord_index+1];
- tinyobj::real_t r = attrib.colors[3*idx.vertex_index+0];
- tinyobj::real_t g = attrib.colors[3*idx.vertex_index+1];
- tinyobj::real_t b = attrib.colors[3*idx.vertex_index+2];
- Vertex vertex = {};
- vertex.position = {vx, vy, vz};
- vertex.uv = {tx, ty};
- vertex.color = {r, g, b};
- if (uniqueVertices.count(vertex) == 0) {
- uniqueVertices[vertex] = static_cast<uint32_t>(vertices.size());
- vertices.push_back(vertex);
- }
- indices.push_back(uniqueVertices[vertex]);
- // increment the index counter for this sub-object
- ++indexCount;
- }
- index_offset += faceVerts;
- }
- // don't forget to save the last sub-object bundle when leaving the loop
- recordIndexInfo(indexCount, indexStart, textureStart + currentMat);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement