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


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

Ресурсы (Direct3D 10)