0
\$\begingroup\$

Recently, I've been trying to use COLLADA files in OpenGL. The problem that a lot of people before me have run into is COLLADA's indice structure. It has multiple sets of indices, the first is for position, the second for the normal. I know by now that it is completely impossible for OpenGL to use multiple sets of indices, so I must rearrange my normals so that I can use my position indices for my normals.

I've already made some code for this, but it doesn't seem to turn out right.

private static Vector3[] RearrangeNormals(Vector3[] norms, Vector3[] pos, int[] posindices, int[] normindices)
{
    Vector3[] newnorms = new Vector3[norms.Length] ;
    for (var i = 0; i < norms.Length; i++)
    {
            newnorms[posindices[i]] = norms[normindices[i]];
    }
    return newnorms;
}

With this function, it seems like half of my Suzanne mesh has it's normals correct, the other half... not so much. Here's an image of what I'm getting with my lighting test.A Suzanne mesh with weird normals, the white means they're correct, while black is a normal of Vector3.Zero

How should I handle rearranging my normals (or texcoords maybe in the future)?

\$\endgroup\$
1
  • \$\begingroup\$ The pos argument is unused. \$\endgroup\$
    – Pharap
    Commented Apr 25, 2017 at 7:04

2 Answers 2

1
\$\begingroup\$

You are assuming that the number of normals and number of positions is the same. This may not be true.

If there are more positions than normals, then you are accessing newnorms out of bounds.

Before fixing this you need to make a choice. Do you:

  1. Want to draw non-indexed.
  2. Want to draw indexed.

In case of 1, you simply generate non-indexed data by looking up the norm/pos before feeding it to OpenGL.

In case of 2, you would need to first determine all unique pos+norm values, before you can assign an index to it.

The first option is easier, and would mean using glDrawArrays, not glDrawElements. Some people argue that indexed primitives can be faster, but personally, I have found it not worth the extra effort.

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

Here's an answer that works for me, although doesn't directly answer the question.

Ready? (Drum roll)

Use .X3D

This format is actually really great. Unlike COLLADA, you can edit the up axis in Blender so that it is exported as Y-Up, it only has one set of indices and all the data for a single mesh is stored in one child (including the materials).

I was actually quite surprised at the fact that not a lot of people are using this, even though it seems like it was made for OpenGL!

\$\endgroup\$

You must log in to answer this question.