您的位置:首页 > 编程语言 > VB

VB+DX游戏编程教程 第三话:多变的矩阵

2015-09-04 15:18 447 查看
         本博客所有内容均来源于  http://www.uoyo.net     。 写的不好还请高手还请多多包涵。 

     在上一次我们说到了如何在DX的环境下绘制出我们最基本的三角形。还是先回顾一下重要的几个步骤:创建好D3D设备→创建顶点缓存→填充顶点缓存→绘制出顶点图形。也是很简单的三步骤。由于我们是初次学习,所以我们直接采用了2D的环境下来绘制三角形。仔细的朋友可以记得起我们当时定义点的自定义类型的时候,里面有一个RHW参数。那这是什么意思呢。





在这幅图中我们就可以看出了缘由。上次我们定义的是2D的平面坐标,所以我们定义了xyz和rhw以及颜色这些参数。为了区分2D和3D坐标,所以引用了rhw这个参数,它表示沿Z轴从观察点到顶点的距离。当然如果我们要定义2D坐标,就不能定义3D坐标。这两者是相矛盾的。这与后文的定义FVF格式的D3DFVF_XYZ和D3DFVF_XYZRHW也是相吻合的。我们不能同时出现这两者。当然说了这么多,既然2D的坐标我们已经学会了,所以我们今天讲试着定义3D的坐标,在3D里面我们可以更容易的操作图形,能够很轻松的就让他旋转,缩放等等。先上这节课案例的效果图:

(点击图片看效果)

     好的,那我们就开始几天的学习笔记。而要让这些对象变化,我们就得引入一个新的概念--矩阵。没错,在线性代数里面出现的矩阵!为了和向量已经点相互区分,在D3D中引入了4维的矩阵。当然在D3D中已经封装好了很多复杂的矩阵转换,所以我们可以很轻松的使用这一些函数或者对象。首先我们在VB中定义一个变量为D3DXMATRIX对象。DIM
Mat as D3DXMATRIX 。然后我们在mat后面输入一个点,Vb的自动提示功能后提示出很多M11,M12,M13…………的东西。因为的D3D的矩阵是一个4*4的矩阵。M11表示第一行第一列的数值,M12为第一行第二列的数值…………同理,一直到M44所构成这一个对象体。





我们可以看到。原全2矩阵与另一个矩阵相乘之后得到的结果比原来小了一倍。如果应用到我们3D的实
4000
际中来,就可以知道图形被我们缩小了一半。当然其他旋转矩阵也是同理。值得庆幸的是,D3Dx已经将这些旋转缩放矩阵为我们设计好了,我们只需要调用函数就可以得到结果,而不需要我们自己去设置。这里提出几个常用的变换矩阵函数

D3DXMatrixRotationX;D3DXMatrixRotationY;D3DXMatrixRotationZ

作用分别为绕X,Y,Z轴旋转。格式为D3DXMatrixRotationX reslut(D3DXMATRIX)输出结果的矩阵,Angle(Single)旋转的角度,单位为弧度

所以我们将上节课的VERT格式变换,取消RHW参数。FVF格式变化为D3DFVF_XYZ + D3DFVF_DEFULT。重新设置顶点位置坐标:

   VERT(0).xyz = Vec(-1, -1, 0):  VERT(0).color = &HFFFF0000

   VERT(1).xyz = Vec(1, -1, 0): VERT(1).color = &HFF00FF00

   VERT(2).xyz = Vec(0, 1, 0): VERT(2).color = &HFF00FFFF

然后我们让这个三角形能够在三维空间中能够绕X轴旋转:

新建一个过程SetMatrix()  

   Dim MatWorld As D3DMATRIX                                              '定义世界矩阵

   Dim MatX As D3DMATRIX

   D3DXMatrixRotationX MatX, Timer * 2                    '将得到的结果输出到MatX

   D3DXMatrixIdentity MatWorld                              '初始化单位矩阵

然后我们将引入另一个函数,目的是让绕X轴旋转的矩阵赋予给我们的另一个定义的世界矩阵

 D3DXMatrixMultiply MatWorld, MatWorld, MatX "格式 D3DXMatrixMultiply 输出矩阵,矩阵1,矩阵2"意思将矩阵1和矩阵合并后传值给输出矩阵

这样我们就得到了绕X轴旋转的矩阵,但是我们要将它转换到世界坐标系中我们才能够看见。而我们刚才定义的MatWorld正是世界变换矩阵。所有我们告诉DX,让他能够转换。用SetTransform D3DTS_WORLD, MatWorld

具体格式为Dirext3DDevice.SetTransform 格式,矩阵。在案例中我们已经创建好了D3D设备,所有我们直接

 IDX3Device.SetTransform D3DTS_WORLD, MatWorld。这样就变换了世界坐标体系。

接下来我们要设置我们的观察体系。坐标有了,但没有观察者,也不能显示出东西。

我们引用D3DXMatrixLookAtLH这个函数来体现我们的观察坐标,结构如下

D3DXMatrixLookAtLH  输出的观察矩阵,观察点的坐标,目标点的坐标, 向上的方向。

一般我们可以讲向上的方向坐标设置为    0,1,0

所有我们设置我们的观察坐标:

  Dim MatView As D3DMATRIX

  D3DXMatrixLookAtLH MatView, Vec(0#, 3#, -5#), Vec(0#, 0#, 0#), Vec(0#, 1#, 0#)           '更改点坐标你将看到不一样的效果

设置好后我们同样告诉DX,让它来转换:

  IDX3Device.SetTransform D3DTS_VIEW, MatView

最后一步:我们的空间是3维的 ,但屏幕是一个平面,我们怎样将3维空间显示在屏幕上呢。

所以我们需要引入投影矩阵。D3DXMatrixPerspectiveFovLH MatProj, g_pi / 4, 1, 1, 100

格式:D3DXMatrixPerspectiveFovLH 输出投影矩阵,视角范围单位弧度,纵横比,近裁剪z值,远裁剪z值

说明:裁剪的意思是当物体大于远裁剪值时将不会被显示出来,近裁剪同理

'投影矩阵

  Dim MatProj As D3DMATRIX

  Const g_pi = 3.1415926

  D3DXMatrixPerspectiveFovLH MatProj, g_pi / 4, 1, 1, 100

  IDX3Device.SetTransform D3DTS_PROJECTION, MatProj

好的。这样我们就设置完了。在我们的渲染过程中加上SetMatrix。让它每次都能够刷新变化。

然后在D3D创建过程中加入 

     IDX3Device.SetRenderState D3DRS_CULLMODE, 1                     '背面剪裁 1为不剪裁 2为剪裁背面。

    IDX3Device.SetRenderState D3DRS_LIGHTING, 0                      ' 灯光效果

好的,运行一下试试。是不是得到了我们刚才gif图上的效果。当然你可以自行修改绕轴的变化和视角的范围等等。将会有不一样的效果。

最后附上源码:

点击→:http://pan.baidu.com/s/1jGITTo6
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  VB directX8 uoyo 尤幽