在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]是一个数组,这是因为混合是与渲染目标对应的。
D3D11_BLEND
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;
这个状态操作起来比较复杂,主要是对深度和模板进行比较并对其相应位进行修改。
ID3D11SamplerState :
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);