我的Direct3D学习之路3:第一个3D绘图程序

之前已经详述过投影变换,这里不再赘述。

写给VR手游开发小白的教程:(四)补充篇,详细介绍Unity中相机的投影矩阵

之前我们一直是在窗口中绘制,使用了D3DFVF_XYZRHW格式的顶点,D3D是默认顶点经过了处理,直接绘制在窗口上

现在我们用D3DFVF_XYZ格式来绘制,熟悉D3D对3D环境的处理过程

打开\Samples\C++\Direct3D\Tutorials\Tut03_Matrices路径下的工程

这个工程和上一个画三角形的工程相比其他都没怎么变,只是两个地方稍作改动
1.全局变量里面宏定义变了
这点不说了,只是为了让D3D去做顶点处理。
2.增加了SetupMatrices函数


我们这里做了三个改变:
1.计算得到一个矩阵去变换场景中的物体(这里就是之前的三角形)
2.计算得到一个矩阵去定义场景中的摄像机,并把它设置成为观察矩阵
3.计算得到一个矩阵来做投影变换,并把它设置成为投影矩阵

首先我们要知道什么是世界矩阵、观察矩阵、投影矩阵。
在这之前,你需要知道一些图形学的基础知识,点和线的齐次坐标表示以及平移缩放旋转的变换:



对于左手系和右手系要补充一点,无论是左手系和右手系,当从x轴->y轴旋转时,角度永远是正的(这一点需牢记),而之所以会有顺时针和逆时针的差异,主要是因为我们观察的方向是从z正轴向原点看。

基于世界坐标系,能否获得其他坐标系的坐标,答案是可以的。这种情况就是图形学中的坐标系变换,理解起来很简单,坐标的变换,就相当于所有物体都做了坐标变换的反变换:


以Unity3D为例:
我们新建一个空物体,置于(0,0,0)点,形成了一个坐标系,这就是我们的世界坐标系。可以看到Unity3D的坐标系是一个左手坐标系,因为Windows环境下使用的图形api是Direct3D

选中Camera,又获得一个坐标系,这是观察坐标系,原点即是Camera在世界坐标中的位置,每个物体在观察坐标系中都有一个对应坐标,而三维投影变换就是通过这个坐标系来做的

已知了坐标系,我们就要在当前坐标系内进行变换。D3D一共有三个变换,世界坐标系对应模型几何变换,观察坐标系对应取景变换,以及投影坐标系对应投影变换。
因此,上面的世界矩阵用来做模型几何变换,观察矩阵用来做取景变换,投影矩阵用来做投影变换。

D3D中对于三种变换,提供了便捷的方法就可以生成相应的变换矩阵:

1.模型几何变换

D3DXMatrixTransformation()//生成一个平移变换矩阵
D3DXMatrixRotationX()//生成一个绕X轴旋转的变换矩阵
D3DXMatrixRotationY()//生成一个绕Y轴旋转的变换矩阵
D3DXMatrixRotationZ()//生成一个绕Z轴旋转的变换矩阵
D3DXMatrixScaling()//生成一个缩放变换矩阵
2.取景变换

D3DXVECTOR3 vEyePt(0.0f, 3.0f, -5.0f);//观察点的位置坐标
D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);//被观察点的坐标
D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);//虚拟相机的向上向量
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec);//生成一个确定画面捕捉相机(位置,旋转)的矩阵
3.投影变换

D3DXMATRIXA16 matProj;
//矩阵存放地址:matProj
//视场角D3DX_PI/4
//输出视口矩形的宽高比:1.0f
//近裁面距离:1.0f
//远裁面距离:100.0f
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);

然后对于工程中的SetupMatrices函数,我们就可以看懂了:

VOID SetupMatrices()
{
	//新建一个世界矩阵
    D3DXMATRIXA16 matWorld;

	//设置旋转矩阵,每1000ms去做一次旋转。
	//对于我们的世界矩阵,我们关于y轴做旋转
    UINT iTime = timeGetTime() % 1000;
    FLOAT fAngle = iTime * ( 2.0f * D3DX_PI ) / 1000.0f;
    D3DXMatrixRotationY( &matWorld, fAngle );

    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

	//设置我们的观察矩阵,一个观察矩阵被给出的观察点位置,观察方向,哪个是“上”方向三个参数来定义。
    D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );//当前相机向上方向的向量,通常是0,1,0
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

	//对于投影矩阵,我们建立投影变换(投影变换把3D转换为2D视口空间,透视投影可以让远的物体看起来更小),我们需要指定视场角(1/4pi是比较正常的),宽高比,以及远近裁剪面
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
根据上面的推导,在运行程序前就可以预测三角形的旋转方向是顺时针,查看运行结果,确实符合了之前的预测。





  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值