第一步,定义一个顶点类型
1、 Vertices 示例项目使用 3 个点渲染了一个 2D 的三角形。
2、 在此介绍了顶点缓冲区的概念, Direct3D 对象用它来存储和渲染 Vertices 。
3、 我们可以通过指定一个传统的 Vertex 结构体和相应的灵活顶点格式( FVF ),灵活的定义 Vertices
4、 Vertices 示例项目中 Vertices 的格式如下:
struct CUSTOMVERTEX
{
FLOAT x, y, z, rhw; // 坐标
DWORD color; // 颜色
};
1、 上面的结构体指定了传统的顶点类型。
2、 下一步就是定义 FVF 来描述顶点内如。
3、 以下代码段定义了一个 FVF ,用来对应上面创建的这个结构体
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
1、 D3DFVF 描述了什么顶点格式被使用了。
2、 上面的示例代码使用 D3DFVF_XYZRHW 与 D3DFVF_DIFFUSE 来告诉顶点缓冲区,它使用了一种顶点可变的带色彩元素的顶点坐标格式。
(提示:三角形中的顶点是可变的,换言之,他们已经在 2D 视口里面了。这意味着,( 0 , 0 )在左上角, x 正方向是向右的, y 正方向是向下的。这些顶点被显示,意味着他们并没有使用 Direct3D 颜色而是使用他们自己的颜色)
第二步,创建一个顶点缓冲区
1、 既然顶点格式已经被定义了,现在就该初始化 vertices 了。 vertices. 示例项目通过调用系统自定义的 InitVB 方法来完成它(在获得一个 Direct3D 对象之后)
2、 以下的代码段是初始化 3 个顶点
CUSTOMVERTEX vertices[] =
{
{ 150.0f,
50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
{ 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
{
50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
};
1 、之前的代码段填写 3 个顶点。他们分别是 (150, 50) 、 (250, 250) 、 (50, 250) ,并且他们的颜色分别是红、绿、蓝绿。每一个点的深度和 RHW 都是 0.5 和 1.0
2 、下一步就是调用 IDirect3DDevice9::CreateVertexBuffer 方法来创建一个顶点缓冲区,如下:
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),0 /*Usage*/,D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
return E_FAIL;
1、 IDirect3DDevice9::CreateVertexBuffer 的 前 2 个参数告诉了 Direct3D 对象,新的缓冲区的大小和用法,接下来 2 个参数为新的缓冲区指定了动态数组的格式和内存地址。
2、 动态数组的格式在这里是 D3DFVF_CUSTOMVERTEX ,它是一个灵活顶点格式( FVF ),就如之前代码指定的那样。
3、 D3DPOOL_DEFAULT 标记告诉 Direct3D 对象创建一个顶点格式的内存地址,这段内存将被这个缓冲区专用。最后一个参数是这个顶点缓冲区将要被创建出来的地址。
4、 在创建完这个顶点缓冲区之后,它就从定义的顶点集中获取数据,如下:
if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) )
return E_FAIL;
memcpy( pVertices, vertices, sizeof(vertices) );
g_pVB->Unlock();
1、 顶点缓冲区首先被加锁,通过 IDirect3DVertexBuffer9::Lock .
2、 第一个参数是被加锁的顶点数据的起始地址, bytes 的形式
3、 第二个参数是将被加锁的这段顶点数据的大小
4、 第三个参数是这个 Bytes 指针的地址,指向顶点数据区
5、 第四个参数告诉顶点缓冲区怎么加锁数据
1 、然后,顶点集通过 memcpy 被拷贝入顶点缓冲区,之后顶点集就在顶点缓冲区了,通过 IDirect3DVertexBuffer9::Unlock 解锁这个顶点缓冲区。这种加锁解锁的机制被用来保证内存缓冲区内数据的完整性
第三步,渲染显示
既然顶点缓冲区已经被填写完成,现在就是渲染并显示它的时候了。渲染舞台首先要清空后台缓冲区为蓝色并且调用 BeginScene.
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0L );
g_pd3dDevice->BeginScene();
1、 从顶点缓冲区中获取数据渲染顶点需要一些步骤。
2、 第一步,你需要设置数据流,在这里我们使用 Stream0
3、 这里的数据流通过调用 IDirect3DDevice9::SetStreamSource . 被指定
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
1、 第一个参数是流的编号,第二个参数是一个指针指向内存缓冲区。
2、 第三个参数是顶点集的起始位置
3、 最后一个参数是每一个顶点所占字节个数
1、 下一步就是调用 IDirect3DDevice9::SetFVF 来调用一个静态方法。
2、 完整的说的话,这个顶点 shaders 是一个高级的话题,但是在这里, vertex shader 只是 FVF 代码。如下:
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
1、 SetFvF 唯一的一个参数是这个准备好的这个顶点布局
2、 下一步就是调用 IDirect3DDevice9::DrawPrimitive 在顶点缓冲区渲染这个三角形,如下:
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
1、 第一个参数通过 DrawPrimitive 接受一个标记,告诉 Direct3D 对象,什么类型的东西将被绘制。
2、 在这个示例里面,使用了 DrawPrimitive 来指定一个三角形集合
3、 第二个参数表示第一个顶点被加载的序号。
4、 第三个参数表示将要绘制的图像的个数
5、 因为这个示例仅画了一个三角形,所以这里的值是 1
1 、最后一步是结束绘制这个舞台,将后台缓冲区显示到前台缓冲区。如下:
g_pd3dDevice->EndScene();
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
1 、在后台缓冲区显示到前台缓冲区之后,客户视口显示了一个三色三角形