Using a different array for vertices and normals in glDrawElements (OpenGL / VBOs)

I am currently programming a .obj loader in OpenGL. I store vertex data in VBO and then bind it using Vertex attributes. The same goes for normals. The thing is, normal data and vertex data are not stored in the same order.

The indexes that I give glDrawElements for rendering the mesh are used, I suppose, by OpenGL to get the vertices at the top of the VBO and get the normals in the VBO normals.

Is there an opengl way besides using glBegin / glVertex / glNormal / glEnd to tell glDrawElements to use an index for vertices and another index for normals? Thanks

+7
source share
3 answers

There is no direct way to do this, although you can simulate it by indexing into the buffer texture (OpenGL 3.1 function) inside the shader.

This is generally not recommended. The OBJ format allows one normal link to refer to several (in principle, any number) vertices at a time, so the usual thing is to build a "full" vertex, including the coordinates and normal and texcords for each vertex (duplication of the corresponding data).

This ensures that a) the smooth shaded surfaces display correctly
b) correct cutting edges

(the difference between them is only in a few vertices that have the same value)

+7
source

You should use the same index for position coordinates / normals / textures, etc. This means that when loading .obj you must insert unique vertices and point your faces at them.

+2
source

OpenGL treats the vertex as one long vector

(position, normal, texcoord[0]…texcoord[n], attrib[0]…attrib[n]) 

and these long vectors are indexed. Your question falls into the same category as using shared vertices with multiple normals. And the canonical answer is that these peaks are not actually separated, because in the long run they are not identical.

So, you need to iterate over the array of face indices and build the β€œlong” vertices by adding them to the (new) list with uniquenes constraint; a (hash map) from the top -> index serves this task. Something like that

 next_uniq_index = 0 for f in faces: for i in f.indices: vpos = vertices[i.vertex] norm = normals[i.normal] texc = texcoords[i.texcoord] vert = tuple(vpos, norm, texc) key if uniq_vertices.has_key(key): uniq_faces_indices.append(uniq_vertices[key].index) else: uniq_vertices[key] = {vertex = key, index = next_uniq_index} next_uniq_index = next_uniq_index + 1 
+2
source

All Articles