DirectX教程(5):了解图形概念

  不论是构建自己的引擎还是改进或使用引擎,都需要了解关于引擎的基本概念。与游戏引擎基本概念同样重要的是D3D的基础知识。本节将介绍D3D的基础知识,以及推出第一个D3D程序所需的知识。这一节主要是理论,下一节将介绍实践练习。

图形硬件

  学习图形编程首先需要对图形所涉及的硬件进行充分的了解。因为与其说D3D是一个游戏平台,还不如说是硬件接口,你在D3D上所做的所有操作实际上都是为了操纵图形硬件本身,如果不了解图形硬件,很难运用好D3D。
  图像编程中,我们最感兴趣的硬件就是GPU,即图形处理单元。GPU和CPU结构上稍有不同,但主要区别还是它们的用途。CPU执行运算并控制整个计算机;GPU对图形执行运算,并将图形定向输出到显示器。
CPU指挥GPU
  图形编程除了拥有自己独立的处理器(GPU)外,还有一块称为显存的独立物理内存与之一起工作。显存通常不在主板上,而是在显卡上,因此GPU可以快速对其进行访问。显存用于存储当前屏幕上的图像,以及可能用于编译下一张图像的所有数据。
CPU和GPU拥有各自独立的内存
  就物理硬件而言,我们只需要知道这些即可。在大多数情况下,D3D负责管理何时将数据存储在系统内存还是存储在显存,程序员不需要关心。

Directx图形基础架构(DXGI)

  Directx图形基础架构是一个组件,它是所有最新版本的Direct3D的基础。它的任务是处理一些基本任务,例如在屏幕上显示图像、找出监视器和显卡可以处理的分辨率。DXGI实际上不是Directx3D的一部分,它是Direct3D和其他图形组件的基础,充当了Direct3D和硬件之间的接口。
DirectX图形基础架构
  有很多直接处理DXGI的方法,但是我们并不需要涉及这些方法。重要的是知道这个组件的存在,因为Direct3D的某些部分专门处理DXGI。

交换链

  GPU在其内存中包含一个指向像素缓冲区的指针,该缓冲区包含当前正在屏幕上显示的图像。当你需要渲染某些东西(例如3D模型或图像)时,GPU会更新这个缓冲区数组,并将此信息发送到显示器进行显示。然后,显示器从上到下重新绘制屏幕,用新图像替换旧图像。
  但是这里存在一个小问题,因为大多数显示器的刷新速度在60HZ到100HZ,达不到实时渲染的刷新速度。如果正在刷新显示器的时候,另一个模型被渲染到GPU的缓冲区,那么该缓冲区中的旧图像就被丢弃,而保存新图像。最终显示在屏幕上的图像将被分成两部分,顶部显示的是旧图像而显示的是新图像,这种现象称为“撕裂”(tearing)。
  为了避免这种情况,DXGI实现了一种称为交换(swapping)的机制。DXGI不会将图像直接渲染到正在屏幕上显示的缓冲区(称为前缓冲区),而是将图像绘制到一个辅助的像素缓冲区(称为后缓冲区)上。所有的图像首先绘制到后缓冲区上,绘制完成后,DXGI将使用后缓冲区的内容更新前缓冲区,并丢弃前缓冲区中的旧图像。
  但是,这样做只是在一定程度上扩增了缓冲区的空间,但仍然会产生“撕裂”,因为在显示器刷新时前缓冲区还是可能会发生图像传输(GPU的速度远比显示器快)。为了避免这种情况(也就是使整个过程更快),DXGI为每个缓冲区(前后)设置了一个指针,并简单切换它们的值,这样后缓冲区就变成了前缓冲区(反之亦然),并且不会发生“撕裂”。
地址立即交换
  当然,我们还可以添加额外的后缓冲区来使我们的游戏具有更好的性能。
多个后备缓冲区可以获得更好的性能
  上述的这种设置称为“交换链”(swap chain),因为这里它是一个缓冲区链,在每次渲染新帧时都会交换指针位置。

渲染管道

  渲染管道是图形编程中经常听到的东西,这是因为渲染管道是一切发生的地方。渲染管道是在屏幕上生成一张渲染3D图像的过程,它像流水线一样,一步一步,其中包含了在GPU上执行的步骤。
渲染管道
  我们不会在这里介绍所有的步骤,只会介绍其中一部分,了解这些步骤之后才能上手编程,后续我们会介绍其余步骤。“输入组装”阶段是流水线的第一步,它的作用就是“咀嚼食物”,它从显存中收集你想要渲染的3D模型的信息,然后编译这些信息并准备进行渲染;“光栅化”阶段负责确定要在后缓冲区上绘制图像的位置,更具体的讲,它负责确定哪些确切像素将被绘制以及它们将是什么颜色;“输出合并”阶段是管道的最后一步,它的工作是将各个模型图像组合成一个完整的图像,并将该图像正确放置在后缓冲区上。

坐标系

  如果不了解3D的基本数学知识,就无法进行3D编程。我们在这里不会介绍所有大学代数的知识,而只要理解3D坐标系的概念。在3D渲染中,我们应该知道两种坐标系。
  1、笛卡尔坐标系:笛卡尔坐标系也可以理解为2D坐标系,换句话说,它是平面上准确定位一个点的系统。
笛卡尔坐标系
  2、3D坐标系:实际上,3D坐标系只是对2D坐标系进行了扩展,在2D坐标系的基础上,添加一个垂直于x轴和y轴的第三轴(Z轴),这样就具有了3D坐标。
3D坐标系

3D几何

  现在,我们将介绍如何将3D坐标系应用到游戏以及游戏编程。如果3D坐标系中的点表示空间中的位置,那么我们可以形成一组精确的位置,这些位置最终构成一个3D模型。当然,设置这么多的点会占用大量的内存空间,因此采用了一种更加简便的方法:采用三角形代替点集。我们之所以采用三角形,是因为三角形可以定位出几乎所有能够想象到的任何形状,例如立方体和球体,如下图所示:
由立方体制成的模型
  由于可以有效利用三角形创建3D模型,因此Direct3D仅围绕三角形进行设计,然后将三角形组合成其他形状。我们是通过称为顶点集(Vertices)的东西去建立一个三角形,顶点集(Vertices)是顶点(vertex)的复数,而一个顶点是3D空间中一个确切的点,它由x、y、z三个值组成。在Direct3D中,我们对这个顶点进行了扩展,增加了这个顶点的各种属性,称为“3D空间中精确点的位置和属性”。
  一个三角形由三个顶点组成,这三个顶点在程序中按顺时针顺序定义。编码后,这三个顶点形成一个平面,然后可以根据需要对其进行旋转、纹理化、定位和修改。
由顶点构成的三角形
  上图中显示的三角形由三个点组成:可以发现,这三个顶点的z值均为1,这是因为我们不是在讨论3D对象,而是一个2D平面的三角形,所以Z取什么值都没有本质的区别。

x = 0, y = 5, z = 1
x = 5, y = -5, z = 1
x = -5, y = -5, z = 1

  要制作实际的3D模型,我们需要组合三角形。举一个简单的例子,立方体的每一面都是由两个三角形放置在一起构成的。然而,反复定义游戏中每个三角形的3D坐标太繁琐,我们要做的是创建一个顶点列表,其中包括了每个顶点的坐标和信息,以及它们进入的顺序。

图元(primitive)

  图元是3D环境中的单个元素,它可以是一个三角形、一条直线、一个点或者其他任何元素。下面将介绍如何通过组合图元来创建3D对象:

  1、点列表

  点列表是顶点的列表,这些顶点在屏幕上显示为单个的点。这种方式对于渲染3D星空、创建虚线、在小地图上显示位置等方面十分有用。下图显示了如何在屏幕上显示“点列表”:
点列表(6个图元)

  2、线列表

  线列表也是一个顶点列表,这些顶点在每个奇数编号的顶点与下一个顶点之间创建单独的线段。这种方式可以用于多种效果,例如3D网格、大雨、轨迹线等。下图显示了如何在屏幕上显示“线列表”(这组顶点和上一组顶点相同):
线列表(3个图元)

  3、线带

  线带与线列表相似,但不同之处在于,此列表中的所有顶点均通过线段进行连接。这对于创建许多线框图像很有用,例如线框地形、草和其他不基于模型的对象。这种方式在程序调试中也十分有用。下图显示了如何在屏幕上显示线带:
线带(5个图元)

  4、三角形列表

  三角形列表也是一个顶点列表,其中每三个顶点组构成一个单独的三角形。这种方式可以用于多种效果,例如力场、爆炸、物体拼接等。下图显示了如何在屏幕上显示“三角形列表”:
三角形列表(2个图元)

  5、三角带

  三角带也是一个顶点列表,这些顶点创建了一系列相互连接的三角形。这是处理3D图形时最常用的方法。这种方式主要是为你的游戏创建3D模型。下图显示了如何在屏幕上显示三角带。请注意,前三个顶点创建了一个三角形,然后每个顶点根据前两个顶点创建另一个三角形。
三角带(4个图元)

  图元怪癖

  在绘制图元时,只是了显示图元的一侧。其实可以显示正反两侧,但一个模型通常是封闭的,你看不到内部。如果一个模型是完全封闭的,则只需要绘制每个三角形的一侧。毕竟,绘制图元的两侧将花费两倍的时间。
  一个三角形图元仅当其顶点按顺时针顺序给出时才绘制。如果你翻转了顶点顺序,就会变成逆时针顺序,因此未显示三角形:
只有顺时针绘制时,图元才可见
  有一种简单的方法来显示图元的两侧,即将图元显示两次,顺时针方向给出一个图元,逆时针方向给出一个图元。
两种方式绘制时均可见

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值