Практическое руководство. Создание буфера констант

Буферы констант содержат данные констант шейдера. В этом разделе показано, как инициализировать буфер констант при подготовке к отрисовке.

Инициализация буфера констант

  1. Определите структуру, описывающую константы вершинного шейдера.

  2. Выделите память для структуры, определенной на шаге 1. Заполните этот буфер данными констант вершинного шейдера. Для выделения памяти можно использовать malloc или new или выделить память для структуры из стека.

  3. Создайте описание буфера, заполнив структуру D3D11_BUFFER_DESC . Передайте флаг D3D11_BIND_CONSTANT_BUFFER члену BindFlags и передайте размер структуры описания буфера констант в байтах члену ByteWidth .

    Примечание

    Флаг D3D11_BIND_CONSTANT_BUFFER нельзя сочетать с другими флагами.

     

  4. Создайте описание данных подресурсов, заполнив структуру D3D11_SUBRESOURCE_DATA . Элемент pSysMem структуры D3D11_SUBRESOURCE_DATA должен непосредственно указывать на константы вершинного шейдера, созданные на шаге 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 );
    

В этом примере показано связанное определение cbuffer HLSL.

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

Примечание

Убедитесь, что макет памяти VS_CONSTANT_BUFFER в C++ соответствует макету HLSL. Сведения о том, как HLSL обрабатывает макет в памяти, см. в статье Правила упаковки для постоянных переменных.

 

Buffers

Использование Direct3D 11