第4章 DIRECT3D初始化及4.1初步

Direct3D的初始化过程要求我们熟悉一些基本的Direct3D类型和基本的图形概念; 本章的第一部分和第二部分解决了这些要求。 然后我们详细介绍初始化Direct3D的必要步骤。 接下来,我们将采取一个小小的弯路来为实时图形应用程序引入准确的时序和时间测量。 最后,我们探索示例框架代码,该代码用于提供本书中所有演示应用程序遵循的一致接口。

目标:
1.了解Direct3D在3D硬件编程中的作用。
2.了解COM在Direct3D中扮演的角色。
3.学习基本的图形概念,例如如何存储2D图像,翻页,深度缓冲,多重采样以及CPU和GPU如何交互。
4.了解如何使用性能计数器功能获取高分辨率定时器读数。
5.了解如何初始化Direct3D。

6.熟悉本书所有演示应用的应用程序框架的一般结构。

4.1初步

Direct3D初始化过程要求我们熟悉一些基本的图形概念和Direct3D类型。 我们在这一节中介绍这些想法和类型,以便我们在覆盖初始化过程时不必离题。

4.1.1 Direct3D 12概述
Direct3D是一款低级图形API(应用程序编程接口),用于从我们的应用程序中控制和编程GPU(图形处理单元),从而允许我们使用硬件加速渲染虚拟3D世界。例如,要向GPU提交命令以清除渲染目标(例如,屏幕),我们将调用Direct3D方法ID3D12CommandList :: ClearRenderTargetView。 Direct3D层和硬件驱动程序会将Direct3D命令转换为系统GPU可以理解的本地机器指令;因此,我们不必担心GPU的细节,只要它支持我们正在使用的Direct3D版本即可。为了做到这一点,NVIDIA,英特尔和AMD等GPU供应商必须与Direct3D团队合作并提供兼容的Direct3D驱动程序。

Direct3D 12增加了一些新的渲染功能,但与以前版本相比的主要改进是,它已经过重新设计,可显着降低CPU开销并改善多线程支持。为了实现这些性能目标,Direct3D 12已经成为比Direct3D 11低得多的API;它具有较少的抽象性,需要开发人员额外的手动“簿记”,并且更加贴近现代GPU架构。当然,改进的性能是使用这个更难的API的奖励。

4.1.2 COM
组件对象模型(COM)是允许DirectX独立于编程语言并具有向后兼容性的技术。我们通常将一个COM对象称为一个接口,这对我们而言可以被认为是一个C ++类。在使用C ++编程DirectX时,COM的大部分细节对我们来说都是隐藏的。我们唯一必须知道的是,我们通过特殊函数或另一个COM接口的方法获得指向COM接口的指针 - 我们不用C ++ new关键字创建COM接口。另外,COM对象被引用计数;当我们完成一个接口的时候,我们调用它的Release方法(所有的COM接口继承了提供Release方法的IUnknown COM接口的功能)而不是删除它 - 当COM对象的引用计数变为0时,COM对象将释放它们的内存。

 为了帮助管理COM对象的生命周期,Windows运行时库(WRL)提供了Microsoft :: WRL :: ComPtr类(#include <wrl.h>),它可以被看作是COM对象的智能指针。当一个ComPtr实例超出范围时,它会自动调用底层COM对象上的Release,从而使我们不必手动调用Release。我们在本书中使用的三种主要的ComPtr方法是:

ComPtr<IDX> x;开始定义COM 指针x,IDX:COM接口名为IDX,x:COM接口指针名为x。当我们使用时只需要调用x的相关函数x.Get()获得x和x.GetAddressOf()获得x的地址

1.Get:返回一个指向底层COM接口的指针。这通常用于将参数传递给采用原始COM接口指针的函数。例如:

ComPtr<ID3D12RootSignature> mRootSignature;

// SetGraphicsRootSignature expects ID3D12RootSignature* argument.

mCommandList->SetGraphicsRootSignature(mRootSignature.Get());

2. GetAddressOf:返回指向底层COM接口的指针的地址。 这通常用于通过函数参数返回COM接口指针。 例如:

ComPtr<ID3D12CommandAllocator>mDirectCmdListAlloc;

ThrowIfFailed(md3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,mDirectCmdListAlloc.GetAddressOf()));

3.Reset:将ComPtr实例设置为nullptr,并减少底层COM接口的引用计数。 等价地,您可以将nullptr分配给ComPtr实例。当然,对于COM来说更是如此,但更多细节对于有效使用DirectX并不是必需的。

COM接口前缀为大写I.例如,表示命令列表的COM接口称为ID3D12GraphicsCommandList。

4.1.3纹理格式

2D纹理是数据元素的矩阵。 2D纹理的一个用途是存储2D图像数据,其中纹理中的每个元素存储像素的颜色。但是,这不是唯一的用法;例如,在一种称为法线贴图的高级技术中,纹理中的每个元素都会存储3D矢量而不是颜色。因此,尽管通常将纹理视为存储图像数据,但它们确实比这更通用。一维纹理就像一维数据元素阵列,二维纹理就像一个二维数据元素阵列,而三维纹理就像一个三维数据元素阵列。正如后面的章节将要讨论的那样,纹理实际上不仅仅是数据数组,它们可以具有mipmap级别,并且GPU可以对它们执行特殊操作,例如应用滤镜和多重采样。

另外,纹理不能存储任意类型的数据元素;它只能存储某些类型的数据元素格式,这些格式由DXGI_FORMAT枚举类型描述。一些示例格式是:

1. DXGI_FORMAT_R32G32B32_FLOAT:每个元素都有三个32位浮点组件。
2. DXGI_FORMAT_R16G16B16A16_UNORM:每个元素有四个映射到[0,1]范围的16位组件。
3. DXGI_FORMAT_R32G32_UINT:每个元素都有两个32位无符号整数分量。
4. DXGI_FORMAT_R8G8B8A8_UNORM:每个元素有四个映射到[0,1]范围的8位无符号分量。
5. DXGI_FORMAT_R8G8B8A8_SNORM:每个元素都有四个映射到[-1,1]范围的8位有符号分量。
6. DXGI_FORMAT_R8G8B8A8_SINT:每个元素都有四个映射到[-128,127]范围的8位有符号整数分量。

7. DXGI_FORMAT_R8G8B8A8_UINT:每个元素都有四个映射到[0,255]范围的8位无符号整数分量。

请注意,R,G,B,A字母分别代表红色,绿色,蓝色和alpha。 颜色形成为红色,绿色和蓝色基础颜色的组合(例如,等红和等绿显示黄色)。 alpha通道或alpha组件通常用于控制透明度。 但是,正如我们前面所说,纹理不需要存储颜色信息,即使格式名称暗示它们的确存在。 例如格式

DXGI_FORMAT_R32G32B32_FLOAT

有三个浮点组件,因此可以存储任何带有浮点坐标的3D矢量。 也有无类型的格式,我们只保留内存,然后指定如何在纹理绑定到管道时稍后重新解释数据(类似于C ++ reinterpret强制转换); 例如,以下无类型格式保留具有四个16位组件的元素,但不指定数据类型(例如,整数,浮点,无符号整数):

DXGI_FORMAT_R16G16B16A16_TYPELESS

我们将在第6章中看到,DXGI_FORMAT枚举类型也用于描述顶点数据格式和索引数据格式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值