Archived

This topic is now archived and is closed to further replies.

Estauns

An Index Buffer? I'm lost.

Recommended Posts

Estauns    103
Okay, I know that by using a vertex buffer, I can cut down on the amount of shared verticies (I think). ie, turning a square into 4 verticies instaed of 6. So what does an index buffer do then?

Share this post


Link to post
Share on other sites
evolutional    1393
You''re getitng them confused.

Think of a cube, there''s 6 sides of 2 triangles each. If you do the math on that, that makes 36 vertices to define the cube.

BUT, as you can probably see, you can easily define the same cube by using only 8 vertices, one for each corner...

An index buffer will store the offsets (or INDEX) of the vertices in the vertex buffer. It''s generally faster for static VB''s. They aren''t without flaws though, consider the case of this cube, a given corner vertex will feature on 3 sides of the cube - so what happens when you want to specify texture co-ords to allow the cube to have a texture displaying on each face.

One set of tex-coords would be u/v 0,0. Another would be 1,0 - yet another for a different face using the same vertex could be 0,1 - do you see the problem?

So it''s a tradeoff you have to make.

Share this post


Link to post
Share on other sites
VolkerG    151
The vertex buffer just stores the vertices (position, normal,...).
Now, when drawing indexed primitives, the index tells what vertex to take from the vertex buffer.
So, indexed primitives actually cut down the number of vertices to pass.

Share this post


Link to post
Share on other sites
Slickfty2    122
An index buffer is used when you''re using indexed primitives (makes sense right! )

Say you have a vertex buffer with

1, 1, 0
-1, 1, 0
-1, -1, 0
1, -1, 0

Then you would have an index buffer with (forgive me if they aren''t in technically correct order... this is just an example)

0, 1, 2
0, 1, 3

and you use drawIndexedPrimitive call with that index buffer.

It''s a way to draw primitives that can''t (or aren''t) be easily divided into srips or fans, but still save on performance. In some articles on directX it actually recommends that you use indexed primitive lists over strips or fans.

Hope this helps, and of course, for more info, go to the directx page on the msdn.

Share this post


Link to post
Share on other sites
Supernat02    604
Index buffers also save you time when you want to add/remove certain vertices from the scene. Say you have a tiled ground with 9 tiles, but 5 of them are of 1 texture and the other 4 are of a different texture. Instead of re-creating the vertex buffer each time, you can just index the vertices from the vertex buffer.

For one thing, you only have to change a few WORDs(16 bit depth) or DWORDs(32 bit depth) that contain the indices, instead of creating a whole new vertex structure and copying it to memory. So, you save on memory and CPU cycles. You can just overwrite the previous DrawIndexedPrimitive indices with the current indices, and change the number of indices to draw.

Be careful though, DirectX will still commit a world transform on the ENTIRE vertex buffer, regardless of which vertices you''re using. So if you create a HUGE vertex buffer, you may not even get a benefit in the end using index buffers. That''s your call though.

Also, as downgraded pointed out, be careful with textures. If you have a mesh that has a single texture that will cover the entire mesh, it''s okay and good to use index buffers. If you have a 9 tile floor, it''s okay but you have to specify texture coords greater than 1 with wrapping enabled as you go down and to the right (in a 2D sense) with each tile. For instance, the top left corner of a texture is 0 and the bottom right is 1. You can, I think your video card has to support it and there is a limit, also call the top left corner 1 and the bottom left corner 2, etc. It''s not possible with a cube because it is closed and the vertices meet up again eventually where they started, causing a paradox of some sorts.

Chris

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
hmm....are you sure, that Dx always transforms the whole vb? IMO it''s only doing this with a SVP and not with a HWVP Device.

But you should ensure, that your IB only uses indices, that a not widely distributed in your buffer, but located near to each other to avoid cache misses. I''m not familiar with OpenGL, but it will suffer from the same problem here, I think.

Share this post


Link to post
Share on other sites
Fidelio66    164
quote:
Original post by Anonymous Poster
hmm....are you sure, that Dx always transforms the whole vb? IMO it's only doing this with a SVP and not with a HWVP Device.

But you should ensure, that your IB only uses indices, that a not widely distributed in your buffer, but located near to each other to avoid cache misses. I'm not familiar with OpenGL, but it will suffer from the same problem here, I think.


It is possibly in the DX help, or else on the pages of robert dunlop. If you use software vertexprocessing DX transforms the whole vertexbuffer between start vertex and last vertex. If you have one of 1000 vertices and you draw a quad using an index buffer using vertices 0,1,500,900 then it will transform 901 vertices for that.

I have edited my post, I got them mixed up, and anonymous poster was right, sorry.

[edited by - Fidelio66 on January 26, 2004 2:01:20 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
hmm...well, I thought a little bit about it and I#m quite sure, that it is the way I said. If the HW would transform all of the vertices, where does it store the transformed vertices? (remember, you can''t get transformed vertices back from Dx/OGL when transformed in HW, so its probably not the GPU ram) and what do you have a vertex cache for (about 12-36 verts or so, but not nearly enough to store a whole vb)?

With a software device (tnl, rasterizer could be in HW) you doesn''t have a vertex cache, so you transform all of them, save them to your ram and the take those you need.

Share this post


Link to post
Share on other sites
Supernat02    604
I have read that somewhere. I''ll see if I can locate it and quote the source directly. You may be right, it may only be when using software processing...but I seem to remember it striking me as odd when I read it. The author could be wrong too I suppose.

Remember, you pass into the DrawIndexedPrimitive the number of vertices that will be represented in the index buffer. The video card doesn''t know which index it''s about to get, so it would have to run the transform on each vertex, after reading in the index data...and it may well do that. Otherwise, it just transforms the entire list (up to the vertex count you put in DrawIndexedPrimitive). I''ll research deeper.

Chris

Share this post


Link to post
Share on other sites
That surely can''t be right, can it?

When you index vertices in the buffer, it can get to the exact vertex you index by using ([start of vertexbuffer] + [index] * [vertex stride].

It needs to upload the entire vertex buffer to video memory, but when it comes to shoving verts through the T&L pipeline it just gets the verts it needs surely?

Share this post


Link to post
Share on other sites
cbenoi1    484
> hmm....are you sure, that Dx always transforms the whole vb?

From MSDN:

When I submit an indexed list of primitives, does Direct3D transform all of the vertices in the buffer, or just the ones I indexed?

When using the software geometry pipeline, Direct3D first transforms all of the vertices in the range you submitted, rather than transforming them "on demand" as they are indexed. For densely packed data, where most of the vertices are used for example, this process is more efficient, particularly when SIMD instructions are available. If your data is sparsely packed, you may want to consider rearranging your data to avoid too many redundant transformations.

When using the hardware geometry acceleration, vertices are typically transformed "on demand" as they are required.


Granted it's ol' DX7, but I would expect this feature to be carried over to DX8 and DX9 as well.

-cb


[edited by - cbenoi1 on January 26, 2004 12:52:04 PM]

Share this post


Link to post
Share on other sites
Supernat02    604
Good find, it''s in the 9.0 FAQ as well. It''s not what I had read somewhere, but I think I''ll trust what the SDK says over a book. Besides, that makes so much more sense than processing all of the vertices in hardware... Sorry for the incorrect information.

Chris

Share this post


Link to post
Share on other sites
Doolwind    213
Estauns-

Do you have a good idea now of how Index Buffers work?? If not I can try redoing my ascii art diagrams to explain it.

Doolwind


---------------------------------------------------------
Who of you by worrying can add a single hour to his life.
Matthew 6:27

Share this post


Link to post
Share on other sites
Estauns    103
I think so, seems kind of like they just point at different verticies in the VB, to make less calculations on the verticies. Maybe I''m wrong =)

ALSO, how do you build Index Buffers for large meshes?

Like, if you have a CTriangle class and it has a VB, and then you make a row of traingles, how are you to build the index buffer out of the VBs from the many different classes? (Assuming they all share points)

Or would you have to make some, CFiveTriangleRow type of deal? =P

Share this post


Link to post
Share on other sites
Doolwind    213
Estauns-

When creating the vertex buffers and index buffers for my terrain I break the terrain up into sections.

Each section is 17x17 vertices. So I just set up these vertices in a vertex buffer. I then have an index buffer which points into the vertex buffer to form a triangle strip of the terrain.

This way I can change the LOD of each section and use culling to only draw the sections of terrain visible to the user.

quote:
how are you to build the index buffer out of the VBs

You don''t build the index buffer out of the VBs. You point the index buffer into the VBs. Depending on whether you are using triangle strips or triangle lists your index buffer will point at different positions in the vertex buffer.

Doolwind

---------------------------------------------------------
Who of you by worrying can add a single hour to his life.
Matthew 6:27

Share this post


Link to post
Share on other sites
Estauns    103
quote:
Original post by Doolwind
Estauns-

When creating the vertex buffers and index buffers for my terrain I break the terrain up into sections.

Each section is 17x17 vertices. So I just set up these vertices in a vertex buffer. I then have an index buffer which points into the vertex buffer to form a triangle strip of the terrain.

This way I can change the LOD of each section and use culling to only draw the sections of terrain visible to the user.

quote:
how are you to build the index buffer out of the VBs

You don''t build the index buffer out of the VBs. You point the index buffer into the VBs. Depending on whether you are using triangle strips or triangle lists your index buffer will point at different positions in the vertex buffer.

Doolwind

---------------------------------------------------------
Who of you by worrying can add a single hour to his life.
Matthew 6:27


So you have many quads for your terrain with many VBs, but only one index buffer stored in your Terrain class, where as your VBs might be stored in the Quad class?

Share this post


Link to post
Share on other sites
Doolwind    213
quote:
So you have many quads for your terrain with many VBs, but only one index buffer stored in your Terrain class, where as your VBs might be stored in the Quad class?


No, the way I do it I have the same amount of IB''s and VB''s. So for each section of land you would have a "section" class. This class would have 1 VB and 1 IB which points into that VB. The VB holds all of the vertices (17*17) for that section and the IB points at these vertices.

The "section" class can then also store info like the bounding sphere/box for quad/octree culling for that section of terrain.

Doolwind


---------------------------------------------------------
Who of you by worrying can add a single hour to his life.
Matthew 6:27

Share this post


Link to post
Share on other sites
If the sections of terrain are all tesselated the same then surely you just need one index buffer for the lot?

The way I currently render terrain is to have multiple vertex buffers (well actually mutiple sections of the same vertex buffer) and use one index buffer to index every terrain section, priming and utilising the vertex cache wherever possible.

I still can''t understand how this whole ''transform the entire section of the vertex buffer'' can possibly work with the vertex cache. Anyone?

Share this post


Link to post
Share on other sites