译:Jove
DXSDK8-Visual Basic教程
创建D3D设备
创建一个简单的D3D设备并进行图形渲染 第一步 创建窗体和picture控件 Caption = "Create Device"
Height = 3600
Left = 0
Top = 0
Width = 4800
LinkTopic = "Form1"
MaxButton = True
MinButton = True
ScaleHeight = 3195
ScaleMode = 1 - Twip
ScaleWidth = 254
StartUpPosition = 3 - Windows Default 第二步 开始D3D设备 首先要用DirectX8.Direct3DCreate方法创建一个Direct3d8对象 代码: get g_D3D = g_DX.Direct3DCreate()
g_D3D Is Nothing Then Exit Function 方法格式: Direct3d8object.direct3dcreate();
备注: 他将返回一个Direct3d8对象只有在创建了DirectX8对象后才可以创建Direct3DDevice8对象
其次要用Direct3D8.GetAdapterDisplayMode方法接受到当前的显示模式 代码: Dim Mode As D3DDISPLAYMODE
g_D3D.GetAdapterDisplayMode D3DADAPTER_DEFAULT, mode 方法格式: Direct3d8object.GetAdapterDisplayMode Adapter As Long,Mode As D3DDISPLAYMODE
备注: 用Direct3d8对象来接收,Adapter参数是要查询的显卡序号,一般是D3DADAPTER_DEFAULT值来指定主显卡,Mode参数为当前显示模式的接收变量,D3DDISPLAYMODE对象有Format,Height,RefreshRate,Width成员.format成员的值为23(&H17)时表示16位RGB像素格式为22时是32位. RefreshRate值表示刷新率,为0时表示为默认的刷新率.
在取得显示模式后,以后就可以用此结构在创建一个运行在窗口模式下的Direct3Ddevice设备时,建立一个与当前显卡相匹配的后缓冲区接下来用D3DPRESENT_PARAMETERS对象来指定3D应用程序的表现 代码: Dim d3dpp As D3DPRESENT_PARAMETERS
d3dpp.Windowed = 1
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC
d3dpp.BackBufferFormat = mode.Format 对象说明: D3DPRESENT_PARAMETERSobject.成员
备注: 成员Windowed用来说明3D应用程序运行的环境为1表示在窗口模式下.成员SwapEffect是个枚举类型,D3DSWAPEFFECT_COPY_VSYNC时值为4用来说明只有一个后缓冲区,并执行COPY操作.成员BackBufferFormat用来指定后缓冲区的格式,在Windowed在被说明成TURE(1)时,必须为GetAdapterDisplayMode方法取到的值.
下面就要用CreateDevice方法利用上面对象的值设置应用程序 代码: Set g_D3DDevice =g_D3D.CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,d3dpp)
If g_D3DDevice Is Nothing Then Exit Function 方法格式: Direct3D8object.CreateDevice Adapter,DeviceType,hFocusWindow, BehaviorFlags,PresentationParameters
备注: 返回一个Direct3DDevice8对象,Adapter参数为查询的显卡序号,一般为D3DADAPTER_DEFAULT,DeviceType参数为D3DDEVTYPE常量,表示设备类型D3DDEVTYPE_HAL意义为硬件驱动软件补充,hFocusWindow参数是设备的窗口句柄.BehaviorFlags控制D3D设备的全局性能,为D3DCREATE_SOFTWARE_VERTEXPROCESSING规定为软件顶进程.
第三步 渲染和显示场景
本例使用一个(Interval=40)timer控件触发场景的后缓冲区进行颜色填充.再把后缓冲与前缓冲交换实现渲染 首先用Direct3DDevice8.Clear方法进行填充颜色 代码: g_D3DDevice.Clear 0,ByVal 0,D3DCLEAR_TARGET,&HFFFF0,1#,0 方法格式: Direct3DDevice8object.Clear Count,ClearD3DRect,Flags,Color,Z,Stencil
备注: ClearD3DRect参数为D3DRECT类型是指明清除的区域可以被说明为ByVal 0表明所有点都被清除.Count参数是指区域的数量,当ByVal 0为ClearD3DRect的值时这里要设为0.flags为D3DCLEARFLAGS常量,为D3DCLEAR_TARGET时表示清除渲染目标,color为填充颜色值.参数Z为深度缓冲的大小取值为0.0到1.0.参数Stencil在有模板缓冲时使用可以是0到2.
在是开始场景和结束场景 代码: g_D3DDevice.BeginScene
g_D3DDevice.EndScene
在渲染完场景后再用Direct3DDevice8.Present方法显示出来 代码: g_D3DDevice.Present ByVal 0, ByVal 0, 0, ByVal 0 方法格式: Direct3DDevice8object.Present SourceRect,DestRect,DestWindowOverride,DirtyRegion
备注: 参数SourceRect为包含源矩形的类型,一般为ByVal 0则全部源表面被呈现.参数DestRect为包含目标矩形的类型,一般为ByVal 0则全部用户区域被填充.DestWindowOverride参数说明用户区域作为这个图象的目标窗口被取得,当为0时则D3DPRESENT_PARAMETERS成员hWndDeviceWindow被取.在窗口模式下此成员为Present方法设定缺省的目标窗口如果没有取值表示焦点窗口被取得.DirtyRegion参数总是被设置成ByVal 0
第四步 关闭应用程序 在DX应用程序结束后必须把所有的DX对象设置成Nothing 代码: Set g_D3D = Nothing
Set g_D3DDevice = Nothing
所有代码如下:
Dim g_DX As New DirectX8
Dim g_D3D As Direct3D8
Dim g_D3DDevice As Direct3DDevice8
Private Sub Form_Load()
Me.Show
DoEvents
b = InitD3D(Picture1.hWnd) '初始化设备
If Not b Then
MsgBox "Unable to CreateDevice (see InitD3D()source for comments)"
End
End If
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
Render '渲染
End Sub
Private Sub Form_Unload(Cancel As Integer)
Cleanup '清除设备
End
End Sub
Function InitD3D(hWnd As Long) As Boolean'初始化
On Local Error Resume Next
Set g_D3D = g_DX.Direct3DCreate()
If g_D3D Is Nothing Then Exit Function
Dim mode As D3DDISPLAYMODE
g_D3D.GetAdapterDisplayMode D3DADAPTER_DEFAULT, mode
Dim d3dpp As D3DPRESENT_PARAMETERS
d3dpp.Windowed = 1
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC
d3dpp.BackBufferFormat = mode.Format
Set g_D3DDevice =g_D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING, d3dpp)
If g_D3DDevice Is Nothing Then Exit Function
InitD3D = True
End Function
Sub Cleanup() '清除设备
Set g_D3DDevice = Nothing
Set g_D3D = Nothing
End Sub
Sub Render() '渲染
If g_D3DDevice Is Nothing Then Exit Sub
g_D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET, &HFF&, 1#, 0
g_D3DDevice.BeginScene
g_D3DDevice.EndScene
g_D3DDevice.Present ByVal 0, ByVal 0, 0, ByVal 0
End Sub
要使用D3D进行渲染就必须创建Direct3DDevice8对象
在DirectX8.Direct3DCreate方法先要创建一个Direct3d8对象
再用Direct3d8.CreateDevice方法创建Direct3DDevice8对象
其中还要Direct3D8.GetAdapterDisplayMode方法接受到当前的显示模式
并要设置D3DPRESENT_PARAMETERS成员来指定3D应用程序的表现
创建完后用Direct3DDevice8.Clear方法进行填充颜色
并开始场景用Direct3DDevice8.Present方法显示出来
最后还要把所有的DX对象设置成Nothing 来结束DX程序
顶点的渲染
使用顶点画几何图形,本例使用3个顶点,并使用了顶点缓冲区的概念
第一步:定义一个顶点类型
首先定义顶点格式,并指定在顶点缓冲区里描述画面顶点的FVF 代码: Private Type CUSTOMVERTEX
x As Single
y As Single
z As Single
rhw As Single
color As Long
End Type
Const D3DFVF_CUSTOMVERTEX=(D3DFVF_XYZRHW Or D3DFVF_DIFFUSE) 说明: FVF(Flexible Vertex Format)用来描述在单个数据流里交错存储的顶点内容,FVF代码通常用来指定:数据用固定的顶点函数来处理;D3DFVF_DIFFUSE说明包含了扩散的颜色部分;D3DFVF_XYZRHW说明包含了已转化了的顶点位置,已转化了的标志着D3D不能对此点进行世界或视图坐标的转化.
第二步:设置顶点缓冲区
本例子用自定义的InitVB过程在创建了D3D所需的对象后来实现初始化顶点缓冲区, 接下来的代码初始了三个特定的顶点类型来填充顶点缓冲区
代码: With Vertices(0)
.x=150
.y=50
.z=0.5
.rhw=1
.color=&HFFFF0000
End With With Vertices(1)
.x=250
.y=250
.z=0.5
.rhw=1
.color=&HFF00FF00
End With With Vertices(2)
.x= 50
.y=250
.z=0.5
.rhw = 1
.color =&HFF00FFFF
End With 说明: 3个点的颜色值,用于进行颜色渐变,red(&HFFFF0000) green(&HFF00FF00) blue-green(&HFF00FFFF)Z和RHW成员说明点的深度和RHW值为0.5,1
下面用CreateVertexBuffer方法建立顶点缓冲区 代码: Set g_VB = g_D3DDevice.CreateVertexBuffer(VertexSizeInBytes* 3,0,D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT)
If g_VB Is Nothing Then Exit Function 方法格式: Direct3DDevice8对象.CreateVertexBuffer LengthInBytes,Usage,FVF,Pool
备注: 参数LengthInBytes用来容纳顶点缓冲区的大小;参数Usage是个D3DUSAGEFLAGS常量,为0时表示新顶点的使用;参数Pool值为D3DPOOL常量,D3DPOOL_DEFAULT指明程序资源要放在显存的首选地址;方法返回值是个Direct3DVertexBuffer8类型
接下来使用D3DVertexBuffer8SetData来添加数据 代码: D3DVertexBuffer8SetData g_VB,0,VertexSizeInBytes*3,0,Vertices(0) 格式: D3DVertexBuffer8SetData VBuffer,Offset,Size,Flags,Data
备注: 参数VBuffer是Direct3DVertexBuffer8类型.参数offset是表示缓冲区的起始位置.参数Size代表缓冲区的大小.参数Flags代表了如何锁定缓冲,这里用0表示使用默认的值,参数Data代表缓冲区要包含的数据
第三步 渲染显示表面
现在仍使用clear方法来清除表面并开始场景 代码: g_D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET, &HFF&, 1#, 0
g_D3DDevice.BeginScene
接下来要用SetStreamSource方法,来设置顶点缓冲区对应的流 代码: Dim v As CUSTOMVERTEX
sizeOfVertex = Len(v)
g_D3DDevice.SetStreamSource 0, g_VB, sizeOfVertex 格式: Direct3DDevice8对象.SetStreamSource(StreamNumber,StreamData,Stride)
备注: 这个方法使顶点缓冲区绑定一个设备数据流.参数StreamNumber表示使用流0;参数StreamData代表要绑定的顶点缓冲区;参数Stride为表示流组件的大小,当使用FVF顶点时,流组件大小必须和顶点大小匹配.
下一步是使用CreateVertexShader方法来创建顶点遮盖 代码: g_D3DDevice.SetVertexShader D3DFVF_CUSTOMVERTEX 格式: Direct3DDevice8对象.SetVertexShader(VertexShaderHandle)
备注: 顶点遮盖运用于顶点处理.参数VertexShaderHandle为顶点遮盖的句柄或者FVF代码.这里使用D3DFVF_CUSTOMVERTEX表示使用FVF代码.说明绑定在设备上的流0被引用
使用DrawPrimitive在顶点缓冲区里渲染顶点 代码: g_D3DDevice.DrawPrimitive D3DPT_TRIANGLELIST, 0, 1 格式: Direct3DDevice8对象.DrawPrimitive(PrimitiveType,StartVertex,PrimitiveCount)
备注: 绘制主平面,参数PrimitiveType是个CONST_D3DPRIMITIVETYPE枚举类型,这里使用D3DPT_TRIANGLELIST表示告诉D3D设备要绘制的主平面为三角形.参数StartVertex为第一个点的索引,参数PrimitiveCount为要绘制的主平面数,这里为1
最后的步骤就是交换前后缓冲,这个例子只是简单说明如何用顶点来绘制几何图形 代码: g_D3DDevice.EndScene
g_D3DDevice.Present ByVal 0, ByVal 0, 0, ByVal 0
所有代码如下:
Dim g_DX As New DirectX8
Dim g_D3D As Direct3D8
Dim g_D3DDevice As Direct3DDevice8
Dim g_VB As Direct3DVertexBuffer8
Private Type CUSTOMVERTEX
x As Single
y As Single
z As Single
rhw As Single
color As Long
End Type
Const D3DFVF_CUSTOMVERTEX = (D3DFVF_XYZRHW Or D3DFVF_DIFFUSE)
Private Sub Form_Load()
Dim b As Boolean
Me.Show
DoEvents
b = InitD3D(Picture1.hWnd)
If Not b Then
MsgBox "Unable to CreateDevice (see InitD3D() source for comments)"
End
End If
b = InitVB()
If Not b Then
MsgBox "Unable to Create VertexBuffer"
End
End If
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
Render
End Sub
Private Sub Form_Unload(Cancel As Integer)
Cleanup
End
End Sub
Function InitD3D(hWnd As Long) As Boolean
Set g_D3D = g_DX.Direct3DCreate()
If g_D3D Is Nothing Then Exit Function
Dim mode As D3DDISPLAYMODE
g_D3D.GetAdapterDisplayMode D3DADAPTER_DEFAULT, mode
Dim d3dpp As D3DPRESENT_PARAMETERS
d3dpp.Windowed = 1
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC
d3dpp.BackBufferFormat = mode.Format
Set g_D3DDevice = g_D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, d3dpp)
If g_D3DDevice Is Nothing Then Exit Function
InitD3D = True
End Function
Function InitVB() As Boolean
Dim Vertices(3) As CUSTOMVERTEX
Dim VertexSizeInBytes As Long
VertexSizeInBytes = Len(Vertices(0))
With Vertices(0): .x = 150: .y = 50: .z = 0.5: .rhw = 1: .color = &HFFFF0000: End With
With Vertices(1): .x = 250: .y = 250: .z = 0.5: .rhw = 1: .color = &HFF00FF00: End With
With Vertices(2): .x = 50: .y = 250: .z = 0.5: .rhw = 1: .color = &HFF00FFFF: End With
Set g_VB = g_D3DDevice.CreateVertexBuffer(VertexSizeInBytes * 3, 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT)
If g_VB Is Nothing Then Exit Function
D3DVertexBuffer8SetData g_VB, 0, VertexSizeInBytes * 3, 0, Vertices(0)
InitVB = True
End Function
Sub Cleanup()
Set g_VB = Nothing
Set g_D3DDevice = Nothing
Set g_D3D = Nothing
End Sub
Sub Render()
Dim v As CUSTOMVERTEX
Dim sizeOfVertex As Long
If g_D3DDevice Is Nothing Then Exit Sub
g_D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET, &HFF&, 1#, 0
g_D3DDevice.BeginScene
sizeOfVertex = Len(v)
g_D3DDevice.SetStreamSource 0, g_VB, sizeOfVertex
g_D3DDevice.SetVertexShader D3DFVF_CUSTOMVERTEX
g_D3DDevice.DrawPrimitive D3DPT_TRIANGLELIST, 0, 1
g_D3DDevice.EndScene
g_D3DDevice.Present ByVal 0, ByVal 0, 0, ByVal 0
End Sub
总结:
首先你要定义CUSTOMVERTEX结构和FVF
象大多数D3D程序一样要初始化3D设备(教程1内容)
再设定3个CUSTOMVERTEX类型的顶点
建立顶点缓冲区是必须的,并为其填充要包含的数据
清除场景,把顶点缓冲区绑定在流上,是渲染的开始
接着创建顶点遮盖,把顶点在顶点缓冲区里进行渲染
后面就是交换前后缓冲,把渲染结果呈现出来
结束所有D3D设备
使用矩阵
本教程介绍了如何使用矩阵,我们在顶点的例子里,渲染了一个2D的三角形,而本例子将把它转化为3D 第一步:定义世界变化矩阵
介绍在3-D空间里矩阵的世界矩阵如何转化,度量,和旋转几何图形
首先使用D3DXMatrixRotationY方法把三角形围绕Y轴旋转 代码: Dim matWorld As D3DMATRIX
D3DXMatrixRotationY matWorld, Timer * 4 格式: D3DXMatrixRotationY(MOut,angle)
备注: 建立一个围Y轴旋转的矩阵, 参数MOut是个D3DMATRIX类型t包含着返回的矩阵; 参数angle是表示旋转的弧度
接下来就是用SetTransform来设置当前的D3D设备的转变 代码: g_D3DDevice.SetTransform D3DTS_WORLD, matWorld 格式: Direct3DDevice8对象.SetTransform(TransformType,Matrix)
备注: 参数TransformType是D3DTRANSFORMSTATETYPE枚举类型D3DTS_WORLD指出一个世界矩阵将被设置,参数Matrix是一个指向单前转化矩阵的指针
第二步:定义视图变化矩阵
视图矩阵定义了视图的位置和转动,相当于一个场景摄象机.
首先使用D3DXMatrixLookAtLH方法 代码: Dim matView As D3DMATRIX
D3DXMatrixLookAtLH matView,vec3(0#,3#,-5#),vec3(0#,0#,0#),vec3(0#,1#,0#)
格式: D3DXMatrixLookAtLH(MOut,VEye,VAt,VUp)
备注: 参数MOut是D3DMATRIX类型,参数VEye为D3DVECTOR类型定义观察点(Y+3,Z-5),参数VAt为D3DVECTOR类型定义摄影机焦距(原点),参数VUp是D3DVECTOR定义向上的方向(0,1,0)
代码: g_D3DDevice.SetTransform D3DTS_VIEW, matView 备注: 参数TransformType是D3DTRANSFORMSTATETYPE枚举类型D3DTS_VIEW指出一个视图矩阵将被设置
第三步:定义投影变化矩阵
投影矩阵定义了几何图形被从2D转化为3D首先使用D3DXMatrixPerspectiveFovLH方法,在观察视野创建一个左手透视投影矩阵(相当于人的视野) 代码: Dim matProj As D3DMATRIX
D3DXMatrixPerspectiveFovLH matProj, g_pi / 4, 1, 1, 100
g_D3DDevice.SetTransform D3DTS_PROJECTION, matProj 格式: D3DXMatrixPerspectiveFovLH(MOut,fovy,aspect,zn,zf)
备注: 参数MOut是D3DMATRIX类型;参数fovy弧度表示的观察视野,让远处的物体看起来更小,一个标准的观察视野是PI/4;参数aspect长宽高度比,标准为1;参数zn和zf设定几何物体在Z上的可视范围最近和最远的两个点
代码: g_D3DDevice.SetTransform D3DTS_VIEW, matView 备注: 参数TransformType是D3DTRANSFORMSTATETYPE枚举类型D3DTS_PROJECTION指出一个投影矩阵将被设置
所有代码
Option Explicit
Dim g_DX As New DirectX8
Dim g_D3D As Direct3D8
Dim g_D3DDevice As Direct3DDevice8
Dim g_VB As Direct3DVertexBuffer8
Private Type CUSTOMVERTEX
x As Single
y As Single
z As Single
color As Long
End Type
Const D3DFVF_CUSTOMVERTEX=(D3DFVF_XYZ Or D3DFVF_DIFFUSE)
Const g_pi = 3.1415
Private Sub Form_Load()
'省略
End Sub
Private Sub Timer1_Timer()
Render
End Sub
Private Sub Form_Unload(Cancel As Integer)
End
End Sub
Function InitD3D(hWnd As Long) As Boolean
'省略
End Function
Sub SetupMatrices()
Dim matWorld As D3DMATRIX
D3DXMatrixRotationY matWorld, Timer * 4
g_D3DDevice.SetTransform D3DTS_WORLD, matWorld
Dim matView As D3DMATRIX
D3DXMatrixLookAtLH
matView, vec3(0#, 3#, -5#), vec3(0#, 0#, 0#), vec3(0#, 1#, 0#)
g_D3DDevice.SetTransform D3DTS_VIEW, matView
Dim matProj As D3DMATRIX
D3DXMatrixPerspectiveFovLH matProj, g_pi / 4, 1, 1, 1000
g_D3DDevice.SetTransform D3DTS_PROJECTION, matProj
End Sub
Function Initvb() As Boolean
'省略
End Function
Sub Cleanup()
'省略
End Sub
Sub Render()
'省略
End Sub
Function vec3(x As Single, y As Single, z As Single) As D3DVECTOR
vec3.x = x
vec3.y = y
vec3.z = z
End Function
[转帖from : GameRes.com ]