Vertex buffer objects enable applications to directly access the memory allocated for vertex data. You can retrieve a pointer to vertex buffer memory by calling the IDirect3DVertexBuffer::Lock method, then access the memory as needed to fill the buffer with new vertex data, or to read any data it already contains.
The IDirect3DVertexBuffer::Lock method accepts three parameters. The first, dwFlags, tells the system how the memory should be locked, and can be used to hint how the application will be accessing the data within the buffer. (You can hint for read-only or write-only access, which allows the driver to lock the memory to provide the best performance given the requested access type. These hints are not required, but can improve performance for memory access in some situations.) Because vertex buffers use DirectDrawSurface objects to contain vertex data, the flags that IDirect3DVertexBuffer::Lock accepts are identical to those accepted by the IDirectDrawSurface4::Lock method, with identical results.
The second parameter accepted by the Lock method, lplpData, is the address of an LPVOID variable that will contain a valid pointer to the vertex buffer memory if the call succeeds. The last parameter, lpdwSize, is the address of a variable that will contain the size, measured in bytes, of the buffer at lplpData after the call returns. You can set lpdwSize to NULL if your application doesn't need information about the buffer size.
Performance Notes Use the DDLOCK_READONLY flag if your application will only be reading from the vertex buffer memory. Including this flag enables Direct3D to optimize its internal procedures to improve efficiency, given that access to the memory will be read-only. Although it is possible to write to memory locked with the DDLOCK_READONLY flag, doing so can produce unexpected results. In addition, attempting to read from a vertex buffer that was created with the D3DVBCAPS_WRITEONLY flag can be extremely slow, even if you lock the buffer for read-only access.
The vertex buffer memory itself is a simple array of vertices, specified in flexible vertex format. If your application is uses the legacy vertex structures, D3DVERTEX, D3DLVERTEX, and D3DTLVERTEX, the stride is simply the size of the structure, in bytes. If you are using a vertex format different from the legacy formats, use the stride of whatever vertex format structure you define. You can calculate the stride of each vertex at run time by examining the flexible vertex format flags contained within the vertex buffer description. The following table shows the size for each vertex component.
Vertex Format Flag | Size |
---|---|
D3DFVF_DIFFUSE | sizeof(DWORD) |
D3DFVF_NORMAL | sizeof(float) × 3 |
D3DFVF_SPECULAR | sizeof(DWORD) |
D3DFVF_TEXn | sizeof(float) × 2 × n |
D3DFVF_XYZ | sizeof(float) × 3 |
D3DFVF_XYZRHW | sizeof(float) × 4 |
The number of texture coordinates present in the vertex format is described by the D3DFVF_TEXn flags (where n is a value from 0 to 8). Because each set of texture coordinates in the vertex format occupies the space of two float variables, multiply the number of texture coordinate sets by the size of one set of texture coordinates to calculate the memory required for that number of texture coordinates.
Use the total vertex stride to increment and decrement the memory pointer as needed to access particular vertices.