Здавалка
Главная | Обратная связь

Инициализация геометрии: 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 );

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







©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.