Question about vertex array transformation handling...

Id like to know the best way to deal with vertex arrays when doing LOD.

Basically I am rendering many seperate surfaces, and each surface is made from a 9*9 grid of vertices.

I have 4 levels of LOD that skip the approriate vertices ie


At the moment I am storing 4 seperate arrays of vertices for each surface, because I am assuming that if I pass the largest array all the time, it will transform all the vertices even if I am only indexing a few of them.

Basically my question is, are the vertex transformations defined by the contents of the vertex array, or by what is indexed?

And does locking the arrays have any affect on this?


Transformations are only done on sent vertices.
If you don’t send a vertex to the OpenGL server, it won’t be transformed.

In other words: you can regroup your 4 vertex arrays in one, only the vertices you send via the indices will be transformed.

Yay, thanks…

Thats what I was hoping for…


It’s of course not QUITE that simple.

If you use DrawRangeElements() or LockArraysEXT() then the implementation may do “something” to all of the verts. If it’s a soft transform card, it’ll probably transform them all. If it’s hardware, it’ll probably copy the vertices out of your array and into some AGP buffer. Typically, doing these things is a win.

To make sure that you get as good effect as possible out of either of these extensions, you should order your verts so that vertex 0-3 are the ones needed for the 2x2 array, 4-8 are the ones you add for the 3x3 array, 9-24 are the ones you add for the 5x5 array, and 25-80 are finally the ones that are only drawn in the 9x9 array. Make sure your index arrays match this arrangement :slight_smile:

Then when you either LockArrays or DrawRangeElements, just lock/specify the appropriate number of vertices for what LOD you’re drawing, and you should run as fast as possible on most implementations.

If you’re using physically different vertices for the different LODs (no sharing) then this of course won’t work.

Also, your biggest blocks (9x9 verts) aren’t that many verts (81 verts, 128 triangles) so you’re probably not going to be able to pump quite the full capacity of modern HT&L cards. And when drawing those 2x2 (and 3x3) vert arrays, overhead from setting up the block is probably going to be way bigger than the cost of transforming those verts. So you might want to look into making 5x5 your lowest lod, 9x9 the next, 17x17 the next and 33x33 the highest (of course, depending on your target hardware and detail needs).


I was kind of worried that there would be issues like this.

I am using drawrangeelements and vertex sharing, so Ill pack my array as you suggest.

The reason for the small number of vertices, is because my scene is made up of hundreds of these surfaces. Its annoying but at the moment Im uploading about 200 different sets of vertex data per frame, which I presume is ‘a bad thing’.

200 * 81 is only 16200. If you’re on HT&L hardware, and ideally if you can use VertexArrayRange, then that shouldn’t be much of a problem. Of course, if you change texture and modelview matrix 200 times, too, then that’s probably something that could be optimized. For example, it might turn out that it’s faster to offset all your vertices and generate an index list in software to submit a larger block, if you can get good overlap with the GPU while doing that and don’t need the CPU for other things.

Anyway, good luck to you!

I am changing texture state for each surface (doh), but thats easy enough to fix.

Anyway… thanks for the help.