Share via


Using Index Buffers (Windows Embedded CE 6.0)

1/6/2010

This topics discuss common tasks that an application performs when working with vertex buffers.

Creating an Index Buffer

Create an index buffer object by calling the IDirect3DMobileDevice::CreateIndexBuffer method, which accepts five parameters. The first parameter specifies the index buffer length, in bytes.

The second parameter is a set of usage controls. Among other things, its value determines whether the vertices being referred to by the indices are capable of containing clipping information. To improve performance, specify D3DMUSAGE_DONOTCLIP (see D3DMUSAGE Values) when clipping is not required.

The third parameter is either the D3DMFMT_INDEX16 or D3DMFMT_INDEX32 member of the D3DMFORMAT enumerated type that specifies the size of each index.

The fourth parameter is a member of the D3DMPOOL enumerated type that tells the system where in memory to place the new index buffer.

The final parameter that CreateIndexBuffer accepts is the address of a variable that is filled with a pointer to the new IDirect3DMobileIndexBuffer interface of the vertex buffer object, if the call succeeds.

The following code example shows what creating a index buffer might look like in code.

/*
 * For the purposes of this example, the d3dmDevice variable is the 
 * address of an IDirect3DMobileDevice interface exposed by a 
 * Direct3DMobileDevice object, g_IB is a pointer to an
 * IDirect3DMobileIndexBuffer interface.
 */

if( FAILED( d3dmDevice->CreateIndexBuffer( 16384 *sizeof(WORD),
                                           D3DMMUSAGE_WRITEONLY,
                                           D3DMFMT_INDEX16,
                                           D3DMPOOL_VIDEOMEM, &g_IB ) ) )
    return E_FAIL;

Accessing the Contents of an Index Buffer

Index buffer objects enable applications to directly access the memory allocated for index data. You can retrieve a pointer to index buffer memory by calling the IDirect3DMobileIndexBuffer::Lock method, and then accessing the memory as needed to fill the buffer with new index data or to read any data it contains. The Lock method accepts four parameters. The first, OffsetToLock, is the offset into the index data. The second parameter is the size, measured in bytes, of the index data. The third parameter accepted by the Lock method, ppbData, is the address of a BYTE pointer filled with a pointer to the index data, if the call succeeds.

The last parameter, Flags, tells the system how the memory should be locked. You can use it to indicate how the application accesses the data in the buffer. Specify constants for the Flags parameter according to the way the index data will be accessed by your application. This allows the driver to lock the memory and provide the best performance given the requested access type. Use D3DMLOCK_READONLY flag (see D3DMLOCK Values) if your application will read only from the index buffer memory. Including this flag enables Microsoft® Direct3D Mobile® to optimize its internal procedures to improve efficiency, given that access to the memory will be read-only.

After you fill or read the index data, call the IDirect3DMobileIndexBuffer::Unlock method, as shown in the following code example.

// This code example assumes the IB is a variable is a pointer to an
// IDirect3DMobileIndexBuffer interface and that g_Indices has been
// properly initialized with indices.

// To fill the index buffer, you must lock the buffer to gain 
// access to the indices. This mechanism is required because index
// buffers may be in device memory.

VOID* pIndices;

if( FAILED( IB->Lock( 0,                 // Fill from start of the buffer.
                      sizeof(g_Indices), // Size of the data to load.
                      (BYTE**)&pIndices, // Returned index data.
                      0 ) ) )            // Send default flags to the
lock.
    return E_FAIL;

memcpy( pIndices, g_Indices, sizeof(g_Vertices) );
IB->Unlock();

Note

If you create an index buffer with the D3DMUSAGE_WRITEONLY flag (see D3DMUSAGE Values), do not use the D3DMLOCK_READONLY locking flag. Use the D3DMLOCK_READONLY flag if your application will read only from the index buffer memory. Including this flag enables Direct3D Mobile to optimize its internal procedures to improve efficiency, given that access to the memory will be read-only.

Because you directly access the memory allocated for the index buffer, make sure your application properly accesses the allocated memory. Otherwise, you risk rendering that memory invalid. Use the stride of the index format your application uses to move from one index in the allocated buffer to another.

Rendering from an Index Buffer

Rendering index data from an index buffer requires a few steps. First, you need to set the stream source by calling the IDirect3DMobileDevice::SetStreamSource method.

d3dmDevice->SetStreamSource( 0, VB, sizeof(CUSTOMVERTEX) );

The first parameter of SetStreamSource tells Microsoft® Direct3D Mobile® the source of the device data stream. The second parameter is the vertex buffer to bind to the data stream. The third parameter is the size of the component, in bytes. In the sample code above, the size of a CUSTOMVERTEX is used for the size of the component.

The next step is to call the IDirect3DMobileDevice::SetIndices method to set the source of the index data.

d3dmDevice->SetIndices( IB, 0 );

The first parameter that SetIndices accepts is the address of the index buffer to set. The second parameter is the starting point in the vertex stream.

After setting the stream and indices source, use the IDirect3DMobileDevice::DrawIndexedPrimitive method to render vertices that use indices from the index buffer.

d3dmDevice->DrawIndexedPrimitive( D3DMPT_TRIANGLELIST, 0,
                                   dwVertices, 0, dwIndices / 3);

The second parameter that DrawPrimitive accepts is the minimum vertex index for vertices used during this call. The third parameter is the number of indices to use during this call starting from BaseVertexIndex + MinIndex. The fourth parameter is the location in the index array to start reading indices. The final parameter that DrawPrimitive accepts is the number of primitives to render. This parameter is a function of the primitive count and the primitive type. The code sample above uses triangles, so the number of primitives to render is the number of indices divided by three.

Retrieving Index Buffer Descriptions

Retrieve information about an index buffer by calling the IDirect3DMobileIndexBuffer::GetDesc method. This method fills the members of the D3DMINDEXBUFFER_DESC structure with information about the vertex buffer.

See Also

Concepts

Index Buffers