Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DirectX.docx
Скачиваний:
2
Добавлен:
01.05.2025
Размер:
1.15 Mб
Скачать

Инициализация геометрии: InitGeometry

Теперь разберемся, что же нужно сделать чтобы вывести геометрию на экран в DirectX11. Перед тем как приступать к изучении примера, вы можете скачать его исходный код, расположенный тут. Напомним, что в предыдущем уроке мы создали функцию InitDevice. В этой программе также есть эта функция а также остальные, которые мы рассматривали в предыдущем примере, но мы их заново рассматривать не будем а просто включим в нашу программу. Функция InitGeometry будет выполняться перед циклом обработки сообщений, то есть после того, как мы произвели инициализацию Direct3D устройства. Итак, подготовим и создадим геометрию в функции InitGeometry. Мы разобьем все наше рисование на две части – на инициализацию – сначала мы подготовим модель для рисования и на рендеринг – далее мы можем рисовать модель столько раз сколько нужно. В данной части урока мы рассмотрим инициализацию. Первое что мы сделаем в нашей функции InitGeometry — это загрузим код шейдера. На самом деле это просто, просто укажем имя файла шейдера в формате .fx и вызовем фукнцию для загрузки:

// Загружаем шейдеры

ID3DBlob* pVSBlob = NULL;

HRESULT hr;

hr = CompileShaderFromFile( L"Article2.fx", "VS", "vs_4_0", &pVSBlob );

 

// Вершинныйшейдер

hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader );

 

// Определение формата вершинного буфера

D3D11_INPUT_ELEMENT_DESClayout[] =

{

{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },

{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },

};

UINT numElements = ARRAYSIZE( layout );

 

// Созданиеформатабуфера

hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &g_pVertexLayout );

pVSBlob->Release();

 

// Установкаформатабуфера

g_pImmediateContext->IASetInputLayout( g_pVertexLayout );

 

// Пиксельныйшейдер

ID3DBlob* pPSBlob = NULL;

hr = CompileShaderFromFile( L"Article2.fx", "PS", "ps_4_0", &pPSBlob );

 

// Пиксельныйшейдер

hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader );

pPSBlob->Release();

Так как код шейдера состоит из пиксельного шейдера и вершинного шейдера, то функцию загрузки мы должны выполнить два раза – сначала для вершинного шейдера а затем для пиксельного. Затем, перед тем как отобразить объект на экране, мы будем также два раза назначать шейдерDirect3D устройству текущим: сначала назначим текущий вершинный шейдер, затем пиксельный; после этого отобразим модель. После того как шейдеры загружены, они представляются в приложении как два объекта: g_pVertexShader и g_pPixelShader соответственно.

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

VS_OUTPUT VS( float4 Pos : POSITION, float4 Color : COLOR ) { ... }

Данное объявление переменных входящих параметров вершинногошейдера соответствует структуре:

struct VS_INPUT

{

float4 Pos   : POSITION;

float4 Color : COLOR;

};

Итак, мы должны передать в вершинныйшейдер для каждой вершины по два числа формата float4.

// Определение формата вершинного буфера

D3D11_INPUT_ELEMENT_DESC layout[] =

{

{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },

{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },

};

Теперь осталось только установить этот формат для D3DDevice. Если в вашей программе все вершины имеют один и тот-же формат, код ниже можно выполнять только один раз в начале программы. Далее Direct3D везде будет использовать этот формат. Установим ранее объявленный формат вершинного буфера:

// Создание формата буфера

hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &g_pVertexLayout );

pVSBlob->Release();

 

// Установка формата буфера

g_pImmediateContext->IASetInputLayout( g_pVertexLayout );

Обратите внимание, что установка формата вершинного буфера выполняется совместно с загрузкой шейдеров, это необходимо потому, что объявление формата вершинного буфера напрямую связано с форматом входящих данных вершинного шейдера, собственно, эти форматы должны совпадать.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]