开发者

What does glDrawElements() expect the normals array to contain?

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 开发者_如何学Pythonright? Thanks for reading.


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);


What you describe sounds like MilkShape3D gives you per-face normals. OpenGL expects per-vertex normals.

So you need to process your data to generate per-vertex from per-face. There's a lot of literature on the web for this, one hit on Google gives this.


I was indeed messing up the order of the normals.

A MilkShape 3D model file structure can be approximated as:

  1. vertex list, float[3]
  2. vertex index list as short[3] for the triangles + 3 normals as float[3] each

You 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜