What's best used for temporarily static geometry?

I’m writing a 3D engine that supports both Direct3D and OpenGL. It displays wide-open areas, and although the LOD means some geometry changes and needs to be updated often, geometry far away will be low-detail most of the time - in other words, as you get closer to the camera, the odds of the detail level of that geometry changing on any given frame increase dramatically.

I take advantage of that with D3D by using static buffers for stuff that’s far away and dynamic buffers for stuff that’s close-up. It resulted in a big framerate increase (compared to using all dynamic buffers).

But I still need to add that to the OpenGL code. Currently I use glDrawElements() for everything. What do I use for static geometry: display lists or compiled vertex arrays? Keeping in mind nothing stays static forever, so the arrays will be changed sometimes…

What about putting all the vertices on static buffers such as the video memory. And then only modify the indices buffer when geometry changes.

Of course this only works if all the LOD versions use the same vertices.

The only way of hinting to OpenGL that something is “static” is to put it in display lists. Unless you use the vertex array object extension, which has explicit dynamic/static hints.

Compiled vertex arrays are only valid for the duration of one or a few sequential DrawElements() calls; it’s not useful as a retention mechanism across multiple object invocations (and even less so inter-frame).

GPSnoopy, besides being a waste of memory, putting all vertices in static buffers is impossible for me because the vertices often change normals and positions. For example, when a heightmap triangle changes to its two subtriangles, the subtriangles are coplanar with the parent, and then expand outwards.

jwatte: What are the vertex array objects you’re referring to? And display lists require me to use glVertex instead of DrawElements, is it still worth it? Keeping in mind I will be updating the static geometry once in a while.

Display lists will compile vertex arrays just fine; they copy all the data in the vertex array at the time of compilation. In fact, using vertex arrays to build a display list, and submitting with DrawRangeElement, is the preferred method to build display lists.

From MSDN documentation:

You cannot include glVertexPointer in display lists.

[This message has been edited by Humus (edited 10-21-2002).]

Look, we have been over this like a hundred times. You can use vertex arrays and display lists together just fine, it’s just that the arrays are dereferenced at display list compilation, not rendering. If vertexpointer is valid or not inside a display list has no effect on this.

We have? Must have missed those hundred times , just remembered this line from the msdn doc.

Well, I have been over it a hundred times Anyway, it’s obvious how this works if you look it up in the spec, it’s pretty clear if you ask me. The MSDN is pretty confusing when it comes to OpenGL in my experience.

Well, I suppose one learns something new each day. Odd that I’ve been completely unaware of this behaviour despite several years of OpenGL coding. And yes, doing a quick search it turns out it has been discussed several times before on this board too.

Well that’s good news for me. Of course it makes sense the pointers are evaluated at compilation, since they need to be uploaded to VRAM.

> glVertexPointer

You are correct that glVertexPointer (and other client state) is not compiled into display lists.

glDrawElements() and friends, however, is compiled into display lists.

The reference for OpenGL, by the way, is in a PDF downloadable from this site; it’s NOT MSDN (believe it or not :slight_smile:

Last, I think you should be careful about assuming anything gets “uploaded to VRAM”. It’s not the case that anything that conceptually gets transfered to “server side” in OpenGL automatically gets “uploaded to VRAM”.

Ah, but that’s confusing, jwatte. What really happens is, when you call glVertexPointer inside a glNewList block, it executes immediately, assigning the current vertex pointer to what you’ve passed to the function. Then, when you call glDrawElements (still within the list block) it compiles the current vertex pointer into the list.

So the only difference it makes is that you can call glVertexPointer before glNewList and it will still get compiled into the list. But by saying “glVertexPointer is not compiled into lists” without elaborating, you make it sound as if vertex arrays can’t be used in lists!

> it compiles the current vertex pointer
> into the list

No, it does not compile the vertex pointer into the list. It compiles the data that the pointer points at into the list.

> you make it sound as if vertex arrays
> can’t be used in lists

I’m sorry if what you’re hearing is not what I’m saying.

Originally posted by jwatte:
The reference for OpenGL, by the way, is in a PDF downloadable from this site; it’s NOT MSDN (believe it or not :slight_smile:

Bah! It’s so much quicker to just hit F1