Evgenii Legotckoi
Evgenii Legotckoi28 января 2016 г. 7:24

Qt и Direct3D 12 - Первая встреча

Перевод официальной новости, автор Laszlo Agocs

Лицо графических API изменяется. Qt Quick 2 был выпущен в 2012 году с Qt 5.0, и опирался на OpenGL и OpenGL ES 2.0. С тех пор были введены изменения и улучшения - был введён Qt Quick 2D Renderer, были проведены эксперименты с программной растеризацией, и добавлена система обеспечения для новейших версий OpenGL в весь графический стек Qt. Однако, как заметил Lars в своём выступлении на Всемирном саммите Qt 2015, ситуация изменяется: новые, низкоуровневые, более эффективные API, такие как Vulkan, Metal и Direct3D 12, собираются стать широко доступны. Некоторые из них ориентированы на конкретные платформы, делая их лучшим выбором в вопросе таргетирования на конкретные платформы, в то время как другие, как ожидается, будут поддерживать широкий спектр платформ. В тоже время, делая комплексные прогнозы, ускорение с графическим API не всегда является лучшим выбором: традиционно, рабочий стол пользовательского интерфейса на устаревшем железе иногда лучше запустить с устаревшей отрисовкой на базе CPU.

Таким образом, что не удивительно, одним из направлений исследований в будущих версиях Qt является создание графического стек, и в частности, Qt Quick, более гибким, с поддержкой различных графических API, а также с поддержкой программного рендеринга.

Такие исследовательские работы часто приводят к полезным эффектам, и эта запись об одном таком. Простой Qt модуль включающий интеграцию с Direct3D 12 в отдельном Qt окне - или в качестве альтернативы приложение основанное на QWidget - и делающий это процесс легким для начала экспериментов с современными методами D3D, в то время как Вы продолжаете наслаждаться знакомыми API, инструментами и средой разработки Qt и предлагаемой ей экосистемой.


What it is

QtD3D12Window module, находится в qt-labs репозитории, и является модулем Qt 5.6, который предоставляет QD3D12Window класс, похожий на QOpenGLWindow,  обрабатывается qmake правилом для компиляции HLSL шейдера через fxc, и имеет исчерпывающий комплект примеров для основного использования (наподобие Hello World samples от Microsoft).

What it is not

Прежде, чем пойти дальше, давайте разберёмся, чем этот модуль не является: он не является способом запускать существующие Qt приложения на Direct3D (то есть именно, что предоставляет ANGLE , когда дело доходит до D3D9 и 11), и в любом случае не поддерживает Qt Quick. Это также не является дополнением к Qt в его нынешнем виде, и не является полным движком и фреймворком в любом его виде (интерфейс QD3D12Window явно предлагает недостаточный функционал для сложных и многопоточных решений).

Window

Первым шагом для интеграции с пользовательским кодом рендеринга является новое графическое API, которое создаёт цель рендеринга в нативном окне основанном на QWindow. В настоящее время OpenGL является единственным выборов и глубокого интегрирован в Qt как внутренне (QPA интерфейсы, плагины платформы), так и внешне (публичные API, см. QOpenGL классы в QtGui). Ожидается, что это изменится в будущем, но сейчас, для нашего автономного эксперимента с D3D, мы сделаем всё самостоятельно. Платформенный плагин окна в Qt позволяет легко получить нативный дескриптор окна, как если бы мы использовали QWindow::winId(), который возвращает id окна в Windows в Qt приложение. Мы можем затем использовать DXGI для перечисления доступным адаптеров, и можем выбрать либо аппаратный, либо WARP адаптер, и создать цепочку подкачки (swap). QD3D12Window обработает всё это, причём, достаточно хорошо для основных типичных приложений.

Говоря о DXGI, отметим, что это первый подобный набег на графический адаптер и управление устройством: в то время как с OpenGL и его оконными интерфейсами обычно такие возможности ограничены, другие же API (особенно платформозависимые и привязанные к определённой модели драйвера) могут предлагать больше возможностей по поиску адаптеров и внесению изменений в настройки, удалению сбросу в течению жизненного цикла приложения. Такая функциональность на тех платформах, где доступны API, получит больше внимания в Qt в будущем.

При реализации QD3D12Window, выяснилось, что не требуется создавать какой-либо общий класс - благодаря тому, что QOpenGLWindow и QRasterWindow были введены в Qt 5.4: Общий базовый класс QPaintDeviceWindow  что, конечно вводит в заблуждение в случае с D3D, поскольку наше окно не используется для отрисовки, основанной на QPainter) предоставляет всю необходимую инфраструктуру, что позволяет сфокусироваться в подклассе на особенности графического API при разработке основного функционала, такого как метод update(). Это хорошие новости, что данная наработка позволяет легко экспериментировать с другими API в будущем (QMetalWindow, QVulkanWindow, и т.д.).

Class

QD3D12Window является зеркалом QOpenGLWindow, который в свою очередь основан на QOpenGLWidget/QGLWidget и методы initializeGL – resizeGL – paintGL, с GL переименованы на D3D, соответственно. Имеются две новых функции подклассов, которые могут быть реализованы: releaseD3D и afterPresent. Последняя вызывается каждый раз после выдачи Present call: большинство простых приложений будут ожидать GPU в этой функции. Первая же используется для того, чтобы приложение могло выжить при удалении устройства: когда графическое устройство становится недоступным, эта функция вызывается и выполняется при освобождении ресурсов во время инициализации/перерисовки/изменении размера. QD3D12Window будет затем запускать initializeD3D заново. В этом случае приложение может оставаться функциональным при обновлении драйвера или ожидании исполнения шейдеров.

Лучше, конечно, показать на примере. Взглянем на hellotriangle, который показывает, что если вы использовали раньше  QOpenGLWindow или QOpenGLWidget, то использование QD3D12Window не будет для Вас сюрпризом.

Widgets

Итак, теперь на нашем окне Мы не имеем ничего, кроме содержания отрисованного D3D12. Это отлично, но что там делают традиционные элементы управления? Этого можно добиться с QD3D12Window, сделав дочернее окно через QWidget::createWindowContainer(). Это связано с обычными ограничениями, о которых Вам в первую очередь следует прочитать в документации. Тем не менее это будет отлично работать для самых простых целей.

Shaders

Обработка кода шейдеров и их компиляция является другой интересной темой. С  OpenGL в Qt и Qt Quick делается ставка на runtime компиляцию из-за того, что это является единственным общедоступным решением не зависящим от производителей и особенностей платформ. С другими графическими API в будущем, ожидается, что Qt больше сфокусируется на автономной компиляции, и интеграции в систему сборки настолько, насколько это возможно. Помимо очевидных преимуществ в производительности это значительно улучшает рабочий процесс разработки: получение компилятором информации об ошибках во время сборки при запуске через Ctrl+B, в Qt Creator сможете легко почувствовать, как новый способ превосходит "старый" путь отладки во время работы приложения.

QtD3D12Window модуль поставляется с простым правилом qmake, которое позволяет вызывать fxc.exe во время сборки. Все примеры используют его для создания заголовочных файлов, где компилируется байт-код, представляющий собой массив символов. Взгляните на .pro файл одного из них и настройку shader.

Это не является совершенно новым Qt: комплект ANGLE в qtbase выполняет компиляцию шейдеров тем же способом. Однако,  то что скрыто не может быть использовано в коде на прикладном уровне D3D, как файл hlsl.prf здесь, то может быть скопировано в папку mkspecs/features в Qt SDK, что сделает его доступным для любого Qt приложения.

Graphics Debugging

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

Другим полезным инструментов является graphics debugger включённый в Visual Studio. Одним из способов запустить Qt приложение является выполнение devenv /debugexe qtapplication.exe из командной строки разработчика и нажатие Alt+F5. (в качестве альтернативы, создание файлов проекта Visual Studio с qmake -tp vc может также хорошо работать). Он оказался весьма полезным во время разработки простых примеров – например, его возможность посмотреть графические ресурсы и также посмотреть, правильно ли сформированы уровни MIPMAP.

Примеры

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

Источник Qt Blog .

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
d
  • dsfs
  • 26 апреля 2024 г. 1:56

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80баллов,
  • Очки рейтинга4
d
  • dsfs
  • 26 апреля 2024 г. 1:45

C++ - Тест 002. Константы

  • Результат:50баллов,
  • Очки рейтинга-4
d
  • dsfs
  • 26 апреля 2024 г. 1:35

C++ - Тест 001. Первая программа и типы данных

  • Результат:73баллов,
  • Очки рейтинга1
Последние комментарии
k
kmssr8 февраля 2024 г. 15:43
Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко4 февраля 2024 г. 22:50
Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 декабря 2023 г. 7:30
Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 декабря 2023 г. 5:38
Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik18 декабря 2023 г. 18:01
Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Сейчас обсуждают на форуме
BlinCT
BlinCT5 мая 2024 г. 2:46
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
BlinCT
BlinCT5 мая 2024 г. 2:44
добавить qlineseries в функции Давно я не работал с виджетами и с формами, на мой взгляд уже пережитов, и в управлении не очень удобное это все. Н оя у вас не увидел в коде где вы QCharts растягиваете на область парента.…
PS
Peter Son3 мая 2024 г. 14:57
Best Indian Food Restaurant In Cincinnati OH Ready to embark on a gastronomic journey like no other? Join us at App india restaurant and discover why we're renowned as the Best Indian Food Restaurant In Cincinnati OH . Whether y…
Evgenii Legotckoi
Evgenii Legotckoi2 мая 2024 г. 11:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.
IscanderChe
IscanderChe30 апреля 2024 г. 1:22
Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…

Следите за нами в социальных сетях