- A+
所属分类:Windows游戏开发 原创文章
Direct3D的学习终于要走入正题了
下面用顶点来渲染一个Cube
创建一个储存顶点信息的结构体
1 2 3 4 5 6 7 8 9 10 11 12 |
struct Vertex { Vertex(float x, float y, float z) { _x = x; _y = y; _z = z; } float _x, _y, _z; static const DWORD FVF = D3DFVF_XYZ; }; |
FVF是顶点格式,x,y,z就是坐标
需要一个顶点缓存和一个索引缓存
定义两个缓存变量指针
1 2 |
LPDIRECT3DVERTEXBUFFER9 VB = NULL; LPDIRECT3DINDEXBUFFER9 VI = NULL; |
然后创建这两个Buffer
1 2 |
d3ddev->CreateVertexBuffer(8 * sizeof(Vertex), D3DUSAGE_WRITEONLY, Vertex::FVF, D3DPOOL_MANAGED, &VB, 0); d3ddev->CreateIndexBuffer(36 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &VI, 0); |
两个创建都差不多
12345678 HRESULT CreateVertexBuffer([in] UINT Length,[in] DWORD Usage,[in] DWORD FVF,[in] D3DPOOL Pool,[out, retval] IDirect3DVertexBuffer9 **ppVertexBuffer,[in] HANDLE *pSharedHandle);
123456789101112131415 HRESULT CreateIndexBuffer([in] UINT Length,[in] DWORD Usage,[in] D3DFORMAT Format,[in] D3DPOOL Pool,[out, retval] IDirect3DIndexBuffer9 **ppIndexBuffer,[in] HANDLE *pSharedHandle);*第一个Length 指的是分配给缓存的字节大小*Usage 是指定关于怎样使用缓存的额外信息。可以查看D3DUSAGE_*FVF 就是顶点格式Pool 缓存存放在哪个内存池 查看D3DPOOL_Format 指定索引的大小,查看D3DFMT_INDEX*PSharedHandle 设置为0 NULL
然后访问这两个缓存
填入相关的顶点数据和索引数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
Vertex *v; VB->Lock(0, 0, (VOID**)&v, 0); v[0] = Vertex(-1.0f, -1.0f, -1.0f); v[1] = Vertex(-1.0f, 1.0f, -1.0f); v[2] = Vertex(1.0f, 1.0f, -1.0f); v[3] = Vertex(1, -1, -1); v[4] = Vertex(-1, -1, 1); v[5] = Vertex(-1, 1, 1); v[6] = Vertex(1, 1, 1); v[7] = Vertex(1, -1, 1); VB->Unlock(); WORD *i; VI->Lock(0, 0, (VOID**)&i, 0); //前面 i[0] = 0; i[1] = 1; i[2] = 2; i[3] = 0; i[4] = 2; i[5] = 3; //背面 i[6] = 4; i[7] = 6; i[8] = 5; i[9] = 4; i[10] = 7; i[11] = 6; //左面 i[12] = 4; i[13] = 5; i[14] = 1; i[15] = 4; i[16] = 1; i[17] = 0; //右面 i[18] = 3; i[19] = 2; i[20] = 6; i[21] = 3; i[22] = 6; i[23] = 7; //顶部 i[24] = 1; i[25] = 5; i[26] = 6; i[27] = 1; i[28] = 6; i[29] = 2; //底部 i[30] = 4; i[31] = 0; i[32] = 3; i[33] = 4; i[34] = 3; i[35] = 7; VI->Unlock(); |
这里讲一下Lock方法
1234567891011 HRESULT Lock([in] UINT OffsetToLock,[in] UINT SizeToLock,[out] VOID **ppbData,[in] DWORD Flags);*offsetToLock 偏移量,开始的位置,字节为单位*sizeToLock 锁定的字节数 长度*ppbData 一个指定锁定内存开始的指针*Flags 描述怎么锁定内存 查看D3DLOCK_*
设置视图矩阵
1 2 3 4 5 6 7 |
//设置视图矩阵 D3DXVECTOR3 position(0, 0, -5); D3DXVECTOR3 target(0, 0, 0); D3DXVECTOR3 up(0, 1, 0); D3DXMATRIX V; D3DXMatrixLookAtLH(&V, &position, &target, &up); d3ddev->SetTransform(D3DTS_VIEW, &V); |
视图变换就是将世界中所有物体
跟随相机做一样的变换
从而使相机到达某一个位置
*position是相机在世界坐标系的位置
*target是相机在世界坐标系的目标点
*up世界坐标系上的方向
设置投影矩阵
1 2 3 4 |
//投影矩阵 D3DXMATRIX project; D3DXMatrixPerspectiveFovLH(&project, D3DX_PI*0.5f, (float)800 / (float)600, 1.0f, 1000.0f); d3ddev->SetTransform(D3DTS_PROJECTION, &project); |
投影就是将N维变成N-1维
这里就是将3d数据变成2d图片
123456789101112 D3DXMATRIX* D3DXMatrixPerspectiveFovLH(_Inout_ D3DXMATRIX *pOut,_In_ FLOAT fovy,_In_ FLOAT Aspect,_In_ FLOAT zn,_In_ FLOAT zf);*fovy 用弧度表示视野的角度*Aspect 宽高比*zn 前裁剪面距离*zf 后裁剪面距离
设置渲染模式
1 2 3 |
//渲染模式 //d3ddev->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); d3ddev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); |
这里就没什么好说了
-
在Update中设置世界坐标系转换矩阵
1 2 3 4 5 6 7 8 9 10 11 12 13 |
D3DXMATRIX Rx, Ry; D3DXMatrixRotationX(&Rx, 3.14f / 4.0f); static float y = 0.0f; D3DXMatrixRotationY(&Ry, y); y += 0.01; if (y >= 6.28) { y = 0; } D3DXMATRIX r = Rx * Ry; d3ddev->SetTransform(D3DTS_WORLD, &r); |
绕X轴旋转45度
然后绕Y轴一直旋转
-
最后进行绘制的准备
1 2 3 4 5 |
d3ddev->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0); d3ddev->BeginScene(); d3ddev->SetStreamSource(0, VB, 0, sizeof(Vertex)); d3ddev->SetIndices(VI); d3ddev->SetFVF(Vertex::FVF); |
1.设置资源流(顶点们)
12345678910 HRESULT SetStreamSource([in] UINT StreamNumber,[in] IDirect3DVertexBuffer9 *pStreamData,[in] UINT OffsetInBytes,[in] UINT Stride);*StreamNumber 与哪个资源挂钩,多重流用。*offsetInBytes 相对流开始的位置,字节为单位*Stride 单位的字节大小
2.设置索引缓存
SetIndices(索引缓存)
-
3.设置顶点格式
SetFVF()
这里只用了D3DFVF_XYZ坐标
具体还有查看D3DFVF
-
最后用索引的方式绘制
1 2 3 |
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12); d3ddev->EndScene(); d3ddev->Present(0, 0, 0, 0); |
1234567891011121314 HRESULT DrawIndexedPrimitive([in] D3DPRIMITIVETYPE Type,[in] INT BaseVertexIndex,[in] UINT MinIndex,[in] UINT NumVertices,[in] UINT StartIndex,[in] UINT PrimitiveCount);*Type 绘制的图元类型,点 线 三角形,查看D3DPT_**BaseVertexIndex 基本数字,加索引的。平常设为0*NumVertices 被引用的顶点数*StartIndex 索引缓存中开始的位置*PrimitiveCount 绘制图元的个数
最后,看看结果