Создание буферных ресурсов (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. Сопоставление текстур и буферы констант.
См. также