4
\$\begingroup\$

I have a custom file format that has all the needed information for a 3D mesh (exported from 3ds Max). I've extracted the data for vertices, vertex indices and normals.

I pass to OpenGL the vertex data, vertex indices and normals data and I render the mesh with a call to glDrawElements(GL_TRIANGLES,...)

Everything looks right but the normals. The problem is that the normals have different indices. And because OpenGL can use only one index buffer, it uses that index buffer for both the vertices and the normals.

I would be really grateful if you could suggest me how to go about that problem.

Important thing to note is that the vertex/normal data is not "sorted" and therefore I am unable to use the functionality of glDrawArrays(GL_TRIANGLES,...) - the mesh doesn't render correctly.

Is there a way/algorithm that I can use to sort the data so the mesh can be drawn correctly with glDrawArrays(GL_TRIANGLES,..) ? But even if there is an algorithm, there is one more problem - I will have to duplicate some vertices (because my vertex buffer consists of unique vertices - for example if you have cube my buffer will only have 8 vertices) and I am not sure how to do that.

\$\endgroup\$
2
  • \$\begingroup\$ related gamedev.stackexchange.com/questions/66401/… \$\endgroup\$
    – concept3d
    Apr 28, 2014 at 19:16
  • \$\begingroup\$ AFAIK you will have to duplicate some vertexes and store the data in a structured (interleaved) format. This is the optimal format for the GPU anyways. It is very cache efficient since the GPU works with all the attributes of a vertex when it is processing one. So it makes sense to keep them together. \$\endgroup\$
    – glampert
    Apr 28, 2014 at 21:29

2 Answers 2

4
\$\begingroup\$

Unfortunately there is no way to do this. What you'll need to do is duplicate the data in places:

TexCoords: 
    1: 0.67, 0.54
Vertices:
    1: 14.65, 24.09, 87.65
    2: 54.76, 34.78, 17.52

Where both these use texture coordinate 1, we need to copy texture coordinate 1 so there are two instances to it. We'll end up with:

Final Vertex Data:
    1: V 14.65, 24.09, 87.65, T 0.67, 0.54
    2: V 54.76, 34.78, 17.52, T 0.67, 0.54

Of course this is a waste of memory, but it saves jumping around in memory a lot, so we save a bit of time. Of course there will be situations where you find EXACTLY the same final vertex( same position, same texture coordinate, same normal etc ). In this case you'll want to index rather than copy it. This will save you A LOT of space.

\$\endgroup\$
1
\$\begingroup\$

I managed to do it without passing index buffer to OpenGL with glDrawArrays(GL_TRIANGLES,..) What I did is the following: Fill a vertex array, vertex indices array, normals array and normals indices array. Then I created new vertex and normal arrays with sorted data and passed them to OpenGL.

for i = 0; i < vertexIndices.size(); ++i
    newVertexArray[i] = oldVertexArray[vertexIndices[i]];

for i = 0; i < normalsIndices.size(); ++i
    newNormalsArray[i] = oldNormalsArray[normalsIndices[i]];

I optimized it a bit, without filling indices arrays at all. But the optimization depends on the way the programmer is reading the mesh data.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .