4. Rasterizer State
Looking at the rotating cube from the last
section you can see the results of using multiple triangles to create
each of the sides, but how do you actually see the triangles? Sure, it’s
good to know that the triangles were placed correctly, but how can you
verify it? Well, Direct3D actually provides a way to look into your
objects. You’ve probably seen 3D modeling software display objects in
wireframe mode. This mode displays 3D objects using only their outline.
This lets you see how objects are made up, sort of like seeing the frame
of a house without the walls getting in the way.
By default, Direct3D operates in solid mode,
which causes faces to be drawn opaquely. This can be changed though by
altering the rasterizer state.
The rasterizer state tells Direct3D how things in
the rasterizer stage should behave, such as what type of culling should
take place, whether features like multisampling and scissoring are
enabled, and the type of fill mode that should be used.
Rasterizer state objects are inherited from the ID3D10RasterizerState interface and are created using the CreateRasterizerState function.
The CreateRasterizerState function takes two parameters. The first is a pointer to a D3D10_RASTERIZER_DESC structure, which is used to detail the properties the new rasterizer state should have. The second parameter is the ID3D10RasterizerState object to be created.
HRESULT CreateRasterizerState(
const D3D10_RASTERIZER_DESC *pRasterizerDesc,
ID3D10RasterizerState **ppRasterizerState
);
As I mentioned before, the D3D10_RASTERIZER_DESC structure contains the properties the new rasterizer state should have when it is created.
typedef struct D3D10_RASTERIZER_DESC {
D3D10_FILL_MODE FillMode;
D3D10_CULL_MODE CullMode;
BOOL FrontCounterClockwise;
INT DepthBias;
FLOAT DepthBiasClamp;
FLOAT SlopeScaledDepthBias;
BOOL DepthClipEnable;
BOOL ScissorEnable;
BOOL MultisampleEnable;
BOOL AntialiasedLineEnable;
} D3D10_RASTERIZER_DESC;
The two parameters I’m going to talk about here are the D3D10_FILL_MODE and the D3D10_CULL_MODE
The D3D10_FILL_MODE parameter controls how the geometry is going to be drawn. If you use the value D3D10_FILL_WIREFRAME, the geometry will be drawn in wireframe mode; otherwise, pass the value D3D10_FILL_SOLID to have all geometry drawn solid.
The second parameter is the culling mode parameter named D3D10_CULL_MODE.
The culling mode tells the rasterizer which faces to draw and which to
ignore. Imagine that you had a sphere made up of triangles. No matter
which way you faced the sphere, not all of the triangles that make it up
will be visible at any one time; only those triangles directly in front
of you could be seen. The triangles on the back of the sphere are said
to be back facing. Because of how the vertices that make up the
triangles are defined, they have a particular winding order to them. The
winding order is the direction in which vertices for a triangle are
defined, clockwise or counterclockwise. Because of the nature of 3D
objects, even if you defined all your triangles using the same winding
order, just the act of rotating the object causes some of the triangles
to be reversed from the camera point of view. Going back to the sphere,
from the camera’s perspective some of the triangles are clockwise and
some are counterclockwise. The culling mode tells Direct3D which
triangles it can safely ignore and not draw. The D3D10_CULL_MODE has three options:
D3D10_CULL_NONE —says that no culling should take place, regardless of the winding order.
D3D10_CULL_FRONT —means that all front facing triangles should be ignored.
D3D10_CULL_BACK —all back facing triangles will not be drawn.
By specifying a culling mode, this cuts down on the number of triangles that you’re asking Direct3D to draw.
If you want the details on all the other parameters in the D3D10_RASTERIZER_DESC structure, please consult the DirectX SDK documentation.
Once you have the structure filled out, it is safe to call the CreateRasterizerState function to create the new rasterizer state.
After the new rasterizer state is created, it must be set before its effects take place. You use the function RSSetState to change the currently active rasterizer state, which is provided by the ID3D10Device interface.
void RSSetState(
ID3D10RasterizerState *pRasterizerState
);
The RSSetState function takes only a single parameter, a pointer to the new rasterizer state object.
The following code shows how a D3D10_RASTERIZER_DESC
structure is created and filled out as well as a new rasterizer state
created and set. The fill mode is being set to wireframe and the cull
mode to front faces. All the other features are being disabled.
// The D3D10_RASTERIZER_DESC structure
D3D10_RASTERIZER_DESC rasterDescription;
rasterDescription.FillMode = D3D10_FILL_WIREFRAME;
rasterDescription.CullMode = D3D10_CULL_FRONT;
rasterDescription.FrontCounterClockwise = true;
rasterDescription.DepthBias = false;
rasterDescription.DepthBiasClamp = 0;
rasterDescription.SlopeScaledDepthBias = 0;
rasterDescription.DepthClipEnable = false;
rasterDescription.ScissorEnable = false;
rasterDescription.MultisampleEnable = false;
rasterDescription.AntialiasedLineEnable = false;
// Create a new rasterizer state
ID3D10RasterizerState *g_pRasterizerState;
pD3DDevice->CreateRasterizerState( &rasterDescription, &g_pRasterizerState);
// Set the new rasterizer state
pD3DDevice->RSSetState(g_pRasterizerState);
At this point the new rasterizer state will be in
effect and all geometry will be drawn using the properties of the new
state. Take a look at Figure 6.5,
which shows the cube before being drawn in wireframe mode.