Reputation: 780
I'm writing a decoder for MilkShape 3D models.
I load the contents to a vertex array and a face index array (as std::vector
), then use glDrawElements()
to render it, so far so good.
But the problem is with the normals array. In what order does OpenGL expect the normals? The MilkShape 3D file contains three float[3]
normals which are the same, following the face (triangle) indices. But if I simply push_back()
what I read into the normals array, OpenGL won't apply lighting correctly.
So I think I'm messing up the order. How to do it right? Thanks for reading.
Upvotes: 1
Views: 1924
Reputation: 780
I was indeed messing up the order of the normals.
A MilkShape 3D model file structure can be approximated as:
float[3]
short[3]
for the triangles + 3 normals as float[3]
eachYou need to load the normals at normals[currentFace.index123]
. In plain English, the normals' indices from the normals
array must correspond to the vertex indices from the vertices
array.
Upvotes: 0
Reputation: 162367
OpenGL assumes the normals being indexed the very same like the vertex positions. One must understand, that a vertex itself is a vector of attribute vectors, or in other words a vector of all the attribute values (position, normal, colour, texture coordinate(s), etc.). The glDrawElements index array addresses the array of vertices, where each vertex is such a higher dimensional vector.
Now what could happen is, that Milkshape mixes the face winding and gives you normals of which some have been flipped into the opposite direction (inwards instead of outwards). I don't know about how it's done in Milkshape, but in Blender there is a function "Recalculate Normals" (accessed by CTRL+N hotkey), that fixes this.
If you don't want to fix the normals, you must enable double sided lighting (this has a performance impact).
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
Upvotes: 1