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

Установка матриц камеры, трансформаций и проективной матрицы в качестве констант шейдера



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

Любые константы шейдера в DirectX11 представляются в виде буфера. Таким образом, создав глобальный буфер для шейдеров можно затем просто устанавливать константы для шейдера, записывая в буфер новые значения констант и затем передавая в шейдер сразу весь буфер, содержащий все константы. Буфер может содержать как переменные для хранения матриц, также переменные для хранения векторов. Сначала объявим в приложении структуру, для хранения всех констант шейдера а также глобальный объект – константный буфер:

//------------------------------------------------------------------------------------ // Структуры //------------------------------------------------------------------------------------ struct ConstantBuffer { XMMATRIX mWorld; XMMATRIX mView; XMMATRIX mProjection; }; //------------------------------------------------------------------------------------ // Глобальные переменные //------------------------------------------------------------------------------------ ID3D11Buffer* g_pConstantBuffer = NULL;

Обратите внимание что пока у нас объект имеет значение NULL, то есть объект еще не инициализирован. Также обратите внимание, что существует отдельно структура для хранения значений буфера ConstantBuffer и собственно объект константного буфера g_pConstantBuffer. В функции инициализации геометрии мы должны создать константный буфер, точно также, как мы создавали вершинный и индексный буферы:

// Создание буфера констант шейдера bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(ConstantBuffer); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; hr = g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pConstantBuffer );

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

Итак, в процедуре Render установим глобальные переменные шейдера для наших матриц (вы помните, что раньше мы получили нужные матрицы, преобразовав их из объекта CameraTarget).

// Установка констант шейдера ConstantBuffer cb; сb.mWorld = XMMatrixTranspose( g_World); cb.mView = XMMatrixTranspose( g_View ); cb.mProjection = XMMatrixTranspose( g_Projection ); g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cb, 0, 0 ); g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 ); g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 ); g_pImmediateContext->VSSetConstantBuffers( 0, 1, &g_pConstantBuffer );

Выможетеспросить, зачемдваразаустанавливатьматрицы? Сначала мы установили матрицы при помощи кода

g_View = XMMatrixLookAtLH( Eye, At, Up ); g_World = XMMATRIXIdentity(); g_Projection=XMMATRIXPerspectiveFovLH( MyCamera.FOV,1.6f.0f,0.1f,100.0f);

А потом установили еще раз, при помощи установки переменных для шейдера (см. выше).

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







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