本文由哈利_蜘蛛侠原创,转载请注明出处!有问题请联系[email protected]
从这一期起,我们进入了本书的第二部分,叫做DirectX Basics (DirectX基础)。这一部分分为以下五个章节:
第2章 Drawing with DirectX Graphics (用DirectX图形进行绘图)
第3章 Interacting with DirectInput (与DirectInput互动)
第4章 Playing Sound and Music with DirectX Audio and DirectShow (用DirectX Audio和DirectShow播放声音和音乐)
第5章 Networking with DirectPlay (用DirectPlay进行联网)
第6章 Creating the Game Core (创建游戏核心)
不过十分遗憾(或者是幸运?哈哈,至少我可以省点力气了……)的是,第4章用到了现在已经过时的DirectShow(DirectX June 2010中没有DirectShow组件了);而第5章用到了DirectPlay,一方面我们不需要给游戏增加网络连接功能(难道不是吗?),另一方面这里的DirectPlay技术也已经过时了,所以我们就省去这两章内容了。
当然,这也就意味着第6章的游戏核心会缺少两个看起来很重要的组件。这也没办法,暂时这样吧!做一个哑巴游戏也不错!等到以后学到了给游戏增加声音的方法后我再扩充这个不完整的游戏核心(Direct Audio部分,或者更准确地说是DirectSound和DirectMusic并没有过时,但是这本书里是和DirectShow组合起来讲的,而“龙书”系列直接没有讲声音部分;本人现在还在寻找这方面的比较新的书籍)。
好的,今天我们来讲第2章的第1节。我们把这一章的结构列在下面:
1、The Heart of 3-D Graphics (3D图形的心脏)
2、GettingStarted with DirectX Graphics (准备使用DirectX图形)
3、TheMath of 3-D (3-D的数学)
4、GettingDown to Drawing (开始绘制)
5、UsingTexture Maps (使用纹理映射)
6、AlphaBlending (阿尔法混合)
7、UsingFonts (使用字体)
8、Billboards(广告牌)
9、Particles(粒子)
10、DepthSorting and Z-Buffering (深度排序和Z-缓存)
11、Workingwith Viewports (运用视口)
12、Workingwith Meshes (运用网格模型)
13、Mesheswith D3DX (D3DX与网格模型)
14、WrappingUp Graphics (总结图形部分)
好啦,现在正式开始啦!
原文翻译:
===============================================================================
最近的游戏用它们那惊人的画面和酷炫的效果让俺们眼花缭乱。正是那些图形效果吸引住了广大玩家的眼球,因此图形是你的项目中的一个主要组成部分。幸运的是,大多数图形引擎以及其背后的概念很直观且易于理解。通过运用绘制图形的基础知识,你可以重新创造你在游戏中见到的炫酷效果,并且还可以创造你自己的新效果。
现在是时候来创建你自己的图形引擎了,那么你可以求助于DirectX Graphics,它是DirectX的图形组件。在本章中,我会教给你如何使用DirectX Graphics,包括基本的是绘制技术以及例如纹理映射和Alpha混合等的DirectX Graphics的高级技术。在本章结束之时,你将会成为一个图形编程专家!
在这一章里,你会学到以下知识:
1、DirectX图形
2、如何在3-D中工作
3、矩阵数学
4、使用D3DX库文件
5、用顶点和多边形来绘图
6、使用纹理映射
7、使用alpha混合
8、广告牌技术和粒子
9、运用网格模型
10、使用.X文件
11、让网格动起来
虽然在本书这时候跳跃到像3-D这样的高端主题上也许看上去不太合乎逻辑,但是实际上这是很符合逻辑的。具体地说,DirectX的整个图形系统建立在微软在3-D领域的侵略——这正是Direct3D——的基础之上。出于这个原因,你用DirectX Graphics所做的所有事情都是使用3-D术语和用法来叙述的。
注意:
===============================================================================
在这一节里,我想向您介绍3-D属于以及用3-D图形绘图的理论。在本章稍后的“Getting Down to Drawing”这一节中,你通过开始使用DirectX Graphics来绘图将 理论运用于实际。
===============================================================================
用Direct3D所绘制的所有东西,我是说所有东西,都是由多边形构成的。一个多边形(polygon)通常是一个由三个点——称为顶点(vertex,复数为vertices)——组成的三角形图形。顶点是3-D中最小的单位;它是位于2-D或3-D空间的单个的点(坐标)。你将两个顶点连接起来,就创建了一条边(edge)(线,line);将三个顶点用三条边连起来,就形成了一个多边形。你可以将顶点、边和多边形的关系想象成一种连点游戏(connect-the-dots game),里面的点是顶点,而你画的线就是边。
相互连接的边形成了一个多边形面(polygon face)(其实我觉得这里说得有问题),而整个的图形称为一个网格(mesh)(网格是所有的基本的绘图对象的顶端——顶点、边和多边形)或这模型(model)。你可以在图2.1中看到顶点、边、多边形和网格的关系。
为了展示出有着更加逼真的外观的3-D物体,Direct3D使用我们称之为材质(materials)的东东、使用我们制定的颜色来填充一个网格的空心的多边形。材质由一个颜色成分的组合来表示,并且还可以包含有被称为纹理(texture)的bitmap格式图片(现在早就不限于bitmap格式了),该图片可以在多边形被渲染的时候铺在其表面上。
当处理图形的时候,你也许已经鼠戏了2-D的坐标了;它们具有用像素来计算的宽度和高度。宽度的水平跨度叫做x-坐标(x-coordinate),而垂直的跨度叫做y-坐标(y-coordinate)。每一个坐标都是从图片左上角的出发点(offset)处开始计量的。
在图2.2中,你可以看到坐标各在其位。x-坐标从左往右跑,其原点(x-坐标=0)在最左端。y-坐标从上往下跑,其原点(y-坐标=0)在最顶端。These coordinates extend in a positive direction to the other end oftheir respective spans.(这句话不知道怎么翻译。)在Direct3D中,2-D坐标一般被称为变换后的坐标(transformed coordinates),因为它们代表用于绘制物体以供展示的最终坐标。
在3-D中,增加了一个额外的坐标——z-坐标。一般来说,z-坐标代表图形的深度。更重要的是,y-坐标反过来了,是从下往上走的(正向朝下)。你可以在图2.3中看到三个坐标的分布。你可以用两种方式来使用z-坐标:让正向从原点往前(远离你)或往后(朝向你)。这两种方式通常被分别称为左手和右手坐标系。在此书中,我使用左手坐标系。
注意:
===============================================================================
左手和右手坐标系的名字来源于这样的事实:你可以通过你的手来确定这些坐标的方向。伸出你的左手让手掌朝向上方。让你的大拇指远离你(你的其余四指应指向右方)。你的大拇指指向的是z-坐标的正向,而你的其余四指指向的是x-坐标的正向。现在,让你的其余四指向上(但是不要移动你的手),现在它们指向的是y-坐标的正向。这就是左手坐标系。用右手做同样的事情,就可以得到右手坐标系的分布了。
===============================================================================
3-D世界中的所有事物都是用这些坐标系进行描述的——对于图片和视频显示是用2-D坐标系,而对于其他的所有东西则用的是3-D。所以,如果你想要在空间中定义一个在你面前(沿着z-轴)、稍微偏向你的右边(沿着x-轴)以及大致和眼睛在同一高度(沿着y-轴)的点(使用3-D坐标),你可能会将其坐标设为X=100, Y=50, Z=200。这些坐标分别表示向右100单位、地面之上50单位以及在你面前200单位。
对于2-D坐标,你会说墙上的一幅画为200单位宽、200单位高。画的中心的坐标为X-100,Y=100,而话的左上角的坐标也许是X=0, Y=0。这些3-D坐标被称为未变换的坐标(untransformed coordinates),因为它们不代表用于绘制物体以供展示的最终坐标。另一方面,2-D坐标被称为变换后的坐标,因为它们直接映射到显示屏坐标上。在本章稍后的一节“3-D的数学”中,你会发现如何将未变换的坐标转换成变换后的坐标,但是现在呢,我们集中来讨论如何使用你刚才读到的坐标来定义物体。
在创建如网格和模型(甚至是平直的2-D图像)等物体时,你会从顶点级别开始。每一个顶点具有一个x-, y-, 和z-坐标的值。你可以用三种方式来设定这些坐标:屏幕空间(screen space)(使用变换后的坐标)、模型空间(model space)(使用未变换的坐标)以及世界空间(world space)(也是使用未变换的坐标)。
你使用屏幕空间来将顶点映射到实际上屏幕坐标上。模型空间(也叫做局部空间,local space)表示你以任意一个代表模型的中心的原点为基准的坐标。局部空间中的顶点属于一个模型,并且你可以随着物体移动这些定点以便进行准确的绘制。在渲染物体之前,你要将局部空间中的顶点转换到世界空间中。在渲染物体之时,你讲世界空间坐标转换成屏幕空间坐标。
位于世界空间中的顶点代表用于渲染一个物体的最后的位置。世界空间是3-D世界中围绕一个固定点的实际位置。例如,把你自己想象成一个网格。你的关节是定义在局部空间中的顶点,因为它们可以用以你的胸部中心为原点的坐标进行定义。
当你在你的房子(这就是世界空间)里走动的时候,你的关节的坐标会在世界中移动,但是对你的身体来说仍然是局部的,如图2.4所示。
在决定了使用什么类型的坐标(屏幕、局部或者世界空间)来绘制一个物体后,你就开始放置顶点(以它们防止的顺序来标号)。然后你将这些顶点以三个为一组进行连接来创建多边形面。图2.5展示了通过对顶点进行分组而创建的一对多边形面。
在创建多边形面的时候你必须要考虑的一件事是顶点的共享(就是一个多边形可以使用另外一个多边形的一个或多个顶点)。一族多边形面可以属于三类之一:三角形列 (triangle lists),三角形带(triangle strips)和三角形扇 (triangle fans)。
三角形列是一族没有公共顶点(但是你仍然可以让这些顶点“重合”)的多边形面,所以每一个多边形都有自己的三个顶点。三角形带是这样一族有公共顶点的多边形面,每一个多边形都与另一个多边形共享一条边。三角形扇在一组多边形面共享同一个顶点时出现,就如一把扇子共享其基点一样。这三种类型在图2.6中进行了展示。
除了使用三角形的多边形外,你还可以渲染单个的点以及线条。Direct3D将你绘制的单个像素称为点(points),而你绘制的线条称为……好吧,线条(lines)。点和线条分别使用一个和两个顶点来渲染到显示屏上。因为我们主要关心3-D图形,我就跳过了点和线条类型的多边形,单单考虑三角形类型了。
稍后,当你进入渲染多边形的过程时,你用于定义一个多边形面的顶点的顺序就会变得重要起来,因为你必须确定多边形面的哪一个面是前面,哪一个面是后面。就你现在的目标而言,你要将定义一个多边形面的顶点用顺时针方向排序(当从多边形的前面观察的时候),如图2.7所示。通过这种方式,如果构成多边形的顶点是以顺时针排序的话,你知道你在看着多边形面的前面。
注意:
===============================================================================
在一个3-D引擎中,一个面的背面一般是不会被绘制的,所以它在渲染过程中就被跳过了。这被称为背面消隐(backface culling),并且是应该被执行的一个主要的优化。如果你在使用右手坐标系,那么顺时针的方向就反过来了,并且所有的多边形面的顶点需要用逆时针方式进行排序。
===============================================================================
机智的读者很可能注意到了图2.7中的三角形带的顶点顺序每过一个面就会反转一次。这种顶点顺序的反转是使用Direct3D绘制三角形带的要求。
一旦你定义了一组多边形或者一个网格,你就可以准备好给多边形面着色了。Direct3D有两种简单的技术来实现这一点,我将在书中讨论。第一种与定义材质有关,一般来说是单色。材质有它们的漫反射光(diffuse)、环境光(ambient)和镜面反射光(specular)颜色成分。漫反射光和环境光颜色一般来说是同种颜色——用来代表物体的实际颜色的光。镜面反射光是一个附近的光照亮一个物体时产生的高亮颜色。(更多关于这些颜色成分的内容,参见本章稍后“材质和颜色”这一节。)
第二种技术,叫做纹理映射(texture mapping),是关于用一张图像来给多边形涂色的。纹理映射通常是从一个bitmap格式(当然,现在早就不止这种格式了)文件载入的图像。这些bitmap图像在多边形面上伸展或者镶嵌(tile)(重复)。
在你定义好一个模型(或者知识一族多边形)后,你就可以准备好将它放置在世界中所需要的位置上了。图2.8展示了几个放置在3-D世界中的模型。只要你乐意,你可以移动、缩放以及旋转任何物体,所以你可以使用同一个模型来绘制一群有着不同的位置和朝向的物体。
你把移动(也叫做平移(translating))、旋转以及缩放这些行为称为变换(transformations)。要把一个物体从其模型空间带到一组便于观察的坐标上,需要进行好几个变换。
首先,要进行世界变换(worldtransformation),它是用来将局部坐标转换到世界坐标的。这包括缩放,绕着x-、y-和z-轴旋转,以及平移(明确地按照这种顺序)。第二个要进行的变换是视角变换(view transformation),它让所有的物体朝着3-D世界中的一个观察点,这样将世界坐标转换成观察坐标。
将视角变换想象成漂浮在你的3-D世界中的一个摄像机。这个摄像机是你的虚拟世界的观察入口,并且它可以自由地移动以及旋转。视角变换将你的3-D世界的物体移动到相对于你的摄像机的位置上。
最后一个重要的变换是投影变换(projectiontransformation),这是用于将3-D世界弄平为2-D图像的变换。它运作起来很像摄像机的镜片,with different zooms, short- and wide-angles, and various othereffects, such as fisheye distortion.(原谅我这句话不会翻译。)
===============================================================================
好啦,费了这么多笔墨,终于搞定了第一节。内容总体来说比较简单,不过初学者仍然可能会感到吃力。其实这里编排结构不是很合理。在此我推荐大家看看“龙书”第二版(Introduction to 3D Game Programming with DirectX 9.0c —— A Shader Approach)的第6章,那里讲述得更加清楚详细。希望大家有所收获!