VB+DX游戏编程教程 第三话:多变的矩阵
2015-09-04 15:18
447 查看
本博客所有内容均来源于 http://www.uoyo.net 。 写的不好还请高手还请多多包涵。
在上一次我们说到了如何在DX的环境下绘制出我们最基本的三角形。还是先回顾一下重要的几个步骤:创建好D3D设备→创建顶点缓存→填充顶点缓存→绘制出顶点图形。也是很简单的三步骤。由于我们是初次学习,所以我们直接采用了2D的环境下来绘制三角形。仔细的朋友可以记得起我们当时定义点的自定义类型的时候,里面有一个RHW参数。那这是什么意思呢。
![](http://uoyo.net/content/uploadfile/201509/thum-229a1441347007.jpg)
在这幅图中我们就可以看出了缘由。上次我们定义的是2D的平面坐标,所以我们定义了xyz和rhw以及颜色这些参数。为了区分2D和3D坐标,所以引用了rhw这个参数,它表示沿Z轴从观察点到顶点的距离。当然如果我们要定义2D坐标,就不能定义3D坐标。这两者是相矛盾的。这与后文的定义FVF格式的D3DFVF_XYZ和D3DFVF_XYZRHW也是相吻合的。我们不能同时出现这两者。当然说了这么多,既然2D的坐标我们已经学会了,所以我们今天讲试着定义3D的坐标,在3D里面我们可以更容易的操作图形,能够很轻松的就让他旋转,缩放等等。先上这节课案例的效果图:
![](http://uoyo.net/content/uploadfile/201509/thum-e87f1441347402.gif)
(点击图片看效果)
好的,那我们就开始几天的学习笔记。而要让这些对象变化,我们就得引入一个新的概念--矩阵。没错,在线性代数里面出现的矩阵!为了和向量已经点相互区分,在D3D中引入了4维的矩阵。当然在D3D中已经封装好了很多复杂的矩阵转换,所以我们可以很轻松的使用这一些函数或者对象。首先我们在VB中定义一个变量为D3DXMATRIX对象。DIM
Mat as D3DXMATRIX 。然后我们在mat后面输入一个点,Vb的自动提示功能后提示出很多M11,M12,M13…………的东西。因为的D3D的矩阵是一个4*4的矩阵。M11表示第一行第一列的数值,M12为第一行第二列的数值…………同理,一直到M44所构成这一个对象体。
![](http://uoyo.net/content/uploadfile/201509/3e601441349074.jpg)
我们可以看到。原全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
在上一次我们说到了如何在DX的环境下绘制出我们最基本的三角形。还是先回顾一下重要的几个步骤:创建好D3D设备→创建顶点缓存→填充顶点缓存→绘制出顶点图形。也是很简单的三步骤。由于我们是初次学习,所以我们直接采用了2D的环境下来绘制三角形。仔细的朋友可以记得起我们当时定义点的自定义类型的时候,里面有一个RHW参数。那这是什么意思呢。
![](http://uoyo.net/content/uploadfile/201509/thum-229a1441347007.jpg)
在这幅图中我们就可以看出了缘由。上次我们定义的是2D的平面坐标,所以我们定义了xyz和rhw以及颜色这些参数。为了区分2D和3D坐标,所以引用了rhw这个参数,它表示沿Z轴从观察点到顶点的距离。当然如果我们要定义2D坐标,就不能定义3D坐标。这两者是相矛盾的。这与后文的定义FVF格式的D3DFVF_XYZ和D3DFVF_XYZRHW也是相吻合的。我们不能同时出现这两者。当然说了这么多,既然2D的坐标我们已经学会了,所以我们今天讲试着定义3D的坐标,在3D里面我们可以更容易的操作图形,能够很轻松的就让他旋转,缩放等等。先上这节课案例的效果图:
![](http://uoyo.net/content/uploadfile/201509/thum-e87f1441347402.gif)
(点击图片看效果)
好的,那我们就开始几天的学习笔记。而要让这些对象变化,我们就得引入一个新的概念--矩阵。没错,在线性代数里面出现的矩阵!为了和向量已经点相互区分,在D3D中引入了4维的矩阵。当然在D3D中已经封装好了很多复杂的矩阵转换,所以我们可以很轻松的使用这一些函数或者对象。首先我们在VB中定义一个变量为D3DXMATRIX对象。DIM
Mat as D3DXMATRIX 。然后我们在mat后面输入一个点,Vb的自动提示功能后提示出很多M11,M12,M13…………的东西。因为的D3D的矩阵是一个4*4的矩阵。M11表示第一行第一列的数值,M12为第一行第二列的数值…………同理,一直到M44所构成这一个对象体。
![](http://uoyo.net/content/uploadfile/201509/3e601441349074.jpg)
我们可以看到。原全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简单实现防止文件被改写
- VB获取文件大小的方法
- VB实现的《QQ美女找茬游戏》作弊器实例
- VB实现禁用任务管理器的方法
- VBS教程:运算符-运算符(+)
- VB实现的16位和32位md5加密代码分享
- VB6中的LSet语句和RSet语句详解
- VB实现的递归复制文件和搜索文件的代码分享
- VB键盘鼠标无动作调用程序的尝试
- VB XMLHTTP使用方法
- VB语言使用ADO连接、操作SQLServer数据库教程
- VB使用ADO操作Access数据库
- VB使用shell函数打开外部exe程序的实现方法
- VB的TextBox文本框实现垂直居中显示的方法
- VB返回记录集结果到HTML表格的方法
- VBS教程:运算符-\ 运算符
- VBS教程:运算符-减运算符 (-)
- VBS教程:运算符-除运算符 (/)
- VB调用Word拼写检查功能实例
- VB读取线程、句柄及写入内存的API代码实例