Microsoft DirectX 8.1 (C++)

Step 2: Setting Up the Vertex Buffer

Now that the custom vertex format is defined, it is time to initialize the vertices. The Vertices sample project does this by calling the application-defined function InitVB after creating the required Microsoft® Direct3D® objects. The following code fragment initializes the values for three custom vertices.

CUSTOMVERTEX g_Vertices[] =
{
    { 150.0f,  50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
    { 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
    {  50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
};

The preceding code fragment fills three vertices with the points of a triangle and specifies which color each vertex will emit. The first point is at (150, 50) and emits the color red (0xffff0000). The second point is at (250, 250) and emits the color green (0xff00ff00). The third point is at (50, 250) and emits the color blue-green (0xff00ffff). Each of these points has a depth value of 0.5 and an RHW of 1.0. For more information on this vector format see Transformed and Lit Vertices

The next step is to call IDirect3DDevice8::CreateVertexBuffer to create a vertex buffer as shown in the following code fragment.

if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),
                                              0 /* Usage */, D3DFVF_CUSTOMVERTEX,
                                              D3DPOOL_DEFAULT, &g_pVB ) ) )
    return E_FAIL;

The first two parameters of CreateVertexBuffer tell Direct3D the desired size and usage for the new vertex buffer. The next two parameters specify the vector format and memory location for the new buffer. The vector format here is D3DFVF_CUSTOMVERTEX, which is the FVF that the sample code specified earlier. The D3DPOOL_DEFAULT flag tells Direct3D to create the vertex buffer in the memory allocation that is most appropriate for this buffer. The final parameter is the address of the vertex buffer to create.

After creating a vertex buffer, it is filled with data from the custom vertices as shown in the following code fragment.

VOID* pVertices;
if( FAILED( g_pVB->Lock( 0, sizeof(g_Vertices), (BYTE**)&pVertices, 0 ) ) )
    return E_FAIL;
memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );
g_pVB->Unlock();

The vertex buffer is first locked by calling IDirect3DVertexBuffer8::Lock. The first parameter is the offset into the vertex data to lock, in bytes. The second parameter is the size of the vertex data to lock, in bytes. The third parameter is the address of a BYTE pointer, filled with a pointer to vertex data. The fourth parameter tells the vertex buffer how to lock the data.

The vertices are then copied into the vertex buffer using memcpy. After the vertices are in the vertex buffer, a call is made to IDirect3DVertexBuffer8::Unlock to unlock the vertex buffer. This mechanism of locking and unlocking is required because the vertex buffer may be in device memory.

Now that the vertex buffer is filled with the vertices, it is time to render the display, as described in Step 3: Rendering the Display.