Getting Vertex from Index Buffer

Started by
10 comments, last by Nik02 19 years, 7 months ago
I understand how the Index and Vertex Buffers themselves work, but I don't know how to pull the vector for a vertex directly out of the index buffer. I tried looking up GetIndices, but I couldn't figure out if I even could get what I needed out of the resulting list.
Advertisement
You get 3 indices, for 3 vertices, that form a triangle.
Quote:Original post by Pipo DeClown
You get 3 indices, for 3 vertices, that form a triangle.
Maybe you don't understand.. I want to get a D3DXVECTOR3 for the vertex from the index buffer.
_____________       ______________|IndexBuffer|       |VertexBuffer||___________|       |____________||  0, 6, 7  |------ | 0) vecPos  ||  0, 3, 5  |   |   |      |     ||     |     |   |   |      |     ||     |     |   |   |      V     ||     |     |   |-- | 6) vecPos  ||     V     |   |-- | 7) vecPos  || 23,45,24  |--     | 8) vecPos  ||___________| |     |      |     |              |     |      |     |              |     |      V     |              |---- |23) vecPos  |              |---- |    ....    |              |     |            |              |     |    ....    |              |-----|45) vecPos  |                    |____________|

Each index, is the 'index' for the vertex in the vertexbuffer. So if your index is 0, it's the FIRST vertex in the vertexbuffer.



But that is what you understand already [wink], so you need to lock the vertexbuffer.

// final vertex storageSVERTEX myVertex;// datapointerVOID* pVertices; // indexshort n = 52;    // LOCK VBUFFERif( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) )    return E_FAIL;// Copy 1 SVERTEX, from pVertices + offsetmemcpy( pVertices+(n * sizeof(SVERTEX)), &myVertex, sizeof(SVERTEX) );	g_pVB->Unlock();
! NOTE: modified version of the DXSDK D3D-tutorial
Ahh thanks.. that looks like it would work.

g_pVB is a Vertex Buffer object? So if I don't have access to the origonal "g_pVB", how would I access the Vertex Buffer?
You absolutely need the vertex buffer in order to access the actual vertex data [smile]

Niko Suni

Quote:Original post by Nik02
You absolutely need the vertex buffer in order to access the actual vertex data [smile]
.. or you'd keep an array of the vertex data in memory somewhere. Having access to the vertexbuffer is still 'the way to go'. I suggest coding a way around it (faster and memory effecient-er- [gimme a break, i need sleep]).
Kudos on the ASCII art!
Alexander Stockinger
Programmer
Quote:Original post by Pipo DeClown
Quote:Original post by Nik02
You absolutely need the vertex buffer in order to access the actual vertex data [smile]
.. or you'd keep an array of the vertex data in memory somewhere. Having access to the vertexbuffer is still 'the way to go'. I suggest coding a way around it (faster and memory effecient-er- [gimme a break, i need sleep]).



Agreed. The most optimal way to use modern graphics hardware is assume all data it's using is WRITE ONLY from the perspective of the CPU.


If your reason for wanting to read the vertices is for something such as collision detection, then you're MUCH better off storing a seperate version of that data which is only used for collision. There are a few reasons:

1) the geometry you use for collision doesn't need to be anywhere as dense/tesselated as the one you use for rendering because you don't have to worry about boundaries for different textures/materials etc. A collision mesh can typically have less than a quarter of the vertices of a render mesh - a big saving in CPU usage for your collision.

2) most of the things you have in a vertex used for rendering aren't required for collision (texture coordinates, colours, vertex normals, skin weights etc). Not having them saves even more memory and potentially further increases performance since more data fits into the CPU cache and there are less page faults the first time it's used.

3) you often want to store extra data for collision such as surface normals, friction values etc - you absolutely don't want to be hanging that data off a render vertex.

4) if the driver/card has decided to store the data in AGP memory or even worse, video memory, then reading data from a locked buffer in that memory will be SLOOOOOW since the memory is marked as Write Combined which can't be cached for reads by the CPU (which makes a huge difference). In the case of true video memory you're also limited by the speed of the AGP bus.

5) Locking a vertex buffer that the graphics chip is currently using for a render operation can kill GPU<->CPU parallelism by stalling the CPU while the GPU is using the data and stalling the GPU while the buffer is locked.


If you still *really* want to do read a vertex back from the render vertex buffer rather than storing a copy of the data more suitable for your needs, I'd advise trying the MANAGED memory pool because D3D will maintain a system memory copy of the data.

When you lock a managed buffer, you'll be given a pointer to the [faster to read] system memory copy and you won't get GPU<->CPU stalls for most reads.



Finally, a couple something to add to Pipo DeClown's code example. Change:
if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) )


to:
if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, D3DLOCK_READONLY ) ) )


1) The read-only flag can be a big hint to D3D and the driver about what you're up to - if you're using a managed resource, that will also ensure the video memory copy doesn't get updated (with associated stalls) - without the read only flag, D3D/the driver doesn't know whether or not you've changed any data in the buffer so will update it regardless.

2) only lock at the offset you require and only the size you require if you can help it rather than locking the whole buffer. Unfortunately if you're de-referencing through an index buffer you can't guarantee which range of vertices you'll need to access.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

S1CA seems to produce much more comprehensive answers than I manage to do [smile]

However, my point was - if your only accessible source of data is the index buffer, you're not going to get the actual vertex data from it. As others have said, you need either the original data or the vertex buffer with the said data in it to access the individual vertices' components.

Niko Suni

This topic is closed to new replies.

Advertisement