tags:

views:

236

answers:

5
CUSTOMVERTEX* pVertexArray;

if( FAILED( m_pVB->Lock( 0, 0, (void**)&pVertexArray, 0 ) ) ) {
    return E_FAIL;
}


pVertexArray[0].position = D3DXVECTOR3(-1.0, -1.0,  1.0);
pVertexArray[1].position = D3DXVECTOR3(-1.0,  1.0,  1.0);
pVertexArray[2].position = D3DXVECTOR3( 1.0, -1.0,  1.0);
...

I've not touched C++ for a while - hence the topic but this bit of code is confusing myself. After the m_pVB->Lock is called the array is initialized.

This is great and all but the problem I'm having is how this happens. The code underneath uses nine elements, but another function (pretty much copy/paste) of the code I'm working with only access say four elements.

CUSTOMVERTEX is a struct, but I was under the impression that this matters not and that an array of structs/objects need to be initialized to a fixed size.

Can anyone clear this up?

Edit:

Given the replies, how does it know that I require nine elements in the array, or four etc...?

So as long as the buffer is big enough, the elements are legal. If so, this code is setting the buffer size if I'm not mistaken.

if( FAILED( m_pd3dDevice->CreateVertexBuffer( vertexCount * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pVB, NULL ) ) ) {
     return E_FAIL;
}
+1  A: 

You're pasing a pointer to the CUSTOMVERTEX pointer (pointer to a pointer) into the lock function so lock itself must be/ needs to be creating the CUSTOMVERTEX object and setting your pointer to point to the object it creates.

Patrick
+1  A: 

In order to modify a vertex buffer in DX you have to lock it. To enforce this the DX API will only reveal the guts of a VB through calling Lock on it.

Your code is passing in the address of pVertexArray which Lock points at the VB's internal data. The code then proceeds to modify the vertex data, presumably in preparation for rendering.

joshperry
+5  A: 

m_pVB points to a graphics object, in this case presumably a vertex buffer. The data held by this object will not generally be in CPU-accessible memory - it may be held in onboard RAM of your graphics hardware or not allocated at all; and it may be in use by the GPU at any particular time; so if you want to read from it or write to it, you need to tell your graphics subsystem this, and that's what the Lock() function does - synchronise with the GPU, ensure there is a buffer in main memory big enough for the data and it contains the data you expect at this time from the CPU's point of view, and return to you the pointer to that main memory. There will need to be a corresponding Unlock() call to tell the GPU that you are done reading / mutating the object.

To answer your question about how the size of the buffer is determined, look at where the vertex buffer is being constructed - you should see a description of the vertex format and an element count being passed to the function that creates it.

moonshadow
+1, could you confirm the additional code I have added is how the size of the buffer is determinde?
Finglas
Yes. CreateVertexBuffer() is where you specify the vertex buffer size.
Donnie DeBoer
@Dockers: yes, the size is determined by the parameters to CreateVertexBuffer. See e.g. http://doc.51windows.net/Directx9_SDK/?url=/Directx9_SDK/graphics/reference/d3d/interfaces/idirect3ddevice9/CreateVertexBuffer.htm for more information.
moonshadow
Thanks for your help - and to everyone else. I'm a XNA/C# guy normally so using C++/DirectX is a big learning experience and one for which I'm glad to finish soon. Cheers.
Finglas
+1  A: 

You're asking the wrong question, it's not how does it know that you require x objects, it's how YOU know that IT requires x objects. You pass a pointer to a pointer to your struct in and the function returns the pointer to your struct already allocated in memory (from when you first initialized the vertex buffer). Everything is always there, you're just requesting a pointer to the array to work with it, then "release it" so dx knows to read the vertex buffer and upload it to the gpu.

Blindy
+1  A: 

When you created the vertex buffer, you had to specify a size. When you call Lock(), you're passing 0 as the size to lock, which tells it to lock the entire size of the vertex buffer.

Donnie DeBoer