1
\$\begingroup\$

I am currently working on a 3d game engine, but am complete stumped on a problem involving texture rendering. Here is the rundown.

My game engine renders meshes of the OBJ wavefront type. I have created a OBJ mesh parser that simply looks through all the vertice/normal/texture indexes(Line by Line) and loads the corresponding data into the right places without altering it.

Mesh Parser Code: (NOTE pseudo codeish)

MY VERTEX STRUCTURE: struct VERTEX { D3DXVECTOR3 Pos; D3DXVECTOR3 Normal; D3DXVECTOR2 TexCoords; };

    if (line[i]->c_str()[0] == 'v' && line[i]->c_str()[1] == ' ') {

        float tmpx = 0;
        float tmpy = 0;
        float tmpz = 0;

        sscanf(line[i]->c_str(), "v %f %f %f", &tmpx, &tmpy, &tmpz);

        D3DXVECTOR3 myVec = {tmpx, tmpy, tmpz };

        vertices.push_back(myVec);


    }
    else if (line[i]->c_str()[0] == 'v' && line[i]->c_str()[1] == 't') {

        float tmpx = 0;
        float tmpy = 0;

        sscanf(line[i]->c_str(), "vt %f %f", &tmpx, &tmpy);

        D3DXVECTOR2 myTexCoords = { tmpx, tmpy };

        texCoords.push_back(myTexCoords);
    }
    else if (line[i]->c_str()[0] == 'v' && line[i]->c_str()[1] == 'n') {

        float tmpx = 0; 
        float tmpy = 0;
        float tmpz = 0;

        sscanf(line[i]->c_str(), "vn %f %f %f", &tmpx, &tmpy, &tmpz);

        D3DXVECTOR3 myNorm = { tmpx, tmpy, tmpz };

        normals.push_back(myNorm);

    }


            sscanf(line[i]->c_str(), "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", 
            &tmpindices1, &tmpTexCoordsIndex1, &tmpNormalsIndex1, 
            &tmpindices2, &tmpTexCoordsIndex2, &tmpNormalsIndex2, 
            &tmpindices3, &tmpTexCoordsIndex3, &tmpNormalsIndex3, 
            &tmpindices4, &tmpTexCoordsIndex4, &tmpNormalsIndex4);

            verticeIndex.push_back(tmpindices1 - 1);
            verticeIndex.push_back(tmpindices2 - 1);
            verticeIndex.push_back(tmpindices3 - 1);
            verticeIndex.push_back(tmpindices4 - 1);

            texCoordsIndex.push_back(tmpTexCoordsIndex1 - 1);
            texCoordsIndex.push_back(tmpTexCoordsIndex2 - 1);
            texCoordsIndex.push_back(tmpTexCoordsIndex3 - 1);
            texCoordsIndex.push_back(tmpTexCoordsIndex4 - 1);

            normalsIndex.push_back(tmpNormalsIndex1 - 1);
            normalsIndex.push_back(tmpNormalsIndex2 - 1);
            normalsIndex.push_back(tmpNormalsIndex3 - 1);
            normalsIndex.push_back(tmpNormalsIndex4 - 1);

for (int i = 0; i < texCoordsIndex.size(); i++) {
    ModelToFill.Vertices[i].TexCoords = texCoords.at(texCoordsIndex.at(i));
}

for (int i = 0; i < normalsIndex.size(); i++) {
    ModelToFill.Vertices[i].Normal = normals.at(normalsIndex.at(i));
}

for (int i = 0; i < vertices.size(); i++) {
    ModelToFill.Vertices[i].Pos = vertices.at(i);
}

for (int i = 0; i < verticeIndex.size(); i++) {
    ModelToFill.Indices[i] = verticeIndex.at(i);
}

But now when my renderer renders the mesh it looks like this:

Cube

As You can see the texture coordinates are all messed up, (for some surfaces). The Bottom, Leftmost and back are messed up but the front and top are fine.

Now I should mention that my mesh is exported from blender with materials, and the mesh is also triangulated. Before importing I also performed the smart UV unwrap.

Finally, I should mention that the parts of the mesh which are not texture mapped correctly vary depending on the mesh.

enter image description here

MY QUESTION though quite general: What is the most probable cause of this issue, the mesh parser, form of blender mesh exporting, or renderer.

\$\endgroup\$
0
\$\begingroup\$

You need to be careful, wavefront files and gpu does not works the same, in the file, you can have a missmatch of indices between position, texcoord and normal because they can be reuse differently. Extreme example, a cube with a texture per face only need 8 point values, 4 texcoord values and 6 normal values.

Now, on the GPU, a vertex need to be a full tuple, it means for our cube, that you need to split points for divergent texcoord and normal, and you ends with 24 vertex.

EDIT: tips for building a proper vertex buffer and index buffer from a wavefront file

use std::map<std::tuple<int,int,int>,int> remap;, the key is the triplet position/uv/normal, the value is an increasing counter, starting at 0, and that you increment every time you that a new triplet.

Once you insert every triplet, counter is your number of unique vertex. you can now create a vertex buffer of that many values, and fill it by reversing the std::map, the value become the vertex offset, the key is the vertex attribut indices.

You do the same for the index buffer, you use the triplet as a key to retrieve the final vertex index.

\$\endgroup\$
  • \$\begingroup\$ Hey! Thanks for the response. Upon recent debugging using the Visual Studio graphics debugger, I did notice that my graphics card was using the same vertex indices for both texture coordinates and normal coordinates. I am currently trying to construct an algorithm to sort the texcoords and normals so that when referenced using the vertex indices, the correct texcoord and normal is in the proper indexed position relative to the vertex indice. Unfortunate I have no clue on how to make this algorithm. Do you have any idea how I can? \$\endgroup\$ – NJ Mercaldo Jul 22 '16 at 0:16
  • \$\begingroup\$ @NJMercaldo I had a tips on how to easy turn the multi indices logic and generate the vertex buffer in the answer. \$\endgroup\$ – galop1n Jul 22 '16 at 0:32
  • \$\begingroup\$ Hey, I am making good progress at implementing your provided algorithm, but I am stuck at one place. How do I reverse the map so that the key becomes the counter number, and the data the map outputs becomes the vertice/texcoord/normal tuple? Is this what you mean by reverse? Thanks :) \$\endgroup\$ – NJ Mercaldo Jul 22 '16 at 14:22
  • \$\begingroup\$ Algorithm is now working beautifully! Thanks again for the help. \$\endgroup\$ – NJ Mercaldo Jul 22 '16 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.