0

I created a .obj loader by modifying some code i found online, to parse to .obj file I do the following

int mesh::getMesh(char* inputFile, std::vector<std::vector<glm::vec3>> & out_vertices,std::vector < glm::vec2 > & out_uvs,std::vector < glm::vec3 > & out_normals){
    std::cout << "Attempting to load file as model " << inputFile << "\n";

    std::vector<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(inputFile, "r");
    if( file == NULL ){
        std::cout << "Impossible to open the file !\n";
        return 0;
    }
    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.

         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 );
            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 ){
            unsigned int vertexIndex[3], uvIndex[3], normalIndex[3];
            int 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){
                std::cout << "File can't be read by the parser : ( Try exporting with other options )\n";
                return 0;
            }

            std::vector<unsigned int> vertexTriangle;
            vertexTriangle.push_back(vertexIndex[0]);
            vertexTriangle.push_back(vertexIndex[1]);
            vertexTriangle.push_back(vertexIndex[2]);
            vertexIndices.push_back(vertexTriangle);

            //uvIndices    .push_back(uvIndex[0]);
            //uvIndices    .push_back(uvIndex[1]);
            //uvIndices    .push_back(uvIndex[2]);

            //std::vector<unsigned int> normalTriangle;
            //normalTriangle.push_back(normalIndex[0]);
            //normalTriangle.push_back(normalIndex[1]);
            //normalTriangle.push_back(normalIndex[2]);
            //normalIndices.push_back(normalTriangle);
        }
    }
    for( unsigned int i=0; i<vertexIndices.size(); i++ ){
        std::vector<unsigned int> vertexIndexs=vertexIndices[i];

        //glm::vec3 vertex0 = temp_vertices[ vertexIndexs[3]-1 ];
        glm::vec3 vertex1 = temp_vertices[ vertexIndexs[0]-1 ];
        glm::vec3 vertex2 = temp_vertices[ vertexIndexs[1]-1 ];
        glm::vec3 vertex3 = temp_vertices[ vertexIndexs[2]-1 ];
        std::vector<glm::vec3> vertex;
        vertex.push_back(vertex1); vertex.push_back(vertex2); vertex.push_back(vertex3);
        out_vertices.push_back(vertex);

    }
    return 1;
}

I then draw it using

<initialization...>

std::vector<std::vector<glm::vec3>> vertices;
std::vector<glm::vec2> uvs;
std::vector<glm::vec3> normals;

mesh::getMesh("Resources/Models/cube.obj",vertices,uvs,normals);

<window handling and whatnot...>

for (unsigned i=0; i < vertices.size(); i++) {
    std::vector<glm::vec3> vertexGroup = vertices[i];
    glBegin(GL_TRIANGLES);
        glVertex3f(vertexGroup[0].x,vertexGroup[0].y,vertexGroup[0].z);
        glVertex3f(vertexGroup[1].x,vertexGroup[1].y,vertexGroup[1].z);
        glVertex3f(vertexGroup[2].x,vertexGroup[2].y,vertexGroup[2].z);
    glEnd();
}

This works fine for this .obj file

# Blender3D v249 OBJ File: untitled.blend
# www.blender3d.org
mtllib cube.mtl
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 0.748573 0.750412
vt 0.749279 0.501284
vt 0.999110 0.501077
vt 0.999455 0.750380
vt 0.250471 0.500702
vt 0.249682 0.749677
vt 0.001085 0.750380
vt 0.001517 0.499994
vt 0.499422 0.500239
vt 0.500149 0.750166
vt 0.748355 0.998230
vt 0.500193 0.998728
vt 0.498993 0.250415
vt 0.748953 0.250920
vn 0.000000 0.000000 -1.000000
vn -1.000000 -0.000000 -0.000000
vn -0.000000 -0.000000 1.000000
vn -0.000001 0.000000 1.000000
vn 1.000000 -0.000000 0.000000
vn 1.000000 0.000000 0.000001
vn 0.000000 1.000000 -0.000000
vn -0.000000 -1.000000 0.000000
usemtl Material_ray.png
s off
f 5/1/1 1/2/1 4/3/1
f 5/1/1 4/3/1 8/4/1
f 3/5/2 7/6/2 8/7/2
f 3/5/2 8/7/2 4/8/2
f 2/9/3 6/10/3 3/5/3
f 6/10/4 7/6/4 3/5/4
f 1/2/5 5/1/5 2/9/5
f 5/1/6 6/10/6 2/9/6
f 5/1/7 8/11/7 6/10/7
f 8/11/7 7/12/7 6/10/7
f 1/2/8 2/9/8 3/13/8
f 1/2/8 3/13/8 4/14/8

but when i move onto something more complicated, like A low poly model of a man i took from a free model site as a testbed, its missing a triangle to every face (see screenshots below)

The Cube: enter image description here

The Humanoid enter image description here

The man renders fine in blender so it must be how I'm parsing the file?

James T
  • 1,155
  • 4
  • 17
  • 39
  • check if the man model has more than 4 vertices per face (legal according to .obj) or make sure to check "triangulate" in the export options in blender – ratchet freak Nov 21 '14 at 11:18
  • OBJ files can have geometry more complicated than triangles, have you checked that none of the "f" lines have no more than three vertices specified in your model? – jcoder Nov 21 '14 at 11:19
  • oh duh yeah you're right why didnt i think of this. Say if i wanted to correct this in my parses whilst still drawing triangles, if a face has `f 773/1191/3605 772/1192/3606 788/1208/3607 789/1207/3608` would i break it up into 2 triangles, `f {773/1191/3605 772/1192/3606 788/1208/3607} 789/1207/3608` and `f 773/1191/3605 {772/1192/3606 788/1208/3607 789/1207/3608}`? – James T Nov 21 '14 at 11:27
  • 1
    @JamesTrotter just say to blender to triangulate during the export – ratchet freak Nov 21 '14 at 12:13
  • f 773/1191/3605 772/1192/3606 [788/1208/3607] 789/1207/3608 and f [773/1191/3605] 772/1192/3606 788/1208/3607 789/1207/3608 might be the better choice to keep your vertice order correct for backface culling. – Andreas Nov 21 '14 at 12:32
  • see http://stackoverflow.com/q/23723993/3530129 – Reto Koradi Nov 21 '14 at 16:21

1 Answers1

3

You need to triangulate the faces in blender while exporting the model to your format. For obj models you always export with normals attached, and the vertices triangulated. You may also need to check "Keep vertex order".

Krythic
  • 4,184
  • 5
  • 26
  • 67