(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、CopySubresourceRegionUpdateSubresource 初始化后,或者通过使用 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 接口 实例处理。 在这种情况下,只有使用 GetVariableByName 等 GetVariable 方法之一从效果中获取变量,并使用 SetMatrixSetVariable 方法之一更新该变量。 有关使用 ID3D10Effect 接口 管理常量缓冲区的示例 ,请参阅教程 7:纹理映射和常量缓冲区

资源 (Direct3D 10)