Home > Software engineering >  Why doesn't my wavefront obj file parser order the vertices properly?
Why doesn't my wavefront obj file parser order the vertices properly?

Time:08-19

I created an obj model parser and decided to follow the tutorial at http://opengl-tutorial.org, but the parsing of the normals and vertices does not work properly. I decided to change the code a bit to see what would happen and to maybe fix it, but when I did that the outputted vertices completely changed from the way they previously looked. I then noticed a mistake I made in the loop and I fixed it and that made the vertices how they were before, but that only had the front side properly rendered. I don't know what I did wrong and I cannot seem to understand enough how the indices work to figure it out. This is the code, that renders only the front side properly (This is just the vertices, the code for the normals works the same way.):

for(i = 0; i < vertexsize; i  = 3){
    verticesind[i] = verticesout[vertexindices[i] - 1];
    verticesind[i   1] = verticesout[vertexindices[i   1] - 1];
    verticesind[i   2] = verticesout[vertexindices[i   2] - 1];
    verticessize  = sizeof(verticesind[i])   sizeof(verticesind[i   1])   sizeof(vertices[i   2]);
}

For any of you wondering this is the model.obj file:

# Blender v2.93.8 OBJ File: ''
# www.blender.org
o Cube
v 0.500000 0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
v 0.500000 0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v -0.500000 0.500000 0.500000
v -0.500000 -0.500000 0.500000
vt 0.875000 0.500000
vt 0.625000 0.750000
vt 0.625000 0.500000
vt 0.375000 1.000000
vt 0.375000 0.750000
vt 0.625000 0.000000
vt 0.375000 0.250000
vt 0.375000 0.000000
vt 0.375000 0.500000
vt 0.125000 0.750000
vt 0.125000 0.500000
vt 0.625000 0.250000
vt 0.875000 0.750000
vt 0.625000 1.000000
vn 0.0000 1.0000 0.0000
vn 0.0000 0.0000 1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
s off
f 5/1/1 3/2/1 1/3/1
f 3/2/2 8/4/2 4/5/2
f 7/6/3 6/7/3 8/8/3
f 2/9/4 8/10/4 6/11/4
f 1/3/5 4/5/5 2/9/5
f 5/12/6 2/9/6 6/7/6
f 5/1/1 7/13/1 3/2/1
f 3/2/2 7/14/2 8/4/2
f 7/6/3 5/12/3 6/7/3
f 2/9/4 4/5/4 8/10/4
f 1/3/5 3/2/5 4/5/5
f 5/12/6 1/3/6 2/9/6

One of the top triangles should be

-0.5, 0.5, -0.5,
 0.5, 0.5,  0.5,
 0.5, 0.5, -0.5

and that results in a full triangle, but for some reason they get shuffled around in the final result and the same triangle turns into

-0.5, -0.5, 0.5,
-0.5,  0.5, 0.5,
 0.5, -0.5, 0.5

This is the full code of my function (I don't think it will be needed as I am loading the obj file properly, but it can still be used to check how I save the values):

int load_obj(const char* filename, float* vertices, float* texcoords, float* normals, unsigned int* vertexindexsize, unsigned int* texcoordindexsize, unsigned int* normalindexsize){
    FILE* file = fopen(filename, "r");
    char lineheader[128];
    int res;
    int i = 0;
    int f = 0;
    int d = 0;
    int g = 0;
    unsigned int vertexsize = 0;
    unsigned int texcoordsize = 0;
    unsigned int normalsize = 0;
    unsigned int verticessize = 0;
    unsigned int texturecoordsize = 0;
    unsigned int normalssize = 0;
    float verticesout[500];
    float texcoordsout[500];
    float normalsout[500];
    float verticesind[500];
    float texturecoordsind[500];
    float normalsind[500];
    unsigned int vertexindex[3];
    unsigned int texindex[3];
    unsigned int normalindex[3];
    vec3 vertex;
    vec2 texcoord;
    vec3 normal;
    int vertexindices[500];
    int texindices[500];
    int normalindices[500];
    if(file == NULL){
        printf("Failed to open file!\n");
        return 1;
    }
    while(1){
        res = fscanf(file, "%s", lineheader);
        if(res == EOF){
            break;
        }
        if(strcmp(lineheader, "v") == 0){
            fscanf(file, "%f %f %f\n", &vertex[0], &vertex[1], &vertex[2]);
            verticesout[i] = vertex[0];
            verticesout[i   1] = vertex[1];
            verticesout[i   2] = vertex[2];
            i  = 3;
        }else if(strcmp(lineheader, "vt") == 0){
            fscanf(file, "%f %f\n", &texcoord[0], &texcoord[1]);
            texcoordsout[f] = texcoord[0];
            texcoordsout[f   1] = texcoord[1];
            f  = 2;
        }else if(strcmp(lineheader, "vn") == 0){
            fscanf(file, "%f %f %f\n", &normal[0], &normal[1], &normal[2]);
            normalsout[d] = normal[0];
            normalsout[d   1] = normal[1];
            normalsout[d   2] = normal[2];
            d  = 3;
        }else if(strcmp(lineheader, "f") == 0){
            fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexindex[0], &texindex[0], &normalindex[0], &vertexindex[1], &texindex[1], &normalindex[1], &vertexindex[2], &texindex[2], &normalindex[2]);
            vertexindices[g] = vertexindex[0];
            vertexindices[g   1] = vertexindex[1];
            vertexindices[g   2] = vertexindex[2];
        vertexsize  = 3;
            texindices[g] = texindex[0];
            texindices[g   1] = texindex[1];
            texindices[g   2] = texindex[2];
        texcoordsize  = 3;
            normalindices[g] = normalindex[0];
            normalindices[g   1] = normalindex[1];
            normalindices[g   2] = normalindex[2];
        normalsize  = 3;
            g  = 3;
        }
    }
    for(i = 0; i < vertexsize; i  = 3){
        verticesind[i] = verticesout[vertexindices[i] - 1];
        verticesind[i   1] = verticesout[vertexindices[i   1] - 1];
        verticesind[i   2] = verticesout[vertexindices[i   2] - 1];
        verticessize  = sizeof(verticesind[i])   sizeof(verticesind[i   1])   sizeof(vertices[i   2]);
    }
    for(i = 0; i < texcoordsize; i  ){
        texturecoordsind[i] = texcoordsout[texindices[i] - 1];
        texturecoordsize  = sizeof(texturecoordsind[i]);
    }
    for(i = 0; i < normalsize; i  = 3){
        normalsind[i] = normalsout[normalindices[i] - 1];
        normalsind[i   1] = normalsout[normalindices[i   1] - 1];
        normalsind[i   2] = normalsout[normalindices[i   2] - 1];
        normalssize  = sizeof(normalsind[i])   sizeof(normalsind[i   1])   sizeof(normalsind[i   2]);
    }
    memcpy(vertices, verticesind, sizeof(verticesind));
    memcpy(texcoords, texturecoordsind, sizeof(texturecoordsind));
    memcpy(normals, normalsind, sizeof(normalsind));
    *vertexindexsize = verticessize;
    *texcoordindexsize = texturecoordsize;
    *normalindexsize = normalssize;
    return 0;
}

CodePudding user response:

I changed the function a bit, as it didn't take use of the indices correctly:

for(i = 0; i < vertexsize; i  ){
      verticesind[i * 3] = verticesout[(vertexindices[i] - 1) * 3];
      verticesind[i * 3   1] = verticesout[(vertexindices[i] - 1) * 3   1];
      verticesind[i * 3   2] = verticesout[(vertexindices[i] - 1) * 3   2];
      verticessize  = sizeof(verticesind[i]) * 3;
}

Now it loads the vertices and normals properly.

  • Related