0
\$\begingroup\$

I have successfully loaded a triangulated Wavefront (.obj) into 6 vectors, the first 3 vectors contain the locations for vertices, UV coords, and normals. The last three have the indices stored for each of the faces.

I have been looking into using VAO's and VBO's to render, and I'm not quite sure how to load and render the data. One of my biggest concerns is the fact that indexed rendering only allows you to have one array of indices, meaning I somehow have to make all of the first three vectors the same size, the only way I thought of doing this, is to make 3 new vertex's of equal size, and load in the data for each face, but that would completely defeat the purpose of indexing.

Any help would be appreciated.

\$\endgroup\$
  • \$\begingroup\$ The OBJ format is an archaic mesh format and very unfriendly with modern OpenGL rendering. It did fulfil its role in the days of immediate mode drawing and limited memory, but for indexed, buffer-base rendering it does not work very well. The only solution I know around this issue is to rearrange the OBJ data into an indexed set of interleaved vertexes, thus repeating a few vertexes if necessary. \$\endgroup\$ – glampert Apr 21 '14 at 21:27
  • \$\begingroup\$ The only reason I chose OBJ is because it's the only format supported by all modelers. \$\endgroup\$ – Jordan LaPrise Apr 21 '14 at 21:36
  • \$\begingroup\$ Sure, I'm not judging your choice, just pointing out that it is really an outdated format. But indeed loadable and editable everywhere. That said, the Collada format is probably just as accepted and much more modern. You might want to take a look: collada.org \$\endgroup\$ – glampert Apr 21 '14 at 21:49
  • \$\begingroup\$ I'm looking more for something that I can write a loader for myself, I'm doing this for a school project. \$\endgroup\$ – Jordan LaPrise Apr 22 '14 at 17:30
1
\$\begingroup\$

You need to reindex the mesh, something like this:

std::vector<Vector3> positions;
std::vector<int> positionIndices;
std::vector<Vector3> normals;
std::vector<int> normalIndices;

std::vector<Vertex> verts;
std::vector<int> newindices;
for(int i = 0; i < positionIndices.size(); i++)
{
    Vertex v;
    v.pos = positions[positionIndices[i]];
    v.normal = normals[normalIndices[i]];

    auto ipos = verts.begin();
    for(; ipos != verts.end(); ++ipos)
    {
        if(memcmp(&v, &(*ipos), sizeof(v)) == 0)
            break;
    }

    if(ipos == verts.end())
        ipos = verts.insert(ipos, v);

    newindices.push_back((int)std::distance(verts.begin(), ipos));
}

I usually do this offline to avoid doing it for every mesh at startup. But if you don't have that many faces it doesn't really matter.

\$\endgroup\$

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.