Direct3D 11 渲染状态

转载 2015年07月08日 11:40:13

从本质上讲,Direct3D是一个状态机(state machine)。在我们改变它的状态之前,驻留在状态机内的当前状态是不会改变的。例如,我们在6.1节、6.2节和6.3节中看到,当顶点缓冲和索引缓冲绑定到管线的输入装配阶段时,如果我们不绑定其他缓冲,那么它们就会一直驻留在那里;同样,在没有改变图元拓扑之前,当前的图元拓扑设置会一直有效。另外,Direct3D将配置信息封装在状态组中,我们可以使用如下3种状态组配置Direct3D:

1.ID3D11RasterizerState:该接口表示用于配置管线光栅化阶段的状态组。

2.ID3D11BlendState:该接口表示用于配置混合操作的状态组。我们将在有关混合的章节讨论这些状态;默认情况下,混合处于禁用状态,所以我们可以先不考虑这方面的问题。

3.ID3D11DepthStencilState:该接口表示用于配置深度测试和模板测试的状态组。我们将在有关模板缓冲的章节讨论这些状态;默认情况下,模板是禁用的,所以我们可以先不考虑这方面的问题。而默认的深度测试是我们在4.1.5节描述的标准深度测试。

目前,我们唯一需要关心的状态块接口是ID3D11RasterizerState。我们可以通过填充一个D3D11_RASTERIZER_DESC结构体并调用如下方法来创建ID3D11RasterizerState对象:

?
1
2
3
HRESULT ID3D11Device::CreateRasterizerState(
    const D3D11_RASTERIZER_DESC *pRasterizerDesc,
    ID3D11RasterizerState **ppRasterizerState);

第1个参数是一个指向D3D11_RASTERIZER_DESC结构体的指针,该结构体用于描述所要创建的光栅化状态块;第二个参数用于返回创建后的ID3D11RasterizerState对象。

D3D11_RASTERIZER_DESC结构体的定义如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
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;

这里面的大部分成员是高级选项或者不常用的选项;因此,我们在这里只讲解前3个成员的含义,其他成员的详情请参见SDK文档。

1.FillMode:当指定为D3D11_FILL_WIREFRAME时,表示以线框模式渲染几何体;当指定为D3D11_FILL_SOLID时,表示以实心模式渲染几何体,这是默认值。

2.CullMode:当指定为D3D11_CULL_NONE时,表示禁用背面消隐功能;当指定为D3D11_CULL_FRONT时,表示消隐朝前的三角形;当指定为D3D11_CULL_BACK时,表示消隐朝后的三角形,这是默认值。

3.FrontCounterClockwise:当设为false时,表示按顺时针方向环绕的三角形(相对于观察者)是朝前的,而按逆时针方向环绕的三角形(相对于观察者)是朝后的,这是默认值。当设为true时,表示按逆时针方向环绕的三角形(相对于观察者)是朝前的,而按顺时针方向环绕的三角形(相对于观察者)是朝后的。

在创建ID3D11RasterizerState对象之后,我们可以使用个新的状态块来更新设备:

?
1
void ID3D11DeviceContext::RSSetState(ID3D11RasterizerState *pRasterizerState);

下面的代码示范了如何通过创建一个光栅化状态块来禁用背面消隐:

?
1
2
3
4
5
6
7
8
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));

注意:因为没有设置的属性的默认值是0或false,所以使用ZeroMemory可以正常初始化这些属性。但是,若有些属性默认值不是0或是true,那么你就必须显式地设置这些值。

注意,对于一个应用程序来说,你可能会用到多个不同的ID3D11RasterizerState对象。所以,你应该在初始化时把它们都创建出来,然后在应用程序的更新/绘图代码中切换些状态。例如,场景中有两个物体,你希望先以线框模式绘制第一个物体,然后再以实心模式绘制第二个物体。那么,你就应该创建两个ID3D11RasterizerState对象,当绘制物体时,切换这两种不同的状态:

?
1
2
3
4
5
6
7
8
9
// 在初始化时创建绘制状态对象
ID3D11RasterizerState* mWireframeRS;
ID3D11RasterizerState* mSolidRS;
...
// 在draw方法中切换渲染状态对象
md3dDeviceContext->RSSetState(mSolidRS);
DrawObject();
md3dDeviceContext->RSSetState(mWireframeRS);
DrawObject();

注意,Direct3D不会从一种状态自动恢复到先前状态。所以,当绘制物体时,你应该根据需要手工指定状态对象。错误地假设设备的当前状态必然会导致错误的渲染结果。每个状态块都有一个默认状态。我们可以通过在调用RSSetState方法时指定空值来恢复默认状态:

?
1
md3dDeviceContext->RSSetState( 0 );

注意:应用程序无需在运行时创建额外的渲染状态组。所以,应该在初始化时就定义并创建所有需要用到的状态组。而且,因为无需在运行时修改状态组,你可以在渲染代码中对这些状态组提供全局只读访问。例如,你可以将所有状态组对象放置在一个静态类中,通过这个方法,你就无需创建重复的状态组,渲染代码的不同部分都能共享这个渲染状态组对象。

DirectX11 渲染状态

渲染状态 1. 渲染状态有哪几种? 从本质上讲,Direct3D是一个状态机(state machine)。在我们改变它的状态之前,驻留在状态机内的当前状态是不会改变的。例如,我们在6.1节、6....
  • sinat_24229853
  • sinat_24229853
  • 2015年09月30日 09:39
  • 1237

D3D11 渲染状态

这儿是在上一个博客基础上修改转换代码。在D3D中,物体都是停留在当前状态中的,没有物体会回退到它的“默认”状态。比如图元拓扑,一旦设置了它,就像之前在一个三角形列表中所做的一样,除非显式的去改变它,否...
  • huhaoxuan2010
  • huhaoxuan2010
  • 2017年09月28日 08:39
  • 425

NULL, '\0',0 '0'的区别

如题,在程序中经常遇到NULL,和'\0',常常疑惑它们是什么关系,其实它们的值是一样的,只不过表现的形式不一样:   1、NULL; NULL 即空指针,在C和C++中的形式不一样,msdn上有...
  • mylinx
  • mylinx
  • 2011年10月14日 14:11
  • 117787

链接:http://pan.baidu.com/s/1geeQWrp 密码:lhqq

链接:http://pan.baidu.com/s/1geeQWrp 密码:lhqq
  • ilovemayverymuch
  • ilovemayverymuch
  • 2015年12月20日 23:00
  • 54316

关于api-ms-win-crt-runtimel1-1-0.dll缺失的解决方案

关于api-ms-sin-crt-runtimel1-1-0.dll缺失的解决方案目录关于api-ms-sin-crt-runtimel1-1-0dll缺失的解决方案 安装VC reditexe程序解...
  • huqiao1206
  • huqiao1206
  • 2016年02月29日 21:30
  • 1055558

Direct3D进行Alpha混合实现半透明效果(演示程序)

  • 2012年02月26日 13:56
  • 440KB
  • 下载

【分享】PotPlayer播放器【整合硬盘版】[带LAV0.68+madVR0.90.13+234皮肤+OpenCodec解码+DSP插件++mad设置注册表+电视直播+免设置&卸载补丁]

本人一直使用pot播放动漫,一直没时间测试下,今日有时间试了下,果然效果真心不错,设置后不但比原720P,1080P使用后清晰度提升了一个阶段。更连一些80年代老番只有480P的片源都提升到清晰度。对...
  • wangzi867258173
  • wangzi867258173
  • 2016年03月27日 22:07
  • 6099

DirectX学习笔记(八):Direct3D融合技术详解及物体透明效果的实现

前言: 融合技术,将当前要进行光栅化的像素的颜色与先前已经光栅化并处于同一位置的像素的颜色进行合成,即:将正在处理的图元颜色值与存储在后台缓存中的像素颜色值进行合成,利用该技术,可以获得很多种效果...
  • lishuzhai
  • lishuzhai
  • 2016年09月18日 22:03
  • 3350

DirectX11 Direct3D基本概念

Direct3D基本概念 1. Direct3D概述 Direct3D是一种底层绘图API(application programming interface,应用程序接口),它可以让我们可以通过...
  • sinat_24229853
  • sinat_24229853
  • 2015年09月27日 19:58
  • 2711

从 Direct3D 9 到 Direct3D 11 的重要更改

本主题介绍 DirectX 9 和 DirectX 11 之间更高级别的差异。 从根本上说,Direct3D 11 与 Direct3D 9 是同类型的 API - 一种到图形硬件的低级别虚拟化...
  • pizi0475
  • pizi0475
  • 2015年06月08日 18:52
  • 2620
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Direct3D 11 渲染状态
举报原因:
原因补充:

(最多只允许输入30个字)