Sign in to follow this  

Getting Vertex from Index Buffer

This topic is 4851 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 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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

_____________ ______________
|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 storage
SVERTEX myVertex;
// datapointer
VOID* pVertices;
// index
short n = 52;

// LOCK VBUFFER
if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) )
return E_FAIL;

// Copy 1 SVERTEX, from pVertices + offset
memcpy( pVertices+(n * sizeof(SVERTEX)), &myVertex, sizeof(SVERTEX) );

g_pVB->Unlock();
! NOTE: modified version of the DXSDK D3D-tutorial

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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]).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Thanks for the help everyone.. I was being stupid with my last post, I do have access to the vertex object.. but doesn't this code just return a vertex? How do I get the vector for that?

Share this post


Link to post
Share on other sites

This topic is 4851 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.

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