Разница в скорости opengl между Qt 4/5 и API Opengl

Я прочитал все вопросы о SO, которые я смог найти о qt 4 и 5 opengl. Этот был самым близким OpenGL vs QOpenGL/QtOpenGL в Qt 5: различия и ограничения?, я не знаю, почему он был закрыт, потому что это отличный вопрос. Единственный аспект, который я вижу в нем, - это разница в скорости.

Я также прочитал этот https://qt-project.org/forums/viewthread/22921, у которого был аналогичный вопрос, но как взад и вперед около 4 против 5, в основном обсуждая новые возможности.

Мой вопрос в том, что использовать встроенные методы QT5 быстрее, чем создавать собственный виджет, используя API opengl напрямую? Если меня беспокоит производительность, то использует QT плохой выбор и там

EDIT:

Чтобы быть более конкретным, мне нужно использовать связь physx, tcp/ip и большие числа быстрого обновления вершин и сеток. Цель состоит в том, чтобы сделать это как можно ближе к реальному времени. Такие вещи, как рендеринг, не являются проблемой, но любой бит накладных расходов от qt повреждает. (Все в 3D с С++)

Ответы

Ответ 1

Я прочитал все вопросы о SO, которые я смог найти о qt 4 и 5 opengl. Этот самый ближайший OpenGL против QOpenGL/QtOpenGL в Qt 5: различия и ограничения?, Я понятия не имею, почему он был закрыт, потому что это отличный вопрос. Единственный аспект, который я вижу в нем, - это разница в скорости.

Чтобы быть более конкретным, мне нужно использовать связь physx, tcp/ip и большие числа быстрого обновления вершин и сеток. Цель состоит в том, чтобы сделать это как можно ближе к реальному времени. Такие вещи, как рендеринг, не являются проблемой, но любой бит накладных расходов от qt повреждает. (Все в 3D с С++)

В вашем вопросе есть несколько вопросов.

"Raw" OpenGL vs "Qt" OpenGL

Этот вопрос плохо поставлен, поскольку нет такой вещи, как "Qt OpenGL". OpenGL является стандартом, принадлежащим и опубликованным Khronos. Qt просто использует его.

Что Qt может сделать для вас, помогает вашему приложению управлять несколькими вещами.

Создание окна/контекста

Вы когда-нибудь пробовали создавать контекст OpenGL под Win32? Для этого требуется куча кода котла (см. здесь или здесь), что предполагает создание временного контекста для проверки для возможностей WGL, а затем создать фактический контекст в конце...

Вы когда-нибудь пробовали создать контекст OpenGL в X11? Для этого требуется куча кода котла (см. здесь), который включает проверку наличия GLX_ARB_create_context, а затем его использование для создания контекста или возврат к GLX 1.3 путь кода и...

Вы когда-нибудь пробовали создать контекст OpenGL в Mac OS X?

Вы когда-нибудь пробовали создавать контекст OpenGL под Android?

Вы когда-нибудь пробовали создать контекст OpenGL в QNX?

Вы когда-нибудь пробовали создавать контекст OpenGL в DirectFB/EGLFS?

Ой, подождите. Здесь это Qt:

class Window : public QWindow {
    QOpenGLContext *context;
public:
    Window() {
        QSurfaceFormat format;
        format.setVersion(3,3);
        format.setProfile(QSurfaceFormat::CoreProfile);

        setSurfaceType(OpenGLSurface);
        setFormat(format);
        create();

        context = new QOpenGLContext;
        context->setFormat(format);
        context->create();
    }
...

Да, это все. Это создает окно OpenGL (toplevel) и контекст основного профиля 3.3. Объедините его с QTimer, и у вас есть жизнеспособный рендерер. Что, конечно, будет работать на всех вышеперечисленных платформах: Win32, Mac, X11, Linux/EGLFS, QNX, iOS, Android.


Есть ли накладные расходы, которые вы должны заплатить за все это? Да, конечно. Но это абсолютно ничтожно; и вы платите за него только один раз, т.е. при создании окна и контекста.

Реальный тяжелый материал происходит из самого чертежа OpenGL, который полностью находится под вашим контролем: вы делаете контекст актуальным в окне и начинаете выдавать необработанные команды OpenGL. Qt здесь не так. Единственный момент, когда Qt и OpenGL снова соберутся, будут в буферах подкачки; но это операция, которая практически не требует затрат.

Итак: Qt не добавляет никаких измеримых служебных данных.

Управление окнами

Конечно, в комплекте с вышесказанным приходит тот факт, что вы можете f.i. управляйте клавиатурой и мышью с идентичным кодом на любой из этих платформ. Или измените размер окна. Или сделайте это в полноэкранном режиме. Или закройте его.

Помощники OpenGL

Qt не "просто" предлагает способ создания поверхности и контекста OpenGL (и связанных с ним операций: устанавливать как текущий, swap-буферы и т.д.). Он идет (много) дальше и предлагает целый ряд вспомогательных классов и функций:

  • QMatrix4x4 - это... 4x4 матрица. У вас есть все хорошие функции, которые вам нужны в программе OpenGL: lookAt(), ortho(), perspective(), normalMatrix() и т.д.
  • QOpenGLContext:: hasExtension и QOpenGLContext:: getProcAddress - это независимые от платформы способы разрешения точек входа OpenGL.
  • QOpenGLContext:: versionFunctions возвращает объект, содержащий всю точку входа OpenGL для уже разрешенной версии или профиля.
  • QOpenGLBuffer обертывает объект буфера.
  • QOpenGLVertexArrayObject обертывает объект массива вершин (и имеет помощник RAII для связывания и развязывания VAO).
  • QOpenGLTexture обертывает объект текстуры.
  • QOpenGLFrameBufferObject обертывает объект буфера фрейма.
  • QOpenGLShader и QOpenGLShaderProgram завершают шейдеры и шейдерные программы, предлагая удобные методы для f.i. устанавливая QMatrix4x4 как единую переменную. Таким образом, вы можете вычислить MVP для заданной сетки на процессоре, используя упомянутые выше методы, затем установите ее как единую.
  • QOpenGLDebugLoggerwraps GL_KHR_debug для отладки ваших приложений OpenGL.
  • и еще одна группа вещей, которые я сейчас не помню.

Есть ли накладные расходы? Да, но еще раз он минимален, а не включает, как вы используете эти объекты в своем коде OpenGL. Если ваш код OpenGL является быстрым и хорошо структурированным, вы найдете эти помощники полезными для его управления, и они не заставят его работать медленнее.

(Пример "полезно для управления": QOpenGLVertexArrayObject позволит вам использовать VAO на OpenGL 3.0 или на любой версии OpenGL для рабочего стола, где присутствует расширение GL_ARB_vertex_array_object, или на OpenGL ES2, если GL_OES_vertex_array_object присутствует. Вам не нужно разрешать правильный набор функций в зависимости от времени выполнения. Qt сделает это для вас и предоставит те же API для создания, связывания, освобождения и уничтожения VAO).

Все ли хорошо? Нет. Я должен быть честным здесь, есть бит и болты, которые выиграют от какой-то любви.

Например, QOpenGLFrameBufferObject имеет ограниченный API, не поддерживающий f.i. любое количество цветных вложений. QOpenGLBuffer потребует некоторой работы для поддержки большего количества типов буферов/привязок. По-прежнему нет поддержки программных конвейеров. Не поддерживается поддержка равномерных буферов.

С другой стороны, у вас есть такие вещи, как QOpenGLTexture, которая поддерживает довольно недавние функции, такие как неизменяемые виды хранения и текстуры.

Означает ли это, что вы не можете использовать эти функции? Конечно вы можете. Просто вернитесь к необработанному OpenGL-коду, если вам нужны функции Qt, которые не дают вам прямо сейчас. Или, рассмотрите предоставляя эти функции Qt!

Qt

Конечно, как только вы идете по пути Qt, у вас есть Qt. Это означает, что в библиотеках QtCore и QtGui:

  • циклов событий
  • таймеры
  • сигналы и слоты
  • темы
  • Строки Unicode + i18n
  • контейнеры
  • регулярные выражения
  • обработка файлов
  • Загрузка плагинов
  • Настройки
  • MIMETYPES
  • обработка ввода
  • image I/O
  • 2d обязательная окраска с использованием растрового движка
  • JSON
  • XML
  • и еще одна группа вещей, которые я сейчас не помню.

Конечно, все вышеперечисленное относится к кросс-платформе.

Кстати, Qt также имеет:

  • QtWidgets для межплатформенных виджетов 2d
  • QtSql для доступа к БД
  • QtNetwork для сокетов TCP/UDP/SSL, а также высокоскоростной HTTP/FTP-движок
  • QtTest для модульных тестов
  • QtWebkit для встраивания webkit
  • и еще одна группа вещей, которые я не помню прямо сейчас.

OpenGL в Qt 4 против 5

Существуют ли какие-либо огромные различия между обработкой OpenGL в Qt 4 и Qt 5? Не совсем...

В Qt 4 классом, используемым для рендеринга OpenGL, был QGLWidget. Он жил в модуле QtOpenGL (а не в QtGui - помните, что в Qt 4 виджеты тоже жили в QtGui). Кроме того, на самом деле подмножество помощников Qt 5 OpenGL, перечисленных выше, было доступно там под именем QGLFoo (f.i. QGLBuffer вместо QOpenGLBuffer).

В Qt 5 модуль QtOpenGL все еще существует, чтобы поддерживать работу старых приложений. Но:

  • QtGui и QtWidgets были разделены. QtGui теперь содержит бит низкого уровня для обработки WM, создания GL-контекстов и поверхностей, рисования 2d и, в основном, материалов, перечисленных выше. QtWidgets вместо этого содержит сами виджеты.

  • QtOpenGL все еще содержит классы QGL *, но теперь ссылки на QtWidgets (так как он содержит QGLWidget). Это означает, что использование QGLWidget означает, что вы будете ссылаться на какую-то большую библиотеку, даже если вы вообще не используете виджеты (потому что f.i. ваше приложение является чистым OpenGL).

  • Как я уже говорил, QtGui достаточно для создания полного окна OpenGL. Но что, если вы хотите встроить его в приложение на основе виджетов? Затем вы можете использовать QGLWidget или встраивать QWindow через QWidget::createWindowContainer. Помимо QGLWidget, вы не должны использовать какой-либо другой класс QtOpenGL (т.е. QGL). Используйте аналоги в QtGui (то есть классы QOpenGL).

  • Все вышеперечисленные классы QOpenGL * находятся в QtGui, а не в QtOpenGL; и они больше, чем аналоги QGL * (например, нет QGLVertexArrayObject), у них больше возможностей (например, QOpenGLShader поддерживает геометрию и шейдеры тэсселяции, QGLShader - нет) и, в общем, те, которые нужно использовать (поскольку они будут видеть исправления и улучшения, QGL * не будет).

  • Учитывая, что теперь QtGui предлагает поддержку OpenGL, было бы естественно ожидать, что замена QGLWidget появится непосредственно в QtWidgets. И действительно, это будет, надеюсь, в 5.4 (подготовительная работа идет в 5.3, но, к сожалению, сама функция пропустит замораживание функции).


Есть ли причина ожидать огромной разницы в производительности между Qt 4 и Qt 5? Нет. Я ожидаю, что ваш код GL будет работать точно так же. В конце концов Qt на самом деле не мешает вам.

Desktop GL/ES 2

Вы можете скомпилировать Qt 5 с поддержкой "Desktop GL" или "ES 2" с помощью таймера настройки времени. Очевидно, это изменит, какие заголовки QtGui будут использовать при компиляции, и к каким библиотекам он будет привязан (libGL или libGLES2 и т.д.). Он также изменит формат по умолчанию: вышеуказанный код QWindow создаст хорошую поверхность OpenGL ES2 (и, вероятно, не сможет создать контекст, так как нет OpenGL ES 3.3, ну хорошо).

Но вы понимаете: с помощью того же кода вы также можете поддерживать ES2.

Проблема (на мой взгляд) заключается в том, что она также изменит некоторые другие более тонкие вещи: например, QOpenGLShader вставляет некоторые макросы, такие как

#define highp
#define mediump
#define lowp

перед всеми вашими шейдерами, если вы используете Desktop GL. Причина в том, что он позволяет повторно использовать одни и те же шейдеры в ES2 и Desktop GL, в которых отсутствуют определители точности; поэтому они стираются через макросы, которые расширяются до нуля.

Я думаю, что эти мелочи на самом деле не выигрыш. Возможно, они уменьшают поддержку очень маленьких и простых шейдеров (и программ, созданных только вершинным и афрагментарным шейдером). Было бы лучше, если бы Qt старался быть настолько умным.

Но ваш путь к коду Desktop GL может использоваться с несколькими этапами шейдеров; или, как правило, использовать функции, недоступные на ES2. В конечном счете, это значительно расходится с вашим кодом кода ES2. (Подумайте, что в 3.3 Core вы должны использовать VAO, в то время как ES2 сам по себе не знает, что такое VAO.)

Личный разбор: я ненавижу, ненавижу, ненавижу тот факт, что ES2 не похожа на профиль OpenGL или так, и вместо этого сидит сама по себе. И нужно, по сути, иметь разложенную базу кода, чтобы сделать ES2 счастливой. Бах бах бах.

Окна

Введите мир боли!, также известный как статус драйвера OpenGL в Windows.

В принципе, все, кроме NVIDIA, ломают OpenGL-драйверы в Windows.

По крайней мере, "из коробки". Обновление драйверов обычно работает, но вы не всегда можете попросить пользователей обновить свои драйверы. Это конечные пользователи, а не про-геймеры. Возможно, у них даже нет привилегий администратора.

Это проблема для приложений OpenGL и особенно для одного из самых сильных инструментов Qt: Qt Quick 2. Qt пытается обойти эту проблему, используя ANGLE, который является слоем трансляции OpenGL ES2 → Direct3D. Итак, под Windows у вас есть выбор между

  • Рабочий стол OpenGL build
  • сборка OpenGL ES2 через ANGLE

Варианты не равны - ES2, конечно, означает забыть о том, что делает какой-либо серьезный Modern GL. Но кроме этого, причины для перехода в одну сторону или другую доступны здесь.

Qt Quick 2

Это важно, и я думаю, что заслуживает отдельного внимания.

Но сначала давайте выясним: нужно ли использовать Qt Quick 2 для создания приложения OpenGL под Qt? NO, NO и NO. Qt Quick 2 - полностью независимая технология, которая также использует OpenGL для рендеринга. Таким образом, вы можете игнорировать его и просто создавать свое приложение OpenGL.

Но что такое Qt Quick 2? Это библиотека, построенная поверх QML-языка, декларативный язык, созданный для создания динамических пользовательских интерфейсов (и теперь используемых для систем сборки... ну хорошо).

Помните о различии: QML - это язык, Qt Quick 2 - это библиотека с набором визуальных элементов (и API С++ для создания собственного), которые вы программируете в QML.

Бывает, что Qt Quick 2 использует OpenGL для рисования этих визуальных элементов. Это гарантирует хорошие результаты без потери качества 60 FPS, очень низкое использование ЦП, все виды шейдеров на основе глаз и т.д.

И что? Ну, вам может быть интересно дать ему удар. Например, API позволяет накладывать на любой чистый контент OpenGL, который вы рисуете. Таким образом, вы можете подумать о том, чтобы использовать Qt Quick 2 для передачи более традиционных пользовательских битов - кнопок, слайдеров и т.д., В то время как вы сохраняете контроль над рендерингом основного контента.

Или вы можете просто игнорировать тот факт, что он существует, и продолжать играть с OpenGL.

Ответ 2

Я думаю, что в вашем вопросе и в полученных комментариях есть много недоразумений. Корень проблемы - это очень свободное использование термина "Qt".

Qt - большая межплатформенная платформа разработки приложений. Он сочетает в себе функции, предлагаемые многими автономными средами. Он предлагает множество функций, которые полностью не связаны с gui. А именно, кросс-платформенные контейнеры, потоки, варианты, метаобъектная система с интроспекцией, таймеры, сетевое взаимодействие, сценарии с использованием qtscript или javascript (через qml), xml, json, state machines и другие. Qt используется для написания веб-сервисов, например, без единой строки кода пользовательского интерфейса.

Когда дело доходит до пользовательского интерфейса, Qt предлагает вам четыре инструментария пользовательского интерфейса. Это полностью ваш выбор, какой инструментарий вы используете. Вы также можете смешивать и сопоставлять их все - вы можете иметь части своего пользовательского интерфейса, реализованные в одном наборе инструментов, в другом. Все зависит от ваших требований.

Я полагаю, что под "Qt5" вы подразумеваете Qt Quick 2, реализацию графика сцены и инструментария UI с использованием QML в качестве платформы описания/сценариев. Если вам нужен только 2D-инструментарий на основе сценграфа, то Qt Quick 2 - хороший выбор. Он не предлагает никаких 3D-функций, поэтому для 3D-функций вы сами по себе. Qt не будет мешать - на самом деле это вам поможет, поскольку оно предоставляет переносимый API-интерфейс для OpenGL, который скрывает некоторые различия в платформе при доступе к OpenGL. Он также предоставляет ANGLE, объединенную реализацию OpenGL поверх Direct3D. Это позволяет вам разрабатывать OpenGL, сохраняя при этом Direct3D в Windows.

Для TCP/IP и общей не-ui функциональности вы должны использовать Qt - это делает жизнь очень простой. Для 3D вы будете использовать OpenGL напрямую через обертки, предоставленные Qt. Затем вы можете выбирать между OpenGL и ANGLE-строками Qt, чтобы решить, используете ли вы напрямую драйвер OpenGL платформы или используете ли вы OpenGL поверх DirectX (ANGLE). Поскольку вы используете physx, у вас уже есть хорошие драйверы nvidia и достойная реализация OpenGL, поэтому предпочтение отдается ANGLE. Вот как я это вижу.