(Direct3D 9) 访问顶点缓冲区的内容

顶点缓冲区对象使应用程序能够直接访问为顶点数据分配的内存。 可以通过调用 IDirect3DVertexBuffer9::Lock 方法检索指向顶点缓冲区内存的指针,然后根据需要访问内存以使用新的顶点数据填充缓冲区或读取它已包含的任何数据。 IDirect3DVertexBuffer9::Lock 方法接受四个参数。 第一个 是 OffsetToLock,是顶点数据的偏移量。 第二个参数是顶点数据的大小(以字节为单位)。 如果调用成功,则接受的第三个参数是指向顶点数据的指针的地址。

最后一个参数 Flags 告知系统应如何锁定内存。 根据访问顶点数据的方式为 Flags 参数指定常量。 确保为 D3DUSAGE 选择的值与为 D3DLOCK 选择的值匹配。 例如,如果要创建仅具有写入访问权限的顶点缓冲区,则尝试通过指定D3DLOCK_READONLY来读取数据是没有意义的。 明智地使用这些标志可让驱动程序锁定内存并提供最佳性能(给定请求的访问类型)。

填充或读取顶点数据后,调用 IDirect3DVertexBuffer9::Unlock 方法,如以下代码示例所示。

// This code example assumes the g_pVB is a variable of type 
//   LPDIRECT3DVERTEXBUFFER9 and that g_Vertices has been  
//   properly initialized with vertices

// Lock the buffer to gain access to the vertices 
VOID* pVertices;

if(FAILED(g_pVB->Lock(0, sizeof(g_Vertices), 
        (BYTE**)&pVertices, 0 ) ) ) 
    return E_FAIL;

memcpy(pVertices, g_Vertices, sizeof(g_Vertices));
g_pVB->Unlock();

如果使用 D3DUSAGE_WRITEONLY 标志创建顶点缓冲区,请不要使用D3DLOCK_READONLY锁定标志。 如果应用程序将仅从顶点缓冲区内存中读取,请使用 D3DLOCK_READONLY 标志。 如果包含此标志,Direct3D 可以优化其内部过程以提高效率,前提是对内存的访问将是只读的。

有关使用 IDirect3DVertexBuffer9::Lock 的 Flags 参数D3DLOCK_DISCARD或D3DLOCK_NOOVERWRITE的信息,请参阅使用动态顶点和索引缓冲区

在 C++ 中,由于直接访问为顶点缓冲区分配的内存,因此请确保应用程序正确访问分配的内存。 否则,可能会使内存无效。 使用应用程序用来从分配的缓冲区中的一个顶点移动到另一个顶点的顶点格式的步幅。 顶点缓冲区内存是在 FVF 中指定的简单顶点数组。 使用所定义的任何顶点格式结构的步幅。 可以通过检查顶点缓冲区说明中包含的 D3DFVF 来计算运行时每个顶点的步幅。 下表显示了每个顶点组件的大小。

顶点格式标志 大小
D3DFVF_DIFFUSE sizeof (DWORD)
D3DFVF_NORMAL sizeof (float) x 3
D3DFVF_SPECULAR sizeof (DWORD)
D3DFVF_TEXn sizeof (float) x n
D3DFVF_XYZ sizeof (float) x 3
D3DFVF_XYZRHW sizeof (float) x 4

 

以顶点格式存在的纹理坐标数由 D3DFVF_TEX n 标志 (其中 n 是一个介于 0 到 8) 的值。 将纹理坐标集的数目乘以一组纹理坐标的大小(范围为 1 到 4 个浮点数),以计算该纹理坐标数所需的内存。

使用总顶点步幅根据需要递增和递减内存指针,以访问特定顶点。

检索顶点缓冲区说明

可以通过调用 IDirect3DVertexBuffer9::GetDesc 方法检索有关顶点缓冲区的信息。 此方法使用有关顶点缓冲区的信息填充 D3DVERTEXBUFFER_DESC 结构的成员。

顶点缓冲区