Создание буферных ресурсов (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;

В этом примере описание буфера инициализируется почти всеми параметрами по умолчанию для использования, доступа к ЦП и прочих флагов. Другие параметры относятся к флагу привязки , который определяет ресурс только как буфер вершин и размер буфера.

Для производительности важны флаги использования и доступа к ЦП. Эти два флага вместе определяют частоту доступа к ресурсу, тип памяти, в которую можно загрузить ресурс, и какой процессор должен получить доступ к ресурсу. Использование по умолчанию этот ресурс не будет обновляться очень часто. Установка доступа к ЦП в значение 0 означает, что ЦП не нужно будет читать или записывать ресурс. В сочетании это означает, что среда выполнения может загрузить ресурс в самую высокопроизводительную память для GPU, так как ресурсу не требуется доступ к ЦП.

Как и ожидалось, существует компромисс между оптимальной производительностью и доступностью в любое время любым процессором. Например, использование по умолчанию без доступа к ЦП означает, что ресурс можно сделать доступным исключительно для GPU. Это может включать загрузку ресурса в память, к которым ЦП не может напрямую обращаться. Ресурс можно изменить только с помощью 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 . В этом случае можно только получить переменную из эффекта с помощью одного из методов GetVariable, таких как GetVariableByName , и обновить переменную с помощью одного из методов SetVariable, таких как SetMatrix. Пример использования интерфейса ID3D10Effect для управления буфером констант см. в руководстве 7. Сопоставление текстур и буферы констант.

Ресурсы (Direct3D 10)