DirectX11学习笔记(1)准备工作与预备知识

一、学习目标

1.对 Direct3D 在规划调度 3D 硬件方面所起的作用有一个基本了解。
2.理解 COM 在 Direct3D 运行时起到的作用。
3.学习基本的绘图概念,比如 2D 图像的存储方式、页面翻转、深度缓存和多重采样。

二、Direct3D 概述

Direct3D 是一种底层绘图 API(application programming interface,应用程序接口), 它可以让我们可以通过 3D 硬件加速绘制 3D 世界。从本质上讲,Direct3D 提供的是一组软件接口,我们可以通过这组接口来控制绘图硬件。
例如,要命令绘图设备清空渲染目标(例如屏幕),我们可以调用 Direct3D 的ID3D11DeviceContext::ClearRenderTargetView 方法来完成这一工作。
Direct3D 层位于应用程序和绘图硬件之间,这样我们就不必担心 3D 硬件的 实现细节,只要设备支持 Direct3D11,我们就可以通过 Direct3D11API 来控制 3D 硬件了。
支持Direct3D 11的设备必须支持Direct3D11规定的整个功能集合以及少数的额外附加功能(有一些功能,比如多重采样数量,仍然需要以查询方式实现,这是因为不同的 Direct3D 硬件这个值可能并不一样)。
在 Direct3D 9 中,设备可以只支持 Direct3D 9 的部分功能;所以,当一个 Direct3D 9 应用程序要使用某一特性时,应用程序就必须先检查硬件是否支持该特性。如果要调用的是一个不为硬件支持Direct3D函数,那应用程序就会出错。 而在Direct3D 11 中,不需要再做这种设备功能检查,因为 Direct3D 11 强制要求设备实现 Direct3D 11 规定的所有功能特性。

三、COM

组件对象模型(COM)技术使 DirectX 独立于任何编程语言,并具有版本向后兼容的特性。
我们经常把 COM 对象称为接口,并把它当成一个普通的 C++类来使用。
当使用 C++ 编写 DirectX 程序时,许多 COM 的底层细节都不必考虑。
唯一需要知道的一件事情是,我们必须通过特定的函数或其他的COM接口方法来获取指向COM接口的指针,而不能用C++的 new 关键字来创建 COM 接口。
另外,当我们不再使用某个接口时,必须调用它的 Release 方法来释放它(所有的 COM 接口都继承于 IUnknown 接口,而 Release 方法是 IUnknown 接口的成员),而不能用 delete 语句——COM 对象在其自身内部实现所有的内存管理工作。 当然,有关 COM 的细节还有很多,但是在实际工作中只需知道上述内容就足以有效地使用 DirectX 了。 注意:COM 接口都以大写字母“I”为前缀。例如,表示 2D 纹理的接口为 ID3D11Texture2D

四、纹理与资源格式

2D 纹理(texture)是一种数据元素矩阵。2D 纹理的用途之一是存储 2D 图像数据,在 纹理的每个元素中存储一个像素颜色。但这不是纹理的唯一用途;例如, 有种称为法线 贴图映射(normal mapping)的高级技术在纹理元素中存储的不是颜色,而是 3D 向量。因此,从通常意义上讲,纹理用来存储图像数据,但是在实际应用中纹理可以有更广泛的用途。
1D 纹理类似于一个 1D 数据元素数组,3D 纹理类似于一个 3D 数据元素数组。但是在随后 的章节中我们会讲到,纹理不仅仅是一个数据数组;纹理可以带有多级渐近纹理层(mipmap level), GPU 可以在纹理上执行特殊运算,比如使用过滤器(filter)和多重采样(multisampling)。 此外,不是任何类型的数据都能存储到纹理中的;
纹理只支持特定格式的数据存储,这些格 式由 DXGI_FORMAT 枚举类型描述。
一些常用的格式如下:

类型含义
DXGI_FORMAT_R32G32B32_FLOAT每个元素包含 3 个 32 位浮点分量
DXGI_FORMAT_R16G16B16A16_UNORM每个元素包含 4 个 16 位分量,分量 的取值范围在[0,1]区间内
DXGI_FORMAT_R32G32_UINT每个元素包含两个 32 位无符号整数分量
DXGI_FORMAT_R8G8B8A8_UNORM每个元素包含 4 个 8 位无符号分量,分 量的取值范围在[0,1]区间内
DXGI_FORMAT_R8G8B8A8_SNORM每个元素包含 4 个 8 位有符号分量,分 量的取值范围在[−1,1] 区间内
DXGI_FORMAT_R8G8B8A8_SINT每个元素包含 4 个 8 位有符号整数分量,分 量的取值范围在[−128,127] 区间内
DXGI_FORMAT_R8G8B8A8_UINT每个元素包含 4 个 8 位无符号整数分量,分 量的取值范围在[0,255]区间内

字母 R、G、B、A 分别表示 red(红)、green(绿)、blue(蓝)和 alpha(透明度)。每种颜色都是由红、绿、蓝三种基本颜色组成的(例如,黄色是由红色和绿色组成的)。 alpha 通道(或 alpha 分量)用于控制透明度。
不过,正如我们之前所述,纹理存储的不一 定是颜色信息;
例如,格式 DXGI_FORMAT_R32G32B32_FLOAT 包含 3 个浮点分量,可 以存储一个使用浮点坐标的 3D 向量。另外,还有一种弱类型(typeless)格式,可以预先 分配内存空间,然后在纹理绑定到管线时再指定如何重新解释数据内容(这一过程与 C++ 中的数据类型转换颇为相似);
例如,下面的弱类型格式为每个元素预留 4 个 8 位分量,且 不指定数据类型(例如:整数、浮点数、无符号整数): DXGI_FORMAT_R8G8B8A8_TYPELESS

五、交换链与页面反转

为了避免在动画中出现闪烁,最好的做法是在一个离屏(off-screen)纹理中执行所有的 动画帧绘制工作,这个离屏纹理称为后台缓冲区(back buffer)。
当我们在后台缓冲区中完 成给定帧的绘制工作后,便可以将后台缓冲区作为一个完整的帧显示在屏幕上;使用这种方 法,用户不会察觉到帧的绘制过程,只会看到完整的帧。
从理论上讲,将一帧显示到屏幕上 所消耗的时间小于屏幕的垂直刷新时间。硬件会自动维护两个内置的纹理缓冲区来实现这一功能,这两个缓冲区分别称为前台缓冲区(frontbuffer)和后台缓冲区。前台缓冲区存储了当前显示在屏幕上的图像数据,而动画的下一帧会在后台缓冲区中执行绘制。
当后台缓冲区的绘图工作完成之后,前后两个缓冲区的作用会发生翻转:后台缓冲区会变为前台缓冲区, 而前台缓冲区会变为后台缓冲区,为下一帧的绘制工作提前做准备。我们将前后缓冲区功能 互换的行为称做呈现(presenting)。提交是一个运行速度很快的操作,因为它只是将前台缓冲区的指针和后台缓冲区的指针做了一个简单的交换。下图说明了这一过程。
在这里插入图片描述
我们首先渲染缓冲区 B,它是当前的后台缓冲区。一旦帧渲染完成,前后缓冲 区的指针会相互交换,缓冲区 B 会变为前台缓冲区,而缓冲区 A 会变为新的后台缓冲区。 之后,我们将在缓冲区 A 中进行下一帧的渲染。一旦帧渲染完成,前后缓冲区的指针会再次进行交换,缓冲区 A 会变为前台缓冲区,而缓冲区 B 会再次变为后台缓冲区。
前 后 缓 冲 区 形 成 了 一 个 交 换 链 ( swap chain )。
在 Direct3D 中 , 交换链由 IDXGISwapChain 接口表示。该接口保存了前后缓冲区纹理,并提供了用于调整缓冲区尺寸的方法(IDXGISwapChain::ResizeBuffers)和呈现方法(IDXGISwapChain::Present)。
使用(前后)两个缓冲区称为双缓冲(double buffering)。缓冲区的数量可多于两个; 比如,当使用三个缓冲区时称为三缓冲(triple buffering)。不过,两个缓冲区已经足够用了。

六、深度缓冲与多重采样

深度缓冲区(depth buffer)是一个不包含图像数据的纹理对象。在一定程度上,深度 信息可以被认为是一种特殊的像素。常见的深度值范围在 0.0 到 1.0 之间,其中 0.0 表示离 观察者最近的物体,1.0 表示离观察者最远的物体。深度缓冲区中的每个元素与后台缓冲区 中的每个像素一一对应(即,后台缓冲区的第 ij 个元素对应于深度缓冲区的第 ij 个元素)。 所以,当后台缓冲区的分辨率为 1280×1024 时,在深度缓冲区中有 1280×1024 个深度元素。
为了说明深度缓存的工作方式,让我们来看一个例子。如下图所示,它展示的是观察 者看到的立体空间(左图)以及该立体空间的 2D 侧视图(右图)。从这个图中我们可以发 现,3 个不同的像素会被渲染到视图窗口的同一个像素点 P 上。(当然,我们知道只有最近 的像素会被渲染到 P 上,因为它挡住了后面的其他像素,可是计算机不知道这些事情。)首 先,在渲染之前,我们必须把后台缓冲区清空为一个默认颜色(比如黑色或白色),把深度 缓冲区清空为默认值——通常设为 1.0(像素所具有的最远深度值) 。
在这里插入图片描述
视图窗口相当于从 3D 场景生成的 2D 图像(后台缓冲区)。我们看到,有 3 个不同 的像素可以被投影到像素 P 上。直觉告诉我们,P1是 P 的最终颜色,因为它离观察者最近, 而且遮挡了其他两个像素。深度缓冲区算法提供了一种可以在计算机上实现的判定过程。 注意,我们所说的深度值是相对于观察坐标系而言的。实际上,当深度值存入深度缓冲区 时,它会被规范到[0.0,1.0]区间内。
现在,假设物体的渲染顺序依次为:圆柱体、球体和圆锥体。下面的表格汇总了在绘制 些物体时像素 P 及相关深度值的变化过程;其他像素的处理过程与之类似。
在这里插入图片描述
从上表可以看到,当我们发现某个像素具有更小的深度值时,就更新该像素以及它在深
度缓冲区中的相应深度值。通过一方式,在最终得到的渲染结果中只会包含那些离观察者最 近的像素。 综上所述,深度缓冲区用于为每个像素计算深度值和实现深度测试。深度测试通过比较 像素深度来决定是否将该像素写入后台缓冲区的特定像素位置。只有离观察者最近的像素才 会胜出,成为写入后台缓冲区的最终像素。这很容易理解,因为离观察者最近的像素会遮挡 它后面的其他像素。 深度缓冲区是一个纹理,所以在创建它时必须指定一种数据格式。
用于深度缓存的格式如下:

类型含义
DXGI_FORMAT_D32_FLOAT_S8X24_UINT32 位浮点深度缓冲区,为模板缓冲区 预留 8 位(无符号整数),每个模板值的取值范围为[0,255],其余 24 位闲置
DXGI_FORMAT_D32_FLOAT32 位浮点深度缓冲区
DXGI_FORMAT_D24_UNORM_S8_UINT无符号 24 位深度缓冲区,每个深度值的 取值范围为[0,1]。为模板缓冲区预留 8 位(无符号整数),每个模板值的取值范围为 [0,255]
DXGI_FORMAT_D16_UNORM无符号 16 位深度缓冲区,每个深度值的取值范围为 [0,1]

七、多重采样

因为计算机显示器上的像素分辨率有限,所以当我们绘制一条任意直线时,该直线很难确地显示在屏幕上。图 4.4 中的第一条直线说明了“阶梯”(aliasing,锯齿)效应,当使用像素矩阵近似地表示一条直线时就会出现这种现象,类似的锯齿也会发生在三角形的边缘上。
在这里插入图片描述
我们可以看到,第一条直线带有明显的锯齿(当使用像素矩阵近似地表示一条直线时就会出现阶梯效应)。而第二条直线使用了抗锯齿技术,通过对一个像素周围的邻接像素进行采样得到该像素的最终颜色;这样可以形成一条较为平滑的直线,使阶梯效果得到缓解。
通过提高显示器的分辨率,缩小像素的尺寸,也可以有效地缓解一问题,使阶梯效应明显降低。 当无法提高显示器分辨率或分辨率不够高时,我们可以使用抗锯齿(antialiasing)技术。 其中的一种技术叫做超级采样(supersampling),它把后台缓冲和深度缓冲的大小提高到屏幕分辨率的 4 倍。3D 场景会以这个更大的分辨率渲染到后台缓存中,当在屏幕上呈现后台缓冲时,后台缓冲会将 4 个像素的颜色取平均值后得到一个像素的最终颜色。从效果上来说, 超级采样的工作原理就是以软件的方式提升分辨率。 超级采样代价昂贵,因为它处理的像素数量和所需的内存数量增加为原来的 4 倍。
Direct3D 支持另一种称为多重采样(multisampling)的抗锯齿技术,它通过对一个像素的 子像素进行采样计算出该像素的最终颜色,比超级采样节省资源。假如我们使用的是 4X 多 重采样(每个像素采样 4 个邻接像素),多重采样仍然会使用屏幕分辨率 4 倍大小的后台缓 冲和深度缓冲,但是,不像超级采样那样计算每个子像素的颜色,而是只计算像素中心颜色 一次,然后基于子像素的可见性(基于子像素的深度/模板测试)和范围(子像素中心在多 边形之外还是之内)共享颜色信息。下图展示了这样的一个例子。
在这里插入图片描述
如图(a)所示,一个像素与多边形的边缘相交,像素中心的绿颜色存储在可见的三个子像素中,而第 4 个子像素没有被多边形覆盖,因此不会被更新为绿色,它仍保持为原来绘制的几何体颜色或 Clear 操作后的颜色。如图(b)所示,要获得最后的像素颜色, 我们需要对 4 个子像素(3 个绿色和一个白色)取平均值,获得淡绿色,通过这个操作,可以减弱多边形边缘的阶梯效果,实现更平滑的图像。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在现有省、市港口信息化系统进行有效整合基础上,借鉴新 一代的感知-传输-应用技术体系,实现对码头、船舶、货物、重 大危险源、危险货物装卸过程、航管航运等管理要素的全面感知、 有效传输和按需定制服务,为行政管理人员和相关单位及人员提 供高效的管理辅助,并为公众提供便捷、实时的水运信息服务。 建立信息整合、交换和共享机制,建立健全信息化管理支撑 体系,以及相关标准规范和安全保障体系;按照“绿色循环低碳” 交通的要求,搭建高效、弹性、高可扩展性的基于虚拟技术的信 息基础设施,支撑信息平台低成本运行,实现电子政务建设和服务模式的转变。 实现以感知港口、感知船舶、感知货物为手段,以港航智能 分析、科学决策、高效服务为目的和核心理念,构建“智慧港口”的发展体系。 结合“智慧港口”相关业务工作特点及信息化现状的实际情况,本项目具体建设目标为: 一张图(即GIS 地理信息服务平台) 在建设岸线、港口、港区、码头、泊位等港口主要基础资源图层上,建设GIS 地理信息服务平台,在此基础上依次接入和叠加规划建设、经营、安全、航管等相关业务应用专题数据,并叠 加动态数据,如 AIS/GPS/移动平台数据,逐步建成航运管理处 "一张图"。系统支持扩展框架,方便未来更多应用资源的逐步整合。 现场执法监管系统 基于港口(航管)执法基地建设规划,依托统一的执法区域 管理和数字化监控平台,通过加强对辖区内的监控,结合移动平 台,形成完整的多维路径和信息追踪,真正做到问题能发现、事态能控制、突发问题能解决。 运行监测和辅助决策系统 对区域港口与航运业务日常所需填报及监测的数据经过科 学归纳及分析,采用统一平台,消除重复的填报数据,进行企业 输入和自动录入,并进行系统智能判断,避免填入错误的数据, 输入的数据经过智能组合,自动生成各业务部门所需的数据报 表,包括字段、格式,都可以根据需要进行定制,同时满足扩展 性需要,当有新的业务监测数据表需要产生时,系统将分析新的 需求,将所需字段融合进入日常监测和决策辅助平台的统一平台中,并生成新的所需业务数据监测及决策表。 综合指挥调度系统 建设以港航应急指挥中心为枢纽,以各级管理部门和经营港 口企业为节点,快速调度、信息共享的通信网络,满足应急处置中所需要的信息采集、指挥调度和过程监控等通信保障任务。 设计思路 根据项目的建设目标和“智慧港口”信息化平台的总体框架、 设计思路、建设内容及保障措施,围绕业务协同、信息共享,充 分考虑各航运(港政)管理处内部管理的需求,平台采用“全面 整合、重点补充、突出共享、逐步完善”策略,加强重点区域或 运输通道交通基础设施、运载装备、运行环境的监测监控,完善 运行协调、应急处置通信手段,促进跨区域、跨部门信息共享和业务协同。 以“统筹协调、综合监管”为目标,以提供综合、动态、实 时、准确、实用的安全畅通和应急数据共享为核心,围绕“保畅通、抓安全、促应急"等实际需求来建设智慧港口信息化平台。 系统充分整合和利用航运管理处现有相关信息资源,以地理 信息技术、网络视频技术、互联网技术、移动通信技术、云计算 技术为支撑,结合航运管理处专网与行业数据交换平台,构建航 运管理处与各部门之间智慧、畅通、安全、高效、绿色低碳的智 慧港口信息化平台。 系统充分考虑航运管理处安全法规及安全职责今后的变化 与发展趋势,应用目前主流的、成熟的应用技术,内联外引,优势互补,使系统建设具备良好的开放性、扩展性、可维护性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值