DirectX 11 游戏编程入门
Allen Sherrod and Wendy Jones
致谢:略
作者简介:
AllenSherrod 是一个在计算机游戏领域富有经验的作者。Allen 过去的工作包括出版两本书《DX 终极 3D 游戏引擎的架构和
设计之终极游戏开发指南》和《游戏开发者的数据结构和算法》。Allen 也对游戏开发者杂志,《游戏编程精粹 6》和 Gamasutra.com
有所贡献。Allen 还创建了 UltimateGameProgramming.com 网站。
WendyJones 是 KittyCode LLC 公司的 CTO 和创立者之一,这家游戏工作站主要在移动平台,诸如 iPhone,WP7 和 Xbox360
上开发。Wendy 过去在 Atari 和 Electronic Arts 的工作经验包括在 PC,操纵台(译者注:就是手摇式和手柄式游戏机)和移动设备
上的游戏开发。Wendy 也在 Full Sail 大学教授 DX,并且是人机交互部门的主席。可以通过她的网站 www.fasterkittycodecode.com
网站联系她。
译者:looyer@sina.com
时间:2013.05.10
目录
第一章 DirectX 的前世今身
介绍
DirectX 是什么?
DirectX 10 对比与 DirectX9
DirectX11 对比与 DirectX10
DirectX11 对比与 OpenGL4.0
为什么需要 DirectX?
DirectX 的组成部分
DirectX11 的组件
过时的 DirectX 组件
Direct3D 11 组件介绍
Direct3D 11 的几个阶段
Direct3D 11 的思考
DirectX 的附属工具
示例程序浏览器和文档
PIX
Caps Viewer
诊断工具
贴图工具
错误查看器
控制面板
跨平台声音创建工具
游戏定义文件编辑器
底层硬件
总结
习题
第二章 第一个 DirectX 程序
创建工程
添加窗口代码
Main 函数入口
窗口初始化
窗口回调过程
Direct3D
添加 DirectX 库
初始化 Direct3D 组件
驱动类型和特征级别
创建设备和缓存交换链 SwapChain
创建渲染目标视图
视口 Viewport
场景的清除和显示
清理 Cleaning Up
格式 Formats
空白的 D3D 窗口
模板框架的设计
Direct3D 类
空窗口演示类
程序的循环更新
DirectX 错误处理库
错误处理函数
错误处理宏
总结
习题
第三章 2D 渲染
开发 2D 游戏
贴图
精灵
2D 几何图形
什么是顶点
三角形的定义
顶点缓存 Vertex Buffers
输入布局
绘制 2D 三角形
2D 三角形演示 Demo
载入几何体
渲染几何体
贴图映射
贴图接口
MIP 映射
贴图的细节
贴图映射演示
精灵
深度缓存 Z-Ordering
精灵图像
从场景中取得精灵
精灵的位置以及缩放
精灵游戏演示
创建和渲染游戏中的精灵
总结
你已经学到的东西
习题
实验
第四章 文本和字体的渲染
游戏中的文本
增加文字
字体贴图
一个字体系统的讲解
使用精灵创建字体系统
高级话题
游戏中的文字窗 Text Box
游戏中的控制台
游戏菜单
游戏状态提示 Heads-Up Display
总结
习题
实验
第五章 输入检测和响应
玩家的输入
输入操作
键盘
Win32 键盘
DirectInput 组件的键盘
DirectInput 键盘输入演示
鼠标
DirectInput 鼠标
XInput-游戏控制器
设置 XInput 输入
控制器的摆动
XInput 中的输入
游戏控制器功能
电量检测
按键检测
耳机声音
XInput 演示
总结
已经学到的东西
习题
实验
第六章 3D 入门
XNA 数学库
实用特性
点
向量
向量运算
位置之间的距离
向量的长度
向量的标准化
向量的叉积
向量的点积
3D 空间
坐标系统
变换
世界变换
视图变换
投影变换
一个对象的变换
矩阵
单位矩阵
放缩矩阵
平移矩阵
旋转矩阵
矩阵间的结合
立方体 Cube 演示
附加的 XNA 数学库主题
编译检测
常量
宏
结构和类型
增加的函数
附加的数学结构主题
游戏的物理特性和碰撞检测
总结
已经学到的东西
习题
第七章 着色器和特效
Direct3D 中的着色器
可编程着色器的历史
特效文件
特效文件的布局
载入特效文件
外部变量和常量缓存
输入输出结构
技术模块
光栅化状态
高级着色语言
变量类型
语法
函数声明
顶点着色器
像素着色器
贴图颜色的转化
颜色偏移
多重贴图
几何着色器
几何着色函数声明
几何着色器的阐述
光照介绍
总结
已经学到的东西
习题
实验
第八章 Direct3D 中的照相机和模型
Direct3D 组件中的照相机
Look-At 照相演示
Arc-Ball 照相演示
网格和模型
OBJ 文件格式
从文件中读取标记
从 OBJ 文件中载入网格模型
高级主题
照相机的复杂性
3D 分级文件
总结
你所学到的东西
习题
索引
介绍
许多人都梦想过制作属于自己的电脑游戏。对于一些人来说游戏是一种爱好,而还有一部分人却无意体会其中的乐趣。但
是对于剩下的我们,游戏和制作我们自己的游戏更多的是一种激情。如果你买了这本书,你将会跟随你的渴望和热情参与其中
并与其他人分享乐趣。
关于此书
这本书是 WendyJones 的《DirectX10 游戏编程入门》的后续版本。此书中,我们教会你使用最新的 Direct3D 版本 Direct3D 11
来开始游戏的学习。
此书的目标就是教会你 DirectX11 的方方面面。内容的适应人群是没有 DirectX 经验的初级或中级 C++开发人员。虽然前面
版本的 DirectX 或者 OpenGL 的经验有用,但这不是必须的。
当你学完本书的全部内容后,你将有足够的 DirectX11 的经验来制作简单的视频游戏和 Demo 演示。理想的情况是,你将
能够制作复杂的游戏和演示程序直到你完全能够完成和发布你自己的 PC 游戏。
推荐材料
本书假设你有关于 C++编程方面的知识,并且假定你有在 VS2010 上开发的知识以及至少是高中水平的数学知识。本书主要
是讲解 DirectX 的知识,故阅读本书前并不需要知道 DirectX。
全书使用的代码环境是 VSC++2010 快速版,可以通过微软官网 www.microsoft.com/express/Downloads 下载。我们使用的 June
2010 DirectX SDK 能够从 http://msdn.microsoft.com/en-us/directx 下载
尽 管 不 是 必 须 的 , 我 们 还 是 推 荐 使 用 Adobe 公 司 的 Photoshop 软 件 来 创 建 贴 图
(www.adobe.com/products/photoshop/photoshopextended/) 和 Autodesk 公 司 的 XSI Mod Tool 7.5 来 创 建 3D 模 型 和 网 格
(http://usa.autodesk.com)。
伴随网站:代码和附加内容
几乎每一章每个主题的讨论都给你动手练习的示例代码和 Demo。 为了能够观察执行或者操纵那些代码,你需要从以下网
站下载本书的附加代码:www.ultimategameprogramming.com/BeginningDirectX11/ or www.courseptr.com/downloads 通过这两个
地址,你能够找到一些材料,包括第九章,总结,附录 A,各章节习题答案,附录 B,DirectX 中的声音(介绍了 DirectX 声音的
各个 API,包括 XAudio2 和 XACT3)。
勘误表
有时在本书发布之前就存在一些没有被发现的错误或者一些我们不可预料的外界因素造成的错误。如果你找到任何书中存
在的错误,请提交到这个网站上去 www.ultimategameprogramming.com/BeginningDX11。查看该网站看其他读者提交的错误对你
也许有用。
第一章
Direct3D 11 的新特性是什么
了解 DirectX 是什么
为什么 DirectX 那么有用
数据流是怎样通过 Direct3D 11 的管线
DirectX 的前世今生
DirectX 之前,游戏开发人员在各种硬件的不兼容性上苦苦挣扎,由于各种各样的硬件配置的存在使得让每个人
享受同样的游戏几乎是不可能的。为了解决工业界的标准化问题,微软在 windows95 上提供了 windows 游戏开发包,
也就是 DirectX1.0 版本。DirectX 提供给游戏制作者一个统一的 API 集合,它几乎保证了不同 PC 硬件的兼容性问题。
随着 DirectX 的发布,windows 平台下的游戏数量有了戏剧性的增长。而在 15 年前这的确是真的。
本章内容:
什么是 DirectX
DirectX,微软提供的应用程序接口集(APIs),被设计为在运行 windows 操作系统平台上用来提供给开发人员控
制硬件的底层接口。它的各个组件提供了访问不同硬件的能力,包括图形(显卡),声音(声卡),GPU,输入设备以及
所有的标准接口(译者注:比如游戏操纵杆,鼠标等)。
这种体系允许开发者使用标准 API(DirectX)开发他们的游戏,而不用担心用户提供的不同硬件的访问接口不同了。
可以想象一旦开发者要面对用户所提供的各种可能的硬件配置上写代码将是多么的困难。你也许会问:如果玩家有
不同的输入设备怎么办?又或者是有不同的操作系统,即使是同一家公司都会产生不同的版本像 DOS 和 Windows95?
那么不同的声卡和各种驱动呢?不同种类的显卡又怎么办?
相比于为市场上的各种可能的设备编写不同的代码,要是能提供一种标准 API 来操纵不同的硬件会是一个更好
的主意,特别是在游戏发布之后市场上出现了一种新的设备,如果是前一种方法则设备是不太可能被游戏识别的,
而如果提供统一的 API 则不难解决这个问题。DirectX 是首先被游戏制作者用来在 Windows 和 Xbox 平台上使用的标
准 API 集。它是在设备上提供驱动层来操作硬件的。(注意:Xbox369 使用 DirectX9 之后的版本开发)
DirectX10 与 DirectX9 的比较
在 2006 年,DirectX10 作为 DirectX 开发包的将来的主要版本被提上日程。通常讨论 DirectX 指的是它其中的组
件 Direct3D,在 DirectX 的 API 中每个版本 Direct3D 都有根本性的变化。DirectX 的其他大部分 API 都或者是过时的(这
意味着它们将在后续版本中移除或者不推荐在新的软件中使用它们),或者主版本的变化它们保持相同,或者被 SDK
完全移除。
Direct3D 10 的 API 相比于前一个版本是显得轻量的,并且其 API 比过去的版本都更加的容易使用。实际上 DirectX
的早期版本是出了名的既难学又难用,但是微软已经对其 API 进行了多年的改近和提升(译者注:微软的成功原因之
一就是不懈的坚持)。Direct3D 10 并不仅仅是升级,而是在各个方面,其 API 都有新的不同。其中一个新的不同的感
受就是它在 Windows Vista 上启动,需要支持 DirectX 10 的硬件,和拥有一个强悍的 API 集,几乎在软件的各个方面
都有极大的影响。
与其他版本一个显而易见的不同就是在 Direct3D 10 中移除了固定的函数管线,而被移除的部分却是渲染状态和
在 API 中构建算法来允许使用公共特效渲染对象的一个必须的集合。在图形硬件上面移除固定函数管线取而代之的
是可编程着色器。通过本书的讨论,图形着色器被用来编写定制的图形硬件处理几何体的特殊代码。图形着色器第
一次被介绍是在 DirectX8 中,但是从那以后图形硬件和着色模型使它演变为 API 中一颗耀眼的明星。
在 Direct3D 9 中,我们能够通过着色器来渲染几何体,开启光照只需要设置少量的性质和渲染状态,那些 API
会转化我们的几何体使得发布时只需要调用少量的 Direct3D 函数。在 Direct3D 10 中我们依旧能够通过着色器做上
述所有的事情,而且还能做得更多。初学者需要记住的关键一点是当第一次学习图形编程时固定管线被内建的 API
所限制,而着色器允许我们创建任何特效,唯一的限制是游戏中的帧率。想使用光照?只需要掉了 Direct3D 函数来
开启它并且设置它的属性(上限是 8 种光照)。想通过多幅图像渲染表面?只需要开启它。甚至能够表现你所想要的
基于像素的模糊运行和深度域,而使用固定管线就没那么幸运了。
如果固定管线不能明显的支持的特效,不用着色器的话你就不能创建你所希望的效果。虽然一些开发者会发现
特效能够通过一些技巧而不依赖于着色器来解决,但是那往往都是非常困难并且低效的做法。我的建议就是这些可
以做得更好,不要错过使用着色器的机会。
现在如果我们需要表现凹凸纹理(凹凸贴图),我们能够编写像素着色器来指导光线的方向,使用它来执行计算
并且在像素级的表面方向被载入一个特殊的图片即法线贴图,一起结合来渲染出最终的像素的颜色。在着色器发布
之前,或者早期版本的那些所提供的特性受限的着色器(比如那个需要与早期的 OpenGL 结合的黑暗的年代),要实
现这种效果几乎是不可能的,或者是做甚至简单的效果比如法线贴图只能仅仅通过低效的方法或者低品质的方法或
者近似的方法来做。当然,这只是一种简单的效果基于人们的经验上。
从 DirectX9 到 DirectX10 是一个巨大的飞跃。DiectX10 通过了两次迭代(译者注 9.0b,9.0c)才被市场所接受。
DirectX 11 与 DirectX 10 的比较
Direct3D 11 构建于 Direct3D 10.1 之上,增加了渲染下一代图形的新特性集。在 DirectX 11 中新增的内容包括:
使用新的 API 组件 DirectComput 在 GPU 上做通用计算
真正的支持多线程渲染
新的基于硬件的细分曲面技术(Tessellation)
着色器模型 5.0 和在着色器中加入面向对象编程概念
增强的贴图(纹理)分辨率
HDR 和 LDR 图像的 BC6 和 BC7 纹理压缩
等等 (注意:应用与几何体表面的图片资源叫做贴图或者纹理。就是经常提到的彩色图像被映射到表面使
得表面看起来更加的细致)
DirectX 11 更像是 DirectX10.1 的一个增强版本而不像从 DirectX9 到 DirectX10 的主版本升级。微软在 DirectX10
上做了冒险的尝试,不仅要求新的硬件支持而且 windows 的版本最低也要求 Vista。几年过去了,现在来看微软所
做的冒险有了回报,因为不仅得到硬件的广泛支持,而且 windows 用户的主要群体现在已经升级到了 Vista 和 Win7
操作系统。DirectX 已经被将来的考虑所采用(译者注:这里主要是指 DirectX10 和 11),并且随着次世代游戏的多年
发展,DirectX11 在未来将会变得越来越重要。
DirectX 11 与 OpenGL 4.0 的比较
OpenGL 很长时间被作为 Direct3D 的图形 API 的对手所考虑。OpenGL 支持 Windows 操作系统以外的平台,比如
Mac,LinuxOS,iPhone 和 iPad,Sony 的 Playstation3(至少有一个实现),和各种各样的移动设备比如手机和 PDA,还
有其他的平台。虽然本地设备所支持的 OpenGL 能够从一个平台到另一个平台,但 API 核心被设计为平台独立的,
不包括拥有很长历史的硬件设备扩展和来自于不同 OpenGL 版本的竞争对手的特性。DirectX,一方面在所有的不同
版本的 WindowsOS 和 Xbox 游戏机都有效,而且还考虑了 DirectX10 和 11 的兼容性,硬件必须提供一个严格的兼容
性列表,说明在 DirectX10 之前的不同情况。而在此种情况下对于硬件厂商所提供的特定扩展 OpenGL 是工作受限的。
硬件市场的各种不兼容性导致要想在所有支持的设备上实现同样的效果需要做各种重复的工作。
整个的 Direct3D 和 OpenGL 的争辩历史,就好像不同宗教的教徒之间的斗争一样,但是事实上 OpenGL 已经落
后于 Direct3D 多年。微软在 Direct3D 上投入了巨大的工作量并且通过了多年的改进,OpenGL 不仅已经落后,而且
也没有履行发布新版本的承诺(译者注很长时间主版本都是 2),而且一次又一次的多年遭受同样的问题困扰(译者注:
OpenGL 各厂商之间的内讧)。当 OpenGL3.0 发布时,OpenGL 的世界已经落后 Direct3D 太多。不幸的是,在 OpenGL
世界,后面所支持它的厂商围绕怎样与 Direct3D 的 API 对抗进行着此起彼伏的讨论时,Direct3D 已经获得了统治地
位。
OpenGL4.0 展现了许多 DirectX11 所拥有的特性,最引人注目的是使用 OpenCL 来支持 GPU 的计算和对
Tessellation(细分曲面)技术的支持,现在的它很接近当年做出的各种没有行动的的承诺了,与 2.0 和 3.0 比较的话就
显得特别的耀眼了。尽管 OpenGL 不再是原地踏步,但是不幸的是,要想既要对抗 DirecX 而且赢回当年的核心地位
和已经转到 Direct3D 阵营的人们(那时 OpenGL 的错误决定太多)的心还需要做大量的工作。图形 API 直接的比赛就好
像是高中时流行的跳山羊赢选票比赛一样。
为什么需要 DirectX
在 Windows 视窗操作系统发布之前,开发者们都在 DOS 上写游戏。那是一种单线程,非 GUI 界面的操作系统,
它提供开发者在他们的应用程序和底层硬件直接交互的方式。这种方式有利也有弊,比如因为游戏代码是直接驱动
底层硬件的,开发者能够压榨机器的每一寸资源和能力,当他们的游戏执行时给他们的硬件的完全控制权。而消极
的一面是需要为每一种硬件写直接的驱动代码或者他们的游戏想要得到任何硬件的支持需要各种各样的第三方库,