DirectX 10 Game Programming : 3D Introduction - Vertex Buffers

2/17/2013 6:50:05 PM

A vertex buffer is at its most basic, an array of vertices. This array is contained within a single chunk of memory ready to be passed to the video card for drawing. The entire job of the vertex buffer is to hold a collection of vertices that Direct3D will use to create 3D objects with. All vertices for an object must live in a vertex buffer so they can be drawn.

Creating a Vertex Buffer

Vertex buffers are based on the ID3D10Buffer interface and are created using the function CreateBuffer. The CreateBuffer function has multiple uses; it can create both vertex and index buffers. Because the function can be used in multiple ways, you have to define what you want it to do by filling out a D3D10_BUFFER_DESC structure. This structure describes not only the type of buffer you want, but the size and type of the data it will contain.

typedef struct D3D10_BUFFER_DESC {
    UINT ByteWidth;
    D3D10_USAGE Usage;
    UINT BindFlags;
    UINT CPUAccessFlags;
    UINT MiscFlags;

The D3D10_BUFFER_DESC structure encompasses five variables.

The first variable, ByteWidth, is the number of bytes required for all the vertices the buffer will contain. This can be calculated by multiplying the number of vertices by the size of the custom vertex structure.

sizeof(VertexPosStruct) * numVertices;

The Usage variable details how the buffer will be used by the system. In most cases using a value of D3D10_USAGE_DEFAULT is acceptable, letting the system know the buffer will be updated only occasionally. If you absolutely will not be changing the data contained in the buffer, use the value D3D10_USAGE_IMMUTABLE. This will allow the system to optimize the access of the vertex buffer. If you will be changing the information in the buffer regularly, the value D3D10_USAGE_DYNAMIC is for you. The system will make sure the buffer is accessible to you for updates.

The BindFlags variable dictates the type of buffer being created. In the case of vertex buffers, a value of D3D10_BIND_VERTEX_BUFFER should be used.

CPUAccessFlags specifies whether the CPU should have access to the data in the buffer. If you want to be able to update a buffer quite often, use the value D3D10_CPU_ACCESS_WRITE. Otherwise, a value of 0 can be used.

The final variable, MiscFlags, should have a value of 0 if you have a single Direct3D device. Setting a value of D3D10_RESOURCE_MISC_SHARED allows the buffer to be shared across multiple devices.

Now that you’ve described what type of buffer you want to create, you have the opportunity to fill that buffer with some data during the buffer creation process using the D3D10_SUBRESOURCE_DATA structure.

The D3D10_SUBRESOURCE_DATA structure builds a subresource filled with your vertex data that is then assigned to the buffer.

Since you’re creating a vertex buffer, the initial data will be filled with vertices. The D3D10_SUBRESOURCE_DATA structure contains a variable called pSysMem whose purpose is to point to an array of data; in this instance, an array of vertices.

InitData.pSysMem = vertices;

You now know the type of buffer you’re creating and have a subresource created to pass into; those were the two items you needed before creating the buffer. You can now call the CreateBuffer function, passing in the buffer description and subresource structures. The CreateBuffer function fills in the pVertexBuffer variable with the newly created vertex buffer.

ID3D10Buffer* pVertexBuffer;

// Do the creation of the actual vertex buffer
hr = pD3DDevice->CreateBuffer(&bufferDescription, &InitData, &pVertexBuffer);


The following code sample shows the steps necessary to create a vertex buffer.

ID3D10Buffer* pVertexBuffer;

// Create vertex buffer
VertexPosStruct vertices[] =
    D3DXVECTOR3(0.0f, 0.5f, 0.5f),
    D3DXVECTOR3(0.5f, -0.5f, 0.5f),
    D3DXVECTOR3(-0.5f, -0.5f, 0.5f),

// Calculate the number of vertices in the array
int numVertices = sizeof(vertices) / sizeof(VertexPosStruct);

D3D10_BUFFER_DESC bufferDescription;
bufferDescription.Usage = D3D10_USAGE_DEFAULT;
bufferDescription.ByteWidth = sizeof(VertexPosStruct) * numVertices;
bufferDescription.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bufferDescription.CPUAccessFlags = 0;
bufferDescription.MiscFlags = 0;

InitData.pSysMem = vertices;

// Do the creation of the actual vertex buffer
hr = pD3DDevice->CreateBuffer(&bufferDescription, &InitData, &pVertexBuffer);
    return false;


Before drawing can take place, the vertex buffer must be bound to the Direct3D pipeline using the IASetVertexBuffers function. This function allows the vertices in the buffer to be accessed and used for drawing. The IASetVertexBuffers function requires five parameters.

The first parameter is the starting slot. Since this function allows for more than one vertex buffer to be bound at a time, this parameter lets Direct3D know which vertex buffer you want to start with. Multiple vertex buffers can be passed into this function as part of an array.

The second parameter is the number of vertex buffers in the array. Most of the time, only a single buffer is being bound so you’ll commonly see 1 being used.

The third parameter is a pointer to the array of vertex buffers. If only one buffer is being used, this will point to the single buffer.

The next parameter is called the stride. The stride is similar to pitch and means the number of bytes that each vertex in the buffer requires. The stride can be determined by using the sizeof function on the custom vertex structure. This parameter allows for an array of stride values to be passed in if more than one vertex buffer is being bound.

The final parameter is the offset value. The offset value defines the first vertex in each buffer to be used. If you intend to use all the vertices in a buffer, then this value should be 0.

The following example call shows how to use the IASetVertexBuffers function.

// Set vertex buffer
UINT stride = sizeof(VertexPosStruct);
UINT offset = 0;
pD3DDevice->IASetVertexBuffers(0, 1, &modelObject->pVertexBuffer, &stride,
Top 10
Review : Sigma 24mm f/1.4 DG HSM Art
Review : Canon EF11-24mm f/4L USM
Review : Creative Sound Blaster Roar 2
Review : Philips Fidelio M2L
Review : Alienware 17 - Dell's Alienware laptops
Review Smartwatch : Wellograph
Review : Xiaomi Redmi 2
Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8