在DX11里出buffer和texture等数据对象以外,还有一类State对象,它们用于描述渲染管道中非着色器阶段。
ID3D11BlendState :此接口用于混合阶段,对混合的方式进行描述。
ID3D11DepthStencilState :创建深度缓存的时候,对深度缓存的方式进行描述。
ID3D11SamplerState:采样器相关的状态描述,这里的采样是对纹理的采样,而不是多重采样 - -。
ID3D11RasterizerState:光栅化程序状态的描述。
SamplerState是用在shader里面的,用于对纹理的采样。 RasterizerState用于光栅化的时候,制定裁剪类规则的。
ID3D11BlendState和ID3D11DepthStencilState状态用于合并阶段。
ID3D11BlendState :
HRESULT CreateBlendState( [in] const D3D11_BLEND_DESC *pBlendStateDesc, [out] ID3D11BlendState **ppBlendState ); typedef struct D3D11_BLEND_DESC { BOOL AlphaToCoverageEnable; // 混合是否覆盖多重采样 BOOL IndependentBlendEnable; // 如果true 所有的渲染都会被混合,如果为false 只会混合第一个渲染目标 D3D11_RENDER_TARGET_BLEND_DESC RenderTarget[8]; // } D3D11_BLEND_DESC; typedef struct D3D11_RENDER_TARGET_BLEND_DESC { BOOL BlendEnable; // 是否启用混合 true = 是 D3D11_BLEND SrcBlend; // 源rgb混合 D3D11_BLEND DestBlend; // 目标rgb混合 D3D11_BLEND_OP BlendOp; // D3D11_BLEND SrcBlendAlpha; // 源a混合 D3D11_BLEND DestBlendAlpha; // 目标a混合 D3D11_BLEND_OP BlendOpAlpha; // UINT8 RenderTargetWriteMask; // } D3D11_RENDER_TARGET_BLEND_DESC; typedef enum D3D11_BLEND_OP { // 混合的规则 D3D11_BLEND_OP_ADD = 1, // 相加 D3D11_BLEND_OP_SUBTRACT = 2, // 相减 D3D11_BLEND_OP_REV_SUBTRACT = 3, // 不懂 D3D11_BLEND_OP_MIN = 4, // 获取两个中较小的一个 D3D11_BLEND_OP_MAX = 5 // 获取两个中较大的一个 } D3D11_BLEND_OP;
这里需要注意的是RenderTarget[8]是一个数组,这是因为混合是与渲染目标对应的。
ID3D11DepthStencilState :(模板:贴花,镜面 深度:很多其它用途)
深度/模板状态,用来控制是否进行深度检测或模板检测,此外在OM的时候目标渲染对象可能有多个但是深度/模板缓存只有一个。
HRESULT CreateDepthStencilState( [in] const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc, [out] ID3D11DepthStencilState **ppDepthStencilState ); typedef struct D3D11_DEPTH_STENCIL_DESC { BOOL DepthEnable; // 是否开启深度缓存,true = 是 D3D11_DEPTH_WRITE_MASK DepthWriteMask; // 控制是否允许写入 D3D11_COMPARISON_FUNC DepthFunc; // 深度比较函数 BOOL StencilEnable; // 是否开启模板缓存,true = 是 UINT8 StencilReadMask; // 默认:D3D11_DEFAULT_STENCIL_READ_MASK UINT8 StencilWriteMask; // 默认:D3D11_DEFAULT_STENCIL_WRITE_MASK D3D11_DEPTH_STENCILOP_DESC FrontFace; // 面向摄像机的面 D3D11_DEPTH_STENCILOP_DESC BackFace; // 背向摄像机的面 } D3D11_DEPTH_STENCIL_DESC; typedef enum D3D11_DEPTH_WRITE_MASK { D3D11_DEPTH_WRITE_MASK_ZERO = 0, // 不允许写入 D3D11_DEPTH_WRITE_MASK_ALL = 1 // 允许写入 } D3D11_DEPTH_WRITE_MASK; typedef enum D3D11_COMPARISON_FUNC { //比较的规则 (源=新,目标=旧,满足比较就把源写入到深度缓存) D3D11_COMPARISON_NEVER = 1, // 不进行比较 D3D11_COMPARISON_LESS = 2, // 源<目标 D3D11_COMPARISON_EQUAL = 3, // 源=目标 D3D11_COMPARISON_LESS_EQUAL = 4, // 源<=目标 D3D11_COMPARISON_GREATER = 5, // 源>目标 D3D11_COMPARISON_NOT_EQUAL = 6, // 源!=目标 D3D11_COMPARISON_GREATER_EQUAL = 7, // 源>=目标 D3D11_COMPARISON_ALWAYS = 8 // 直接通过比较(直接写入) } D3D11_COMPARISON_FUNC; typedef struct D3D11_DEPTH_STENCILOP_DESC {1-3 是用来对模板进行操作的,但是尽然只有三种状态 D3D11_STENCIL_OP StencilFailOp; // 模板测试失败 D3D11_STENCIL_OP StencilDepthFailOp; // 模板测试通过,深度测试失败 D3D11_STENCIL_OP StencilPassOp; // 模板测试和深度测试都通过 D3D11_COMPARISON_FUNC StencilFunc; // 与深度的比较规则类型是一样的 } D3D11_DEPTH_STENCILOP_DESC; typedef enum D3D11_STENCIL_OP { D3D11_STENCIL_OP_KEEP = 1, // 保持现状 D3D11_STENCIL_OP_ZERO = 2, // 值设置为0? D3D11_STENCIL_OP_REPLACE = 3, // 替换掉(得知道如何替换) D3D11_STENCIL_OP_INCR_SAT = 4, // 模板值递增1,夹紧的结果? D3D11_STENCIL_OP_DECR_SAT = 5, // 模板值递减1,夹紧的结果? D3D11_STENCIL_OP_INVERT = 6, // 反转模板数据 D3D11_STENCIL_OP_INCR = 7, // 模板值递增1,包装的结果 D3D11_STENCIL_OP_DECR = 8 // 模板值递减1,包装的结果?不懂 } D3D11_STENCIL_OP;
这个状态操作起来比较复杂,主要是对深度和模板进行比较并对其相应位进行修改。
ID3D11RasterizerState :(3D->2D,剔除和裁剪)
光栅化过程是变3维为2维的过程,并且伴随剔除背面和裁剪的操作,它发生在顶点类着色器之后,像素着色器之前,是它确定调用那个像素着色器的。
HRESULT CreateRasterizerState( [in] const D3D11_RASTERIZER_DESC *pRasterizerDesc, [out] ID3D11RasterizerState **ppRasterizerState ); typedef struct D3D11_RASTERIZER_DESC { D3D11_FILL_MODE FillMode; // 填充形式 D3D11_CULL_MODE CullMode; // 这个是剔除方式 BOOL FrontCounterClockwise; // 确定三角形的正反面,true为正面 INT DepthBias; // 深度值,会添加到一个给定的像素,深度模板上的。 FLOAT DepthBiasClamp; // 最大的深度偏差 FLOAT SlopeScaledDepthBias; // 给定像素的斜率 BOOL DepthClipEnable; // 设置深度是否被裁剪,true为被裁剪 BOOL ScissorEnable; // 设置是否启用裁剪,true启用 BOOL MultisampleEnable; // 是否启用多重采样抗锯齿 BOOL AntialiasedLineEnable; // 是否启用线性抗锯齿,如果多重为false,它为true才行 } D3D11_RASTERIZER_DESC; typedef enum D3D11_FILL_MODE { D3D11_FILL_WIREFRAME = 2, // 填充为线框 D3D11_FILL_SOLID = 3 // 填充为实心 } D3D11_FILL_MODE; typedef enum D3D11_CULL_MODE { D3D11_CULL_NONE = 1, // 不剔除任何三角形 D3D11_CULL_FRONT = 2, // 剔除面向正面的三角形 D3D11_CULL_BACK = 3 // 剔除面向背面的三角形 } D3D11_CULL_MODE;
例子:光栅扫描规则
ID3D11RasterizerState1 * g_pRasterState; D3D11_RASTERIZER_DESC1 rasterizerState; rasterizerState.FillMode = D3D11_FILL_SOLID; rasterizerState.CullMode = D3D11_CULL_FRONT; rasterizerState.FrontCounterClockwise = TRUE; rasterizerState.DepthBias = FALSE; rasterizerState.DepthBiasClamp = 0; rasterizerState.SlopeScaledDepthBias = 0; rasterizerState.DepthClipEnable = TRUE; rasterizerState.ScissorEnable = TRUE; rasterizerState.MultisampleEnable = FALSE; rasterizerState.AntialiasedLineEnable = FALSE; rasterizerState.ForcedSampleCount = 0; pd3dDevice - > CreateRasterizerState1(rasterizerState,g_pRasterState);