The order in which the
vertices appear in the vertex buffer is important. When Direct3D is
drawing, the order the vertices are used is based on their order within
the vertex buffer. Ordering the vertices in a haphazard way can cause
objects to appear to be missing sides.
The rendering of an object defined by a vertex
buffer is easy. Techniques can consist of one or more passes. When
drawing, you need to loop through these passes and apply the technique
to each pass and then draw the vertices in the vertex buffer. This
allows the vertices to be drawn based on the currently active technique.
The following code shows a simple drawing call that uses an effect
technique.
// Bind the vertex buffer and set the input layout before drawing
// Set the input layout
pD3DDevice->IASetInputLayout(modelObject->pVertexLayout);
// Set vertex buffer
UINT stride = sizeof(VertexPosStruct);
UINT offset = 0;
pD3DDevice->IASetVertexBuffers(0,
1,
&modelObject->pVertexBuffer,
&stride,
&offset);
// Set primitive topology
pD3DDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Render an object
D3D10_TECHNIQUE_DESC techniqueDescription;
pTechnique->GetDesc(&techniqueDescription);
// Loop through the technique passes
for(UINT p=0; p < techniqueDescription.Passes; ++p)
{
pTechnique->GetPassByIndex(p)->Apply(0);
pD3DDevice->Draw(numVertices, 0);
}
Topology
At
this point, Direct3D knows you have a vertex buffer and it knows you
want to draw the vertices, but it is still unsure how those vertices
should be drawn. Direct3D supports multiple ways of drawing the same set
of vertices. Your vertices can be drawn as a series of individual
triangles, as a series of lines, or as interconnected triangles with
each depending on the one before it. How the vertices are drawn is
referred to as primitive types or topology.
The topology determines how the vertices that
make up an object are used. If you draw the vertices as a series of
individual triangles, that is called a triangle list. A bunch of
interconnected triangles is called a triangle strip. A triangle strip
takes three vertices to create the first triangle, but only one vertex
is needed to define the second and subsequent triangles. When optimizing
your drawing, it is best to send as little information to be drawn as
possible.
The topology is set using the IASetPrimitiveTopology function. This function takes only a single parameter and should be used before the vertices in a buffer are sent to be drawn.
// Set primitive topology
pD3DDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
Some of the acceptable values that can be sent to the IASetPrimitiveTopology function are:
D3D10_PRIMITIVE_TOPOLOGY_POINTLIST— the vertices are a series of unconnected points in space.
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST— a collection of unconnected triangles.
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP— a series of interconnected triangles.
A few more values can be found in the DirectX SDK help documents.
The Draw Function
The Draw function is the final step needed to get your object on the screen. Draw requires only two parameters.
The first parameter is the number of vertices
that are to be drawn. Most of the time, this will reflect the number of
vertices within your vertex buffer.
The second parameter is the starting vertex
index. You don’t have to draw all the vertices within a buffer, so this
value allows you to start anywhere.
pD3DDevice->Draw(numVertices, 0);
Figure 1 shows what the triangle will look like when it’s drawn.
typedef struct
{
// Shader variables
ID3D10Effect* pEffect;
ID3D10EffectTechnique* pTechnique;
// Vertex information
ID3D10Buffer* pVertexBuffer;
UINT numVertices;
ID3D10InputLayout* pVertexLayout;
}ModelObject;