简体   繁体   中英

Indicies, glDrawElements and/or other methods of drawing big vertex arrays

I am trying to display an isosurface, built using a marching cubes algorithm, which, I suppose, produces a set of triangles. I a complete amateur in graphics programming, however, and I am struggling with understanding the few methods of effectively drawing them.

What I had in mind is to draw it all in a one call using something like glVertexPointer-glDrawElement construction. The latter, though, requires me to know the indices, and I clearly do not know them. Furthermore, I am actually not exactly sure of their purpose: I think that they are a merely a, duh, indexes, the order in which the driver will use them and also a way to save up memory by excluding the same vertex appearing multiple times.

So, is my vision of indices' purpose correct and what is the correct way to solve my problem?

If you want to draw a big thing with one call, you do it by providing the drawing function 2 things:

The vertex array

Which is an array of, you guessed it, vertices. Co-ordinates in 3D space. They don't have to be in any particular order.

The index array

Which is an array of indices in the vertex array. This array tells your driver the order of the vertexes (what connects with what).

You should upload all vertices, and then turn them in to triangles in the index array.

If you don't have a need for indices, then... don't use indices! Yes, they can be used to make rendering more efficient if the same vertex is used multiple times. But they are entirely optional.

The draw call you use when rendering without indices is glDrawArrays() . This will use the vertices in your vertex buffer in their natural order, based on the primitive type passed to the draw call. For example, with GL_TRIANGLES , it will draw a triangle with vertices at positions (0, 1, 2) in the buffer, a triangle with vertices (3, 4, 5), etc.

So in your isosurface algorithm, you can simply calculate the 3 vertices every time you generate a triangle, and append them to a list of vertices you end up storing in the vertex buffer. Then draw the whole thing with glDrawArrays(GL_TRIANGLES, ...) , and that's all there is.

Now, in a mesh that covers a surface, the same vertex is shared by an average of approximately 6 triangles (look at a regular mesh to see how this number is derived). So if you generate the vertices separately for each triangle, you'll have the same vertex approximately 6 times, resulting in a substantial amount of unnecessary memory use, and time for vertex processing.

This is where indices come in. One approach you can use is that, for each edge of the grid, you track if an isosurface vertex on the edge was already created, and store its index if it was. Then, anytime you need a vertex for a grid edge while generating your triangles, you create a new vertex (with a new index) if the edge does not have a vertex yet, or use the index of the already created vertex. Then you store the resulting index sequence in an index buffer, and draw with glDrawElements(GL_TRIANGLES, ...) .

A minor variation of the above is that you loop over all mesh edges first, calculate all vertices for edges that intersect the isosurface, and again store the vertex index for each of those edges. Then, when you iterate over the mesh cubes to generate the triangles, you can simply grab the vertex index from each of its intersecting edges.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM