Russian Qt Forum
Ноябрь 27, 2024, 21:01 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QGraphicsScene + QGraphicsView + десятки тысяч QGraphicsItem  (Прочитано 6287 раз)
vintik
Гость
« : Август 20, 2011, 21:37 »

Всем привет!
Наверное, многие видели кутешную демку с чипами. Если не ошибаюсь в этой демке сцена содержит около 40 тысяч одинаковых
итемов. Для отображения итемов применяется QGraphicsView, у которого в качестве вьюпорта используется обычный или GL виджет.
Вид можно вращать и масштабировать. Проблема в том, что вся эта красота сильно тормозит. Особенно это эаметно
при маленьком масштабе, когда в виде отображаются все итемы.

Вопрос:
есть ли способы борьбы с тормозами, когда на сцене так много объектов?

Сразу оговорюсь, делал некий тестовый пример, где на сцену добавлял порядка 50 тысяч простейших итемов (унаследованы от QGraphicsItem, переопределены paint, boundingRect, shape). Итемы должны сохранять способность принимать события мыши. Вид должен иметь возможность для перемещения и масштабирования. Пример собирал на разных машинах, под разными осями, с разными версиями Qt и разными видеокартами и драйверами к ним. ВЕЗДЕ наблюдались тормоза при маленьком масштабе, когда все итемы отображены в области экрана. Пробовал различные варианты оптимизирующих флагов для сцены и вида, найти оптимальную комбинацию не удалось... Может кому-то повезло больше?)) поделитесь опытом)
Записан
Sancho_s_rancho
Гость
« Ответ #1 : Август 21, 2011, 09:26 »

Нет. Столько item-ов будут с вечными тормозами. Они и в демке успешно тормозят. Вам скорее всего надо делать свое решение, с уровнем детализации, зависящей от масштаба.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Август 21, 2011, 11:48 »

Я бы двигался в таком направлении

- отключил анти-алиас и посмотрел не порылась ли там собака

- попробовал рисовать через glBegin(GL_QUADS). Потому что на 50К полигонов тормозов быть не должно даже на допотопных картах. Если это пройдет - то порубать айтемы на triangles (для вывода), и все дела
Записан
vintik
Гость
« Ответ #3 : Август 27, 2011, 21:05 »

Спасиб за  ответы)

Igors, я правильно понял мысль?

void PointItem::paint(QPainter *_painter, const QStyleOptionGraphicsItem *_option, QWidget *_widget)
{
  Q_UNUSED(_widget);               
  Q_UNUSED(_painter);               
  Q_UNUSED(_widget);                 
 
  glPointSize(10);
  glBegin(GL_POINTS);
  glVertex2f(0, 0);
  glEnd();
}

И соответственно рисование в QGLWidget: view->setViewport(new QGLWidget(QGLFormat()));
Такой подход ничего не дал, тормозит с пержней силой... или тут вся соль в рисовании итема по частям (разбивать на triangles)?
Если да, то где можно нарыть пример такого подхода?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Август 28, 2011, 08:51 »

Поняли правильно. Попробуйте сделать всего 1 айтем но с 50К полигонов, напр quadrangles - это не должно тормозить, по крайней мере без AA.
Записан
vintik
Гость
« Ответ #5 : Август 28, 2011, 11:01 »

Поняли правильно. Попробуйте сделать всего 1 айтем но с 50К полигонов, напр quadrangles - это не должно тормозить, по крайней мере без AA.
Да! Это действительно работает! Но тогда как действовать, если мне необходимо, чтобы каждый из этих 50К полигонов мог принимать события мыши и реагировать на него отдельно от других полигонов?
Вообщем, вёл бы себя как самостоятельный итем.
Может быть мне нужно вникнуть вот в эту фразу? Улыбающийся

Если это пройдет - то порубать айтемы на triangles (для вывода), и все дела

Пока, если честно, не очень-то получается...)
« Последнее редактирование: Август 28, 2011, 12:26 от vintik » Записан
vintik
Гость
« Ответ #6 : Август 28, 2011, 22:10 »

появилась такая мысль: итемы создавать и добавлять на сцену обычным образом, а потом отрисовывать их
в переоперделённом методе drawItems() сцены.

Код
C++ (Qt)
void MуScene::drawItems(
   QPainter *painter,
   int numItems,
   QGraphicsItem *items[],
   const QStyleOptionGraphicsItem options[],
   QWidget *widget)
{
 glPointSize(4);
 glBegin(GL_POINTS);
 glColor3f(0, 0, 0);
 QPointF pnt;
 for (int i = 0; i < numItems; ++i)
 {
   pnt = items[i]->mapToScene(QPointF(0, 0));
   glVertex2f(pnt.x(), pnt.y());
 }
 glEnd();
}

Товарищи) подскажите, правильная идея?
может быть, есть подводные камни при таком подходе?
« Последнее редактирование: Август 28, 2011, 22:12 от vintik » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Август 29, 2011, 10:58 »

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

Интересно, а что показывает профайлер, где съедается все время?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.092 секунд. Запросов: 23.