I spent some time updating my geometry classes to allow for all of the myriad primitive topologies that are allowed for in D3D11. Its a bit surprising to see, but there are 32 different types of control patch primitives for use with the new tessellation shader stages. I basically allow my index buffer classes to add individual indices and let the application take care of ensuring that there is an appropriate number of indices for a given number of primitives of a given type. One by-product of adding this functionality is that I needed to be able to determine how many primitives are going to be rendered when a user specifies the number of indices and the topology type. Have you ever tried to figure out how to do this with a triangle strip with adjacency? Here's an image to show you what I mean - can you figure out the formula???
It took me a good 15 minutes of thinking about it to get it straight [rolleyes]! Anyhow, after getting my geometry classes straightened out, I ported over my geometry loader. The bottom line is that I can now load in my MilkShape3D files again, letting me render the old standby (do you know who it is?):
I'm going to periodically post programming tips that I come across while working with D3D11, and this is going to be the first one. When building a renderer around D3D11, it is pretty commong to create a function that recieves an object description that creates a state of some sort, such as a BlendState, RasterizerState, or DepthStencilState. Typically these descriptions are an actual D3D11 struct, and they can be quite verbose and unsightly to type out. Here is an example of how it would look to do create a DepthStencil state in this manner:
State.DepthEnable = true;
State.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
State.DepthFunc = D3D11_COMPARISON_LESS;
State.StencilEnable = FALSE;
State.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
State.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
State.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
State.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
State.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
State.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
State.BackFace.StencilFunc = D3D11_COMPARISON_NEVER;
State.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
State.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
State.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
Renderer.CreateDepthStencilState( State );
This isn't too bad for one or two states, but by the time you get to 5 or 10 it becomes a real mess. Instead, if you create a class to wrap the structure you can take away a couple of nice advantages:
1. The constructor can be used to initialize the description to a known set of values.
2. Requesting the state to be created by the renderer is still simple - just pass a pointer.
3. You can add methods for setting the description to particular common settings.
So, given a class header like this:
void SetDepthEnable( bool state );
void SetDepthWriteMask( D3D11_DEPTH_WRITE_MASK state );
void SetDepthComparisonFunction( D3D11_COMPARISON_FUNC state );
void SetStencilEnable( bool state );
void SetStencilReadMask( UINT8 state );
void SetStencilWriteMask( UINT8 state );
void SetFrontFace( D3D11_DEPTH_STENCILOP_DESC state );
void SetBackFace( D3D11_DEPTH_STENCILOP_DESC state );
Now you can create the state object in the renderer like so:
Renderer.CreateDepthStencilState( &DepthStencilState );
I have implemented these configuration classes for each of the state objects, and I will be adding them into the texture, buffer, and resource view creation schemes. It is a nice and clean solution, plus you can use it to add sanity checks on all of the different configurations and make sure there are no invalid state combinations.