如何:创建常量缓冲区

常量缓冲区 包含着色器常量数据。 本主题演示如何初始化 常量缓冲区 以准备呈现。

初始化常量缓冲区

  1. 定义描述顶点着色器常量数据的 结构。

  2. 为在步骤 1 中定义的结构分配内存。 使用顶点着色器常量数据填充此缓冲区。 可以使用 mallocnew 来分配内存,也可以从堆栈中为结构分配内存。

  3. 通过填充 D3D11_BUFFER_DESC 结构来创建缓冲区说明。 将 D3D11_BIND_CONSTANT_BUFFER 标志传递给 BindFlags 成员,并将常量缓冲区说明结构的大小(以字节为单位)传递给 ByteWidth 成员。

    注意

    D3D11_BIND_CONSTANT_BUFFER标志不能与任何其他标志组合使用。

     

  4. 通过填写 D3D11_SUBRESOURCE_DATA 结构创建子资源数据说明。 D3D11_SUBRESOURCE_DATA 结构的 pSysMem 成员必须直接指向在步骤 2 中创建的顶点着色器常量数据。

  5. 调用 ID3D11Device::CreateBuffer ,同时传递 D3D11_BUFFER_DESC 结构、 D3D11_SUBRESOURCE_DATA 结构和指向要初始化的 ID3D11Buffer 接口的指针的地址。

这些代码示例演示如何创建常量缓冲区。

此示例假定 g_pd3dDevice 是有效的 ID3D11Device 对象, g_pd3dContext 是有效的 ID3D11DeviceContext 对象。

ID3D11Buffer*   g_pConstantBuffer11 = NULL;

// Define the constant data used to communicate with shaders.
struct VS_CONSTANT_BUFFER
{
    XMFLOAT4X4 mWorldViewProj;                              
    XMFLOAT4 vSomeVectorThatMayBeNeededByASpecificShader;
    float fSomeFloatThatMayBeNeededByASpecificShader;
    float fTime;                                            
    float fSomeFloatThatMayBeNeededByASpecificShader2;
    float fSomeFloatThatMayBeNeededByASpecificShader3;
} VS_CONSTANT_BUFFER;

// Supply the vertex shader constant data.
VS_CONSTANT_BUFFER VsConstData;
VsConstData.mWorldViewProj = {...};
VsConstData.vSomeVectorThatMayBeNeededByASpecificShader = XMFLOAT4(1,2,3,4);
VsConstData.fSomeFloatThatMayBeNeededByASpecificShader = 3.0f;
VsConstData.fTime = 1.0f;
VsConstData.fSomeFloatThatMayBeNeededByASpecificShader2 = 2.0f;
VsConstData.fSomeFloatThatMayBeNeededByASpecificShader3 = 4.0f;

// Fill in a buffer description.
D3D11_BUFFER_DESC cbDesc;
cbDesc.ByteWidth = sizeof( VS_CONSTANT_BUFFER );
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
cbDesc.StructureByteStride = 0;

// Fill in the subresource data.
D3D11_SUBRESOURCE_DATA InitData;
InitData.pSysMem = &VsConstData;
InitData.SysMemPitch = 0;
InitData.SysMemSlicePitch = 0;

// Create the buffer.
hr = g_pd3dDevice->CreateBuffer( &cbDesc, &InitData, 
                                 &g_pConstantBuffer11 );

if( FAILED( hr ) )
   return hr;

// Set the buffer.
g_pd3dContext->VSSetConstantBuffers( 0, 1, &g_pConstantBuffer11 );
    

此示例显示关联的 HLSL cbuffer 定义。

cbuffer VS_CONSTANT_BUFFER : register(b0)
{
    matrix mWorldViewProj;
    float4  vSomeVectorThatMayBeNeededByASpecificShader;
    float fSomeFloatThatMayBeNeededByASpecificShader;
    float fTime;
    float fSomeFloatThatMayBeNeededByASpecificShader2;
    float fSomeFloatThatMayBeNeededByASpecificShader3;
};

注意

请确保将 C++ 中的 VS_CONSTANT_BUFFER 内存布局与 HLSL 布局匹配。 有关 HLSL 如何处理内存中的布局的信息,请参阅 常量变量的打包规则

 

缓冲区

如何使用 Direct3D 11