Sign in to follow this  
DuckWizard

Index Buffering

Recommended Posts

I'm drawing a terrain (for now, let's say 128x128 vertices). I have a vertex buffer of the 128x128 vertices, and I'm using an index buffer to create a triangle list with each corner of each triangle indexing into the single vertex buffer (so right now I have 128*128*6 indices). This is working fine by drawing the entire terrain at once using a DrawIndexedPrimitive call. However, I am trying to optimize by having a list of 16x16 vertex patches, and drawing only the patches that are visible. I have an index buffer for each patch that contains the 16*16*6 indices into the single vertex buffer. I tested this out by drawing two patches. It works fine in that I can see the patches and they render flawlessly. However, I've found that the framerate is staggeringly higher when I render the whole terrain at once than it is when I render only these two 16x16 patches! I'm not really sure why this is, but I suspect it's because my DrawIndexedPrimitive call still passes 128*128 for numVertices. However, if I use 16*16 for numVertices, I get an error that the indices are illegal. Even setting minVertexIndex to the first vertex of the patch doesn't help alleviate this error. I suppose I could rework the code to create a vertex buffer for each patch instead of trying to index into the single master VB. But it seems like there should be a way to get it to index into the main VB without slowing down so much. In fact, I ran a test, and it is only a few FPS slower to draw the entire terrain TWICE than it is to just draw those two patches! What's a coder to do? Thanks for any tips you can give me!

Share this post


Link to post
Share on other sites
Here is the code I am using to draw a single patch:


//this->terrainVB is a vertex buffer of 128*128 vertices
pD3DDevice->SetStreamSource(0, this->terrainVB, 0, sizeof(D3DVERTEX));

//this->quadIB[x][y] is an index buffer of 16*16*6 indices ( 16*16*2 triangles forming 16*16 quadrilaterals)
pD3DDevice->SetIndices(this->quadIB[x][y]);

//texturing stuff snipped

//this->width and this->height are both 128
int err = pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, this->width * this->height, 0, 16 * 16 * 2);







Apparently it borks the > sign... so where it says -> what it actually means is -> (i.e. this-> == this->)

Share this post


Link to post
Share on other sites
Not sure if it will help (but maybe)...
int n = 16*16;
int triangleCount = n*2;
//Draw first patch
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0,n,0,triangleCount);
//Draw another
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, startVertex,n,startIndex,triangleCount);

You could change the triangle list to a triangle strip to save a bit of space.

Share this post


Link to post
Share on other sites
Thanks for your reply. I think the reason that won't work is because the patch is in the middle of a larger array of vertices. So when the rightmost edge of the patch is reached, and you want to skip to the next row of triangles, you cannot simply ignore the vertices between the edge of the patch and the edge of the entire terrain. That is, there will be a large jump in the index whenever the end of a row of vertices in the patch is reached. If the next index is therefore larger than minIndex + numVertices, D3D will throw an error.

I guess the only thing I can do is create a vertex buffer for each patch :-/

Share this post


Link to post
Share on other sites
Masterworks: I tried your suggestion, and guess what? It's WAY faster. Thanks!

In fact, I can render every single patch this way and hardly lose any framerate. Which means the overhead is much lower than I expected. You genius, you! :-)

Share this post


Link to post
Share on other sites
Glad it worked out, I would figure the overhead of just uploading indices to be minimal compared to the overhead of having multiple drawprimitive calls. This is a pretty small amount of data to send to the card, and then your render call is very fast since the vertex data is ready to go (if you use static VB especially). If you are using WRITEONLY locking flag except when full (and DISCARD otherwise) with as large an index buffer as possible you will get extremely good performace.

Share this post


Link to post
Share on other sites
hi there, i've heard that the performance of rendering Primitive is just the same regardless the complexity of the data, which means rendering lots of little indexbuffers may be a lag. i've a same problem, see: http://www.gamedev.net/community/forums/topic.asp?topic_id=355337

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this