Урок DirectX 12. Рисуем первый треугольник

<?the_title()?>

DirectX 12 — это последняя версия собственного API компьютерной графики от Microsoft, используемого для платформ Windows и Xbox. Он, как и Vulkan, нацелен на создание менее сложного драйвера и API, более близкого к архитектуре современных графических процессоров.

DirectX фокусируется на рендеринге в реальном времени, поэтому он предназначен для разработчиков игр и систем автоматизированного проектирования (CAD). Поскольку это отраслевой стандарт API компьютерной графики, можно ожидать, что почти все совместимые аппаратные средства будут иметь его надежную поддержку, и он станет стандартом для коммерческих проектов.

Этот графический API является самым популярным и вездесущим из всех: от программ для создания 3D/изображений наподобие Marmoset Toolbag 3, Adobe PhotoShop, Autodesk Maya, до коммерческих игр вроде OverWatch от Blizzard и Fortnite от Epic, подавляющего большинства игр на Steam от Valve и многого другого (несмотря на эксклюзивность платформы).

DirectX 12 сейчас поддерживается в:

  • Windows 10
  • Xbox One
  • Xbox One X

В Windows 7 имеется частичная поддержка через D3D12 On 7.

Его поддерживает множество языков:

  • C
  • C++
  • C#
  • Rust (через dx-sys)

Я подготовил хранилище Github со всем, что понадобится. На современном C++ мы собираемся пройтись по приложению Первый Треугольник. Это программа, которая создает треугольник и визуализирует его на экране.

Подготовка

Сначала установите:

Теперь напечатайте в терминале следующее.

# Клонируйте хранилище

git clone https://github.com/alaingalvan/directx12-seed --recurse-submodules

# Зайдите в папку

cd directx12-seed

# Если вы забыли про рекурсию подмодулей, всегда можно запустить:

git submodule update --init

# Создать папку для компиляции проекта

mkdir build

cd build

# Чтобы сделать ваше Visual Studio решение на Windows x64

cmake .. -A x64

# Чтобы сделать XCode проект на Mac OS

cmake .. -G Xcode

# Чтобы сделать .make файл на Linux

cmake ..

# Для любой платформы:

cmake --build .

Обзор

Документация DirectX 12 рекомендует использовать ComPtr <T> в качестве альтернативы к std :: shared_ptr <T>, потому что так лучше отлаживать и легче инициализировать структуры данных DirectX 12.

Независимо от того, выберете ли вы ComPtr <T> или нет, этапы рендеринга растровой графики с помощью DirectX 12 очень похожи на этапы других современных графических API:

  1. Инициализация API — создаются ваши Фабрика, Адаптер, Устройство, Очередь, Распределитель команд, Список команд, Цепочка обмена.
  2. Инициализация ресурсов — ваш Буфер вершин, Индексный буфер, Однородный буфер, Представления целей визуализации, Графический конвейер, Примитивы синхронизации.
  3. Визуализация — обновление ваших однородных данных, добавление команд в очередь и ожидание следующего фрейма.

Далее будут объяснены фрагменты, которые можно найти в хранилище Github, с определенными опущенными частями и переменными-членами (mMemberVariable), объявленными встроенными без префикса m, чтобы их тип был легче видеть. Примеры здесь могут работать сами по себе.

Создание окна

Мы используем CrossWindow для создания кроссплатформенного окна, поэтому создать окно и обновить его очень просто:

Инициализация API

Фабрика

Точка входа в DirectX 12 API

Фабрики — это точка входа в DirectX 12 API, и следовательно, первое, что вам нужно создать.

Вы также можете создавать отладочные структуры данных, такие как debugController, которые могут включать проверку использования API.

Адаптер

характеристики устройства DirectX

Адаптер предоставляет информацию о физических характеристиках данного устройства DirectX.

Устройство

устройство и устройство отладки

Устройство — это ваша основная точка входа в DirectX 12 API, предоставляющая доступ к внутренним частям API. Это ключ к важным структурам данных, таким как конвейеры, шейдеры, состояние рендеринга и т.д.

Устройство отладки позволяет вам полагаться на режим отладки DirectX 12. Структуры данных, созданные с помощью DirectX, может быть трудно отслеживать. С Device вы сможете предотвратить утечку данных или проверить, правильно ли вы создаете или используете API.

Очередь команд

очередь команд

Очередь команд позволяет вам отправлять группы вызовов отрисовки, известных как списки команд, для выполнения по порядку, что позволяет графическому процессору оставаться занятым и оптимизировать скорость его работы.

Распределитель команд

Чтобы создавать списки команд, то есть структуру данных, в которой выполняются ваши вызовы отрисовки к GPU, нужен распределитель команд.

Синхронизация

синхронизация

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

Swap chain

swapchain

Swap chain занимается обменом между фрейм-буферами, чтобы показать ваш рендер в заданном окне.

Инициализация ресурсов

Корневая подпись

Корневая подпись представляет собой объекты, которые определяют тип ресурсов, привязанных к графическому конвейеру:

Буфер вершин

вершинный буфер

Буфер вершин хранит информацию о каждой вершине, доступную в виде атрибутов в вашем вершинном шейдере. Все буферы являются объектами ID3D12Resource в DirectX 12, хоть вершинные, хоть индексные, однородные и т.д.

Индексный буфер

буфер индексов

Индексный буфер содержит индивидуальные индексы каждых треугольника/линии/точки, которые вы собираетесь нарисовать.

Константный uniform буфер

uniform buffer

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

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

vertex shader in DirectX 12

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

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

pixel shader

Пиксельные шейдеры выполняются для каждого пикселя вашего вывода, включая добавочные отрисовки, которые соответствуют этой пиксельной координате.

Этап конвейера

DirectX 12 конвейер

Этап конвейера описывает все необходимое для выполнения основанного на растеризации данного вызова отрисовки.

Рендеринг

рендеринг треугольника

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

Устранение дескрипторов

Если вы используете структуры данных ComPtr <T>, то как и в случае с общими указателями, вам не нужно беспокоиться об устранении любых созданных вами дескрипторов. Если же вы этого не сделаете, вы можете вызвать функцию Release (), встроенную в каждую структуру данных DirectX.

Заключение

DirectX 12 — это многофункциональный и надежный API компьютерной графики, идеально подходящий для коммерческих проектов. Он похож на другие современные графические API по своей архитектуре, а также является основным API, поддерживаемым как разработчиками драйверов оборудования, так и создателями коммерческих продуктов. В этом посте рассматривается отрисовка, основанная на растровых данных, однако есть и другие достойные рассмотрения аспекты DirectX, которые здесь не обсуждались, такие как:

  • DirectML — Аппаратно ускоренное выполнение модели машинного обучения.
  • DirectX Raytracing — Аппаратно ускоренные трассировка лучей и обход сцены.
  • Вычислительные шейдеры — Основанное на GPGPU выполнение произвольных задач, таких как обработка изображений, физика и т.д.

Весь исходный код, описанный в этом посте, вы найдете в хранилище Github.

Также обязательно ознакомьтесь со следующими проектами:

Источник: https://alain.xyz/blog/raw-directx12

Понравилась статья? Поделиться с друзьями:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *