DX8使用介绍

2008-08-21
首先要说明的是使用DX8必须引用DirectX 8 for Visual Basic Type Library,以下是对DX8使用的初步介绍。
一、DX设备的创建
1.DX基本设备的创建
(1)定义变量
Public DXForm As Form
Public D3DPresentParam As D3DPRESENT_PARAMETERS
Public DX As DirectX8
Public D3D As Direct3D8
Public D3DDevice As Direct3DDevice8
Public D3DX As D3DX8
(2)定义语句
参数说明:
Set DX = New DirectX8
Set D3D = DX.Direct3DCreate

D3DPresentParam.BackBufferWidth = BackBufferWidth
D3DPresentParam.BackBufferHeight = BackBufferHeight
'这两句设置分辨率,BackBufferWidth、BackBufferHeight分别是游戏中使用分辨率的宽度、高度,分辨率的设计必须是机子上有的才可以,否则会报错
D3DPresentParam.BackBufferFormat = BackBufferFormat
'这句设置显示模式,属于CONST_D3DFORMAT常数类型,里面可以根据需要定义不同的A、R、G、B的位数,本教程使用D3DFMT_A8R8G8B8。
D3DPresentParam.SwapEffect = D3DSWAPEFFECT_DISCARD
'设置换页效果为丢弃后台缓存
D3DPresentParam.Windowed = 0
'这句设置是否是窗体,如果为1是窗体,为0是全屏
Set D3DDevice = D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, DXForm.hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, D3DPresentParam)
'这句是创建D3DDevice设备,游戏中常常用到,这里的DXForm指的是窗体对象(本文之后用到的窗体对象都叫DXForm)
Set D3DX = New D3DX8
2.DX的Sprite对象的创建
(1)定义变量
Public Sprite As D3DXSprite
(2)创建语句
Set Sprite = D3DX.CreateSprite(D3DDevice)
3.DX控制设备的创建
(1)定义变量
Public DI As DirectInput8
Public DIDEVKeyboard As DirectInputDevice8
Public DIKeyboard As DIKEYBOARDSTATE
Public DIDEVMouse As DirectInputDevice8
Public DIMouse As DIMOUSESTATE
(2)创建语句
Set DI = DX.DirectInputCreate()
'创建DirectInput8对象
Set DIDEVKeyboard = DI.CreateDevice("GUID_SysKeyboard")
'创建键盘对象
DIDEVKeyboard.SetCommonDataFormat DIFORMAT_KEYBOARD
设置它的数据格式
DIDEVKeyboard.SetCooperativeLevel DXhFocusWindow, DISCL_BACKGROUND Or DISCL_NONEXCLUSIVE
设置它的协作级
DIDEVKeyboard.Acquire
'获取设备
Set DIDEVMouse = DI.CreateDevice("GUID_SysMouse")
'创建鼠标对象
DIDEVMouse.SetCommonDataFormat DIFORMAT_MOUSE
设置它的数据格式
DIDEVMouse.SetCooperativeLevel DXhFocusWindow, DISCL_BACKGROUND Or DISCL_NONEXCLUSIVE
设置它的协作级
If D3DPresentParam.Windowed <> 1 Then
DIDEVMouse.Acquire
End If
'这里需要判断是否为窗口模式,因为如果是窗口模式获取设备会出错
二、DX的使用
1.主循环
Do
If D3DDevice.TestCooperativeLevel = 0 Then '检测是否可以渲染
DIDEVKeyboard.GetDeviceStateKeyboard DIKeyboard '更新键盘信息
If DIKeyboard.Key(DIK_ESCAPE) Then End '如果按下ESC键,则程序退出(这里只是举例怎么判断键盘按下哪个键,DIK_ESCAPE属于CONST_DIKEYFLAGS常数类型,其它的按键都有相应的常数,判断某个键按下只要写入相应的参数就行)
DIDEVMouse.GetDeviceStateMouse DIMouse'更新鼠标信息
If DIMouse.Buttons(0) Then End'如果按下鼠标左键,则程序退出(这里只是举例怎么判断鼠标按下哪个键,上面的0代标左键,1是代表右键)
'这里可以写游戏数据的改变的代码
D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET, 0, 0, 0 '清屏
D3DDevice.BeginScene'开始场景
'渲染代码(后面会提到)
D3DDevice.EndScene'结束场景
D3DDevice.Present ByVal 0, ByVal 0, 0, ByVal 0'显示场景
Else
If DXForm.WindowState <> 1 Then‘检测窗体是否是最小化,如果不是,才可以进行设备重置
'文字设备摧毁(后面会有介绍)
'用来渲染纹理设备摧毁(后面会有介绍)
Set Sprite = Nothing'DX图形设备摧毁
D3DDevice.Reset D3DPresentParam 'DX重置
Set Sprite = D3DX.CreateSprite(D3DDevice)'DX图形设备重建
'文字设备重建(后面会有介绍)
'纹理设备重建(后面会有介绍)
End If
End If
DoEvents
Loop
2.纹理
(1)定义变量
Public tex As Direct3DTexture8'纹理对象
Public TexDesc(1) As D3DXIMAGE_INFO'用来储存纹理大小信息(只有当从文件里读数据才需要,创建空的纹理时不需要)
(2)创建对象
方法一:通过文件名载入图片来创建纹理
Set tex = D3DX.CreateTextureFromFileEx(D3DDevice, FileName, width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE, Transcolor, TexDesc(0), ByVal 0)
方法二:创建空的纹理对象
Set tex = D3DX.CreateTexture(D3DDevice, width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED)

'其中FileName指文件名,width, height分别指纹理的高度和宽度,如果都设为-1则由DX本身决定其大小,D3DFMT_A8R8G8B8指的就是图片显示模式,Transcolor指透明色(DX的透明色有专门的一组函数来输入颜色,本文中使用的是D3DFMT_A8R8G8B8模式,因此使用D3DcolorARGB函数,如果用紫色表示透明色,则用D3DcolorARGB(255,255,0,255),这四个参数的含义分别是透明度、红、绿、蓝),TexDesc数组是用来读取纹理大小信息,读取以后TexDesc(0).height、TexDesc(0).width分别表示纹理高度、宽度
(3)访问纹里的内存(这里仅说明在D3DFMT_A8R8G8B8模式下的操作方法)
Dim pData As D3DLOCKED_RECT'用来存储纹理中数据
Dim pxArr() As Byte'这个数组用来存储纹理中各点的颜色数据
Tex.LockRect 0, pData, ByVal 0, 0'在内存访问之前必须锁定纹理
ReDim pxArr(pData.Pitch * height) As Byte'height'代表纹理高度
DXCopyMemory pxArr(0), ByVal pData.pBits, pData.Pitch * height'将纹理中数据拷贝到pxArr数组
pos = posy * pData.Pitch + posx * 4'posx,posy代表纹理上某一点的坐标
'此时pxArr(pos + 3)、pxArr(pos + 2)、pxArr(pos + 1)、pxArr(pos)分别代表A、R、G、B值,获取这些点的值方法很简单,比如a=pxArr(pos + 3)就获取了该点的R值
pxArr(pos + 3) =100
pxArr(pos + 2) = 100
pxArr(pos + 1) = 100
pxArr(pos) = 100
'以上就修改了pos点的ARGB值,但要想修改生效还需下面那句的拷贝
DXCopyMemory ByVal pData.pBits, pxArr(0), pData.Pitch * height
Tex.UnlockRect 0'在内存访问之后解锁纹理
3.表面
(1)定义变量
Public Sur As Direct3DSurface8
(2)获取纹理的表面
Set Sur = Tex.GetSurfaceLevel(0)
(3)拷贝贴图
拷贝一张贴图一部分到目标贴图一个位置的方法:
Dim SouSur As Direct3DSurface8
Dim DesSur As Direct3DSurface8
Set SouSur = soutex.GetSurfaceLevel(0)'soutex代表源纹理
Set DesSur = destex.GetSurfaceLevel(0)'destex代表目标纹理
Dim tRect As RECT'表示源纹理截取的部分(left、right、top、bottom分别代表要截取部分的左右上下的坐标
tRect.left = 10
tRect.Right = 20
tRect.top = 10
tRect.bottom = 20
Dim tDest As Point'表示要拷贝到的目标纹理的坐标
tDest.x = desx
tDest.y = desy
D3DDevice.CopyRects SouSur, tRect, 1, DesSur, tDest
'SouSur代表源纹理表面,tRect代表源纹理截取位置,1代表只拷贝一张图(如果要拷贝2张图就写2)tDest代表目标纹理位置DesSur代表目标纹理表面
拷贝一张贴图多个部分到目标贴图多个位置的方法:
dim sou() as rect'一张贴图多个截取部分用数组存放
dim des() as rect'目标贴图多个位置用数组存放
Dim SouSur As Direct3DSurface8
Dim DesSur As Direct3DSurface8
Set SouSur = soutex.GetSurfaceLevel(0)
Set DesSur = destex.GetSurfaceLevel(0)
D3DDevice.CopyRects SouSur, sou(LBound(sou)), UBound(sou) - LBound(sou) + 1, DesSur, des(LBound(des))
4.Sprite对象的使用
(1)定义变量
public Rect1 As RECT
public Tran As D3DVECTOR2'D3DVECTOR2结构有x,y两个属性
public Scal As D3DVECTOR2
public Center As D3DVECTOR2
(2)贴图
Sprite.Begin'开启Sprite对象
Sprite.Draw tex, Rect1, Scal, Center, Rotation, Tran, color
'tex代表纹理对象,rect1代表从纹理截取的部分,scal代表放大倍数(x代表横向放大倍数,y代表纵向放大倍数),Center代表旋转点的坐标,Rotation代表旋转的角度,旋转时是以Center为中心点旋转Rotation角度,Tran代表在目标位置贴图的坐标,color表示渲染时显示图片的程度(比如d3dcolorargb(128,255,255,255)就表示A值只显示纹理本身A值的一半,又如d3dcolorargb(255,0,0,255)就表示只显示该图的B值分量,R,G的分量不显示,所以这时显示出来的图片就是蓝色的效果)
Sprite.End'关闭Sprite对象
'要说明的是在Sprite.Begin和Sprite.End可以写若干句Sprite.Draw,由于游戏里面主要是图片,所以Sprite.Begin和Sprite.End经常也写到主循环里面,但是在Sprite.Begin和Sprite.End之间是不能够画点线面的,所以本文不把它作为主循环的一部分
5.在纹理中渲染
DX中有种用来渲染的纹理,它可以把文字等等内容都渲染到纹理上,以实现显示文字的一部分等等效果
(1)定义变量
Public rendertex As Direct3DTexture8'纹理对象
(2)创建对象
Set rendertex = D3DX.CreateTexture(D3DDevice, width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT)'注意D3DUSAGE_RENDERTARGET这个参数,它说明的是这个纹理用来渲染
(3)在纹理中渲染
主循环中默认是对屏幕渲染,当前渲染的对象D3DDevice.GetRenderTarget(是Direct3DSurface8类型的),在改变渲染对象之前要将当前渲染的对象保存以来,以免改变渲染对象之后改变不回来了
dim oldSur As Direct3DSurface8
set oldSur=D3DDevice.GetRenderTarget
dim rendersur As Direct3DSurface8
set rendersur=rendertex.GetSurfaceLevel(0)
D3DDevice.EndScene'要先结束对当前对象(屏幕)的渲染
D3DDevice.SetRenderTarget rendersur, Nothing, ByVal 0'这句是设置渲染对象,以下的代码跟之前所说的主循环是一样的
D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET, 0, 0, 0
D3DDevice.BeginScene
'渲染代码(这里都是对rendertex进行渲染,不会显示在屏幕上)
D3DDevice.EndScene'结束场景
D3DDevice.Present ByVal 0, ByVal 0, 0, ByVal 0'显示场景
'如果想让rendertex显示在屏幕上,就需要如下的代码
D3DDevice.SetRenderTarget oldSur, Nothing, ByVal 0
D3DDevice.BeginScene
Sprite.Begin
Sprite.Draw rendertex, Rect1, Scal, Center, Rotation, Tran, color
Sprite.End
6.渲染文字
(1)定义变量
public Rect1 As RECT
public IFont As IFont
public Font As D3DXFont
(2)创建对象
Dim tStdFont As New StdFont
tStdFont.name = FontName'字体名
tStdFont.Bold = Bold'是否粗体
tStdFont.Italic = Italic‘是否斜体
tStdFont.Underline = Underline'是否下划线
tStdFont.Size = size'字的大小
Set IFont = mStdFont
Set Font = D3DX.CreateFont(D3DDevice, IFont.hFont)'这句执行以后,文字对象就建立了
(3)渲染文字
D3DX.DrawText Font, color, caption, Rect1, DT_VCENTER
'Font代表文字对象,color代表文字颜色,caption代表文字内容,rect1代表渲染文字的目标位置,DT_VCENTER代表文字的对齐方式,这里是代表垂直居中显示(DT_VCENTER属于CONST_DTFLAGS常数类型,里面的各个参数用来实现靠左、靠右、居中等等)
7.画图形
首先要注意不能在Sprite.Begin和Sprite.End之间画图形,所以如果之前有Sprite.Begin,此时得先Sprite.End。
(1)定义类型
Private Type TLVERTEX
x As Single
y As Single
Z As Single
rhw As Single
color As Long
Tu As Single
Tv As Single
End Type
(2)画点
D3DDevice.SetVertexShader D3DFVF_XYZRHW Or D3DFVF_TEX1 Or D3DFVF_DIFFUSE
Dim CreateTLVertex2D(0) As TLVERTEX'因为点本身只有一个顶点,所以数组元素只需要一个
CreateTLVertex2D(0).x = x
CreateTLVertex2D(0).y = y
'设置点的坐标
CreateTLVertex2D(0).rhw = 1
CreateTLVertex2D(0).color = color
'设置点的颜色
D3DDevice.DrawPrimitiveUP D3DPT_POINTLIST, 1, CreateTLVertex2D(0), Len(CreateTLVertex2D(0))
'画点
(3)画线
D3DDevice.SetVertexShader D3DFVF_XYZRHW Or D3DFVF_TEX1 Or D3DFVF_DIFFUSE
Dim CreateTLVertex2D(1) As TLVERTEX'因为线有两个顶点,所以数组元素需要两个
CreateTLVertex2D(0).x = x1
CreateTLVertex2D(0).y = y1
CreateTLVertex2D(0).rhw = 1
CreateTLVertex2D(0).color = color
'设置第一个顶点的坐标、颜色
CreateTLVertex2D(1).x = x2
CreateTLVertex2D(1).y = y2
CreateTLVertex2D(1).rhw = 1
CreateTLVertex2D(1).color = color
'设置第二个顶点的坐标、颜色
D3DDevice.DrawPrimitiveUP D3DPT_LINELIST, 1, CreateTLVertex2D(0), Len(CreateTLVertex2D(0))
'画线
(4)画矩形
D3DDevice.SetVertexShader D3DFVF_XYZRHW Or D3DFVF_TEX1 Or D3DFVF_DIFFUSE
Dim CreateTLVertex2D(3) As TLVERTEX'因为矩形有四个顶点,所以数组元素需要四个
CreateTLVertex2D(0).x = x1
CreateTLVertex2D(0).y = y1
CreateTLVertex2D(0).rhw = 1
CreateTLVertex2D(0).color = color
CreateTLVertex2D(1).x = x2
CreateTLVertex2D(1).y = y1
CreateTLVertex2D(1).rhw = 1
CreateTLVertex2D(1).color = color
CreateTLVertex2D(2).x = x1
CreateTLVertex2D(2).y = y2
CreateTLVertex2D(2).rhw = 1
CreateTLVertex2D(2).color = fcolor
CreateTLVertex2D(3).x = x2
CreateTLVertex2D(3).y = y2
CreateTLVertex2D(3).rhw = 1
CreateTLVertex2D(3).color = fcolor
'以上根据矩形的四点的坐标设置四个顶点
D3DDevice.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, CreateTLVertex2D(0), Len(CreateTLVertex2D(0))
'画面
'这里要说明的是,第二个参数为什么之前写1而这里写2,实际上这个面是由2个三角形构成的,CreateTLVertex2D(0),CreateTLVertex2D(1),CreateTLVertex2D(2)这三个顶点构成了一个三角形,CreateTLVertex2D(1),CreateTLVertex2D(2),CreateTLVertex2D(3)这三个顶点又构成了一个三角形,DX是先把前三个顶点作成一个三角形,再把后三个顶点作成一个三角形,然后形成了矩形的效果,如果把各个顶点的数据修改下,两个三角形就体现了很明显了。这里所说的只是四个顶点的情形,当有五个顶点的时侯,就会有3个三角形,六个的时侯就有4个三角形,以此类推。
8.设备重置
在DX中Sprite对象、文字、用来渲染的纹理、表面对象需要重置,设备重置的大体流程在主循环中已经写过,这里只说明文字和用来渲染的纹理设备重置方法
(1)文字设备重置方法
摧毁代码:
Set Font = Nothing
重建代码:
Set Font = D3DX.CreateFont(D3DDevice, IFont.hFont)
(2)用来渲染的纹理设备重置方法
摧毁代码:
Set rendertex = Nothing
重建代码:
Set rendertex = D3DX.CreateTexture(D3DDevice, width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT)

要注意的是DX所有的文字、用来渲染的纹理对象、表面对象都需要重置,只要漏了一个,D3DDevice.Reset D3DPresentParam这句就不能执行,所以当出现切换回游戏有自动化错误的时侯,就是因为对象没有清空干净。
最新评论
暂无评论
参与评论

商务合作 查看更多

编辑推荐 查看更多
【爆款新游】【潜力佳作】分析系列
推广