tags:

views:

1945

answers:

2

This is something I've been looking into for while, but I have yet to find any concrete information or good examples. I have, say, a bunch of unconnected objects (triangle strips for instance). What is the efficient way to render these?

I've heard about putting several objects in one VBO to reduce openGL calls, but have not seen a proper example of how to do this. I've also seen posts that contradict this idea. So right now, I'm mostly just confused.

A: 

Look into glDrawElements(), it is one good way of achieving what you want. Note that performance might drop if your data changes each frame, since you then need to update the relevant portions of the data, which means copy them to the graphics card's memory. For static data, this is very fast.

unwind
+4  A: 

First off, you should probably use VBO all the time. For small and large objects.

Then, the second issue is "how to combine several separate objects into one large object?" - so to reduce the number of OpenGL calls that have to be made. Generally, objects that use the same texture(s), material settings and shaders can be combined. E.g. if you have tons of identical crates lying around, it might make sense to combine them into several larger "crate piles".

If an object is a triangle list, then combining is easy - just create a large triangle list out of the source lists. If an object is a triangle strip, then you have to use "degenerate triangles" to join the strips (this is a very useful optimization for a single object as well, if it can't be represented as a single strip).

A "degenerate triangle" is a triangle that has two or three identical vertex indices. Graphics hardware can recognize them and skip them very fast.

So if you have, e.g. two strips with one triangle each, for a total of six vertices.

The original triangle indices of the strips would be:

1) 0, 1, 2
2) 0, 1, 2

Now you join all vertices together, so you end up with 6 vertices.

1) 0, 1, 2 (unchanged)
2) 3, 4, 5

By now you have one vertex array, but still two separate strips. Have to join them by inserting degenerate triangles:

1) 0, 1, 2, 2, 2, 3, 4, 5

(I think the above is correct, but haven't actually verified)

The idea is this: with the above strip, the graphics card would draw triangles out of these vertices:

0, 1, 2
1, 2, 2 <- degenerate! won't be drawn
2, 2, 2 <- degenerate! won't be drawn
2, 2, 3 <- degenerate! won't be drawn
3, 4, 5

In general case, you either have to insert two or three degenerate triangles based on the original strip length, so that triangle winding remains correct.

NeARAZ
Why can't you just compile a display list that uses GL_TRIANGLE_STRIP ?
aib
@aib: because you can never be sure *what* compiling a display list does. Display lists are deprecated in OpenGL 3.0, and don't exist on most other platforms (D3D, OpenGL ES, console APIs, ...). They just don't map well to the hardware.
NeARAZ
Shouldn't that be 0 1 2 [2 2 3] 3 4 5?Drawn as 0 1 2, [2 1 2, 2 2 2, 2 2 3, 3 2 3, 3 3 4,] 3 4 5?
eplawless