#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. Если для каждого отдельного виджета будет выполняться пользовательское рисование, это может вскоре поставить ваш рендеринг на колени.