The CommonStates class is a factory which simplifies setting the most common combinations of Direct3D rendering states.
For exception safety, it is recommended you make use of the C++ RAII pattern and use a std::unique_ptr or std::shared_ptr
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476087.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/hh404435.aspx
For drawing alpha-blended objects, you should use AlphaBlend() if using premultiplied alpha, or
NonPremultiplied() if using 'straight' alpha.
For multipass rendering, you'd typically use Additive().
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476110.aspx
For drawing alpha blended objects (which is typically done after all opaque objects have been drawn), use DepthRead() which will respect the existing z-buffer values, but will not update them with 'closer' pixels.
For drawing objects without any depth-sort at all, use DepthNone().
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476198.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/hh404489.aspx
For "double-sided" geometry, use CullNone(). Keep in mind this is a potentially large performance hit, so use it sparingly.
Wireframe() is self-explanatory.
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476207.aspx
Remember that ??SetSamplers() actually takes an array of sampler state objects, rather than a pointer directly to the sampler state object, since there can be multiple textures in use at the same time.
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
Header
#include <CommonStates.h>
Initialization
The CommonStates constructor requires a Direct3D 11 device.
std::unique_ptr<CommonStates> states(new CommonStates(device));
Using this helper to set device state
deviceContext->OMSetBlendState(states->Opaque(), Colors::Black, 0xFFFFFFFF);
deviceContext->OMSetDepthStencilState(states->DepthDefault(), 0);
deviceContext->RSSetState(states->CullCounterClockwise());
auto samplerState = states->LinearWrap();
deviceContext->PSSetSamplers(0, 1, &samplerState);
Blending State
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.blendstate_fields.aspxhttp://msdn.microsoft.com/en-us/library/windows/desktop/ff476087.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/hh404435.aspx
- ID3D11BlendState* Opaque();
- ID3D11BlendState* AlphaBlend();
- ID3D11BlendState* Additive();
- ID3D11BlendState* NonPremultiplied();
Typical usage
For standard drawing, typically you should make use of Opaque().For drawing alpha-blended objects, you should use AlphaBlend() if using premultiplied alpha, or
NonPremultiplied() if using 'straight' alpha.
For multipass rendering, you'd typically use Additive().
Depth/Stencil State
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.depthstencilstate_fields.aspxhttp://msdn.microsoft.com/en-us/library/windows/desktop/ff476110.aspx
- ID3D11DepthStencilState* DepthNone();
- ID3D11DepthStencilState* DepthDefault();
- ID3D11DepthStencilState* DepthRead();
Typical usage
For standard rendering with a z-buffer, you should use DepthDefault().For drawing alpha blended objects (which is typically done after all opaque objects have been drawn), use DepthRead() which will respect the existing z-buffer values, but will not update them with 'closer' pixels.
For drawing objects without any depth-sort at all, use DepthNone().
Rasterizer State
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.rasterizerstate_fields.aspxhttp://msdn.microsoft.com/en-us/library/windows/desktop/ff476198.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/hh404489.aspx
- ID3D11RasterizerState* CullNone();
- ID3D11RasterizerState* CullClockwise();
- ID3D11RasterizerState* CullCounterClockwise();
- ID3D11RasterizerState* Wireframe();
Typical usage
For default geometry winding use CullCounterClockwise(). For inverted winding (typically when using assets designed for left-handed coordinates but rendering with right-handed coordinates or vice-versa), use CullClockwise().For "double-sided" geometry, use CullNone(). Keep in mind this is a potentially large performance hit, so use it sparingly.
Wireframe() is self-explanatory.
Sampler State
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.samplerstate_fields.aspxhttp://msdn.microsoft.com/en-us/library/windows/desktop/ff476207.aspx
- ID3D11SamplerState* PointWrap();
- ID3D11SamplerState* PointClamp();
- ID3D11SamplerState* LinearWrap();
- ID3D11SamplerState* LinearClamp();
- ID3D11SamplerState* AnisotropicWrap();
- ID3D11SamplerState* AnisotropicClamp();
Typical usage
Usually LinearClamp() is the standard setting, and covers a large number of cases. For improved mipmap filtering quality use the Ansiotropic settings.Remember that ??SetSamplers() actually takes an array of sampler state objects, rather than a pointer directly to the sampler state object, since there can be multiple textures in use at the same time.
Feature level usage
All common states work with all feature levels. Anisotropic*() uses a MaxAnisotropy of 2 for this reason.http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
Remarks
These common states are equivalent to using the following descriptors:// Opaque() CD3D11_DEFAULT default; CD3D11_BLEND_DESC desc(default); // AlphaBlend CD3D11_DEFAULT default; CD3D11_BLEND_DESC desc(default); desc.RenderTarget[0].BlendEnable = TRUE; desc.RenderTarget[0].SrcBlend = desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; desc.RenderTarget[0].DestBlend = desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; // Additive CD3D11_DEFAULT default; CD3D11_BLEND_DESC desc(default); desc.RenderTarget[0].BlendEnable = TRUE; desc.RenderTarget[0].SrcBlend = desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; desc.RenderTarget[0].DestBlend = desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; // NonPremultiplied CD3D11_DEFAULT default; CD3D11_BLEND_DESC desc(default); desc.RenderTarget[0].BlendEnable = TRUE; desc.RenderTarget[0].SrcBlend = desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; desc.RenderTarget[0].DestBlend = desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
// DepthNone CD3D11_DEFAULT default; CD3D11_DEPTH_STENCIL_DESC desc(default); desc.DepthEnable = FALSE; desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; // DepthDefault CD3D11_DEFAULT default; CD3D11_DEPTH_STENCIL_DESC desc(default); desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; // DepthRead CD3D11_DEFAULT default; CD3D11_DEPTH_STENCIL_DESC desc(default); desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
// CullNone CD3D11_RASTERIZER_DESC desc(D3D11_FILL_SOLID, D3D11_CULL_NONE, FALSE, 0, 0.f, 0.f, TRUE, FALSE, TRUE, FALSE); // CullClockwise CD3D11_RASTERIZER_DESC desc(D3D11_FILL_SOLID, D3D11_CULL_FRONT, FALSE, 0, 0.f, 0.f, TRUE, FALSE, TRUE, FALSE); // CullCounterClockwise CD3D11_RASTERIZER_DESC desc(D3D11_FILL_SOLID, D3D11_CULL_BACK, FALSE, 0, 0.f, 0.f, TRUE, FALSE, TRUE, FALSE); // Wireframe CD3D11_RASTERIZER_DESC desc(D3D11_FILL_WIREFRAME, D3D11_CULL_BACK, FALSE, 0, 0.f, 0.f, TRUE, FALSE, TRUE, FALSE);
// PointWrap CD3D11_SAMPLER_DESC desc; desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; desc.AddressU = desc.AddressV = desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; desc.MaxAnisotropy = (device->GetFeatureLevel() > D3D_FEATURE_LEVEL_9_1) ? 16 : 2; desc.MaxLOD = FLT_MAX; desc.ComparisonFunc = D3D11_COMPARISON_NEVER; // PointClamp CD3D11_SAMPLER_DESC desc; desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; desc.AddressU = desc.AddressV = desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; desc.MaxAnisotropy = (device->GetFeatureLevel() > D3D_FEATURE_LEVEL_9_1) ? 16 : 2; desc.MaxLOD = FLT_MAX; desc.ComparisonFunc = D3D11_COMPARISON_NEVER; // LinearWrap CD3D11_SAMPLER_DESC desc; desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; desc.AddressU = desc.AddressV = desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; desc.MaxAnisotropy = (device->GetFeatureLevel() > D3D_FEATURE_LEVEL_9_1) ? 16 : 2; desc.MaxLOD = FLT_MAX; desc.ComparisonFunc = D3D11_COMPARISON_NEVER; // LinearClamp CD3D11_SAMPLER_DESC desc; desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; desc.AddressU = desc.AddressV = desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; desc.MaxAnisotropy = (device->GetFeatureLevel() > D3D_FEATURE_LEVEL_9_1) ? 16 : 2; desc.MaxLOD = FLT_MAX; desc.ComparisonFunc = D3D11_COMPARISON_NEVER; // AnisotropicWrap CD3D11_SAMPLER_DESC desc; desc.Filter = D3D11_FILTER_ANISOTROPIC; desc.AddressU = desc.AddressV = desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; desc.MaxAnisotropy = (device->GetFeatureLevel() > D3D_FEATURE_LEVEL_9_1) ? 16 : 2; desc.MaxLOD = FLT_MAX; desc.ComparisonFunc = D3D11_COMPARISON_NEVER; // AnisotropicClamp CD3D11_SAMPLER_DESC desc; desc.Filter = D3D11_FILTER_ANISOTROPIC; desc.AddressU = desc.AddressV = desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; desc.MaxAnisotropy = (device->GetFeatureLevel() > D3D_FEATURE_LEVEL_9_1) ? 16 : 2; desc.MaxLOD = FLT_MAX; desc.ComparisonFunc = D3D11_COMPARISON_NEVER;