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

本文详细介绍了在DirectX环境下如何定义3D坐标并利用矩阵进行旋转、缩放等变换操作,包括定义矩阵、使用旋转矩阵、设置观察体系和投影矩阵等关键步骤,最终实现3D图形在三维空间中的展示。

         本博客所有内容均来源于  http://www.uoyo.net     。 写的不好还请高手还请多多包涵。 

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

QQ截图20150904140949.jpg

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

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

x.jpg

我们可以看到。原全2矩阵与另一个矩阵相乘之后得到的结果比原来小了一倍。如果应用到我们3D的实际中来,就可以知道图形被我们缩小了一半。当然其他旋转矩阵也是同理。值得庆幸的是,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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值