【翻(xue)译(xi)】3D Game Programming With DirectX11 - 4.2

来源:互联网 发布:阿里云域名 跳转 编辑:程序博客网 时间:2024/04/28 16:45

4.2 初始化Direct3D

初始化Direct3D可以被分成以下步骤:
(1) 使用D3DCreateDevice来创建一个ID3D11Device 和 ID3D11DeviceContextd接口;
(2) 使用ID3D11Device::CheckMultisampleQualityLevels来检查4重采样抗锯齿所支持的质量等级;
(3) 填充一个DXGI_SWAP_CHAIN_DESC 来描述我们将要创建的交换链实例;
(4) 查询我们创建设备时使用的IDXGIFactory实例,然后创建一个IDXGISwapChain实例;
(5) 创建一个渲染对象视图到后台缓存;
(6) 创建 深度/模板缓存,它和 深度/模板视图是对应的
(7) 把渲染对象和深度/模板缓存都绑定到渲染管线的输出阶段,这样一来他们可以被Direct3D使用
(8) 设置一个观看的视角

4.2.1 创建设备和环境
初始化Direct3D首先要创建设备(ID3D11Device)和环境(ID3d11DeviceContext)。这两个接口是Direct3D的主要接口,可以让我们用软件控制物理硬件。比如我们可以在GPU中开辟内存,清除后台缓存,把资源绑定到不同的渲染阶段,画几何体,等。
(1) ID3D11Device接口用来检查我们的版本支持,和为资源开辟内存
(2) ID3D11DeviceContext接口用来设置渲染阶段,绑定资源到图形管线,发出渲染指令
我们使用下面这个函数来创建设备和环境:
HRESULT D3D11CreateDevice( 创建渲染设备和环境
IDXGIAdapter *pAdapter,想要让设备成为的适配器(null为默认)
D3D_DRIVER_TYPE DriverType, 驱动类型(D3D_DRIVER_TYPE_HARDWARE)
HMODULE Software, 软件驱动(常为null因为楼上hardware)
UINT Flags, (可选)创建设备时的标识(可以位运算到一块)
CONST D3D_FEATURE_LEVEL *pFeatureLevels, 特征级的数组(见前文)
UINT FeatureLevels, 上边那个数组的长度。上边null则这里0
UINT SDKVersion, 就是 D3D11_SDK_VERSION
ID3D11Device **ppDevice, 我们的Device接口
D3D_FEATURE_LEVEL *pFetureLevel, 最高支持的特征级
ID3D11DeviceContext **ppImmediateContext, 我们的DeviceContext接口
);
DriverType一般被设置为D3D_DRIVER_TYPE_HARDWARE ,不过也有以下选项:
D3D_DRIVER_TYPE_REFERENCE: 创建一个参考设备。参考设备是用软件渲染的,一般是为了正确性,它十分慢。这个只对开发者开放,不应该用在正式应用中。只有两种情况下会使用这个参考设备:
1) 检查你的硬件是否支持你的代码,比如当你没有Direct3D11图形卡的时候检查你的Direct3D11代码。
2) 检查驱动的bug。如果你的代码在之前的设备运行正常但是这个不行的时候可能你的驱动有问题
3D_DRIVER_TYPE_SOFTWARE: 创建一个软件驱动来模拟3d硬件。为了使用一个一个软件驱动程序,你必须建立一个你自己的或者使用一个第三方的软件驱动。不同于下边将要提到的WARP,Direct3D并不提供一个软件驱动
D3D_DRIVER_TYPE_WARP: 创建一个高表现的Direct3D 10.1 软件驱动。WARP(Windows Advanced Rasterization Platform)。我们不感兴趣因为11不支持啊哈。
Flags 创建设备的标识,常用的有以下:
D3D11_CREATE_DEVICE_DEBUG: 用于debug模式,如果要debug的话这个flag应该被设置。此时Direct3D会发送debug信息到vc++的输出窗口。
D3D_CREATE_DEVICE_SINGLETHREADED: 如果你能保证Direct3D不会被多线程调用的话,这个可以提高性能。如果这个flag被设置了的话,ID3D11Device::CreateDeferredContext 这个功能将会失败。

然后作者举了一个程序的栗子。
Tips: 注意到,我们把我们的设备环境叫做立即的环境。其实,也有一个类似的叫做延期的环境:ID3D11Device::CreateDeferredContext。这是DX11所支持的多线程的一部分。多线程作为高级主题本书中不讲,不过它的基本思想是这样的:
1) 在主线程上使用立即的环境
2) 在独立的其他工作线程上使用延期的环境
每一个工作线程都可以记录图形卡命令到一个命令列表(ID3DCommandList);每个工作线程的命令列表都可以被主渲染线程执行。
如果命令列表的收集需要时间,比如复杂的图形渲染会出现这一情况,那么在平行线程中收集这些命令就有优势了。

4.2.2 检查4倍 多重采样反走样的质量等级的支持性
现在我们已经创建了一个设备了。我们可以开始检查多重采样所支持的质量等级了。还记得那年我们讲过的DX11会支持所有渲染目标格式的多重采样吗?不过它支持的质量等级可能不一样。
因为设备总是支持的,所以我们检查出来的质量等级应该总是大于0的。

4.2.3 描述交换链
接下来我们要创建一个交换链。首先我们要填充一个 DXGI_SWAP_CHAIN_DESC 结构体实例。这个实例描述了我们要创建的交换链。
Tips: 如果你想要在运行时改变多重采样的设置,你得重新创建后台缓存了
Tips: 我们使用DXGI_FORMAT_R8G8B8A8_UNORM 这个格式作为后台缓存的像素格式,因为显示器一般不支持24位以上的颜色,所以多余的精度就被浪费了。多余的8位alpha值,不会被显示在显示器上,但是有它我们可以做一些别的事情。

4.2.4 创建交换链
交换链(IDXGISwapChain)是由一个IDXGIFactory实例,通过IDXGIFactory::CreateSwapChain这个方法创建的。
我们可以通过CreateDXGIFactory这个函数获得一个纸箱IDXGIFactory实例的指针。不过,如果我们获得这样的一个IDXGIFactory实例,然后再调用CreateSwapChain,我们会报这个错:
DXGI Warning: IDXGIFactory::CreateSwapChain: 这个函数正在调用的设备是另外一个IDXGIFactory上的。
正确的方法是,使用那个创建设备的IDXGIFactory来创建后处理链。为了得到这个实例,我们通过以下COM查询来得到。

Tips: DXGI(DirectX Graphics Infrastructure )(DX图形基础设施)是一个独立于Direct3D的API,它处理图像相关的东西,比如说交换链、枚举图形硬件、切换全屏模式。之所以把它做成独立的API,是因为其他例如Direct2D也会需要交换链、枚举图形硬件、切换全屏模式。这样一来,多种图形API都可以使用DXGI API。

4.2.5 创建渲染目标视图
如前所述,我们不需要把资源直接绑定到管线的某个阶段。我们需要创建一个资源视图给这个资源,然后把这个资源视图绑定到这个管线阶段。准确的说,为了把后台缓存绑定到管线的输出阶段(从而Direct3D可以渲染它),我们需要给后台缓存创建一个渲染目标视图。例子如下。
ID3D11RenderTargetView *mRenderTargetView;
ID3D11Texture2D *backBuffer;
mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
reinterpret_cast

翻译存疑:

reference device: 参考设备
WARP(Windows Advanced Rasterization Platform):?
This function is being called from a device from a different IDXGIFactory.:这个函数正在调用的设备是另外一个IDXGIFactory上的
mipmap level: 多纹理映射的级别/多分辨率纹理
usage flag: 用途标签
CPU access flag: CPU 权限标志
output merger state: 输出混合阶段
viewpoint: 视窗

0 0
原创粉丝点击