任何物体的模型都可以用三角形来逼近表示,这就是说可以把一堆三角形组合成任意希望的形状。
三角形两边的交点为顶点,这个顶点和数学中的顶点不一样,他可以有很多属性,
比如位置,法线(通常用来描述光照射到物体表面的明暗程度),颜色等。
别忘了对于自己设计的顶点结构而言,还需为他加上一个FVF(灵活顶点格式),他指明了顶点的各个值代表的意思。
struct CustomVertex
{
float _x, _y, _z;
float _nx, _ny, _nz;
float _u, _v;
const DWORD Vertex_FVF;
};
#define Vertex_FVF ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 )
//用到一个纹理时设为TEX1,用到两个纹理时设为TEX2,纹理后面会说到,他能让物体更逼真
1.局部坐标系
局部坐标系的优势在于 简化建模过程,这意味着无需考虑 位置、大小或相对于场景中其他物体的朝向。
位于 局部坐标系的物体 通过一个称为 世界变换 的运算转换到 世界坐标系 中。
这个 世界变换 用一个矩阵表示。
//以上将一个立方体沿x轴左移3.0,y轴上移2.0,z轴前移6.0
D3DXMATRIX cube;
D3DXMatrixTranslation(&cube, -3.0f, 2.0f, 6.0f);
Device->SetTransform(D3DTS_WORLD, &cube);
3.观察坐标系
从世界坐标系转换到观察坐标系:先将摄像机变换至 坐标系原点 并使摄像机 光轴 指向 Z轴的正方向 ,注意,空间中的物体应随摄像机一起变换。
用到的函数:D3DXMatrixLookAtLH
D3DXVECTOR3 position(5.0f, 3.0f, -10.0f); //摄像机的坐标
D3DXVECTOR3 targetPoint(0.0f, 0.0f, 0.0f); //观察点的坐标,这里是原点,其实就是被观察的点的位置。
D3DXVECTOR3 worldUp(0.0f, 1.0f, 0.0f); //y轴正方向的向量
D3DXMATRIX V;
D3DXMatrixLookAtLH(&V, &position, &targetPoint, &worldUp);
Device->SetTransform(D3DTS_VIEW, &V);
顾名思义,显示多边形的正面,背面的不显示。
默认状态下,在观察坐标系中,Direct3D认为 顶点排列顺序 为
顺时针的三角形单元 是 正面 朝向的;
逆时针的三角形单元 是 背面 朝向的。如果默认的消隐方式不能满足应用的需求,可以用下面的方法:
Device->SetRenderState(D3DRS_CULLMODE, value);
其中value可以为下面的值:D3DCULL_NONE //完全禁用背面消隐
D3DCULL_CW //只对顺时针绕序的三角形单元进行消隐
D3DCULL_CCW //默认值,只对逆时针绕序的三角形单元进行消隐
5.光照
6.裁剪
获取3D场景的2D表示,从n维到 n-1 维称为投影
创建投影矩阵:D3DXMatrixPerspectiveFovLH
投影矩阵应用的方法:IDirect3DDevice->SetTransform
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(&proj, PI*0.5f, (float)width/(float)height, 1.0f, 1000.0f);
//近裁减面到坐标原点的距离是1,远裁剪面到原点的距离是1000
Device->SetTransform(D3DTS_PROJECTION, &proj);
从投影窗口转换到屏幕的一个区域中,该区域称为视口。默认情况下是把整个投影窗口全部转换到视口
D3DVIEWPORT9 vp={0,0,640,480,0,1};
Device->SetViewport(&vp);