производительность qt – OpenGL

#qt #qt4 #embedded-linux

#qt #qt4 #встроенный-linux

Вопрос:

я не хочу использовать собственный OpenGL в функции рисования моих виджетов (QPainter), чтобы повысить производительность. я увидел, что существует функция QPainter::begin / endNativePainting(), которая может мне помочь. но я не могу найти примеров для этого … я хотел знать, являются ли эти функции недорогими, или любое их использование снижает производительность? 2. могу ли я определить beginNativePainting () и endNativePainting (), в общем, для всех виджетов, которые я использую, вместо того, чтобы использовать это в каждой функции рисования, которая у меня есть.

спасибо за любую помощь….

Ответ №1:

Несколько базовых примеров кода есть прямо в документации:http://doc.qt.io/qt-4.8/qpainter.html#beginNativePainting

Сами функции должны быть довольно недорогими, но их вызов все равно может привести к заметным накладным расходам, потому что Qt при beginNativePainting() вызове очищает свою внутреннюю очередь рисования и, вероятно, предполагает, что все изменяется сразу после endNativePainting() вызова.

Что касается второй части, я не уверен, понимаю ли я, к чему вы стремитесь. В принципе, если у вас есть объект QPainter, вы можете вызвать его beginNativePainting() один раз. Но вы должны сопоставить это с endNativePainting() вызовом. Таким образом, обычным местом был бы метод paint().

Комментарии:

1. я видел этот пример, но нет программы (в примерах qt / демонстрациях / nokia-forum), которая его использует … и мне интересно, действительно ли это полезно, или есть другой способ сделать это. 2. если я собираюсь использовать его для множества виджетов в приложении, я могу поместить beginNativePainting() в ctor QWidget… а функция endNativePainting() в этом dtor? ….. действительно ли это полезно, когда у меня много виджетов?

2. Платформа Qt предоставляет вам QPainter в качестве параметра метода paintEvent() вашего QWidget. Использование begin / endNativePainting() имеет смысл только внутри этого метода (пока существует QPainter). Таким образом, вы не можете просто вызвать beginNativePainting() в ctor (для чего?) Если вы не уверены, что делаете, я бы посоветовал просто использовать QPainter для рисования и игнорировать begin / endNativePainting(). Только если вы столкнетесь с какой-то проблемой, которую не можете решить с помощью Qt API, возможно, пришло время пересмотреть. (Если все, что вам нужно, это использовать OpenGL, возможно, вы захотите взглянуть на графические системы Qt.)

3. я должен использовать opengl для улучшения производительности …. я не хочу знать, каков наилучший способ сделать это, не изменяя множество частей в моем коде виджетов.

4. Так вы вообще не используете OpenGL в данный момент? Тогда begin / endNativePainting() для использования собственных вызовов OpenGL все равно не будет работать. Попробуйте запустить свое приложение с «-graphicssystem opengl» в качестве (дополнительного) параметра командной строки. Это переключает серверную часть рендеринга Qt по умолчанию на OpenGL, никаких изменений в вашем коде не требуется. Если это работает и заметно (или, по крайней мере, ощутимо) быстрее, вы можете изменить инициализацию вашего приложения, чтобы установить серверную часть по умолчанию с помощью чего-то вроде QApplication::setGraphicsSystem («opengl»), см. doc.trolltech.com/4.7/qapplication.html#setGraphicsSystem

5. я использую это, но я получил ошибку: QGLFramebufferObject: неполное вложение фреймбуфера. Не удалось создать буфер текстур растрового изображения размером QSize (158, 17), возвращаясь к движку рисования растров

Ответ №2:

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

beginNativePainting / endNativePainting предназначены для того, чтобы позволить движку рисования Qt сохранять этот контекст и извлекать его, как только пользователь закончит рисовать.

Было бы неплохо, чтобы xxxNativePainting методы делали обратное (т. Е. автоматически сохраняли и восстанавливали пользовательскую конфигурацию OpenGL), но поскольку Qt позволяет напрямую вызывать примитивы OpenGL, сохранение глобального состояния практически невозможно без тонны кода и потенциального серьезного снижения производительности.

Вместо этого эти методы просто сохраняют внутреннее состояние OpenGL Qt и, вместо того, чтобы запускать пользовательский код в конфигурации, которая в любом случае была бы бессмысленной (и, вероятно, менялась с каждой новой версией Qt), переводят OpenGL в «нейтральное» состояние.
Это означает, что внутри раздела begin / end вы начнете с чистого листа: без привязки шейдеров, без массива вершин, сброса большинства глобальных параметров и т.д.

В отличие от простого QGLWidget / PaintGL сценария, где вы можете позволить себе настроить глобальное состояние OpenGL раз и навсегда и просто вызывать примитивы рендеринга в каждом кадре, вам придется восстанавливать практически все сразу после вызова beginNativePainting (связать ваши шейдеры, установить глобальные параметры, выбрать и включить различные буферы и т.д.).

Это также означает, что вы должны экономно использовать native painting. Если для каждого отдельного виджета будет выполняться пользовательское рисование, это может вскоре поставить ваш рендеринг на колени.