The CPU sends a list of vertices and indices to the graphics card. Each vertex holds data such as position, normal, diffuse colour, texture coordinates, etc. Each index is simply a number identifying one of the vertices.
The CPU also tells the GPU how to interpret the indices. They can be interpretted as points, lines or triangles, and each of those have different types. For example, a triangle fan uses the first index and the previous index along with the current index to define each triangle, resulting in fan shaped objects (not very useful). A line strip uses the last index as the starting point to draw each line so you get a continuous line going through the vertices.
Once the GPU has the vertices, it may process them (unless the CPU tells it that they are already processed). Normally this would involve transforming the vertices from model space into view space so they appear in the correct position on the screen, and calculating the amount of light received by each vertex according to its normal. This behaviour can be competely customized by using a vertex shader. Some very old cards don't support any vertex processing and so in this case Direct3D can do it in software first.
Then there is the rasteriser. This does the filling in. For points, this means drawing a dot at the vertex position. For a line it means filling in the pixels along the line, and the same for a triangle.
Each pixel that is drawn to the screen needs a colour. To do this, the rasteriser interpolates the properties of the surrounding vertices, and then passes this information to the pixel shader if there is one, or just interpolates the colour of each vertex otherwise (as calculated by the vertex processing part). The pixel shader is called once for every pixel that is about to be coloured in. The pixel shader can also override the depth of the pixel if it wants to.
Before the pixel is drawn to the screen, it undergoes depth testing (and possibly stencil testing, but I won't go into that). The way that works is that there is a depth buffer which holds a depth value for each pixel on the screen. The pixel is only drawn if its depth is closer than the depth currently in the depth buffer. If it is, the pixel is drawn and its depth is written into the depth buffer.
Direct3D has two main features:
- It is a standard interface that works for almost all graphics cards. Otherwise you would have to separately code for each individual card manufacturer.
- It can fill in the gaps when cards don't support a particular feature (such as hardware vertex processing)
[b]
