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

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

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


person dan    schedule 12.04.2011    source источник


Ответы (2)


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

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

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

person Steffen    schedule 12.04.2011
comment
я видел этот пример, но нет программы (в qt examples/demos/nokia-forum), которая бы его использовала... и мне интересно, действительно ли это полезно, или есть другой способ сделать это. 2. если я собираюсь использовать его для множества виджетов в приложении, я могу поместить beginNativePainting() в ctor QWidget... и endNativePainting() в dtor? ..... это действительно полезно, когда у меня много виджетов? - person dan; 12.04.2011
comment
Платформа Qt предоставляет вам QPainter в качестве параметра метода paintEvent() вашего QWidget. Использование begin/endNativePainting() имеет смысл только внутри этого метода (пока существует QPainter). Таким образом, вы не можете просто вызвать beginNativePainting() в ctor (для чего?). Если вы не уверены, что делаете, я бы посоветовал просто использовать QPainter для рисования и игнорировать begin/endNativePainting(). Только если вы столкнетесь с какой-то проблемой, которую не можете решить с помощью Qt API, возможно, пришло время пересмотреть свое решение. (Если все, что вам нужно, это использовать OpenGL, вы можете взглянуть на графические системы Qt.) - person Steffen; 12.04.2011
comment
я должен использовать opengl, чтобы улучшить производительность .... я не хочу знать, как это лучше всего сделать, не меняя много частей в моем коде виджетов. - person dan; 12.04.2011
comment
Так вы вообще не используете OpenGL в данный момент? Тогда begin/endNativePainting() для использования собственных вызовов OpenGL все равно не будет работать. Попробуйте запустить приложение с -graphicssystem opengl в качестве (дополнительного) параметра командной строки. Это переключает бэкэнд рендеринга Qt по умолчанию на OpenGL, никаких изменений в вашем коде не требуется. Если это сработает и станет заметно (или, по крайней мере, заметно) быстрее, вы можете изменить инициализацию своего приложения, чтобы установить серверную часть по умолчанию с чем-то вроде QApplication::setGraphicsSystem(opengl), см. doc.trolltech.com/4.7/qapplication.html#setGraphicsSystem - person Steffen; 12.04.2011
comment
я использую это, но я получил ошибку: QGLFramebufferObject: Framebuffer неполное вложение. Не удалось создать буфер пиксельной текстуры размера QSize(158, 17), возврат к растровому движку рисования - person dan; 12.04.2011
comment
Хм. Похоже, что-то не так с поддержкой Qt OpenGL на вашей платформе. Вам нужно сначала заставить это работать, прежде чем что-либо из обсуждаемого здесь материала будет иметь какой-либо смысл. Я бы сказал, попробуйте решить это в другом вопросе, если это необходимо, предоставив больше информации об окружающей среде. Если вы не зациклены на OpenGL, вы также можете попробовать растр -graphicssystem. На многих устройствах это дает лучшую производительность, чем собственный бэкенд. - person Steffen; 12.04.2011

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

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

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

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

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

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

person kuroi neko    schedule 11.05.2014