Directx11 渲染阶段

    D3D基本上是一个状态机。其中的事物都会停留在当前的状态,直到我们去改变他们。例如我们之前看到的,输入布局,顶点缓冲区,索引缓冲区在绑定到输入装备阶段后驻留在那,直到我们绑定其他的缓冲;同样地,当前设置的图元拓扑在它被改变之前一直都生效。另外,D3D具有状态组,可以封装用来配置D3D的设置。

    1.ID3D11RasterizerState:该接口表示用于配置光栅化阶段的状态组。
    2.ID3D11BlendState:该接口表示配置混合操作的状态组。默认设置中,混合是禁用的,所以暂时不用管它。
    3.ID3D11DepthStencilState:该接口表示用于配置深度和模版的状态组。默认设置中,模版是禁用的,所以暂时不用管它。默认的深度测试设置是标准深度测试。

    目前,我们唯一关注的状态块接口是ID3D11RasterizerState接口。我们可以通过填写一个D3D11_RASTERIZER_DESC结构体来创建一个该类型的接口并调用它。

HRESULT ID3D11Device::CreateRasterizerState(
    const D3D11_RASTERIZER_DESC *pRasterizerDesc,
    ID3D11RasterizerState **ppRasterizerState);

    第一个参数是D3D11_RASTERIZER_DESC的指针,用于描述创建的光栅化状态块。第二个参数用于返回一个已创建好的ID3D11RasterizerState接口的指针。
    ID3D11RasterizerState定义如下:

typedef struct D3D11_RASTERIZER_DESC {
    D3D11_FILL_MODE FillMode; // Default: D3D11_FILL_SOLID
    D3D11_CULL_MODE CullMode; // Default: D3D11_CULL_BACK
    BOOL FrontCounterClockwise; // Default: false
    INT DepthBias; // Default: 0
    FLOAT DepthBiasClamp; // Default: 0.0f
    FLOAT SlopeScaledDepthBias; // Default: 0.0f
    BOOL DepthClipEnable; // Default: true
    BOOL ScissorEnable; // Default: false
    BOOL MultisampleEnable; // Default: false
    BOOL AntialiasedLineEnable; // Default: false
} D3D11_RASTERIZER_DESC;

    大多数成员都是高级的或者很少用到的;因此, 若要全部了解就自个儿去查SDK。现在只说前三个。

    1.FillMode:指定D3D11_FILL_WIREFRAME就是线框渲染;指定D3D11_FILL_SOLID就是实体渲染。
    2.CullMode:指定D3D11_CULL_NONE禁用剔除;指定D3D11_CULL_BACK剔除面朝后方的三角形;指定D3D11_CULL_FRONT剔除面朝前方的三角形。
    3.FrontCounterClockwise:指定为false时三角形为顺时针方向(相对于相机)为正面;指定为true时,三角形的逆时针方向(相对于相机)为正面。

    一旦一个ID3D11RasterizerState对象被创建,我们可以用新的状态块去更新设备:

void ID3D11DeviceContext::RSSetState(ID3D11RasterizerState *pRasterizerState);

    如下代码展示了如何创建一个禁用剔除的光栅化状态:

D3D11_RASTERIZER_DESC rsDesc;
ZeroMemory(&rsDesc, sizeof(D3D11_RASTERIZER_DESC));
rsDesc.FillMode = D3D11_FILL_SOLID;
rsDesc.CullMode = D3D11_CULL_NONE;
rsDesc.FrontCounterClockwise = false;
rsDesc.DepthClipEnable = true;
HR(md3dDevice->CreateRasterizerState(&rsDesc, &mNoCullRS));

    注意,对于一个应用,你可能需要多个不同的ID3D11RasterizerState对象。所以你应该在初始化阶段创建它们,然后根据需要在更新/绘制代码里切换它们。例如,假定你有两个物体,而且你希望用线框模式绘制第一个,用实体模式绘制第二个。那么你需要用两个ID3D11RasterizerState对象,并在绘制两个物体的时候切换它们。

// Create render state objects as initialization time.
ID3D11RasterizerState* mWireframeRS;
ID3D11RasterizerState* mSolidRS;
...
// Switch between the render state objects in the draw function.
md3dImmediateContext->RSSetState(mSolidRS);
DrawObject();
md3dImmediateContext->RSSetState(mWireframeRS);
DrawObject();

    注意,D3D不会存储之前设置的状态。因此,当你绘制一个对象时,你通常需要设置状态。为当前状态做出不正确的假设通常会导致不正确的输出。
    每一个状态快有一个默认的阶段。我们可以通过调用RSSetState方法指定空值来恢复回默认状态。

// Restore default state.
md3dImmediateContext->RSSetState(0);

 

你可能感兴趣的:(dx11)