深入浅出Direct3D 蔡军生 版权所有

 /***********************************
 *作者:蔡军生
 *出处:http://blog.csdn.net/caimouse/
 ************************************/
 
 深入浅出Direct3D
深入浅出Direct3D 蔡军生 版权所有
·第 1 章 3D基础知识
·1.1 什么是3D?
·1.2 3D相关概念
·1.3 DirectX介绍
·1.4 Direct3D中3D基元
·1.5 Direct3D的表面和顶点法向矢量
·第 2 章 Direct3D系统架构
·2.1 Direct3D在系统中的位置
·2.2 Direct3D各个组件位置
·2.3 渲染
·第 3 章 Direct3D程序
 
·附录A 1. Direct3D对象 
·附录A 2. Direct3D的设备
·附录A 3. Direct3D的资源
·附录A 4. Direct3D的着色
·附录A 5. Direct3D显示场境
·附录A 6. Direct3D基元渲染
·附录A 7. Direct3D表面缓冲区翻转
·附录A 8. Direct3D中的3D坐标变换
·附录A 9. 矩阵


 什么是3D
3D是three-dimensional的缩写,就是三维图形。在计算机里显示3D图形,就是说在平面里显示三维图形。不像现实世界里,真实的三维空间,有真实的距离空间。计算机里只是看起来很像真实世界,因此在计算机显示的3D图形,就是让人眼看上就像真的一样。人眼有一个特性就是近大远小,就会形成立体感。
计算机屏幕是平面二维的,我们之所以能欣赏到真如实物般的三维图像,是因为显示在计算机屏幕上时色彩灰度的不同而使人眼产生视觉上的错觉,而将二维的计算机屏幕感知为三维图像。基于色彩学的有关知识,三维物体边缘的凸出部分一般显高亮度色,而凹下去的部分由于受光线的遮挡而显暗色。这一认识被广泛应用于网页或其他应用中对按钮、3D线条的绘制。比如要绘制的3D文字,即在原始位置显示高亮度颜色,而在左下或右上等位置用低亮度颜色勾勒出其轮廓,这样在视觉上便会产生3D文字的效果。具体实现时,可用完全一样的字体在不同的位置分别绘制两个不同颜色的2D文字,只要使两个文字的坐标合适,就完全可以在视觉上产生出不同效果的3D文字。

 相关概念
大家学习立体几何时,都要用到坐标系,才能把几何体定位和计算。在计算机里要显示3D的图像,就是显示几何体,就是把那些数字化的坐标转换成几何图像显示。因此坐标系必须要学习的,否则那一大堆坐标数据就没有办法显示,或者显示出来是乱七八糟的。
在Direct3D里也要用到坐标系,它的坐标系是左手坐标系。目前常见的有两种坐标系,如下图所示:
 原图丢失了
 
  图1.1:左手坐标系,右手坐标系

  左手坐标系就是x轴的正方向指向右,y轴正方向批向上,z轴的正方向指向里面。当伸出左手,让四个手指指着x轴的正方向,大母指指向z轴的正方向,牚心指向y轴的正方向。符合这样规则的坐标系,就叫做左手坐标系。
右手坐标系就是x轴的正方向指向右,y轴正方向批向上,z轴的正方向指向外面。当伸出右手,让四个手指指着x轴的正方向,大母指指向z轴的正方向,牚心指向y轴的正方向。符合这样规则的坐标系,就叫做右手坐标系。
当然还有很多其它坐标系,就不一一介绍了。
  如果想从文件中读取不是左手坐标系的几何模型时,就要作相应的转换。比如从右手坐标系转换到左手坐标系,就是进行三角形顶点顺序改变和翻转。
  3D绘图就是在二维的计算机屏幕上创建三维幻觉。为了做到这一点,使用了数学变换进行建模和处理图像。为了熟悉3D算法和概念,作为使用Direct3D创建和处理3D世界和对象的准备。理解3D算法是怎么实现的将有助于你领悟使用Direct3D。
3D绘图比2D绘图要复杂的多,这是因为程序需要理解的三维图形在二维平面显示的原理,比显示在屏幕上的要多得多。创建三维图形通常使用商业三维建模软件,比如3DS,或3D MAX等等。
可以使用3D绘图算法实时处理各种类似这样的模型,使你的世界中的模型更具有真实感。这种具有真实感的模型由物体、摄像机和光源组成。
3D世界中包含的3D物体有各种属性,可以通过处理这些属性来改变物体。
  一个物体的形状由表面定义,而表面可以被定义成平面或二次曲面。如果已经看过一些轮廓模型,就会知道用于实体物体的基本表面。每个物体都有纹理,定义了表面的粗糙度和光滑度。每个对象都有漫反射和镜面反射,反射属性决定了射到物体上的光线反射的程度。漫反射代表对象明暗程度。一个新的干净的球要比又旧又脏求具有更高的漫反射。镜面反射代表了物体看起来的亮度,水晶瓶比木块有更高的镜面反射。物体的位置,在3D空间中由三个坐标轴定义:x,y,z坐标。物体方位性,即三维空间的某个方向。对方位进行转动处理的效果是物体旋转。
把小的、或最基本的物体组成大物体,这个处理被称为组合。组合简化了复杂的大物体的移动。比如说一个自行车,它由两个旋转的车轮。当车轮旋转的时候,整个车向前移动。车轮旋转和移动的相对静态坐标系统。组合能使向前移动坐标系统,同时保持把车轮约束在上面;无需明确的向前移动车轮。组合对一些复杂的移动物体,比如说轿车、飞机、动物等等是非常有用的。
为了能看见物体,定义了摄像机代表用户对3D世界的关联。摄像机有一个位置和一个方向,它们定义了观察者在3D世界的什么地方看和看到的物体是什么样。在3D世界里移动摄像机和改变它的方向使看到物体不同部份。
虽然有了物体和摄像机,但是还是什么都看不见,除非把一些光线打到物体表面上。可以创建不同风格的光线,通过改变光线照亮的程度来改变物体在场景中的外观。不同光线类型和效果占用CPU和其它资源是不一样的。
环境光对场景中所有的物体都提供了固定不变的照明,所有其它的光线光的强度和方向上都是不同的。
  点光源是从一个点发出的光,反射的角度取决于光点和物体位置之间的角度。就会在物体表面出反射现象。
  平行光同点光源类似,但它是从一个平面发射出来的光,经过反射后入射角和反反射角是一样大小。这是的平行光计算量少的原因,但损失了一些真实感。
  聚光源正如它的的名字一样,随着接近物体,光线强度产生变化。
  方向光最经常用于模拟太阳光和其它无穷远的光源。这种光源被看作来自无穷远,一次它的强度不随着接近物体而变化。在唯一的方向上,亮度是固定的。
  可以确定亮度或强度,来影响物体被照亮的程度。聚光源和其它的光源有一个确定光线从哪里发出的方向。
  某些光源的强度受距离的影响。但对环境光来说不是这样的,它没有位置,不是有方向的光远。通常与场景有无限远的距离。
  可以创建不同的有色光。这比白色光要复杂的多,因为它改变了所照到的每一个物体的颜色。
  3D绘图有两种重要的裁剪概念:视区(View Volumes)和可视表面(Visible Surface)。视区用于减少被渲染的对象的数量。越靠近摄像机,物体就越大,细节也越多。当远离摄像机的时候,物体就变小了,细节也少。当物体非常远的时候,它可以从视野中消失,而没有丢失可被察觉的真实感。实际上,物体总是在一个适当的距离上被不被察觉地模拟得更简单。
在摄像机后面的物体能够很好的被裁剪;在2D应用程序中,超过屏幕四个边的对象被裁剪。在裁剪中使用两种投影。一种是平行(正交)投影,另一种是透视投影。透视投影使用没影点。正如它的名字所示,距离观察者远的物体就变小了。
可视表面检测是通过避免计算渲染不可见物体而加速渲染算法的一种方法。它需要计算出哪一个对象的表面在视区中没有被裁剪以及哪些面远离摄像机。
  实时地渲染3D场景需要处理大量的计算,因此就要找到一些好的方法来减少计算量,优化程序性能,但随着技术的发展,越来越不那么重视优化,并且显示的场境非常的真实性。
随着对3D图形编程的概述,可以考虑使用Direct3D开始制作应用程序了。Direct3D使无须直接地写驱动程序,就能够访问许多显卡的3D硬件加速功能,让很多3D算法可以在显卡中直接运行,极大地加速3D程序性能。

 DirectX介绍
DirectX介绍     蔡军生

微软发布"具有多项令人兴奋功能"的DirectX 9.0!DirectX获得更好的图像显示质量,使多人游戏具可伸缩性,以及更棒的音频效果。DirectX 9.0至少在以下几个方面表现出色:
1、 强化了针对DirectDraw和Direct3D的接口,简化了应用扩展,提升性能
2、 改善了图形创作工具,更易于做出最佳的3-D角色和环境
3、 点光源式光影和像素式光影使图象更逼真
4、 强化了DirectSound和DirectMusic,简化了其应用扩展
5、 DLS2音频合成功能提高了乐器音频的真实感
6、 DirectInput的设备影射功能令对设备的支持更简单;
7、 DirectPlay使多人游戏的性能和可扩展性得到了提高;
8、 DirectPlay提供了IP声音通讯;
9、 DirectShow的应用编程接口提供了音频/视频的实时合成和即时编辑;
10、DirectShow支持Windows媒体音频和视频(WMA和WMV)的读写;
11、Microsoft TV技术可以支持数字电视节目

DirectX是一种图形应用程序接口(API),它的意思不难理解,Direct是直接的意思,X是很多东西,加在一起就是一组具有加束访问硬件的东西。微软定义它为"硬件设备无关性,提高非常多媒体能力"。DirectX主要由以下几个部分组成:
1、DirectDraw(2D绘图)
2、Direct3D(3D绘图)(注意:DirectDraw和Direct3D已经合并)
3、DirectSound(声音相关)
4、DirectMusic(MIDI相关)
5、DirectInput(输入相关)
6、DirectPlay(网络相关)
7、DirectSetup(Setup相关)
8、DirectShow(动画播放)
9、DirectX Media Objects(媒体数据流对象)
微软在94年推出了WinG和WAVEMix。WinG拥有较高速的图形处理能力,WAVEMix可以同时播放八声道的声音。其后又推出了能使得影像高速化的WinToon,但是这些产品的实用性不大。一直到Window95的问世,微软开发了DirectX 1.0,并且根据硬件制造厂商和游戏厂商合作共同更新升级DirectX的标准。
随着DirectX版本的升级,功能越來越强大,DirectX已经成为游戏的工业标准。

 
 /***********************************
 *作者:蔡军生
 *出处:http://blog.csdn.net/caimouse/
 ************************************/
 
 附录A 1. Direct3D对象
附录A 1. Direct3D对象 (蔡军生 版权所有)
在Direct3D应用程序里,最先创建的对象是Direct3D对象,最后删除的对象也是Direct3D对象。那么Direct3D对象是用来作什么的呢?是怎么样创建的呢?
由于Direct3D对象是用COM实现,所以要用到Direct3D对象,就要先初始化COM库,然后创建Direct3D的COM对象。如果在C++时创建Direct3D对象如下:
LPDIRECT3D9 g_pD3D = NULL;
if( NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
D3D_SDK_VERSION参数是用来确定用那个版本SDK头文件来编译。创建Direct3D对象后,就可以通过来枚举设备和检查设备的兼容性。就可以进一步去创建显示设备对象,对特定的设备选择合适的显示模式,特别硬件加速的编程。
 


 附录A 2. Direct3D的设备
·附录A 2. Direct3D的设备 (蔡军生 版权所有)
  在Direct3D应用程序里,Direct3D的设备是非常重要的。因为Direct3D的设备提供矩阵变换,三维图像渲染和三维图像光栅化显示。这些操作都需要大最运算,目前大部份集中在显卡中处理。Direct3D的设备就是硬件显卡的一种抽象,当然它是高于硬件的,因为它不但可以直接使用硬件功能,还可以用软件来模拟显卡不存在的功能。
  要使用Direct3D的设备,就要根据不同类型,选择合适的设备来创建。显卡在应用程序里不是独占的,就会造成设备丢失。因此,应用程序要处理这种情况,当发现丢失之后,就要去尝试恢复设备,如果设备不能恢复就要当作错误处理。
  在使用设备之前,还要检查设备是否支持应用程序要求支持的功能,如果不支持就要退出程序。如果不退出,整个系统就有可能出错。同时检测硬件支持什么样的顶点处理,是否支持硬件,或软件,或软件硬件混合,或只能其中一种等等。根据不同的处理,程序作相应的优化。还要把顶点的数据合适地传送给相应的设备,否则就处理不了。
  在Direct3D的设备里有两大类,一类是HAL设备(HAL Device),一类是基准设备(Reference Device)。HAL设备主要用于速度要求高,实时处理快的程序里,因为它是用硬件加速的。而基准设备是全部用软件实现,所有数据都用CPU来处理,主要用于测试和研究领域,正确性和精确性是最主要的目的,不考虑其速度。所以在游戏里用到的设备,应都是HAL设备。 

 附录A 3. Direct3D的资源
·附录A 3. Direct3D的资源 (蔡军生 版权所有)
在Direct3D里的资源,有很多种,但主要有纹理和缓冲区。应用程序要创建,加载,拷贝和使用这些资源。资源的接口都是继承于COM接口IDirect3DResource9,其中纹理和缓冲区日的接口都是继承上面的接口。这些的资源的接口如下图所示:


资源有很多事情要做,比如了解资源属性,操作资源,进行资源访问时同步,同步就要用到锁等,还有资源关系,应用程序怎么样管理和分配资源。很事情都要处理,处理资源的好坏关系程序的性能,比如什么样的纹理放到显卡内存里,什么样的顶点数据放到系统内存里。
 
 附录A 4. Direct3D的着色
·附录A 4. Direct3D的着色 (蔡军生 版权所有)
现在来介绍一下Direct3D里的3D多边形着色。在Direct3D里有什么样的着色模式呢?怎么样设置着色模式呢?在Direct3D里有两种着色模式,分别是平面着色和Gouraud着色。两种着色区分就是在多边形里每点着色的区别。平面着色就是用多边形第一个顶点的颜色作来整个多边形里每个点的颜色;而Gouraud着色就是根据每个顶点的颜色,法线和光线来计算出多边形里每个点的颜色,这个就内部进行插值运算着色。比如顶点1的红色成分为0.8,顶点2的红色成分为0.4,用Gouraud着色计算出来顶点1和顶点2中间的红色成分就是0.6。平面着色的优点,就是着色速度快。而Gouraud着色的优点,就是平面比较光滑,看起来比较真实。
下图就两种不同着色的茶壶比较:

两种着色模式还有很多不同点,平面着色模式让两个平面连接的棱看起更尖,而Gouraud着色看起来棱就会变成平滑。但在光线着色里,平面着色不大好,因为整个平面都统一的颜色,看起来不真实,但Gouraud着色刚好相反,看起来比较真实,更加接近现实中光线照着的物体。不过Gouraud着色也会因为进行插值运算,会丢掉一些实物的细节。像下图进行Gouraud着色,就丢掉中间聚光灯。

在Direct3D里的缺省着色模式是Gouraud着色,可以调用函数IDirect3DDevice9::SetRenderState来设置参数D3DRS_SHADEMODE来选择不同的着色模式。下面的代码就是怎么样设置着色模式。
// 设置为平面着色模式。
// pDev是指向IDirect3DDevice9的指针。
hr = pDev->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
if(FAILED(hr))
{
// 这里处理出错程况。
}

// 设置Gouraud着色模式。缺省是这种模式。
hr = pDev->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
if(FAILED(hr))
{
//这里处理出错程况。
}
 
 附录A 5. Direct3D显示场境
·附录A 5. Direct3D显示场境 (蔡军生 版权所有)
在Direct3D里怎么显示场境呢?或者说怎么样显示一帧的画面?带着这个问题,我们来看看Direct3D显示过程。由于任何的动画,都是基于电影的播放原理。就是由于人眼具有图像视觉延迟性,当看到一帧图画时,并不能立即就从大脑里消失。如果一秒钟内至少保持24帧图画播放,就会看到的图画是连续的动画。因此,Direct3D里只要有显示一帧图画的能力就行了。
Direct3D里用函数IDirect3DDevice9::Present来显示一帧动画。要显示这一帧动画,有很多工作要做,先要计算好图像位置、着色、贴图、背景等等,然后把数据放到后备缓冲区(back buffer)里,接着用上面的函数来把后备缓冲区换成前面缓冲区(front buffer),就可以显示一帧动画出来。Direct3D里每个显示设备都有一个后备缓冲区切换列表(swap chain),它用来保存后备缓冲区,当然可以添加很多后备缓冲区到里面,关键看程序需要和显存大小或者系统内存大小。Direct3D就是通过不断从后备缓冲区切换列表里取得后备缓冲区,显示到前面缓冲区里,就可以让显卡显示动画在显示器上。把已经显示的前面缓冲区,又放回到后备缓冲区切换列表里,让应用程序可以不断地拷贝显示数据到后备缓冲区切换列表的后备缓冲区里面。
 

 附录A 8. Direct3D中的3D坐标变换
·附录A 8. Direct3D中的3D坐标变换(蔡军生 版权所有)
在游戏里有很多物体,就拿CS来说,常常看到里面有很多木箱,这些木箱位置是怎么样放上去的呢?因为这些木箱都相同的,同样大小,同样纹理,但摆的位置不一样,要表示这种不一样的位置,就要用到3D坐标空间,而用坐标来表示两个木箱相对位置。

坐标变换是3D游戏里最基本知识,时时都要用到变换。比如从模型的坐标空间转换到世界坐标空间,因为很多模型创建时的坐标空间都是相对创建时的坐标空间。比如创建一个正方体,就是用来表示一个木箱,它的坐标空间就是左手坐标,但它的中心顶点是左手坐标系的原点,要把这个木箱放到不同位置上,就要进行平移。要不同方向对着用户,就要旋转。这些平移和旋转,都是怎么样计算的呢?其实学习过立体几何都知道,使用矩阵来变换。矩阵就是一个3D变换的最好工具。矩阵可以保存变换的值,并还有可以通矩阵相乘得到各种变换。下面主要介绍矩阵,以及怎么样生成world、view、projection等变换的矩阵。

矩阵
world变换-从模型空间变换到world空间
view变换-从world空间变换到view空间
projection变换-从view空间变换到projection空间

 
·附录A 9. 矩阵(蔡军生 版权所有)

Direct3D使用矩阵这个工具来实现3D变换。其实矩阵是用来计算线性代数最方便工具,因为坐标变换都是线性方程组组成,肯定要用到矩阵这个工具来计算,才是最佳的方法。在3D里,最常用的是4行4列的矩阵,因为它才可以更加方便地计算三维坐标的平移,旋转和缩放等。如果用3行的矩阵,要表示平移是有困难的。
后面接讨论下面内容:
3D变换
平移和缩放
旋转
矩阵组合

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值