- •Урок 1. Простейшее приложение DirectX11
- •Инициализация DirectX:InitDevice
- •Отображение сцены:Render
- •Цикл обработки сообщений
- •Очистка объектов:CleanupDevice
- •Цикл обработки сообщений
- •Обзор приложения
- •Дополнение к уроку. Настройка среды разработки
- •Заключение
- •Урок 2. Вывод 3d геометрии на экран в DirectX11
- •Обзор архитектуры для вывода геометрии в DirectX11
- •Инициализация геометрии: InitGeometry
- •Инициализация геометрии – создание вершин: InitGeometry
- •Создание буфера глубины: zBuffer
- •Отображение геометрии: Render
- •Обзор приложения
- •Обзор шейдера для нашего приложения
- •Заключение
- •Урок 3. Математические основы Direct3d
- •Знакомство с базовыми 3d представлениями данных
- •Норма вектора
- •Нормализованный вектор
- •Символические обозначения векторов
- •Преобразования матриц и операции с ними
- •Математические операции с матрицами
- •Единичная матрица
- •Модуль матрицы
- •Нормализованная матрица
- •Матрицы трансформаций
- •Матрицы, используемые в DirectX
- •Заключение
- •Урок 4. Установка матриц трансформаций и камеры в DirectX11
- •Урок 5. Процедурная генерация моделей для DirectX11
- •Процедурная генерация
- •Определение формата исходных данных
- •Обзор приложения
- •Заключение
- •Урок 6. Установка источников освещения DirectX11
- •Урок 7. Текстуры в Direct3d11
- •Урок 8. Загрузка мешей в DirectX11
- •Урок 9. Шейдеры в Direct3d11
- •Урок 10. Различные шейдеры DirectX11
- •Шейдеры
- •Шейдер для эффекта bump
- •Шейдер для эффекта металлической поверхности
- •Использование нескольких шейдеров в приложении
- •Обзор приложения
- •Заключение
Создание буфера глубины: zBuffer
Несмотря на то, что мы отлично создали геометрию и заполнили данными геометрии вершинный и индексный буфер, геометрия не будет отображаться правильно, если не будет создан ZBuffer. Еще более очевидно будет влияние ZBuffera, если на экране будет две примитивы, одна впереди другой. Если ZBuffer не будет создан, то один объект может некорректно перекрывать другой, то есть задний объект может неожиданно отобразиться на переднем плане.
// Создание поверхности для Z-буфера D3D11_TEXTURE2D_DESC descDepth; ZeroMemory( &descDepth, sizeof(descDepth) ); descDepth.Width = width; descDepth.Height = height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; hr = g_pd3dDevice->CreateTexture2D( &descDepth, NULL, &g_pDepthStencil );
// Создание z-буфреа D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory( &descDSV, sizeof(descDSV) ); descDSV.Format = descDepth.Format; descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; hr = g_pd3dDevice->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView ); |
Чтобы этого не произошло, в функции InitDevice мы добавим код для создания объекта типа ID3D11DepthStencilView, представляющий из себяZBuffer и далее назначим этот объект Direct3D устройству. Еще одна важная часть операций с буфером глубины заключается в том, что в функции Render мы должны очищать его содержимое.
Отображение геометрии: Render
На самом деле код Render небольшой. Это потому, что все подготовительные данные уже сделаны и каждый кадр ничего изменять не нужно, нужно просто отображать то что имеется. Посмотримнакод:
void Render() { // Установка трансформации для куба g_World = XMMatrixRotationY( 3.14159f/4.0f );
// Очистка рендер-таргета и буфера глубины float ClearColor[4] = { 0.0f, 0.9f, 0.5f, 1.0f }; // цвет g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor ); g_pImmediateContext->ClearDepthStencilView( g_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0 );
// Установка констант шейдера ConstantBuffercb; cb.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->VSSetConstantBuffers( 0, 1, &g_pConstantBuffer ); g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 ); g_pImmediateContext->DrawIndexed( 36, 0, 0 ); // 36 вершин образуют 12 полигонов, по три вершины на полигон
// Вывод на экран содержимого рендер-таргета g_pSwapChain->Present( 0, 0 ); } |
В этом коде нужно обратить внимание на то, что перед вызовом метода DrawIndexed необходимо установить вершинный и пиксельный шейдеры. Причем это делается раздельно, сначала устанавливается вершинный и затем пиксельный шейдер. Это очень полезно, так как мы можем назначать различные шейдеры, наподобие материалов. Причем мы можем использовать один вершинный шейдер и несколько различных пиксельных, или наоборот.
