LoadOBJPlus
From class_wiki
bool loadOBJPlus(const char * path, std::vector<glm::vec3> & out_vertices, std::vector<glm::vec2> & out_uvs, std::vector<glm::vec3> & out_normals) { printf("Loading OBJ file %s...\n", path); std::vector<unsigned int> vertexIndices, uvIndices, normalIndices; std::vector<glm::vec3> temp_vertices; std::vector<glm::vec2> temp_uvs; std::vector<glm::vec3> temp_normals; FILE * file = fopen(path, "r"); if( file == NULL ){ printf("Impossible to open the file ! Are you in the right path ? See Tutorial 1 for details\n"); getchar(); return false; } while( 1 ){ char lineHeader[128]; // read the first word of the line int res = fscanf(file, "%s", lineHeader); if (res == EOF) break; // EOF = End Of File. Quit the loop. // else : parse lineHeader if ( strcmp( lineHeader, "v" ) == 0 ){ glm::vec3 vertex; fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z ); temp_vertices.push_back(vertex); }else if ( strcmp( lineHeader, "vt" ) == 0 ){ glm::vec2 uv; fscanf(file, "%f %f\n", &uv.x, &uv.y ); uv.y = -uv.y; // Invert V coordinate since we will only use DDS texture, which are inverted. Remove if you want to use TGA or BMP loaders. temp_uvs.push_back(uv); }else if ( strcmp( lineHeader, "vn" ) == 0 ){ glm::vec3 normal; fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z ); temp_normals.push_back(normal); }else if ( strcmp( lineHeader, "f" ) == 0 ){ std::string vertex1, vertex2, vertex3; unsigned int vertexIndex[3], uvIndex[3], normalIndex[3]; int matches; // remember position in case fscanf fails long int fpos = ftell (file); matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2] ); if (matches == 9) { vertexIndices.push_back(vertexIndex[0]); vertexIndices.push_back(vertexIndex[1]); vertexIndices.push_back(vertexIndex[2]); uvIndices .push_back(uvIndex[0]); uvIndices .push_back(uvIndex[1]); uvIndices .push_back(uvIndex[2]); normalIndices.push_back(normalIndex[0]); normalIndices.push_back(normalIndex[1]); normalIndices.push_back(normalIndex[2]); continue; } // go back to before fscanf and try again fseek(file, fpos, SEEK_SET); matches = fscanf(file, "%d %d %d\n", &vertexIndex[0], &vertexIndex[1], &vertexIndex[2]); if (matches != 3){ printf("File can't be read by our simple parser :-( Try exporting with other options\n"); return false; } vertexIndices.push_back(vertexIndex[0]); vertexIndices.push_back(vertexIndex[1]); vertexIndices.push_back(vertexIndex[2]); if (temp_normals.size() == temp_vertices.size()) { normalIndices.push_back(vertexIndex[0]); normalIndices.push_back(vertexIndex[1]); normalIndices.push_back(vertexIndex[2]); } }else{ // Probably a comment, eat up the rest of the line char stupidBuffer[1000]; fgets(stupidBuffer, 1000, file); } } // For each vertex of each triangle for( unsigned int i=0; i<vertexIndices.size(); i++ ){ // Get the indices of its attributes, get the attributes thanks to the index, and put attributes in buffers unsigned int vertexIndex = vertexIndices[i]; glm::vec3 vertex = temp_vertices[ vertexIndex-1 ]; out_vertices.push_back(vertex); if (uvIndices.size() == vertexIndices.size()) { unsigned int uvIndex = uvIndices[i]; glm::vec2 uv = temp_uvs[ uvIndex-1 ]; out_uvs.push_back(uv); } if (normalIndices.size() == vertexIndices.size()) { unsigned int normalIndex = normalIndices[i]; glm::vec3 normal = temp_normals[ normalIndex-1 ]; out_normals.push_back(normal); } } return true; }