Advertisement

Vertex Arrays Question

Started by January 30, 2004 03:25 PM
6 comments, last by snisarenko 21 years, 1 month ago
I wanted to ask how do you use vertex arrays to speed up rendering with out dynamic memory allocation (which as i assume takes up a lot of time) while using octree subdivision or whatever ? What I mean is that each frame you cull you octree and extract the nodes that are visible, right ?. So every frame there are different nodes with different polygons in them, and the total amouont of polygons to be rendered is different every frame. But vertex arrays need a pointer to an already predfined array. So in order to push all the currently visible polygons into a vertex array each frame you need to recreate an array every frame, right? Which means dynamic memory allocation, right ? (This is a simple case, I am not even talking about sorting your vertex data per state, like texture, or material) This problem could be partially resolved if vetex arrays supported passing an array of pointers to data (vetecies, tex. coordinates etc.), and not arrays of actual data, right ? (meaning that you dont have to copy data out every octree node into a new array, but just assign pointers to it) But they don't!! (i am wondering why ?) So how do you people do it ? How is it done in proffesional games ? Is there some sort of algorithm ? One way that i guessed was to load all the vertex data into one big vertex array, or several big vertex arrays, and then in the octree nodes just store the indicies. So instead of recreating an array of vertex data every frame, you just build a current array of indicies and pass it to glDrawElements. But building an array of current indicies still requires dynamic memory allocation every frame, Since the amount of indicies each frame is going to be different. But since indicies take up less memory than all of the vertex data, i am guessing that recreating an indicies array is faster than recreating a whole vertex array, right ? But still, is there any way to avoid dynamic memory allocation during actuall frames? Or is it impossible and u should just minimize the dynamic memory allocation ? _____________________________________________________ P.S. Sorry for long post. I hope it makes sense. [edited by - snisarenko on January 30, 2004 4:30:22 PM]
The way to do it is have you level made out of geometry ''chunks'' you could have one of these chunks for each octree leaf, or something. So when you''re loading the level each chunk gets it''s own array and when you do the rendering you transverse the octree get a list of chunks that are within the view frustum and then render each of those vertex arrays individually. So you only have to do dynamic memory allocation when you load the level.
Advertisement
Here''s how most basic octree based rendering engines work:

Each octree node has an array of vertices for the static geometry that''s in it (walls, trees, sewers, alien space goo from the planet Laxx; whatever).

When you decide a node is visible, you draw that vertex array.

Each node also has a list of all the movable objects that are within it.

Each object has an array of ITS vertices.

When you decide a node is is visible, you also draw the arrays for each of the objects.

This means you specify and draw more than one array per frame. That''s fine. You can get 100 fps drawing 100 arrays per frame. You''re more likely to be fill bound than geometry bound.

enum Bool { True, False, FileNotFound };
you can always just do either:

make a dynamic index array each frame. You still keep the vertex data arrays as is.

Or, simply use chunks like mentioned, and draw ranges of a single index array.

Both methods have their pros and cons and will be faster/slower depending on the hardware (eg, the second will be faster on a radeon 9500 but the first will be faster on a radeon 8500)

both are prefectly fine approaches to take.

[edit]

an even better option would be to use the draw multi arrays extension to combine the best of both.

| - My (new) little website - | - email me - |
Ok i got it. Thanks for explaining.

What about Occlusion culing? After Occlusion culing some polygons in visible nodes wont be visible ? so do u have to use indicies then ?


Also I have this idea for optimizing. Please tell me if it would work. Each polygon can have a different state like texture, or material. And a vertex array can only be rendered with one state of each type at a time. Of course you sort your polygons in each octree node so that you have all the polys that use a certain texture in one array "chunk", and polies that use another texture in another "chunk". What i though of optimizing was to check in each node the most used textures and put them next to each other on a bigger texture(of course not going over max texture size) during loading so u have less arrays. Would that be a good optimization ?

- RipTorn "an even better option would be to use the draw multi arrays extension to combine the best of both."

never heard of multi array extension. maybe u could give me some link with info ?

[edited by - snisarenko on January 31, 2004 1:17:35 AM]
You just don''t render nodes or objects that you can prove are completely culled. You do render nodes that are not proven culled (i e, might be visible). It''s more expensive to try and separate out the triangles that are visible, than just throwing them all at the card.

Note that building index lists or vertex arrays (rather than just referencing them) each frame will use a lot of CPU and memory bandwidth, so if you''re planning on using your CPU for other things, creating anything dynamically is going to make you slower on (almost) any card -- especially the really fast cards, where the CPU/memory system already has problems keeping up!
enum Bool { True, False, FileNotFound };
Advertisement
Putting multiple textures into one big texture is known as "texture sheeting". This is pretty much a must on consoles with little texture memory (like the PS/2).

Note that filtering at the edge of textures is going to be troublesome, as will MIP mapping, because of bleeding. You also can''t do wrap this way; you have to break your geometry along [0,1] texture coordinate boundaries.

I''ve found that once you stop to change state (such as modelview matrix), binding a new texture really doesn''t cost much anymore, assuming there''s enough memory on the card. I''d actually try to get front-to-back draw order, more than worrying about texture switches.
enum Bool { True, False, FileNotFound };
quote:
Original post by hplus0603
Putting multiple textures into one big texture is known as "texture sheeting". This is pretty much a must on consoles with little texture memory (like the PS/2).

Note that filtering at the edge of textures is going to be troublesome, as will MIP mapping, because of bleeding. You also can't do wrap this way; you have to break your geometry along [0,1] texture coordinate boundaries.

I've found that once you stop to change state (such as modelview matrix), binding a new texture really doesn't cost much anymore, assuming there's enough memory on the card. I'd actually try to get front-to-back draw order, more than worrying about texture switches.



->hplus0603

by front to back order, you mean front to back order of nodes in octree, right ?


P.S. sorry for not asking earlier





[edited by - snisarenko on February 5, 2004 1:51:29 AM]

This topic is closed to new replies.

Advertisement