I've created an OpenGL ES app based on the simplecube demo in the symbian 60 examples. One thing that has struck me is the apparent inability of opengl to reuse vertex data when different normals or texture coordinates are required for each vertex.
- for a cube each of the 8 vertex's shares exactly 3 faces (6 triangles)
- this poses a problem if you want flat shaded (not averaged) lighting to the sides of the cube
- glDrawElements expects exactly the same number of normals and texcoords as vertices in the lists
- this means you can't have 3 normals (one for each face) per vertex unless you copy each vertex 3 times
- this creates a vertex list 3 times as big (trivial for a cube but not for bigger objects)
Ideally (I've done this in my software only renderer in the past) each polygons vertex would be a structure with seperate indexes for the vertex list, the normal list and the texcoord list. Then you could reuse normals and texture coords without duplicating vertex points. This list of vertex structures can be passed to an equivalent of the glDrawElements call.
int v1, v2, v3; //index into the vertex array
int n; //index into the normal array
int u, v; //index into the textcoord array
TTriangle *triangles; //list of objects triangles
In terms of efficiency, if you create duplicate vertex's so that you can have unique normals and texcoords this obviously increases memory usage and bandwidth, but also means that OpenGL is transforming and clipping 3 times as many vertex's than needed. Also on large objects it would allow normals to be reused.
The most effecient method would be to send 8 vertices, 24 normals, 24 texcoords and 12 triangle index structs, instead of 24 vertices, 24 normals, 24 texcoords and 12 triangle index triplets.
Is there a way round this duplication of data to keep a minimal vertex, normal and texcoord list while still using the vertex array calls like (glDrawEllements etc)?
Thanks for your advice,