Название: Оптимизация отрисовки сцены Отправлено: Fregloin от Август 17, 2011, 14:43 Народ, подскажите как грамотно оптимизировать скорость отрисовки сцены.
Имеется сцена, на которой порядка тысячи элементов, различной сложности, от примитивных кружков до довольно сложных полигонов, рисунки, виджеты (не много правда). Проблема в том, что: -сцена будет отображаться на мониторах большого разрешения (даже на нескольких мониторах одновременно) -на сцене по ходу перемещения мыши нужно будет рисовать стрелку от определенного места до текущей позиции курсора (реализовал через QGraphicsItem, в котором пересчитываю координаты точек и по ним рисую красивую стрелку-указатель) -эта стрелка рисоваться должна поверх всех объектов, и поэтому когда курсор провожу через весь экран, затрагивается вся сцена -многие элементы нужно обновлять (в зависимости от режима работы, от текущего состояния объекта). Сейчас в моем view стоят такие флаги в конструкторе: Код: QEditorView::QEditorView(QWidget *parent) : Мне кажется, нужно копать в сторону update(x,y,...). Раньше над оптимизацией не задумывался, так как стояла задача написать движок. Сейчас движок готов на 95%, и в целом функционален, но тормозит (при использовании FullViewportUpdate). Заманчивым выглядит MinimalViewportUpdate, SmartViewportUpdate - но в этих режимах наблюдаю артефакты, зато скорость очень быстрая). Кто подскажет, как грамотно работать с этими двумя режимами? Название: Re: Оптимизация отрисовки сцены Отправлено: GreatSnake от Август 17, 2011, 15:09 BoundingRectViewportUpdate пробовал?
Зачем используешь DontAdjustForAntialiasing? Или в QGraphicsItem::boundingRect() сам увеличиваешь границы элемента? Если нет, то будут артефакты. Цитировать иногда за мышью остаются артефакты прорисовки, стрелка-указатель при перемещении мыши не всегда отрисовывается. Проверь boundingRect() элемента стрелки.Цитировать setCacheMode(QGraphicsView::CacheBackground); Как рисуешь подложку? Кеширование может даже очень сильно тормозить.Нужно иметь ввиду что при отрисовке такой стрелки через всю сцену и особенно при масштабировании тормоза будут в любом случае. Избежать их можно только отрисовкой стрелки поверх окна минуя QGraphicsScene, но сделать это не так-то просто. Название: Re: Оптимизация отрисовки сцены Отправлено: Fregloin от Август 17, 2011, 16:33 я уже думал, поверх одного view, расположить другой view с пустой сценой, на которой рисовать указатель буду. но тогда все события нужно будет как то перенаправлять на view, который находится ниже. и опять, не факт, что рисование указателя не вызовет отрисовку нижней сцены.
Название: Re: Оптимизация отрисовки сцены Отправлено: Fregloin от Август 17, 2011, 16:40 вот прилагаю картину с артефактами (картина одинаковая в режимах minimal и bounding).
Название: Re: Оптимизация отрисовки сцены Отправлено: Fregloin от Август 17, 2011, 16:41 при чем, когда я вожу указатель, он отрисовывается только в тех случаях, когда конечная точка находится ниже и правее начальной, иначе не рисуется вообще.
Название: Re: Оптимизация отрисовки сцены Отправлено: GreatSnake от Август 17, 2011, 16:54 при чем, когда я вожу указатель, он отрисовывается только в тех случаях, когда конечная точка находится ниже и правее начальной, иначе не рисуется вообще. Как реализована стрелка?Название: Re: Оптимизация отрисовки сцены Отправлено: Fregloin от Август 17, 2011, 17:01 это QGraphicsItem, в котором есть массив точек (просчитываю в отдельной процедуре), в методе update рисую полигон по этим точкам.
для расчета нужна начальная и конечная точка (в координатах сцены), сам итем по сути покрывает всю сцену, и рисуется в позиции (0,0) Код: class QRouteArrow : public QRailItem и вот часть реализации Код: QRouteArrow::QRouteArrow(bool Init, QGraphicsItem *parent): Название: Re: Оптимизация отрисовки сцены Отправлено: GreatSnake от Август 17, 2011, 17:05 это QGraphicsItem, в котором есть массив точек (просчитываю в отдельной процедуре), в методе update рисую полигон по этим точкам. и какой boundingRect() у него?для расчета нужна начальная и конечная точка (в координатах сцены), сам итем по сути покрывает всю сцену, и рисуется в позиции (0,0) Название: Re: Оптимизация отрисовки сцены Отправлено: Fregloin от Август 17, 2011, 17:11 вот, я тупанул, исправил
Код: QRectF QRouteArrow::boundingRect() const Название: Re: Оптимизация отрисовки сцены Отправлено: GreatSnake от Август 17, 2011, 17:14 В общем у тебя неправильный расчёт границ элемента. Не учитываются размер "наконечника" стрелки и толщина линии.
Причём при сглаживании нужно учитывать, что толщина линии будет больше. Название: Re: Оптимизация отрисовки сцены Отправлено: Fregloin от Август 17, 2011, 17:17 добавить adjusted в rect?
Название: Re: Оптимизация отрисовки сцены Отправлено: GreatSnake от Август 17, 2011, 17:20 добавить adjusted в rect? Наверное)Зачем используешь DontAdjustForAntialiasing? Или в QGraphicsItem::boundingRect() сам увеличиваешь границы элемента? Если нет, то будут артефакты. Не ответил на вопрос.Название: Re: Оптимизация отрисовки сцены Отправлено: Fregloin от Август 17, 2011, 17:29 на счет adjust не уверен, что есть смысл его добавлять (по крайней мере пока ни на что не влияет, а линия у меня не интеркативный элемент - она только отображается).
на счёт fontadjusting - не помню, в самом начале выставил, когда только разбирался с view/scene. впрочем я его убрал, никакой разницы не заметил. сейчас конечно работать стало на порядок быстрее, но будет ли корректно прорисовываться сцена при частой принудительной перерисовке отдельных итемов (вызовом update, сменить цвет например)? Название: Re: Оптимизация отрисовки сцены Отправлено: Igors от Август 18, 2011, 06:47 Если стрелка "поверх" всех айтемов, то и рисовать ее надо на отдельном слое/пиксмапе, а потом "собирать" (как здесь говорят). С такой мышачьей активностью без слоев все равно не обойтись.
Избежать их можно только отрисовкой стрелки поверх окна минуя QGraphicsScene, но сделать это не так-то просто. Завести еще одну QGraphicsScene, в ней рисовать только мышиные айтемы, рендерить и результат класть на первуюНазвание: Re: Оптимизация отрисовки сцены Отправлено: Fregloin от Август 18, 2011, 12:46 в принципе и так работает, но тут вылазит ньюанс, при движении стрелкой-указателем, мне при клике по сцене нужно отловить, на каком итеме я кликнул. и часто возникает ситуация, что itemAt() возвращает мне указатель на стрелку(так как она рисутеся поверх всех), а мне нужно узнать какой итем под ней. Как этого добиться?
Название: Re: Оптимизация отрисовки сцены Отправлено: GreatSnake от Август 18, 2011, 12:49 Используй items() и игнорируй стрелку.
Название: Re: Оптимизация отрисовки сцены Отправлено: mal от Август 23, 2011, 15:21 Динамику рисовать в drawForeground - намного быстрее выходит, чем использовать айтем, всобаченый на сцену. Это про вашу стрелку от места нажатия до текущего положения курсора.
Плюс QGLWidget. Название: Re: Оптимизация отрисовки сцены Отправлено: Fregloin от Август 23, 2011, 21:16 я так и подозревал, попробую на днях.
на счёт GL я создам новую тему и опишу некоторые трудности с его использованием. |