收藏 分销(赏)

VB6.0使用DIRECTX8-3d编程资料.doc

上传人:天**** 文档编号:3131292 上传时间:2024-06-19 格式:DOC 页数:32 大小:620.50KB
下载 相关 举报
VB6.0使用DIRECTX8-3d编程资料.doc_第1页
第1页 / 共32页
VB6.0使用DIRECTX8-3d编程资料.doc_第2页
第2页 / 共32页
VB6.0使用DIRECTX8-3d编程资料.doc_第3页
第3页 / 共32页
VB6.0使用DIRECTX8-3d编程资料.doc_第4页
第4页 / 共32页
VB6.0使用DIRECTX8-3d编程资料.doc_第5页
第5页 / 共32页
点击查看更多>>
资源描述

1、你是否曾惊叹VB的简单易用与开发的速度之快?你是否对编写二维的游戏早已感到厌倦和无聊?你是否想有朝一日自己也能写出魔兽、CS、起义、古墓丽影之类的3D游戏?你是否想过利用D3D甚至可以把你去过的旅游景点或你的家这些场景在电脑中构造出来,然后加入自己的创意、故事和情节搞点什么东西?你是否想过利用D3D可以构造你的岛屿、你的天堂,把你在现实世界中无法实现的梦想在虚拟世界中实现,或者预先把你的梦想可视化以便更快速地实现它?那么还犹豫什么?!让我们开始一趟激动人心的D3D学习之旅吧! 首先选择一下各个工具的版本。VB我选择VB6,一是它速度比较快,二是我对它比较熟悉。然后由于VB6只含有DX7和DX8

2、的函数库,因此对于DX版本的选择嘛,我就选用它所支持的最高版本DX8啦。常用的3D建模软件有3ds max和Maya,我个人觉得Maya的性能较好,而Maya导出X文件的插件能用于D3D中的最高版本是Maya 6(Maya 7虽然导出的X文件能在mesh viewer里查看,但是导入D3D后不正常),因此我选用Maya 6. 学习D3D,在软件方面需要一些类的知识,在数学方面需要一些向量代数、空间解析几何、矩阵的知识;对缺乏这些知识的初学者来说学习起来可能比较困难,如果实在看不懂,建议还是自己先补一下基础知识吧。不过请千万别灰心,想一想,能够随自己的意愿来设计3D游戏是多么激动人心的事情啊!请

3、用这个目标来激励自己吧! 下面让我们通过一个最简单的D3D的程序来开始讲解一些基本的DX和D3D概念:请大家首先动手完成以下步骤:1. 新建一个标准的exe工程;2. 在窗体上放一个Timer控件,设置Enabled=False,Interval=200;3. 选择菜单“工程(Project) - 引用(Reference)”,然后找到“DirectX 8 for Visual Basic Type Library”打勾,确定;4. 在窗体内输入如下代码: 1. Option Explicit2.3. Private MyDirectX8 As New DirectX84. Private M

4、yDirect3D8 As Direct3D85. Private MyDirect3DDevice8 As Direct3DDevice86.7. Private Sub Form_Load()8. Dim DispMode As D3DDISPLAYMODE9. Dim d3dpp As D3DPRESENT_PARAMETERS10.11. Set MyDirect3D8 = MyDirectX8.Direct3DCreate12. MyDirect3D8.GetAdapterDisplayMode D3DADAPTER_DEFAULT, DispMode13.14. With d3dp

5、p15. .Windowed = 116. .SwapEffect = D3DSWAPEFFECT_COPY_VSYNC17. .BackBufferFormat = DispMode.Format18. End With19.20. Set MyDirect3DDevice8 = MyDirect3D8.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Me.hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, d3dpp)21. Timer1.Enabled = True22. End Sub23.24. Pr

6、ivate Sub Timer1_Timer()25. Const WORLD_COLOR As Long = &HFF00&26. 27. With MyDirect3DDevice828. .Clear 0, ByVal 0, D3DCLEAR_TARGET, WORLD_COLOR, 1#, 029. .BeginScene30. .EndScene31. .Present ByVal 0, ByVal 0, 0, ByVal 032. End With33. End Sub运行。如果看见一个绿色的窗体的话,那么恭喜你,你已经编写了一个真正的D3D程序! 这个程序很简单,但它的确是一个完

7、整的D3D程序。 下面来分析程序: 先看模块的声明部分,声明了三个模块级变量,为了在以后的程序中能够一眼看出变量类型,我的命名采用“My+变量类型”的原则。第一个变量在声明类型的同时还创建了一个DirectX8对象(由New关键字可见),而后两个变量仅仅是声明类型而已,并没有新的对象被创建。到了Form_Load事件里的这一句:Set MyDirect3D8 = MyDirectX8.Direct3DCreate才创建了一个Direct3D8对象并让MyDirect3D8指向它,到这一句:Set MyDirect3DDevice8 = MyDirect3D8.CreateDevice(D3DA

8、DAPTER_DEFAULT, D3DDEVTYPE_HAL, Me.hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, d3dpp)才创建了一个Direct3DDevice8对象并让 MyDirect3DDevice8 指向它。 让我们来再看一下这三句来理顺这三个对象之间的关系:Private MyDirectX8 As New DirectX8 Set MyDirect3D8 = MyDirectX8.Direct3DCreate Set MyDirect3DDevice8 = MyDirect3D8.CreateDevice(.)首先创建MyDirect

9、X8对象,然后由它来创建 MyDirect3D8 对象,最后由 MyDirect3D8 来创建 MyDirect3DDevice8 对象,简写为:DirectX8 - Direct3D - Direct3DDevice显然从左往右是整体和部分之间的关系(例如 Direct3D 是 DirectX8 的一个组件等等),这样够清楚了吧?为了更深刻地理解VB里的对象、对象指针、Set、New这些概念(语句),我们来看看VC+里是怎么写的: 1. LPDIRECT3D8 MyDirect3D8= NULL; 2. LPDIRECT3DDEVICE8 MyDirect3DDevice8 = NULL;

10、3.4. MyDirect3D8 = Direct3DCreate8( D3D_SDK_VERSION );5. MyDirect3D8-CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &MyDirect3DDevice8)其中变量类型前缀LP是 Long Pointer(32位指针)的意思,LPDIRECT3D8 MyDirect3D8 等价于 DIRECT3D8* MyDirect3D8,MyDirect3D8是指向 DIRECT3D8

11、对象的指针类型。首先定义了两个指针 MyDirect3D8、MyDirect3DDevice8 分别指向 DIRECT3D8 和 DIRECT3DDEVICE8 对象,然后用函数 Direct3DCreate8 创建 DIRECT3D8 对象(当然该函数返回的是指向该对象的指针),赋值给MyDirect3D8,然后用 MyDirect3D8 指向的 Direct3D8 对象的 CreateDevice 方法创建 Direct3DDevice8 对象,并将其地址以传址方式传给 MyDirect3DDevice8。与VB程序最大的不同是没有DirectX8对象,不像VB那样用 MyDirectX8

12、.Direct3DCreate 来创建Direct3D8对象,而直接使用库函数Direct3DCreate8来创建(而且多了个参数D3D_SDK_VERSION)。第二个不同是VB里 MyDirect3DDevice8 的赋值是通过函数的返回值的方式,而VC里则是通过参数传址的方式赋值。 把对象的创建和它们之间的关系弄清楚后,让我们来逐个看看各个对象吧。DirectX8:DirectX8 类是使用微软 DX 技术的起点,编写任何DX程序都由它开始,在程序中,我们用它的 Direct3DCreate 方法来创建一个 Direct3D 对象,其实它还有DirectInputCreate、Direc

13、tMusicComposerCreate、DirectPlayClientCreate、DirectSoundCreate、DirectXFileCreate等方法来创建其他的DX对象。Direct3D8:这个类用来创建 Direct3D 对象和设置环境,程序中用了它的CreateDevice方法来创建设备,用了它的 GetAdapterDisplayMode 方法来获取显卡的显示模式。Direct3DDevice8:这是D3D中最重要的类了,鼠标、纹理、图元、材质、灯光、缓冲区、阴影、渲染场景都由它来完成,前面的两个类只是初始化时用到一下而已,后面的程序中全部都是 Direct3DDevic

14、e8 的方法,例如:SetCursorPosition、ShowCursor、CreateIndexBuffer、CreateTexture、CreateVertexBuffer、SetRenderState、SetTransform、SetIndices、GetLight、SetMaterial、Present、Reset、DrawPrimitive、BeginScene、EndScene、Clear 从名字就可大致看出它们的功能。下面让我们来看一下Form_Load事件里的两个变量类型:D3DDISPLAYMODE 和 D3DPRESENT_PARAMETERS,它们都是结构体类型。顾名思

15、义,D3DDISPLAYMODE 是用来描述显示模式的:Type D3DDISPLAYMODE Format As CONST_D3DFORMAT Width As Long Height As Long RefreshRate As LongEnd Type后面三个参数很好理解,和Windows的显示属性对话框里的是一致的,可是第一个参数是什么呢?关键在于 CONST_D3DFORMAT 是什么。CONST_D3DFORMAT 是这样的枚举类型:Enum CONST_D3DFORMAT D3DFMT_UNKNOWN = 0 D3DFMT_R8G8B8 =20 (&H14) D3DFMT_A8

16、R8G8B8 =21 (&H15) D3DFMT_X8R8G8B8 =22 (&H16) D3DFMT_R5G6B5 =23 (&H17) End Enum为简明起见,以上只列出了几种常见的取值,理解概念即可。D3DFMT_UNKNOWN:顾名思义,未知格式。D3DFMT_R8G8B8:24位RGB 格式,R、G、B分别占8位。D3DFMT_A8R8G8B8:32位ARGB格式,A表示alpha.D3DFMT_X8R8G8B8:32位RGB格式,X8是保留的8位,未来可以根据情况灵活地分配给R、G、B。D3DFMT_R5G6B5:16位RGB格式。5+6+5=16.好,这样结构体 D3DDIS

17、PLAYMODE 我们就理解了,里面存放的是屏幕的宽、高、刷新率和颜色空间。下来我们再来看结构体D3DPRESENT_PARAMETERS。这里面包含了一个重要的单词(概念):Present。它既不是“礼物”,也不是“现在的”,也不是“介绍,引见”,而是“呈现,展现”的意思。我们在计算机构建了3D场景后,最终要在显示器上显示出来,这个3D变2D,矢量变点阵的过程就叫做:Present,展现。好了,下面看看它的定义:Type D3DPRESENT_PARAMETERS AutoDepthStencilFormat As CONST_D3DFORMAT BackBufferCount As Lon

18、g BackBufferFormat As CONST_D3DFORMAT (*) BackBufferHeight As Long BackBufferWidth As Long EnableAutoDepthStencil As Long Flags As Long FullScreen_PresentationInterval As Long FullScreen_RefreshRateInHz As Long hDeviceWindow As Long MultiSampleType As CONST_D3DMULTISAMPLE_TYPE SwapEffect As CONST_D3

19、DSWAPEFFECT (*) Windowed As Long (*)End Type有四个成员变量均含前缀 BackBuffer,意思是后台缓存或屏幕缓存,是为了解决绘图时的闪烁而引进的,先在缓存区绘好,再一次复制到显存来显示。为了更大限度地缓解“卡”的现象,还可设置多个缓存,组成“缓存链表”,缓存数由BackBufferCount指定。上面三个打了星号的成员变量 BackBufferFormat、SwapEffect 和 Windowed 是本程序中用到的:BackBufferFormat(1/3) 是 CONST_D3DFORMAT 类型的,存放颜色空间信息,上面已经说过了,BackB

20、uffer 刚刚才解释过,把它们组合在一起自然就是后天缓冲区的颜色空间格式咯。SwapEffect(2/3) 有如下四种取值:Enum CONST_D3DSWAPEFFECT D3DSWAPEFFECT_DISCARD = 1 D3DSWAPEFFECT_FLIP = 2 D3DSWAPEFFECT_COPY = 3 D3DSWAPEFFECT_COPY_VSYNC = 4End Enum其含义我还没弄懂,先照抄 SDK 的原文:D3DSWAPEFFECT_DISCARD When a swap chain is created with a swap effect of D3DSWAPEFF

21、ECT_FLIP, D3DSWAPEFFECT_COPY or D3DSWAPEFFECT_COPY_VSYNC, the runtime will guarantee that a Direct3DDevice8.Present operation will not affect the content of any of the back buffers. Unfortunately, meeting this guarantee can involve substantial video memory or processing overheads, especially when im

22、plementing flip semantics for a windowed swap chain or copy semantics for a full-screen swap chain. An application may use the D3DSWAPEFFECT_DISCARD swap effect to avoid these overheads and to enable the display driver to select the most efficient presentation technique for the swap chain. This is a

23、lso the only swap effect that may be used when specifying a value other than D3DMULTISAMPLE_NONE for the MultiSampleType member of D3DPRESENT_PARAMETERS. As with a swap chain that uses D3DSWAPEFFECT_FLIP, a swap chain that uses D3DSWAPEFFECT_DISCARD might include more than one back buffer, any of wh

24、ich may be accessed using Direct3DDevice8.GetBackBuffer or Direct3DSwapChain8.GetBackBuffer. The swap chain is best envisaged as a queue in which 0 always indexes the back buffer that will be displayed by the next Present operation and from which buffers are discarded once they have been displayed.

25、An application that uses this swap effect cannot make any assumptions about the contents of a discarded back buffer and should therefore update an entire back buffer before invoking a Present operation that would display it. Although this is not enforced, the debug version of the runtime will overwr

26、ite the contents of discarded back buffers with random data to enable developers to verify that their applications are updating the entire back buffer surfaces correctly. For a full-screen swap chain, the presentation rate is determined by the value assigned to the FullScreen_PresentationInterval me

27、mber of the D3DPRESENT_PARAMETERS structure when the device or swap chain is created. Unless this value is D3DPRESENT_INTERVAL_IMMEDIATE, the presentation will be synchronized with the vertical sync of the monitor. For a windowed swap chain, the presentation is implemented by means of copy operation

28、s and always occurs immediately. D3DSWAPEFFECT_FLIP The swap chain may comprise multiple back buffers and is best envisaged as a circular queue that includes the front buffer. Within this queue, the back buffers are always numbered sequentially from 0 to (N -1), where N is the number of back buffers

29、, so that 0 denotes the least recently presented buffer. When Present is invoked, the queue is rotated so that the front buffer becomes back buffer (N - 1), while back buffer 0 becomes the new front buffer. For a full-screen swap chain, the presentation rate is determined by the value assigned to th

30、e FullScreen_PresentationInterval field of the D3DPRESENT_PARAMETERS structure when the device or swap chain is created. Unless this value is D3DPRESENT_INTERVAL_IMMEDIATE, the presentation will be synchronized with the vertical sync of the monitor. For a windowed swap chain, the flipping is impleme

31、nted by means of copy operations and the presentation always occurs immediately. D3DSWAPEFFECT_COPY This swap effect may be specified only for a swap chain comprising a single back buffer. Whether the swap chain is windowed or full-screen, the runtime will guarantee the semantics implied by a copy-b

32、ased Present operation, namely that the operation leaves the content of the back buffer unchanged, instead of replacing it with the content of the front buffer as a flip-based Present operation would. For a windowed swap chain, a Present operation causes the back buffer content to be copied to the c

33、lient area of the target window immediately. No attempt is made to synchronize the copy with the vertical retrace period of the display adapter, so tearing effects may be observed. Windowed applications may wish to use D3DSWAPEFFECT_COPY_VSYNC instead to eliminate, or at least minimize, such tearing

34、 effects. For a full-screen swap chain, the runtime uses a combination of flip operations and copy operations, supported if necessary by hidden back buffers, to accomplish the Present operation. Accordingly, the presentation is synchronized with the display adapters vertical retrace and its rate is

35、constrained by the chosen presentation interval. A swap chain specified with the D3DPRESENT_INTERVAL_IMMEDIATE flag is the only exception. (Refer to the description of the FullScreen_PresentationInterval member of the D3DPRESENT_PARAMETERS structure.) In this case, a Present operation copies the bac

36、k buffer content directly to the front buffer without waiting for the vertical retrace. D3DSWAPEFFECT_COPY_VSYNC Like D3DSWAPEFFECT_COPY, this swap effect may only be used with a swap chain comprising a single back buffer and guarantees that a Present operation applied to the swap chain will exhibit

37、 copy semantics, as described above for D3DSWAPEFFECT_COPY. For a windowed swap chain, a Present operation causes the back buffer content to be copied to the client area of the target window. The runtime will attempt to eliminate tearing effects by avoiding the copy operation while the adapter is sc

38、anning within the destination rectangle on the display. It will also perform at most one such copy operation during the adapters refresh period and thus limit the presentation frequency. Note, however, that if the adapter does not support the ability to report the raster status, the swap chain will

39、behave as though it had been created with the D3DSWAPEFFECT_COPY swap effect. (Refer to the description of the D3DCAPS_READ_SCANLINE flag value for the Caps member of D3DCAPS8.) For a full-screen swap chain, D3DSWAPEFFECT_COPY_VSYNC is identical to D3DSWAPEFFECT_COPY, except that the D3DPRESENT_INTE

40、RVAL_IMMEDIATE flag is meaningless when used in conjunction with D3DSWAPEFFECT_COPY_VSYNC. (Refer to the description of the FullScreen_PresentationInterval member of the D3DPRESENT_PARAMETERS structure.) Windowed(3/3) 取TRUE(非零)时,以窗体模式运行,取FALSE(零)时,以全屏模式运行。“等一下,为什么我设置全屏方式运行会出错呢?”呵呵,那是因为没有设置后台缓冲区的尺寸大小

41、,只需在.BackBufferFormat = DispMode.Format的后面加两句: .BackBufferWidth = DispMode.Width .BackBufferHeight = DispMode.Height就可以了。下面看这一句:MyDirect3D8.GetAdapterDisplayMode D3DADAPTER_DEFAULT, DispModeGetAdapterDisplayMode方法,顾名思义就是获取显示适配器的显示模式,第一个参数是要查询的显卡序号,对于绝大多数人来说只有一个显卡,令其为0(D3DADAPTER_DEFAULT)就可以了。GetAdap

42、terDisplayMode 方法将查询到的显示模式(宽、高、刷新率和颜色模式)放入到结构体DispMode中。我们可以在这一句的后面插入以下三条语句来看看结果是不是和我们的显示设置相一致:Debug.Print DispMode.WidthDebug.Print DispMode.HeightDebug.Print DispMode.RefreshRate接下来到这句:Set MyDirect3DDevice8 = MyDirect3D8.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Me.hWnd, D3DCREATE_SOFTWARE_

43、VERTEXPROCESSING, d3dpp)上面已经说过,这是创建D3D设备对象,现在主要解释一下 CreateDevice 方法的各个参数:第一个参数和 GetAdapterDisplayMode 的第一个参数一样,第五个(最后一个)参数上面也已经解释过,就不说了,以下主要说明中间的三个参数:第二个参数是如下的枚举类型:Enum CONST_D3DDEVTYPE D3DDEVTYPE_HAL = 1 D3DDEVTYPE_REF = 2 D3DDEVTYPE_SW = 3End Enum有三种取值:HAL是硬件加速,REF是软件模拟,SW是软件插件。在我(VBProFan)的电脑里,HA

44、L正常,REF黑屏,SW直接出错第三个参数是要创建的D3D设备的窗口(控件)句柄,也就是说后面的3D场景要在哪里展示。本程序中是窗体Form,当然也可以是PictureBox,CommandButton,OptionButton,CheckBox,大家不妨在窗体上放上这些控件,然后改一下这个参数看看。不过这些控件只能在窗体模式下运行,不能全屏。第四个参数是行为标志,由“或”运算组合而成,类似MsgBox的buttons参数Enum CONST_D3DCREATEFLAGS D3DCREATE_FPU_PRESERVE = 2 D3DCREATE_MULTITHREADED = 4 D3DCRE

45、ATE_PUREDEVICE = 16 (&H10) D3DCREATE_SOFTWARE_VERTEXPROCESSING = 32 (&H20) D3DCREATE_HARDWARE_VERTEXPROCESSING = 64 (&H40) D3DCREATE_MIXED_VERTEXPROCESSING = 128 (&H80)End Enum由名字可大致看出其含义。至此,Form_Load事件里的代码基本讲解完毕,除了SwapEffect其含义我还没弄懂,Timer1.Enabled = True 没讲以外。待续。继续讲解顶楼的代码:初始化完毕后,用Timer1.Enabled = T

46、rue来启动时钟。这个时钟是用来干什么的呢?用来渲染场景的。我们知道,在2D的编程中,当 WM_PAINT 消息(Form_Paint)发生时,系统将会重绘大多数界面,用户数据部分由用户在事件中写代码来自己重绘。但 3D 编程就不用了,需要定时重绘(渲染)整个场景,当然你也可以只重绘发生变化的部分,但要计算哪个矩形区域发生变化非常麻烦,还不如重绘整个场景算了。以下的 Timer 事件就是用来渲染场景的: 1.2. Private Sub Timer1_Timer()3. Const WORLD_COLOR As Long = &HFF00&4.5. With MyDirect3DDevice8

47、6. .Clear 0, ByVal 0, D3DCLEAR_TARGET, WORLD_COLOR, 1#, 07. .BeginScene8. .EndScene9. .Present ByVal 0, ByVal 0, 0, ByVal 010. End With11. End Sub先用 Clear 清除场景,然后在 .BeginScene 和 .EndScene 之间渲染(绘制)场景,现在场景里没有任何东西,所以这之间暂时没有代码,但这片“空地”就是以后我们需要大做文章的地方。最后用 .Present 来展现整个场景。下面解释一下 .Clear 的各个参数:object.Clear( _ Count As Long, _

展开阅读全文
相似文档                                   自信AI助手自信AI助手
猜你喜欢                                   自信AI导航自信AI导航
搜索标签

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服