绘制流水线中,前面几个坐标系的相互转换,要想D3D来完成坐标转换,我们所必须做的仅仅是提供描述坐标的变换矩阵,应用一个变换矩阵的方法是使用SetTransform方法,例如坐局部坐标系到世界坐标系的坐标变换我们可以这样写
g_pDevice->SetTransform(D3DTS_WORLD,&worldMatrix);
1.局部坐标系
局部坐标系或建模坐标系是用于定义构成物体的三角形单元列表的坐标系,优势在于它可以简化建模过程,例如局部坐标系我们构建模型时无需考虑位置,大小,或相对于场景中其它物体的朝向,如下图所示
2.世界坐标系
构建各种物体时,每个物体模型都位于自身的局部坐标系中,我们还需要将这些物体组织在一起构成世界坐标系的场景,位于局部坐标系中的物体通过一个称为世界变换的运算过程变换到世界坐标系中,该变换通常包括平移,旋转,以前比较运算,
世界变换用一个矩阵表示,并通用Idirect3Ddevice9::SetTransform方法加以应用,假如我们想让一个立方体的中心位于世界坐标系中的点(-3,2,6)上,让一个球体的中心位于点(5,0,-2),我们可以这样做
D3DXMATRIX cubeWorldMatrix;
D3DXMatrixTranslation(&cubeWorldMatrix,-3.0f,2.0f,6.0f);
//
D3DXMATRIX sphereWorldMatrix;
D3DXMatrixTranslation(&sphereWorldMatrix,5.0f,0.0f,-2.0f);
//
g_pDevice->SetTransform(D3DTS_WORLD,&cubeWorldMatrix);
drawcube();
//
g_pDevice->SetTransform(D3DTS_WORLD,&sphereWorldMatrix);
drawsphere();
3.观察坐标系
在世界空间中,几何体和摄像机都是相对于世界坐标系定义的,但是当摄像机的位置和朝向任意时,投影变换及其它类型的变换就要略显的困难或是效率不高手,为了简化运算,我们将摄像机的变换至坐标系中的原点,并将其旋转,使摄像机的光轴与世界坐标系z轴方向一致,同时,世界空间中的所有几何体都随着摄像机一同进行变换,以后证摄像机的视场恒定,这种变换称为取景变换,我们称变换后的几何体位二观察坐标系中
取景变换矩阵可由如下函数计算得到
D3DXMATRIX *D3DXMAtrixLookAtLH(
D3DXMATRIX* pOut, //position to receive resulting view matrix
CONST D3DXVECTOR3* pEye, //position of camera in world
CONST D3DXVECTOR3* pAt, //point camera is looking at in world
CONST D3DXVECTOR3* pUp //the world’s up vector(0,1,0);
)
其中,参数pEye,指定了摄像机在世界坐标系中的位置,
参数pAt指定了世界坐标系中的被观察点,
参数pUp是世界坐标中表示’向上’的分量
例如,假定摄像机位于(5,3,-10),其观察点为世界坐标系中的原点,(0,0,0),我们可以这样创建取景变换矩阵:
D3DXVERTOR3 pos(5.0f,3.0f,-10.0f);
D3DXVERTOR3 tar(0.0f,0.0f,0.0f);
D3DXVERTOR3 worldup(0.0f,1.0f,0.0f);
D3DXMATRIX V;
D3DXMatrixLookAtLH(&V,&pos,&tar,&worldup);
g_pDevice->SetTransform(D3DTS_VIEW,&V);
4.背面消隐
每个多边形有两个侧面,我们将其它一个侧面标记为正面(frontside),另一个侧面标记为背面(backside),通常,多边形的背面是不可见的,这是由于场景中的多数物体都是封闭的,而且摄像机总是禁止进入物体内部空间的,所以摄像机是不能观察多边形的背面的,
下图展示了观察坐标系中的一个物体,其正面有一个伸出的箭头,正面朝向摄像果肉的多边形称正面朝向(front facing)多边形,正面偏离摄像机的多边形称为背面朝向(back facing).
为了实现背面消陷,D3D需要区分哪些多边形是正面朝向的,哪些是背面朝向的,默认状态下,D3D认为顶点排列顺序为顺时针(观察坐标系中)的三角形单元是正面朝向的,顶点排列顺序为逆时针的三角形单元是背面朝向的
如果默认的消隐方式不能满足我们应用的需求,我们可以修改绘制状态来达到目的
g_pDevice->SetRenderState(D3DRS_CULLMODE, value);
value可以取如下值
1. D3DCULL_NONE,禁用背面消隐
2. D3DCULL_CW,对顺时针的三角形单元消隐
3. D3DCULL_CCW,,默认值 , 对逆时针的三角形单元消隐
5.光照
光源是在世界坐标系中定义的,但是必须经取景变换至观察坐标系中才可使用,在观察坐标系中,源源照亮了场景中的物体,从而可以得到较为逼真的显示效果
6.裁剪
将那些位于视域体外的几何体剔除掉,这个过程称为裁剪,一个三角形单元与视域体相位位置有以下三种
1. 完全在内部,
2. 完全在外部,
3. 部分在内,部分在外
7.投影
投影变换定义了视域体,并负责将视域体中的几何体投影到投影窗口中,
D3DXMATRIX *D3DXMatrixPerspectiveFovLH(
D3DXMATRIX &pOut, //returns projection matrix
float fovY, //verticalfield of view angle in radians,弧度 = 角度*PI/180,
float Aspect, //aspect ratio = width/height
float zn, //distanceto near plane
float zf //distanceto far plane
)
投影响矩阵的应用方法Idirect3Ddevice::SetTransform,来实现,其中对应的变换类型需指定为D3DTS_PROJECTION,下面的例子说明了如何依据描述参数来创建投影矩阵,本例中视域体的视域角为90’,近剪裁面到坐标原点的距离是1,远剪裁面到原点的距离是1000,
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(
&proj,PI*0.5f,(float)width/(float)height,
1.0f,
1000.0f
);
g_pDevice->SetTransform(D3DTS_PROJECTION,&proj);
8.视口变换
视口变换的任务是将顶点坐标从投影窗口转换到屏幕的一个矩形区域,该矩形区域称为视口,矩形的视口是相对二窗口来描述的.