Поделиться через


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

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

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

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

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

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

    Заметка

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

     

  4. Создайте описание данных подресурса, заполнив структуру D3D11_SUBRESOURCE_DATA. Элемент pSysMem структуры D3D11_SUBRESOURCE_DATA должен указывать непосредственно на данные константы вершинного шейдера, созданные на шаге два.

  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 обрабатывает макет в памяти, см. в правила упаковки для константных переменных.

 

буферы

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