学习目标:
1.了解D3D中的顶点和索引数据的存储方式。
2.掌握如何用绘制状态(render state)来修改几何体的绘制方式。
3.掌握如何绘制场景。
4.掌握如何用D3DXCreate*函数创建较为复杂的3D形状。
3.1 顶点缓存与索引缓存
这2个缓存是保存在显存中连续的存储区域
顶点接口:IDirect3DVertexBuffer9
索引接口:IDirect3DIndexBuffer9
3.1.1 创建

1 HRESULT IDirect3DDevice9::CreateVertexBuffer{
2 UINT Length,
3 DWORD Usage,
4 DWORD FVF,
5 D3DPOOL Pool,
6 IDirect3DVertexBuffer9** ppVertexBuffer,
7 HANDLE* pSharedHandle
8 };
9
10 HRESULT IDirect3DDevice9::CreateIndexBuffer{
11 UINT Length,
12 DWORD Usage,
13 D3DFORMAT Format,
14 D3DPOOL Pool,
15 IDirect3DIndexBuffer9** ppVertexBuffer,
16 HANDLE* pSharedHandle
17 };
FVF是灵活顶点格式,对FVF更详细的讨论:http://www.cnblogs.com/xmzyl/articles/1604096.html
Usage 指定使用缓存的附加属性。特别需要注意的是 D3DUSAGE_DYNAMIC (这个可以展开讨论)
创建函数的详细说明参考sdk帮助文档,
3.1.2 访问缓存内容
UINT SizeToLock,
BYTE** ppbData,
DWORD Flags);
HRESULT IDirect3DIndexBuffer9::Lock(UINT OffsetToLock,
UINT SizeToLock,
BYTE** ppbData,
DWORD Flags);
lock操作结束时,必须调用Unlock方法。
3.1.3 获取顶点缓存和索引缓存的信息
3.2 绘制状态
DWORD Value // value of the new state
);
更多关于绘制状态的描述请看:http://www.cnblogs.com/xmzyl/articles/1605430.html
3.3 绘制的准备工作
设置好顶点缓存和索引缓存后,还必须进行3个步骤:
(1) 指定数据流输入流。将顶点缓存和数据流进行链接,实质上是将几何体的信息传输到绘制流水线中。下面的方法用于设置顶点输入流的输入源。
UINT StreamNumber,
IDirect3DVertexBuffer9* pStreamData,
UINT OffsetInByte,
UINT Stride
);
实际是把建立好的顶点缓存作为数据流,例如:假定vb是一个存储为Vertex类型的顶点数据的顶点缓存。
_device->SetStreamSource(0, vb, 0, sizeof(Vertex));
(2) 设置顶点格式。指定后续绘制调用中使用的顶点格式。
_device->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
(3) 设置索引缓存。任意时刻只允许一个索引缓存,如果需要使用一个不同的索引缓存绘制物体时必须切换。
_device->SetIndives(_ib);
3.4 使用顶点缓存和索引缓存进行绘制
准备工作完成后,就可以对几何体进行绘制了。使用DrawPrimitive或DrawIndexedPrimitive,将待绘制的几何体的信息通过绘制流水线传输。这2个方法从顶点数据流获取顶点信息,并从当前设定的索引缓存提取索引信息。
3.4.1 IDirect3DDevice9::DrawPrimitive
该方法用于绘制未使用索引信息的图元
D3DPRIMITIVETYPE PrimitiveType,
UINT StartVertex,
UINT PrimivieCount
);
- PrimitiveType 所要绘制图元的类型,基本的图元有点,线,三角形。
- StartVertex 顶点数据流中标识顶点数据读取起点的元素索引。改参数赋予了程序员一定的自由度,使得我们可以只对顶点缓存的某一部分进行绘制。
- PrimitiveCount 所要绘制的图元数量。
//draw four triangles
_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4)
3.4.2 IDirect3DDevice9::DrawIndexedPrimitive
2 D3DPRIMITIVETYPE Type,
3 INT BaseVertexIndex,
4 UINT MinIndex,
5 UINT NumberVertices,
6 UINT StartIndex,
7 UINT PrimitiveCount
8 );
- Type 图元类型
- BaseVertexIndex 为索引增加一个基数。
局部索引缓存的内容应该与局部顶点缓存中的缓存一致。假定场景中有一个球,盒子和圆柱体,它们的顶点合并到一个全局缓存中,对于每个物体,我们必须重新计算索引,以保证这些索引正确的指向全局顶点缓存中对应的点。新索引的计算方法就是为每个索引增加一个指定了物体顶点在全局缓存中存储的起始位置的偏移量。注意:改偏移量用顶点个数来度量而非字节。 - MinIndex 允许引用的最小索引值。
- NumberVertices 本次调用中将引用的顶点总数。
- StartIndex 顶点缓存标识索引的读取起始点的元素的索引。
- PrimitiveCount 所要绘制的图元总数。
所有的绘制方法都必须在 IDirect3DDevice9::BeginScene 和 IDirect3DDevice::EndScene 之间调用。例如:
2 _device->DrawPrimitive(

3 _device->EndScene();
3.5 D3DX 几何体
D3DX 库提供了6个网格创建函数。网格是一些3角面的组合。
- D3DXCreateBox
- D3DXCreateSphere
- D3DXCreateCylinder
- D3DXCreateTeapot
- D3DXCreatePolygon
- D3DXCreateTorus
2 D3DXCreateTeapot(_device, &Mesh, 0);
然后调用 DrawSubset 函数进行绘制。例如:
2 mesh->DrawSubset(0);
3 _device->EndScene();
4
5 //释放
6 mesh->Release();
7 mesh = 0;
3.6 例程
Triangel 按线框模式创建和绘制一个三角形。
Cube 绘制一个旋转的线框立方体。
Teapot 用 D3DXCreateTeapot 函数创建并绘制一个旋转的茶壶。
D3DXCreate 绘制了几种不同类型的可用 D3DXCreate* 函数创建的3D物体。