Platform SDK: DirectX

Creating a Vertex Buffer

[C++]

The following figure illustrates the steps necessary to create a single vertex buffer from C++.

Note  As discussed in Accessing Direct3D, the DirectDraw component comprises two COM objects. The newest object—called DirectDraw7 and created by calling the DirectDrawCreateEx function—is the only object that exposes the IDirect3D7 interface, and is the only object capable of spawning a vertex buffer that exposes the IDirect3DVertexBuffer7 interface. The Direct3DDevice object created in this manner doesn't expose legacy Direct3D interfaces. Applications that require previous iterations of the Direct3D must use the DirectDrawCreate method to create a DirectDraw object and then create the desired legacy objects.

You create a vertex buffer object by calling the IDirect3D7::CreateVertexBuffer method, which accepts four parameters. The first parameter is the address of a D3DVERTEXBUFFERDESC structure that describes the desired vertex format, buffer size, and general capabilities. These capabilities are detailed in Vertex Buffer Descriptions. Normally, the system automatically determines the best memory location (system or display memory) for the vertex buffer. However, a software device or a HAL Device (IID_IDirect3DHALDevice) can only be used with explicit system-memory vertex buffers. For more information, see Device Types and Vertex Processing Requirements.

The second parameter that CreateVertexBuffer accepts is the address of a variable that will be filled with a pointer to the new IDirect3DVertexBuffer7 interface of the vertex buffer object if the call succeeds. The third parameter determines if the vertex buffer will be capable of containing clipping information—in the form of clip flags—for vertices that exist outside the viewing area. Set this to 0 to create a "clipping-capable" vertex buffer, or include the D3DDP_DONOTCLIP flag to create a vertex buffer that cannot contain clip flags. The D3DDP_DONOTCLIP flag is only applied if you also indicate that the vertex buffer will contain transformed vertices (the D3DFVF_XYZRHW flag is included in the dwFVF member of the description structure). The CreateVertexBuffer method ignores the D3DDP_DONOTCLIP flag if you indicate that the buffer will contain untransformed vertices (the D3DFVF_XYZ flag). Clipping flags occupy additional memory, making a clipping-capable vertex buffer slightly larger than a vertex buffer incapable of containing clipping flags. Because these resources are allocated when the vertex buffer is created, you must request a clipping-capable vertex buffer ahead of time.

Note  Creating a vertex buffer that can contain clip flags does not necessarily mean that you must request that clip flags be generated during vertex processing or applied during rendering. Each vertex buffer rendering method accepts the D3DDP_DONOTCLIP flag to bypass clipping during rendering, and the IDirect3DVertexBuffer7::ProcessVertices method accepts the D3DVOP_CLIP flag, which can be omitted to prevent the system from generating clip flags while it processes vertices.

There is no way to produce clip flags for a vertex buffer that was created without support for them. Attempts to use the IDirect3DVertexBuffer7::ProcessVertices method to do this will fail in debug builds, returning D3DERR_INVALIDVERTEXFORMAT. Rendering methods will ignore clipping requests when rendering from a transformed vertex buffer that does not contain clip flags.

The last parameter that CreateVertexBuffer accepts is provided for future compatibility with COM aggregation features. Currently, aggregation isn't supported, so this parameter must be set to NULL.

The following C++ example shows what creating a vertex buffer might look like in code.

    /*
     * For the purposes of this example, the g_lpD3D variable is the 
     * address of an IDirect3D7 interface exposed by a Direct3D
     * object, g_vbVertexBuffer is a variable of type LPD3DVERTEXBUFFER7,
     * and the fIsATLHardwareDevice variable is a BOOL variable that is 
     * assumed to be set during application initialization.
     */
 
    D3DVERTEXBUFFERDESC vbdesc;
    ZeroMemory(&vbdesc, sizeof(D3DVERTEXBUFFERDESC));
    vbdesc.dwSize= sizeof(D3DVERTEXBUFFERDESC);
    vbdesc.dwCaps        = 0L;
    vbdesc.dwFVF         = D3DFVF_VERTEX;
    vbdesc.dwNumVertices = NUM_FLAG_VERTICES;
    
    // If this isn't a transformation and lighting capable hardware device,
    // make sure the vertex buffer uses system memory.
    if( !fIsATLHardwareDevice )
        vbdesc.dwCaps |= D3DVBCAPS_SYSTEMMEMORY;
    
    // Create a clipping-capable vertex buffer.
    if(FAILED(g_lpD3D->CreateVertexBuffer(&vbdesc,
                                          &g_pvbVertexBuffer, 0L,
                                          NULL)))
        return E_FAIL;
[Visual Basic]

The following figure illustrates the steps necessary to create a single vertex buffer from Visual Basic.

You create a vertex buffer object from Visual Basic by calling the Direct3D7.CreateVertexBuffer method, which accepts four parameters. The first parameter is the address of a D3DVERTEXBUFFERDESC type that describes the desired vertex format, buffer size, and general capabilities. These capabilities are detailed in Vertex Buffer Descriptions. Normally, the system automatically determines the best memory location (system or display memory) for the vertex buffer. However, a software device or a HAL Device (IID_IDirect3DHALDevice) can only be used with explicit system-memory vertex buffers. For more information, see Device Types and Vertex Processing Requirements.

The second parameter determines if the vertex buffer will be capable of containing clipping information—in the form of clip flags—for vertices that exist outside the viewing area. Set this to 0 to create a "clipping-capable" vertex buffer, or include the D3DDP_DONOTCLIP flag to create a vertex buffer that cannot contain clip flags. The D3DDP_DONOTCLIP flag is only applied if you also indicate that the vertex buffer will contain transformed vertices (the D3DFVF_XYZRHW flag is included in the lFVF member of the description). The CreateVertexBuffer method ignores the D3DDP_DONOTCLIP flag if you indicate that the buffer will contain untransformed vertices (the D3DFVF_XYZ flag). Clipping flags occupy additional memory, making a clipping-capable vertex buffer slightly larger than a vertex buffer incapable of containing clipping flags. Because these resources are allocated when the vertex buffer is created, you must request a clipping-capable vertex buffer ahead of time.

The CreateVertexBuffer method returns a reference to a new Direct3DVertexBuffer7 object if the call succeeds.

Note  Creating a vertex buffer that can contain clip flags does not necessarily mean that you must request that clip flags be generated during vertex processing or applied during rendering. Each vertex buffer rendering method accepts the D3DDP_DONOTCLIP flag to bypass clipping during rendering, and the Direct3DVertexBuffer7.ProcessVertices method accepts the D3DVOP_CLIP flag, which can be omitted to prevent the system from generating clip flags while it processes vertices.

There is no way to produce clip flags for a vertex buffer that was created without support for them. Attempts to use the Direct3DVertexBuffer7.ProcessVertices method to do this will fail in debug builds, raising the D3DERR_INVALIDVERTEXFORMAT error. Rendering methods will ignore clipping requests when rendering from a transformed vertex buffer that does not contain clip flags.

The following Visual Basic example shows what creating a vertex buffer might look like in code.

    '
    ' For the purposes of this example, the g_D3D variable is a reference
    ' to a Direct3D7 object and g_VertexBuffer is a reference to a
    ' Direct3DVertexBuffer7 object.
    '
    On Local Error Resume Next

    Dim VBDesc As D3DVERTEXBUFFERDESC
    VBDesc.lFVF = D3DFVF_VERTEX
    VBDesc.lNumVertices = NUM_FLAG_VERTICES
    
    ' Create a clipping-capable vertex buffer.
    Set g_VertexBuffer = g_D3D.CreateVertexBuffer(VBDesc, D3DDP_DEFAULT)

    If Err.Number <> DD_OK Then
        ' Code to handle error goes here.
    End If