Класс QOpenGLWindow
Класс QOpenGLWindow — это удобный подкласс QWindow для выполнения отрисовки OpenGL. Подробнее...
| Заголовок: | #include <QOpenGLWindow> |
| qmake: | QT += gui |
| С тех пор: | Qt 5.4 |
| Наследует: | QPaintDeviceWindow |
Открытые типы
| перечисление | UpdateBehavior { NoPartialUpdate, PartialUpdateBlit, PartialUpdateBlend } |
Открытые функции
| QOpenGLWindow(QOpenGLWindow::UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = nullptr) | |
| QOpenGLWindow(QOpenGLContext *shareContext, QOpenGLWindow::UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = nullptr) | |
| виртуальный | ~QOpenGLWindow() |
| QOpenGLContext * | context() const |
| GLuint | defaultFramebufferObject() const |
| void | doneCurrent() |
| QImage | grabFramebuffer() |
| bool | isValid() const |
| void | makeCurrent() |
| QOpenGLContext * | shareContext() const |
| QOpenGLWindow::UpdateBehavior | updateBehavior() const |
- 2 открытые функции, унаследованные от QPaintDeviceWindow
- 82 открытые функции, унаследованные от QWindow
- 14 открытые функции, унаследованные от QPaintDevice
- 34 открытые функции, унаследованные от QObject
- 6 открытые функции, унаследованные от QSurface
Сигналы
| void | frameSwapped() |
Защищенные функции
| виртуальный void | initializeGL() |
| виртуальный void | paintGL() |
| виртуальный void | paintOverGL() |
| виртуальный void | paintUnderGL() |
| виртуальный void | resizeGL(int w, int h) |
Переопределенные защищенные функции
| виртуальный void | paintEvent(QPaintEvent *event) override |
| виртуальный void | resizeEvent(QResizeEvent *event) override |
- 1 защищенная функция, унаследованная от QPaintDeviceWindow
- 18 защищенных функций, унаследованных от QWindow
- 1 защищенная функция, унаследованная от QPaintDevice
- 9 защищенных функций, унаследованных от QObject
Дополнительные унаследованные члены
- 16 свойств, унаследованных от QWindow
- 1 свойство, унаследованное от QObject
- 1 открытый слот, унаследованный от QPaintDeviceWindow
- 24 открытых слота, унаследованных от QWindow
- 1 открытый слот, унаследованный от QObject
- 1 открытая переменная, унаследованная от QObject
- 1 статический открытый член, унаследованный от QWindow
- 10 статических открытых членов, унаследованных от QObject
- 2 защищенных переменных, унаследованных от QObject
Подробное описание
Класс QOpenGLWindow — это удобный подкласс QWindow для выполнения отрисовки OpenGL.
QOpenGLWindow — это расширенный QWindow, который позволяет легко создавать окна, выполняющие отрисовку OpenGL с помощью API, совместимого с QOpenGLWidget, и похожим на устаревший QGLWidget. В отличие от QOpenGLWidget, QOpenGLWindow не зависит от модуля виджетов и обеспечивает лучшую производительность.
Типичное приложение будет наследоваться от QOpenGLWindow и переопределять следующие виртуальные функции:
- initializeGL() для инициализации ресурсов OpenGL
- resizeGL() для настройки матриц преобразования и других ресурсов, зависящих от размера окна
- paintGL() для выполнения команд OpenGL или рисования с помощью QPainter
Чтобы запланировать перерисовку, вызовите функцию update(). Обратите внимание, что это не приведет к немедленному вызову paintGL(). Вызов update() несколько раз подряд не изменит поведение никоим образом.
Это слот, поэтому его можно подключить к сигналу QTimer::timeout() для выполнения анимации. Однако в современном мире OpenGL гораздо лучше полагаться на синхронизацию с вертикальной частотой обновления экрана. См. setSwapInterval() для описания интервала обмена. С интервалом обмена 1, который используется по умолчанию на большинстве систем, вызов swapBuffers(), который выполняется внутренне классом QOpenGLWindow после каждой перерисовки, блокирует и ожидает vsync. Это означает, что всякий раз, когда происходит обмен, можно снова запланировать обновление, вызвав update(), без использования таймеров.
Чтобы запросить определённую конфигурацию для контекста, используйте setFormat(), как и для любого другого QWindow. Это позволяет, среди прочего, запросить заданную версию и профиль OpenGL или включить буферы глубины и шаблона.
В отличие от QWindow, QOpenGLWindow позволяет открыть painter на себе и выполнить рисование на основе QPainter.
QOpenGLWindow поддерживает несколько стратегий обновления. По умолчанию, NoPartialUpdate эквивалентен обычному окну OpenGL QWindow или устаревшему QGLWidget. В отличие от них, PartialUpdateBlit и PartialUpdateBlend более соответствуют подходу QOpenGLWidget, где всегда присутствует дополнительный выделенный буфер кадра. Эти режимы позволяют, пожертвовав некоторой производительностью, перерисовывать только меньшую область на каждом рисунке и сохранять остальное содержимое из предыдущего кадра. Это полезно для приложений, которые выполняют рендеринг постепенно с помощью QPainter, так как таким образом они не должны перерисовывать всё содержимое окна при каждом вызове paintGL().
Аналогично QOpenGLWidget, QOpenGLWindow поддерживает атрибут Qt::AA_ShareOpenGLContexts. При включении контексты OpenGL всех экземпляров QOpenGLWindow будут совместно использоваться. Это позволяет получить доступ к совместно используемым ресурсам OpenGL друг друга.
Для получения дополнительной информации о графике в Qt см. Графика.
Документация по типам членов
перечисление QOpenGLWindow::UpdateBehavior
Это перечисление описывает стратегию обновления QOpenGLWindow.
| Константа | Значение | Описание |
|---|---|---|
QOpenGLWindow::NoPartialUpdate |
0 |
Указывает, что вся поверхность окна будет перерисована при каждом обновлении, поэтому дополнительные буферы кадров не нужны. Это значение используется в большинстве случаев и эквивалентно отрисовке непосредственно через QWindow. |
QOpenGLWindow::PartialUpdateBlit |
1 |
Указывает, что отрисовка, выполняемая в paintGL(), не покрывает всё окно. В этом случае создаётся дополнительный объект framebuffer, и отрисовка, выполняемая в paintGL(), будет нацелена на этот framebuffer. Затем этот framebuffer копируется на стандартный framebuffer поверхности окна после каждого обновления. Это позволяет использовать код отрисовки на основе QPainter в paintGL(), который перерисовывает только меньшую область за раз, поскольку, в отличие от NoPartialUpdate, предыдущее содержимое сохраняется. |
QOpenGLWindow::PartialUpdateBlend |
2 |
Аналогично PartialUpdateBlit, но вместо копирования framebuffer содержимое дополнительного framebuffer рендерится путём рисования текстурированного квада с включённым смешиванием. В отличие от PartialUpdateBlit, это позволяет использовать альфа-смешивание и работает даже в тех случаях, когда glBlitFramebuffer недоступен. С точки зрения производительности этот вариант, вероятно, будет немного медленнее, чем PartialUpdateBlit. |
Документация по функциям-членам
QOpenGLWindow::QOpenGLWindow(QOpenGLWindow::UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = nullptr)
Создаёт новый объект QOpenGLWindow с заданным parent и updateBehavior.
См. также QOpenGLWindow::UpdateBehavior.
QOpenGLWindow::QOpenGLWindow(QOpenGLContext *shareContext, QOpenGLWindow::UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = nullptr)
Создаёт новый объект QOpenGLWindow с заданным parent и updateBehavior. Контекст QOpenGLWindow будет совмещён с shareContext.
См. также QOpenGLWindow::UpdateBehavior и shareContext.
[virtual] QOpenGLWindow::~QOpenGLWindow()
Удаляет экземпляр QOpenGLWindow, освобождая его ресурсы.
Контекст OpenGLWindow становится текущим в деструкторе, что позволяет безопасно удалить любой дочерний объект, которому может потребоваться освободить ресурсы OpenGL, принадлежащие контексту, предоставляемому этим окном.
Предупреждение: если у вас есть объекты, оборачивающие ресурсы OpenGL (например, QOpenGLBuffer, QOpenGLShaderProgram и т. д.) в качестве членов подкласса QOpenGLWindow, вам может потребоваться добавить вызов makeCurrent() и в деструкторе этого подкласса. Из-за правил уничтожения объектов C++, эти объекты будут уничтожены до вызова этой функции (но после того, как будет выполнен деструктор подкласса), поэтому сделать контекст OpenGL текущим в этой функции произойдёт слишком поздно для их безопасного удаления.
Эта функция была добавлена в Qt 5.5.
См. также makeCurrent.
QOpenGLContext *QOpenGLWindow::context() const
Возвращает QOpenGLContext, используемый этим окном, или 0, если он ещё не инициализирован.
GLuint QOpenGLWindow::defaultFramebufferObject() const
Дескриптор объекта framebuffer, используемого этим окном.
Когда режим обновления установлен на NoPartialUpdate, отдельный объект framebuffer отсутствует. В этом случае возвращаемое значение — идентификатор стандартного framebuffer.
В противном случае возвращаемое значение — идентификатор объекта framebuffer или 0, если он ещё не инициализирован.
void QOpenGLWindow::doneCurrent()
Освобождает контекст.
В большинстве случаев вызывать эту функцию не нужно, так как виджет позаботится о корректном связывании и освобождении контекста при вызове paintGL().
См. также makeCurrent().
[signal] void QOpenGLWindow::frameSwapped()
Этот сигнал испускается после потенциально блокирующей операции обмена буферами swapBuffers. Приложения, которые хотят непрерывно перерисовывать синхронно с вертикальной частотой обновления, должны вызывать update() при получении этого сигнала. Это обеспечивает гораздо более плавную работу по сравнению с традиционным использованием таймеров.
QImage QOpenGLWindow::grabFramebuffer()
Возвращает 32-битное RGB изображение framebuffer.
Примечание: Это потенциально дорогостоящая операция, так как она использует glReadPixels() для считывания пикселей. Это может быть медленным и может блокировать конвейер GPU.
Примечание: При использовании режима обновления NoPartialUpdate, возвращаемое изображение может не содержать необходимого содержимого, если оно вызвано после обмена передним и задним буферами (если сохранение обмена не включено в интерфейсе подсистемы окон). В этом режиме функция читает из заднего буфера, и его содержимое может не соответствовать содержимому на экране (передний буфер). В этом случае единственное место, где эта функция может быть безопасно использована, — это paintGL() или paintOverGL().
[virtual protected] void QOpenGLWindow::initializeGL()
Эта виртуальная функция вызывается один раз до первого вызова paintGL() или resizeGL(). Переопределите её в подклассе.
В этой функции следует настроить все необходимые ресурсы и состояние OpenGL.
Вызывать makeCurrent() не нужно, так как это уже сделано при вызове этой функции. Однако имейте в виду, что framebuffer, если используется режим частичного обновления, ещё недоступен на этом этапе, поэтому избегайте выдачи команд рисования отсюда. Передайте такие вызовы в paintGL() вместо этого.
См. также paintGL() и resizeGL().
bool QOpenGLWindow::isValid() const
Возвращает true, если ресурсы OpenGL окна, например, контекст, были успешно инициализированы. Обратите внимание, что возвращаемое значение всегда false до тех пор, пока окно не станет видимым.
void QOpenGLWindow::makeCurrent()
Подготавливает для рендеринга содержимого OpenGL для этого окна, делая соответствующий контекст текущим и связывая объект framebuffer, если он есть, в этом контексте.
В большинстве случаев вызывать эту функцию не нужно, так как она вызывается автоматически перед вызовом paintGL(). Тем не менее, она предоставляется для поддержки расширенных многопотоковых сценариев, когда поток, отличный от GUI или основного потока, может захотеть обновить поверхность или содержимое framebuffer. См. QOpenGLContext для получения дополнительной информации о проблемах, связанных с потоками.
Эта функция подходит для вызова и тогда, когда родное окно платформы уже уничтожено. Это означает, что эту функцию безопасно вызывать из деструктора подкласса QOpenGLWindow. Если родного окна больше нет, вместо него используется автономная поверхность. Это гарантирует, что операции по очистке ресурсов OpenGL в деструкторе всегда будут работать, если эта функция вызывается в первую очередь.
См. также QOpenGLContext, context(), paintGL() и doneCurrent().
[override virtual protected] void QOpenGLWindow::paintEvent(QPaintEvent *event)
Переопределено из QPaintDeviceWindow::paintEvent().
Обработчик события event. Вызывает paintGL().
См. также paintGL().
[virtual protected] void QOpenGLWindow::paintGL()
Эта виртуальная функция вызывается всякий раз, когда содержимое окна нужно перерисовать. Переопределите её в подклассе.
Вызывать makeCurrent() не нужно, так как это уже сделано при вызове этой функции.
Перед вызовом этой функции контекст и framebuffer, если он есть, связываются, а viewport настраивается с помощью вызова glViewport(). Другое состояние не устанавливается, и никакое очищение или рисование не выполняется фреймворком.
Примечание: При использовании режима частичного обновления, например, PartialUpdateBlend, выход предыдущего вызова paintGL() сохраняется, и после дополнительной отрисовки, выполненной в текущем вызове функции, содержимое копируется или смешивается с содержимым, нарисованным непосредственно на окне в paintUnderGL().
См. также initializeGL(), resizeGL(), paintUnderGL(), paintOverGL() и UpdateBehavior.
[virtual protected] void QOpenGLWindow::paintOverGL()
Эта виртуальная функция вызывается после каждого вызова paintGL().
Когда режим обновления установлен в NoPartialUpdate, между этой функцией и paintGL() нет различий; выполнение отрисовки в любой из них приводит к одному и тому же результату.
Как и paintUnderGL(), отрисовка в этой функции направлена на буфер кадра по умолчанию окна, независимо от поведения обновления. Она вызывается после того, как paintGL() вернула значение и выполнена обработка сжатия (PartialUpdateBlit) или отрисовка четырёхугольника (PartialUpdateBlend).
См. также paintGL(), paintUnderGL() и UpdateBehavior.
[virtual protected] void QOpenGLWindow::paintUnderGL()
Виртуальная функция вызывается перед каждым вызовом paintGL().
Когда режим обновления установлен в NoPartialUpdate, между этой функцией и paintGL() нет различий; выполнение отрисовки в любой из них приводит к одному и тому же результату.
Различия становятся значимыми при использовании PartialUpdateBlend, где используется дополнительный объект буфера кадра. В этом случае paintGL() направлена на этот дополнительный объект буфера кадра, сохраняющий его содержимое, в то время как paintUnderGL() и paintOverGL() направлены на буфер кадра по умолчанию, то есть непосредственно на поверхность окна, содержимое которой теряется после каждого отображённого кадра.
Примечание: Избегайте полагания на эту функцию, когда поведение обновления равно PartialUpdateBlit. Этот режим включает сжатие дополнительного буфера кадра, используемого paintGL(), в буфер кадра по умолчанию после каждого вызова paintGL(), тем самым перезаписывая всю отрисовку, сгенерированную в этой функции.
См. также paintGL(), paintOverGL() и UpdateBehavior.
[override virtual protected] void QOpenGLWindow::resizeEvent(QResizeEvent *event)
Переопределено из QWindow::resizeEvent().
Обработчик события изменения размера. Вызывает resizeGL().
См. также resizeGL().
[virtual protected] void QOpenGLWindow::resizeGL(int w, int h)
Эта виртуальная функция вызывается всякий раз, когда виджет был изменён. Переопределите её в подклассе. Новый размер передаётся в w и h.
Примечание: Это всего лишь вспомогательная функция для обеспечения API, совместимого с QOpenGLWidget. В отличие от QOpenGLWidget, производные классы могут свободно выбрать переопределение resizeEvent() вместо этой функции.
Примечание: Избегайте выдачи команд OpenGL из этой функции, так как в момент её вызова контекст может быть отсутствовать. Если этого избежать нельзя, вызовите makeCurrent().
Примечание: Планирование обновлений из этой функции не требуется. Системы окон отправляют события expose, которые автоматически запускают обновление.
См. также initializeGL() и paintGL().
QOpenGLContext *QOpenGLWindow::shareContext() const
Возвращает QOpenGLContext, запрошенный для совместного использования с QOpenGLContext этого окна.
QOpenGLWindow::UpdateBehavior QOpenGLWindow::updateBehavior() const
Возвращает поведение обновления для этого QOpenGLWindow.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.11/qopenglwindow.html