(Direct3D 10) 创建缓冲区资源
创建缓冲区需要定义缓冲区将存储的数据、提供初始化数据以及设置适当的用法和绑定标志。 若要创建纹理,请参阅 (Direct3D 10) 创建纹理资源 。
创建顶点缓冲区
创建 顶点缓冲区 的步骤如下所示。
创建缓冲区说明
创建顶点缓冲区时,缓冲区说明 (看到 D3D10_BUFFER_DESC) 用于定义如何在缓冲区内组织数据、管道如何访问缓冲区以及如何使用缓冲区。
以下示例演示如何为包含位置和颜色值的顶点的单一三角形创建缓冲区说明。
struct SimpleVertex
{
D3DXVECTOR3 Position;
D3DXVECTOR3 Color;
};
D3D10_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D10_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof( SimpleVertex ) * 3;
bufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
在此示例中,缓冲区说明是使用、CPU 访问和杂项标志的几乎所有默认设置初始化的。 其他设置用于 绑定标志 ,该标志仅将资源标识为顶点缓冲区,以及缓冲区的大小。
使用和 CPU 访问标志对于性能非常重要。 这两个标志一起确定资源访问的频率、可以加载到资源的内存类型以及需要访问资源的处理器。 此资源的默认使用情况不会经常更新。 将 CPU 访问设置为 0 意味着 CPU 不需要读取或写入资源。 综合考虑,这意味着运行时可以将资源加载到 GPU 的最高性能内存中,因为资源不需要 CPU 访问。
如预期所示,任一处理器在最佳性能和任意时间辅助功能之间存在权衡。 例如,没有 CPU 访问的默认用法意味着资源可以独占地提供给 GPU。 这可能包括将资源加载到 CPU 不可直接访问的内存中。 只能使用 UpdateSubresource 修改资源。
为缓冲区创建初始化数据
缓冲区只是元素的集合,并作为 1D 数组进行布局。 因此,系统内存间距和系统内存切片间距都是相同的:顶点数据声明的大小。 当使用 子资源说明创建缓冲区时,应用程序可以提供初始化数据,该说明包含指向实际资源数据的指针,并包含有关该数据的大小和布局的信息。
使用不可变用法创建的任何缓冲区 (请参阅创建时必须初始化 D3D10_USAGE_IMMUTABLE) 。 使用 CopyResource、 CopySubresourceRegion 和 UpdateSubresource 初始化后,也可以使用 Map 方法访问其基础内存来更新使用任何其他使用标志的缓冲区。
创建缓冲区
使用缓冲区说明和初始化数据 (,这是可选的) 调用 CreateBuffer 来创建顶点缓冲区。 以下代码片段演示如何从应用程序声明的顶点数据数组创建顶点缓冲区。
struct SimpleVertexCombined
{
D3DXVECTOR3 Pos;
D3DXVECTOR3 Col;
};
ID3D10InputLayout* g_pVertexLayout = NULL;
ID3D10Buffer* g_pVertexBuffer[2] = { NULL, NULL };
ID3D10Buffer* g_pIndexBuffer = NULL;
SimpleVertexCombined verticesCombo[] =
{
D3DXVECTOR3( 0.0f, 0.5f, 0.5f ),
D3DXVECTOR3( 0.0f, 0.0f, 0.5f ),
D3DXVECTOR3( 0.5f, -0.5f, 0.5f ),
D3DXVECTOR3( 0.5f, 0.0f, 0.0f ),
D3DXVECTOR3( -0.5f, -0.5f, 0.5f ),
D3DXVECTOR3( 0.0f, 0.5f, 0.0f ),
};
D3D10_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D10_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof( SimpleVertexCombined ) * 3;
bufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA InitData;
InitData.pSysMem = verticesCombo;
InitData.SysMemPitch = 0;
InitData.SysMemSlicePitch = 0;
hr = g_pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &g_pVertexBuffer[0] );
创建索引缓冲区
创建索引缓冲区与创建顶点缓冲区非常相似;有两个差异。 索引缓冲区仅包含 16 位或 32 位数据 (而不是顶点缓冲区可用的各种格式。 索引缓冲区还需要索引缓冲区绑定标志。
以下示例演示如何从索引数据数组创建索引缓冲区。
ID3D10Buffer *g_pIndexBuffer = NULL;
// Create indices
unsigned int indices[] = { 0, 1, 2 };
D3D10_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D10_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof( unsigned int ) * 3;
bufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA InitData;
InitData.pSysMem = indices;
InitData.SysMemPitch = 0;
InitData.SysMemSlicePitch = 0;
hr = g_pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &g_pIndexBuffer );
if( FAILED( hr ) )
return hr;
g_pd3dDevice->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );
创建常量缓冲区
Direct3D 10 引入了常量缓冲区。 常量缓冲区或着色器常量缓冲区是包含着色器常量的缓冲区。 下面是创建常量缓冲区的示例,该缓冲区取自 HLSLWithoutFX10 示例。
ID3D10Buffer* g_pConstantBuffer10 = NULL;
struct VS_CONSTANT_BUFFER
{
D3DXMATRIX mWorldViewProj; //mWorldViewProj will probably be global to all shaders in a project.
//It's a good idea not to move it around between shaders.
D3DXVECTOR4 vSomeVectorThatMayBeNeededByASpecificShader;
float fSomeFloatThatMayBeNeededByASpecificShader;
float fTime; //fTime may also be global to all shaders in a project.
float fSomeFloatThatMayBeNeededByASpecificShader2;
float fSomeFloatThatMayBeNeededByASpecificShader3;
};
D3D10_BUFFER_DESC cbDesc;
cbDesc.ByteWidth = sizeof( VS_CONSTANT_BUFFER );
cbDesc.Usage = D3D10_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
hr = g_pd3dDevice->CreateBuffer( &cbDesc, NULL, &g_pConstantBuffer10 );
if( FAILED( hr ) )
return hr;
g_pd3dDevice->VSSetConstantBuffers( 0, 1, g_pConstantBuffer10 );
请注意,使用 ID3D10Effect 接口接口 时,创建、绑定和组合常量缓冲区的过程由 ID3D10Effect 接口 实例处理。 在这种情况下,只有 nescesary 才能使用 GetVariableByName 等 GetVariable 方法之一从效果中获取变量,并使用 SetMatrix 等一个 SetVariable 方法更新变量。 有关使用 ID3D10Effect 接口 管理常量缓冲区的示例,请参阅 教程 7:纹理映射和常量缓冲区。
相关主题