Jump to content
  • Advertisement
Sign in to follow this  
James Trotter

Static meshes and spatial partitioning...

This topic is 5413 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm in the design phase of creating a renderer for my engine. A large amount of the game world will be composed of static meshes. I'm going to use a spatial-partitioning techinque with an own (quad- or oct-)tree for static geometry. This is all static so it would be stored in a file, and the tree hierarchy would be loaded upon game initialization. My problem is that I'm not sure about where to store the geometry information. 1) I could store both vertices and indices in the leaf nodes of the tree. 2) Vertices could be stored in a large pool, while only indices are stored in the leaf nodes of the tree. 3) This is just an idea that occured to me just now... You could use several node types in the tree, for instance one node containing vertex indices, another type containing the vertex data (vertices, normals, texture coordinates, etc.). That way when you traverse the tree, and reach a vertex-data node, you would bind the VBOs for those nodes. When you reach the index-data node (leaf node), you'd render the indices using the VBO data that was bound at the level above in the tree. I guess that in the third case, you could also sort them all easily by shader/material as well. Does anyone have any recommendations, or suggestions?

Share this post


Link to post
Share on other sites
Advertisement
4) Dont work with vertices on a leaf basis, but rather objects that contain the vertex indices (less overhead).

Share this post


Link to post
Share on other sites
Quote:
Original post by X-0ut
4) Dont work with vertices on a leaf basis, but rather objects that contain the vertex indices (less overhead).


that depends on the scale of you leaf nodes

if the geometry is complex enough the arrays would be large enough and probably too large for a single VBO

i have read some threads where people complaint about slow downs when rendering too small or too large VBOs

use indexed interleaved arrays as discussed in here
and stick with the 32 bytes on agp environments as suggested by _phantom_

http://www.gamedev.net/community/forums/topic.asp?topic_id=272287

Share this post


Link to post
Share on other sites

Just my small tip: its always good to sort the vertices with respect to the textures - this way you can render at big collection of triangles with the same texture ... and modern cards are really fast at drawing many triangles in on go.

1)
bind texture 1 -> render 30 primes
bind texture 2 -> render 10 primes
bind texture 1 -> render 40 primes

2)
bind texture 1 -> render 70 primes
bind texture 2 -> render 10 primes

I would go for number 2)
Good luck :)









Share this post


Link to post
Share on other sites
and since you have to sort by texture you often won t be able to avoid passing mesh data to the card

so if you have a mesh with 5 textures and one huge stack as a interleaved array what is faster?
5 small stacks and a single texture bound or several texture switches and only passing a huge stack of geometry data to the card?

id say the 5 small stacks are faster as long your leave if your partition tree isn t too small and thus the small stack is really tiny this would result in a function call overhead sooner or later

Share this post


Link to post
Share on other sites
Quote:
Original post by X-0ut
4) Dont work with vertices on a leaf basis, but rather objects that contain the vertex indices (less overhead).


I suppose you mean, only store a pointer to a VBO object rather than directly storing a list of indices in an array. That makes sense. I'd have a class that wraps around OpenGLs interface to VBOs.


Quote:
Original post by Mille
Just my small tip: its always good to sort the vertices with respect to the textures - this way you can render at big collection of triangles with the same texture ... and modern cards are really fast at drawing many triangles in on go.

1)
bind texture 1 -> render 30 primes
bind texture 2 -> render 10 primes
bind texture 1 -> render 40 primes

2)
bind texture 1 -> render 70 primes
bind texture 2 -> render 10 primes

I would go for number 2)
Good luck :)


Yes, naturally that's the way you'd have to go about it. But IMO, this is inherent in the third approach. Let me show you a diagram:


Root node
/ \\
/ \\
Material 1 Material 2
| | \\
| | \\
Vertex pool 1 Vertex pool 2 Vertex pool 3
| | |
| | |
Index data 1 Index data 2 Index data 3


(Sorry for the crappy ASCII diagram)...

Anyway, here you can clearly see what I'm thinking. This would be simple for the renderer to traverse, and would also avoid unnecessary state changes.

Spatial partitioning could be introduced either in the same tree, or use just have a pointer to a tree structure like this in each leaf node of the spatial partitioning tree...

Quote:
Original post by Basiror
and since you have to sort by texture you often won t be able to avoid passing mesh data to the card

so if you have a mesh with 5 textures and one huge stack as a interleaved array what is faster?
5 small stacks and a single texture bound or several texture switches and only passing a huge stack of geometry data to the card?

id say the 5 small stacks are faster as long your leave if your partition tree isn t too small and thus the small stack is really tiny this would result in a function call overhead sooner or later


What do you mean by "you won't often be able to avoid passing mesh data to the card"? I don't understand...

If you have five textures associated with a mesh, you're going to have to bind each of the textures at some stage anyway, it's just best to make sure that you don't bind each texture more than once. Sorting your triangles by texture/material is important.

Yes, it's inefficient to render several small VBOs/vertex arrays... And it's also expensive to swap texturs. So, it's really dependent upon what exactly you will be rendering.

[Edit]Fixed diagram.[/Edit]

Share this post


Link to post
Share on other sites

Not sure if I'm helping here, but I assume you have one big vertex buffer, and for each vertex Pool, in your nice ASCII drawing, you should have an instance of the following:

struct tMeshPool
{
int vertexStart;
int indexStart;
:
int noPrimes;
int materialID;
};

where the vertexStart and indexStart are just index into the vertex-index buffers.

To start with, you could ignore the index buffer and just try getting DrawPrimitive(D3DPT_TRIANGLELIST, vertexStart, noPrimest) to work.









Share this post


Link to post
Share on other sites
well so id go for sorting by textures at first since with increasing polygon detail the bottleneck of function call over head loses importance


and you can still implement a gfx card specific implementation that creates a VBO out of several small meshes at loading time

Share this post


Link to post
Share on other sites
First of all, unless you're using Direct3D, there is no need to use a single vertex buffer for all static geometry and even then I don't know how useful that is although I'm no D3D expert. Secondly, any aproach that requires you to sort triangles or vertices is broken and slow. Store a geometry chunk object in each leaf. This should contain a pointer to what index and vertex buffer to use and what material/shader setup to use. Essentially, one of these chunks is a bunch of triangles (at least 100 or so for decent performance but more is better, although more than 2000 tris per chunk is probably overkill)that can be drawn in a single draw call and that has a single material/shader. Once you have a list of potentially visible chunks you can sort the chunks based on the material/shader ID and render away.

Share this post


Link to post
Share on other sites
i structure it a follows

CMeshlist(/*contains a list if meshes each with a different texture and shader*/)
CMesh(/*each mesh has a vertex normal and uv array a texture and a shader, you can combine the vertex normal uv array to interleaved arrays+ it fits into the 32 byte AGP thing*/)


don t know how go this will work in complex scenes, but when i create a list of meshes that are visible i test against the meshlist and sort the meshes by texture


each leave has a meshlist


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!