OpenGL: efficient way to render a batch of geometry?

☆樱花仙子☆ 提交于 2019-12-03 06:57:29

问题


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.


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/487244/opengl-efficient-way-to-render-a-batch-of-geometry

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!