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 хостинг.

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

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
г
  • ги
  • 23 апреля 2024 г. 22:51

C++ - Тест 005. Структуры и Классы

  • Результат:41баллов,
  • Очки рейтинга-8
l
  • laei
  • 23 апреля 2024 г. 16:19

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

  • Результат:10баллов,
  • Очки рейтинга-10
l
  • laei
  • 23 апреля 2024 г. 16:17

C++ - Тест 003. Условия и циклы

  • Результат:50баллов,
  • Очки рейтинга-4
Последние комментарии
k
kmssr9 февраля 2024 г. 2:43
Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко5 февраля 2024 г. 9:50
Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 декабря 2023 г. 18:30
Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 декабря 2023 г. 16:38
Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik19 декабря 2023 г. 5:01
Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Сейчас обсуждают на форуме
G
Gar22 апреля 2024 г. 12:46
Clipboard Как скопировать окно целиком в clipb?
DA
Dr Gangil Academics20 апреля 2024 г. 14:45
Unlock Your Aesthetic Potential: Explore MSC in Facial Aesthetics and Cosmetology in India Embark on a transformative journey with an msc in facial aesthetics and cosmetology in india . Delve into the intricate world of beauty and rejuvenation, guided by expert faculty and …
a
a_vlasov14 апреля 2024 г. 13:41
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
Павел Дорофеев
Павел Дорофеев14 апреля 2024 г. 9:35
QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
f
fastrex4 апреля 2024 г. 11:47
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

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