欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    3D游戏程序设计入门43754.pdf

    • 资源ID:84866297       资源大小:4.17MB        全文页数:72页
    • 资源格式: PDF        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    3D游戏程序设计入门43754.pdf

    3D 游戏程序设计入门(DirectX 9.0)(更新:04-10)翁云兵 声明:本教程内容绝大部分来自Frank D.Luna 所著的Introduction to 3D Game Programming with DirectX 9.0。教程内容(特别是语言表达上)大部分是我根据自己理解所写的,因此也不是此书的中文翻译版。由于我的英文水平很差,翻译过来就难免有错了,望读者原谅。当然如你认为我的水平实在是让人无法忍受那么请直接查阅英文教程。由于我的工作太忙且水平有限,计划一周一篇文章。希望读者能够支持我。给我多提意见。此中文教程版权归我所有。非 商 业 应 用 可 免 费 使 用 本 教 程。商 业 应 用 请 同 作 者 联 系,Email:WengYB。特别感谢:www.GameR 是他让我走上了游戏开发的道路。一直关心支持我的同事、同学。我最最亲爱的老婆,没有她我不可能写出这本教程。第一部分 必备的数学知识 在这最开始的一部分中我们将介绍本书所要用到的数学知识。我们讨论的主题是向量,矩阵和相应的变换,当然还有一些有关面和线的内容。最开始阅读时这部分是可选的。本教程对这些知识的讨论是很有限的,因此对于不同数学知识背景的读者来说都容易阅读。对于想了解更多更全的这方面信息的读者,请查看有关线性代数的书籍。当然已经学习过线性代数的读者也可将它作为有必要的复习内容来阅读。(这里推荐你看看线性代数与空间解析几何)除此之外,我们还将展示D3DX 类中相关的数学模型和执行特殊变换的函数。目标 学习向量以及它们的3D 计算机图形程序 学习矩阵以及学会使用它们来变换3D 图形 学习怎样模拟面和线以及它们的3D 图形程序 熟悉用于3D 数学运算的D3DX 库中包含的类和程序的子集 三维空间中的向量 几何学中,我们用有向线段表示向量,如图1。向量的两个属性是他的长度和他的顶点所指的方向。因此,可以用向量来模拟既有大小又有方向的物理模型。例如,以后我们要实现的粒子系统。我们用向量来模拟粒子的速度和加速度。在3D 计算机图形学中我们用向量不仅仅模拟方向。例如我们常常想知道光线的照射方向,以及在3D 世界中的摄象机。向量为在3 维空间中表示方向的提供了方便。图 1 向量与位置无关。有同样长度和方向的两个向量是相等的,即使他们在不同的位置。观察彼此平行的两个向量,例如在图1 中 u 和 v 是相等的。我们继续学习左手坐标系。图2 显示的是左手坐标系和右手坐标系。两者不同的是Z轴的方向。在左手坐标系Z 轴是向书的里面跑的而右手坐标系是向书的外边跑的。图 2 因为向量的位置不能改变它的性质,我们能把所有向量平移使他们的尾部和坐标系的原点重合。因此,当一个向量在标准位置我们能通过头点来描述向量。图 3 显示的是图1 中的向量在标准位置的样子。图 3 我们通常用小写字母表示一个向量,但有时也用大写字母。如 2、3 和 4 维向量分别是:u=(ux,uy),N=(Nx,Ny,Nz),c=(cx,cy,cz,cw)。我们现在介绍3D 中的4 个向量,就象图4 显示的。首先是都由含有0 的零向量;它被表示成加粗的0=(0,0,0)。接下来3 个特殊的向量标准基向量。它们被叫做i,j 和 k 向量,分别沿着坐标系的x 轴,y 轴和 z 轴,并且有1 的单位长:i=(1,0,0),j=(0,1,0),and k=(0,0,1)。注意:只有1 个单位长度的向量叫做单位向量。图 4 在 D3DX 库中,我们能用D3DXVECTOR3 类表示3 维空间中的向量。它的定义是:typedef struct D3DXVECTOR3:public D3DVECTOR public:D3DXVECTOR3();D3DXVECTOR3(CONST FLOAT*);D3DXVECTOR3(CONST D3DVECTOR&);D3DXVECTOR3(CONST D3DXFLOAT16*);D3DXVECTOR3(FLOAT x,FLOAT y,FLOAT z);/casting operator FLOAT*();operator CONST FLOAT*()const;/assignment operators D3DXVECTOR3&operator+=(CONST D3DXVECTOR3&);D3DXVECTOR3&operator-=(CONST D3DXVECTOR3&);D3DXVECTOR3&operator*=(FLOAT);D3DXVECTOR3&operator/=(FLOAT);/unary operators D3DXVECTOR3 operator+()const;D3DXVECTOR3 operator-()const;/binary operators D3DXVECTOR3 operator+(CONST D3DXVECTOR3&)const;D3DXVECTOR3 operator-(CONST D3DXVECTOR3&)const;D3DXVECTOR3 operator*(FLOAT)const;D3DXVECTOR3 operator/(FLOAT)const;friend D3DXVECTOR3 operator*(FLOAT,CONST struct D3DXVECTOR3&);BOOL operator=(CONST D3DXVECTOR3&)const;BOOL operator!=(CONST D3DXVECTOR3&)const;D3DXVECTOR3,*LPD3DXVECTOR3;注意D3DXVECTOR3 是从D3DVECTOR 继承的。它的定义是:typedef struct _D3DVECTOR float x,y,z;D3DVECTOR;向量有它们自己的算法,就象你在D3DXVECTOR3 定义中看到的数学运算。现在你不需要知道它们怎么使用。以后介绍这些向量运算以及一些有用的函数和关于向量它们重要的详细资料。注意:在3D 图形程序中,虽然我们主要关心3D 向量,但有时也会用到2D 和 4D 向量。在D3DX 库中提供了D3DXVECTOR2 和 D3DXVECTOR4 类来分别表现2D 和 4D 向量。不同维数的向量有着和3D 向量一样的性质,也就是它们描述大小和方向,仅仅是在不同的维数中。所有这些向量的数学运算对于不同维数向量都有效只是有一个除外,就是向量积。这些运算我们可通过论述3D 向量扩展到2D,4D 甚至n 维向量。向量相等 几何学上,有同样方向和长度的两个向量相等。数学上,我们说有同样维数和分量的向量相等。例如:如果ux=vx,uy=vy,且 uz=vz.那么(ux,uy,uz)=(vx,vy,vz)。在代码中我们能够用“=”判断两个向量相等。D3DXVECTOR u(1.0f,0.0f,1.0f);D3DXVECTOR v(0.0f,1.0f,0.0f);if(u=v)return true;同样的,我们也能用“!=”判断两个向量不相等。if(u!=v)return true;注意:当比较浮点数时,必须注意。因为浮点数不是精确的,我们认为相等的两个浮点数是有细微差别的;因此,我们测试它们近似相等。我们定义一个常数EPSILON,把它当作非常小的“buffer”。假如两个数和EPSILON 相差很小我们说它们近似相等。换句话说,EPSILON让浮点数有一定的精度。接下来的实例函数是怎样用EPSILON 比较两个浮点数相等。bool Equals(float lhs,float rhs)/if lhs=rhs their difference should be zero return fabs(lhs-rhs)0,那么两个向量的角度 小于90 度。假如u v 0,那么点p 在平面的前面且在平面的正半空间里。假如n p+d 0)/v is in positive half-space.if(x GetDesc(&surfaceDesc);/Get a pointer to the surface pixel data.D3DLOCKED_RECT lockedRect;_surface-LockRect(&lockedRect,/pointer to receive locked data 0,/lock entire surface 0);/no lock flags specified /Iterate through each pixel in the surface and set it to red.DWORD*imageData=(DWORD*)lockedRect.pBits;for(int i=0;i surfaceDesc.Height;i+)for(int j=0;j UnlockRect();程序中D3DLOCKED_RECT 结构的定义如下:typedef struct _D3DLOCKED_RECT INT Pitch;/the surface pitch void*pBits;/pointer to the start of the surface memory D3DLOCKED_RECT;在这里有一些关于表面锁定代码的一些说明。32-bit像素格式设定这是很重要的,我们把bits 转换成DWORDs。这让我们能把每一个DWORD 视为表示一个像素。同样我们暂时不用去关心为什么0 xffff0000 表示红色,关于颜色的说明将在第四章谈到。1.3.2 Multisampling 由于使用像素矩阵来表示图像,在显示时会出现锯齿状,Multisampling 就是使其变得平滑的技术。它的一种最普通的用法即为全屏抗锯齿(看图1.3)。图 1.3 D3DMULTISAMPLE_TYPE 枚举类型使我们可以指定全屏抗锯齿的质量等级:D3DMULTISAMPLE_NONE不使用全屏抗锯齿。D3DMULTISAMPLE_1_SAMPLE D3DMULTISAPLE_16_SAMPLE设定116 级的等级。本书的示例程序中没有使用全屏抗锯齿的功能,因为它大大的降低了程序运行速度。如果你实在很想使用它的话,要记住使用IDirect3D9:CheckDeviceMultisampleType 来检测你的显卡是否支持。1.3.3 像素格式 当我们创建一个表面或纹理时候,经常需要指定这些Direct3D 资源的像素格式。它是由 D3DFORMAT 枚举类型的一个成员来定义的。这里例举一部分:D3DFMT_R8G8B8表示一个24 位像素,从左开始,8 位分配给红色,8 位分配给绿色,8 位分配给蓝色。D3DFMT_X8R8G8B8表示一个32 位像素,从左开始,8 位不用,8 位分配给红色,8 位分配给绿色,8 位分配给蓝色。D3DFMT_A8R8G8B8表示一个32 位像素,从左开始,8 位为ALPHA 通道,8位分配给红色,8 位分配给绿色,8 位分配给蓝色。D3DFMT_A16B16G16R16F表示一个64 位浮点像素,从左开始,16 位为ALPHA 通道,16 位分配给蓝色,16 位分配给绿色,16 位分配给红色。D3DFMT_A32B32G32R32F表示一个128 位浮点像素,从左开始,32 位为ALPHA 通道,32 位分配给蓝色,32 位分配给绿色,32 位分配给红色。想了解全部的像素格式请查看SDK 文档中的D3DFORMAT 部分。注意:这前三种格式(D3DFMT_R8G8B8、D3DFMT_X8R8G8B8、D3DFMT_A8R8G8B8)是最常用并为大部分显卡所支持。但浮点像素格式或其它一些类型的支持并不是很广泛,在使用它们前请先检测你的显卡,看是否支持。1.3.4 内存池 表面和其它一些Direct3D 资源被放在多种内存池中。内存池的种类由D3DPOOL 枚举类型的一个成员来指定。可用到的内存池有下列几种:D3DPOOL_DEFAULT表示Direct3D 将根据资源的类型和用途把它们放在最合适的地方。这有可能是显存、AGP 内存或者系统内存中。值得注意的是,这种内存池中的资源必须要在IDirect3DDevice9:Reset 被调用之前消毁掉,并且再次使用时必须重新初始化。D3DPOOL_MANAGED资源将由Direct3D 管理并且按设备的需要来指定放在显存还是放在AGP 内存中。当应用程序访问和改变资源时它先把这些资源拷贝到系统内存中,当需要时Direct3D 会自动把它们拷贝到显存里。D3DPOOL_SYSTEMMEM指定资源放在系统内存中。D3DPOOL_SCRATCH指定资源放在系统内存中,它与D3DPOOL_SYSTEMMEM 不同之处在于使用这个参数使图形设备不能直接使用本内存池的资源,但资源可以被拷贝出去。1.3.5 交换链和页面切换 Direct3D通常创建23个表面组成一个集合,即为交换链,通常由IDirect3DSwapChain接口来表示。我们不必去了解它更详细的细节。我们也很少去管理它,通常Direct3D 会自己去管理。所以我们只要大概的了解一下它就可以了。交换链以及页面切换技巧被用在使两帧动画之间过度更平滑。图 1.4 展示的是一个有两个绘制表面的交换链。图 1.4 如图 1.4,在 Front Buffer 中的表面将用来在屏幕上显示。显示器不能及时显示 Front Buffer中表示的图像。通常情况下,它是每六十分之一秒刷新显示一次,即刷新率为 60 赫兹。应用程序的帧率经常与监视器的刷新率不同步(比如应用程序的渲染帧速度可能比显示器的刷新速度快)。然而,我们并不希望在显示器已经显示完成当前帧之前就更新有下一帧动画的Front Buffer 内容,但是我们又不想让程序停止渲染而去等待显示器显示。因此,我们渲染另一个屏幕表面 Back Buffer。当监视器将 Front Buffer 显示出来后,Front Buffer 就被放到交换链的末端,即变成图中的Back Buffer,而Back Buffer就会变成交换链中的Front Buffer。这个过程就叫做 presenting。图 1.5 表示了交换的整个过程。图 1.5 因此,我们绘图代码的结构就会像下面这样:1 Render to back buffer 2 Present the back buffer 3 Goto(1)1.3.6 深度缓冲 深度缓冲也是一个表面,但它不是用来存储图像数据而是用来记录像素的深度信息。它将确定哪一个像素最后被绘制出来。所以,如果要绘制 640*480 分辨率的图片,那么就会有 640*480 个深度值。图 1.6 图 1.6 展示了一个简单的场景,在这个场景里,一个物体把将另一个物体的一部分遮住了。为了使Direct3D 能确定物体的前后关系并正确的绘制出来,我们使用一种深度缓冲,又叫做 z-buffering 的技术。深度缓冲为每一个像素计算深度值并进行深度测试。通过深度测试我们可以比较得出哪个像素离摄相机更近并将它画出来。这样就可以只绘制最靠近摄相机的像素,被遮住的像素就不会被画出来。深度缓冲的格式决定着深度测试的精确性。一个24 位的深度缓冲比16 位的深度缓冲更精确。通常,应用程序在24 位深度缓冲下就能工作的很好,但是Direct3D 也同时支持32 位的深度缓冲。D3DFMT_D32表示32 位深度缓冲 D3DFMT_D24S8表示24 位深度缓冲并保留8 位模版缓冲(stencil buffer)D3DFMT_D24X8表示24 位深度缓冲 D3DFMT_D24X4S4表示24 位深度缓冲并保留4 位模版缓冲 D3DFMT_D16表示16 位深度缓冲 注意:关于模版缓冲的问题将在第八章详细说明。1.3.7 顶点处理 顶点是3D 图形学的基础,它能够通过两种不同的方法被处理,一种是软件方式(software vertex processing),一种是硬件方式(hardware vertex processing),前者总是被支持且永远可用,后者必须要显卡硬件支持顶点处理才可用。使用硬件顶点处理总是首选,因为它比软件方式更快,而且不占用CPU 资源,这意味CPU 至少可以有更多的空闲时间进行别的计算。注意:如果一块显卡支持硬件顶点处理的话,也就是说它也支持硬件几何转换和光源计算。1.3.8 设备能力 Direct3D 支持的每一项特性都对应于D3DCAPS9 结构的一个数据成员。初始化一个D3DCAPS9 实例应该以你的设备实际支持特性为基础。因此,在我们的应用程序里,我们能够通过检测D3DCAPS9 结构中相对应的某一成员来检测设备是否支持这一特性。下面将举例说明,假设我们想要检测显卡是否支持硬件顶点处理(换句话说,就是显卡是否支持硬件几何转换和光源计算)。通过查阅SDK 中的D3DCAPS9 结构,可以得知数据成员D3DCAPS9:DevCaps 中的D3DDEVCAPS_HWTRANSFORMANDLIGHT 位表示硬件是否支持硬件顶点处理即硬件几何变换和光源计算。程序如下:bool supportsHardwareVertexProcessing;/If the bit is“on”then that implies the hardware device/supports it.if(caps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT)/Yes,the bit is on,so it is supported.supportsHardwareVertexProcessing=true;else /No,the bit is off,so it is not supported.hardwareSupportsVertexProcessing=false;注意:DevCaps 即为“device capabilities”下一节将学习怎样根据硬件的实际情况来初始化D3DCAPS9 我们建议你阅读SDK 中关于D3DCAPS9 的结构,它完整的列出了Direct3D 支持的特性。1.4 初始化 Direct3D 下面几点说明怎样初始化Direct3D。根据下边的步骤你能初始化Direct3D:1 获得一个IDirect3D9 接口指针。这个接口用于获得物理设备的信息和创建一个IDirect3DDevice9 接口,它是一个代表我们显示3D 图形的物理设备的C+对象。2 检查设备的技术特性(D3DCAPS9),搞清楚主显卡是否支持硬件顶点处理。我们需要知道假如它能支持,我们就能创建IDirect3DDevice9 接口。3 初始化一个D3DPRESENT_PARAMETERS 结构实例,这个结构包含了许多数据成员允许我们指定将要创建的IDirect3DDevice9 接口的特性。4 创建一个基于已经初始化好的D3DPRESENT_PARAMETERS 结构的IDirect3DDevice9 对象。它是一个代表我们显示3D 图形的物理设备的C+对象。请注意,本书使用主显示设备绘制3D 图形,如果你的机子只有一块显卡,那它就是主显示设备。如果你有多个显卡,那么你当前使用的显卡将会成为主显示设备(如:用来显示Windows 桌面的显卡)。1.4.1 获得IDirect3D9 接口 Direct3D 的初始化是从获得一个IDirect3D9 接口指针开始的。使用一个专门的Direct3D 函数来完成这个工作是非常容易的,代码如下:IDirect3D9*_d3d9;_d3d9=Direct3DCreate9(D3D_SDK_VERSION);Direct3DCreate9 的唯一一个参数总是D3D_SDK_VERSION,这可以保证应用程序通过正确的头文件被生成。如果函数调用失败,那么它将返回一个空指针。IDirect3D9 对象通常有两个用途:设备列举和创建IDirect3DDevice9 对象。设备列举即为查明系统中显示设备的技术特性,显示模式、格式,以及其它每一种显卡各自支持的特性。创建 代表物理设备的IDirect3DDevice9 对象,我们需要利用这个物理设备的显示模式结构和格式来创建它。为了找到一个工作配置,我们必须使用IDirect3D9 的列举方法。然而,设备列举实在太慢了,为了使Direct3D 运行得尽可能快,我们通常不使用这个测试,除了下一节所谈到的一项测试。为了安全跳过它,我们可以选择总是被所有显卡都支持的“安全”配置。1.4.2 检测硬件顶点处理 当我们创建一个IDirect3DDevice9 对象来表示主显示设备时,必须要设定其顶点处理的类型。如果可以的话,当然要选用硬件顶点处理,但是由于并非所有显卡都支持硬件顶点处理,因此我们必须首先检查显卡是否支持。首先我们要根据主显示设备的技术特性来初始化D3DCAPS9 实例。可以使用如下方法:HRESULT IDirect3D9:GetDeviceCaps(UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9*pCaps);Adapter指定要获得哪个显示适配器的特性 DeviceType指定设备类型(硬件设备(D3DDEVTYPE_HAL),软件设备(D3DDEVTYPE_REF)PCaps返回一个已初始化的D3DCAPS9 结构 然后,我们就可以象1.3.8 部分那样检测显卡的能力了。下面就是代码片段:/Fill D3DCAPS9 structure with the capabilities of the/primary display adapter.D3DCAPS9 caps;d3d9-GetDeviceCaps(D3DADAPTER_DEFAULT,/Denotes primary display adapter.deviceType,/Specifies the device type,usually D3DDEVTYPE_HAL.&caps);/Return filled D3DCAPS9 structure that contains /the capabilities of the primary display adapter./Can we use hardware vertex processing?int vp=0;if(caps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT)/yes,save in vp the fact that hardware vertex /processing is supported.vp=D3DCREATE_HARDWARE_VERTEXPROCESSING;else /no,save in vp the fact that we must use software /vertex processing.vp=D3DCREATE_SOFTWARE_VERTEXPROCESSING;观察代码,我们使用变量 vp 来存储顶点处理类型。这是因为在稍后创建 IDirect3DDevice9对象时要求指定其顶点处理的类型。注意:标识符 D3DCREATE_HARDWARE_VERTEXPROCESSING 和D3DCREATE_SOFTWARE_VERTEXPROCESSING 是预定义的值,它们分别代表硬件顶点处理和软件顶点处理。技巧:若我们开发有一些新的,高级的特性的程序,在使用前我们总是先检查硬件是否支持这些特性。注意:如果一个应用程序在你的机子上不能运行,说明它用到的一些特性可能你的显卡并不支持,可以试试把设备类型换成 REF。1.4.3 填充 D3DPRESENT_PARAMETERS 结构 初始化过程的下一步是填充一个 D3DPRESENT_PARAMETERS 结构的实例。这个结构用于设定我们将要创建的 IDirect3DDevice9 对象的一些特性,它的定义如下:typedef struct _D3DPRESENT_PARAMETERS_ UINT BackBufferWidth;UINT BackBufferHeight;D3DFORMAT BackBufferFormat;UINT BackBufferCount;D3DMULTISAMPLE_TYPE MultiSampleType;DWORD MultiSampleQuality;D3DSWAPEFFECT SwapEffect;HWND hDeviceWindow;BOOL Windowed;BOOL EnableAutoDepthStencil;D3DFORMAT AutoDepthStencilFormat;DWORD Flags;UINT FullScreen_RefreshRateInHz;UINT PresentationInterval;D3DPRESENT_PARAMETERS;下面介绍其比较重要的数据成员,至于更详细的信息,请查阅 SDK:BackBufferWidth后备缓冲表面的宽度(以像素为单位)BackBufferHeight后备缓冲表面的高度(以像素为单位)BackBufferFormat后备缓冲表面的像素格式(如:32 位像素格式为 D3DFMTA8R8G8B8)BackBufferCount后备缓冲表面的数量,通常设为“1”,即只有一个后备表面 MultiSampleType全屏抗锯齿的类型,详情请看 SDK MultiSampleQuality全屏抗锯齿的质量等级,详情看 SDK SwapEffect指定表面在交换链中是如何被交换的,取 D3DSWAPEFFECT 枚举类型中的一个成员。其中 D3DSWAPEFFECT_DISCARD 是最有效的 hDeviceWindow与设备相关的窗口句柄,你想在哪个窗口绘制就写那个窗口的句柄 WindowedBOOL 型,设为 true 则为窗口模式,false 则为全屏模式 EnableAutoDepthStencil设为 true,D3D 将自动创建深度/模版缓冲 AutoDepthStencilFormat深度/模版缓冲的格式 Flags一些附加特性,设为 0 或 D3DPRESENTFLAG 类型的一个成员。下列两个最常用的标志 全部的标志请查阅 SDK:D3DPRESENTFLAG_LOCKABLE_BACKBUFFER设定后备表面能够被锁定,这会降低应用程序的性能 D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL 深 度/模 版 缓 冲 在 调 用IDirect3DDevice9:present 方法后将被删除,这有利于提升程序性能 FullScreen_RefreshRateInHz刷新率,设定 D3DPRESENT_RATE_DEFAULT 使用默认刷新率 PresentationInterval属于 D3DPRESENT 成员,又有两个常用标志,其余请查 SDK:D3DPRESENT_INTERVAL_IMMEDIATE立即交换 D3DPRESENT_INTERVAL_DEFAULTD3D 选择交换速度,通常等于刷新率 填充示例如下:D3DPRESENT_PARAMETERS d3dpp;d3dpp.BackBufferWidth=800;d3dpp.BackBufferHeight=600;d3dpp.BackBufferFormat=D3DFMT_A8R8G8B8;/pixel format d3dpp.BackBufferCount=1;d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;d3dpp.MultiSampleQuality=0;d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;d3dpp.hDeviceWindow=hwnd;d3dpp.Windowed=false;/fullscreen d3dpp.EnableAutoDepthStencil=true;d3dpp.AutoDepthStencilFormat=D3DFMT_D24S8;/depth format d3dpp.Flags=0;d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE;1.4.4 创建 IDirect3DDevice9 对象 在填充完了 D3DPRESENT_PARAMETERS 结构后,我们就可以用下面的方法创建一个 IDirect3DDevice9 对象了:HRESULT IDirect3D9:CreateDevice(UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS*pPresentationParameters,IDirect3DDevice9*ppReturnedDeviceInterface);Adapter指定对象要表示的物理显示设备 DeviceType设备类型,前面说过 hFocusWindow同我们在前面 d3dpp.hDeviceWindow 的相同 BehaviorFlags设定为 D3DCREATE_SOFTWARE_VERTEXPROCESSING 或者D3DCREATE_HARDWARE_VERTEXPROCESSING pPresentationParameters指定一个已经初始化好的D3DPRESENT_PARAMETERS 实例 ppReturnedDeviceInterface返回创建的设备 例子:IDirect3DDevice9*device=0;hr=d3d9-CreateDevice(D3DADAPTER_DEFAULT,/primary adapter D3DDEVTYPE_HAL,/device type hwnd,/window associated with device D3DCREATE_HARDWARE_VERTEXPROCESSING,/vertex processing type&d3dpp,/present parameters&device);/returned created device if(FAILED(hr):MessageBox(0,CreateDevice()-FAILED,0,0);return 0;1.5 初始化 Direct3D 实例 在本章的例程中,初始化了一个Direct3D 应用程序并用黑色填充显示窗口(如图1.7)。图 1.7 本书所有的应用程序都包含了d3dUtility.h 和 d3dUtility.cpp 这两个文件,它们所包含的函数实现了所有Direct3D 应用程序都要去做的一些常见的功能。例如:创建一个窗口、初始化Direct3D、进入程序的消息循环等。将这些功能封装在函数中能使示例程序更加突出该章的主题。另外,在我们学习本书的过程中还会在这两个文件中加上一些通用的代码。1.5.1 d3dUtility.h/cpp 在开始本章的例程之前,让我们先熟悉一下 d3dUtility.h/cpp 所提供的函数。d3dUtility.h如下:/Include the main Direct3DX header file.This will include the/other Direct3D header files we need.#include namespace d3d bool InitD3D(HINSTANCE hInstance,/in Application instance.int width,int height,/in Back buffer dimensions.bool windowed,/in Windowed(true)or /full screen(false).D3DDEVTYPE deviceType,/in HAL or REF IDirect3DDevice9*device);/out The created device.int EnterMsgLoop(bool(*ptr_display)(float timeDelta);LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);template void Release(T t)if(t)t-Release();t=0;template void Delete(T t)if(t)delete t;t=0;InitD3D初始化一个应用程序主窗口并进行Direct3D的初始化。如果成功,则输出IDirect3DDevice9 接口指针。从它的参数我们可以发现,我们能够设置窗口的大小和以窗口模式运行还是全屏模式运行。要知道它实现的细节,请看示例代码。EnterMsgLoop这个函数封装了应用程序的消息循环。它需要输入一个显示函数的函数指针,显示函数为程序中绘制图形的代码块,这样做是为了使显示函数能够在空闲的时候被调用并显示场景,它的实现如下:int d3d:EnterMsgLoop(bool(*ptr_display)(float timeDelta)MSG msg;:ZeroMemory(&msg,sizeof(MSG);static float lastTime=(float)timeGetTime();while(msg.message!=WM_QUIT)if(:PeekMessage(&msg,0,0,0,PM_REMOVE):TranslateMessage(&msg);:DispatchMessage(&msg);else float currTime=(float)timeGetTime();float timeDelta=(currTime-lastTime)*0.001f;ptr_display(timeDelta);/call display function lastTime=currTime;return msg.wParam;与“time”有关的代码用于计算每次调用显示函数的时间间隔,即是每帧的时间。Release这个模板函数能方便的释放COM 接口并将它们的值设为NULL Delete这个模板函数能方便的删除一个对象并将指向其的指针设为NULL WndProc应用程序主窗口的回调函数 1.5.2 实例框架 通过实例框架,我们形成了一种通用的方法去构造本书的示例程序。每一个例程都含有三个函数的实现,当然这不包括回调函数和WinMain 主函数。这三个函数用特定的代码实现特定的功能。这三个函数是:bool Setup()在这个函数里,我们将准备一切该程序需要用到的东西,包括资源的分配,检查设备技术特性,设置应用程序的状态 void Clearup()这个函数将释放Setup()中分配的资源,如分配的内存。bool Display(float timeDelta)这个函数包含所有与我们绘图和显示有关的代码。参数timeDelta 为每一帧的间隔时间,用来控制每秒的帧数。1.5.3 D3D Init 实例 这个示例程序将创建并初始化一个Direct3D 应用程序,并用黑色填充屏幕。注意,我们使用了通用函数简化了初始化过程。首先,我们要包含d3dUtility.h 头文件,并为设备声明一个全局变量:#include d3dUtility.h IDirect3DDevice9*Device=0;然后实现我们的框架函数:bool Setup()return true;void Cleanup()在这个程序中,我们不需要使用任何资源或触发任何事件,所以这两个函数都为空。bool

    注意事项

    本文(3D游戏程序设计入门43754.pdf)为本站会员(得**)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开