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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Помогите с архитектурой графической части приложения  (Прочитано 8883 раз)
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« : Апрель 22, 2013, 12:21 »

Доброго дня! Подскажите, какими средствами Qt можно добиться максимально быстрой скорости отрисовки следующей информации:
1.   матрицы данных (2400х4096, которая обновляется с периодичностью в 12 ms, т.е. по индексу от 0 до 4096 приходит массив новых данных размером 2400). Отрисовывать можно и нужно конечно реже.
2.   Сетки, которая меняется только при изменении масштаба.
3.   10-ки тыс.!!! меток в виде простых точек
4.   Сектора, полигоны, простые значки (квадратики, кружочки). В сумме пару 10ков.  
+ масштабирование, панорамирование.
Как пробовал реализовывать:
1.   На QGraphicsScene рисовать матрицу в отдельный items или drawBackground() в QImage и выводить painter->drawImage(). Заполнял QImage по индексу setPixel(). Заполняется/рисуется довольно шустро, пока не начинаешь рисовать метки..
2.   Рисовать каждую метку в отдельным item оказалось вообще не вариант, начинает тормозить уже после пару тысяч объектов. Метку рисовал drawPoint(). Сделать один item на всю сцену и в нем циклом рисовать по нужным координатам все точки, тоже начинает тормозить, но уже после 10 тыс точек.. медленно.
Следующий вариант был рисовать поверх матрицы картинку QImage::Format_ARGB32_Premultiplied и в ней подсвечивать нужные пиксели имитирую метку… такой вариант как наиболее быстрый и предлагался в google по моей задаче. НО как только делался scale() QGraphicsView, то все останавливалось и именно из-за прозрачности картинки… без нее масштабируется все шустро!

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

3.   Естественно не обошел и OpenGL, пока на нем и остановился. Но пробовал выводить опять же в сцене на QGLWidget. В плане вывода меток да, рисует быстрее. Если в drawForeground() выводить 52 441 точек таким образом, то масштабирование осуществляется приемлемо
Код:
 
   for(double i = -80.0; i < 80; i+= 0.7)
          for(double j = -80.0; j < 80; j+= 0.7)
          {
                glColor3f(0.0,0.0,1.0);
                glPointSize(3);
                glBegin(GL_POINTS);
                    glVertex2f(i,j);
                glEnd();
          }
           но здесь возникает вопрос как вывести матрицу.. т.е. нужно как-то рисовать           картинку на QGLWidget. painter->drawImage() не пойдет потому что тормозит дико.. Пробовал выводить функцией glDrawPixels(), но не очень получилось.. вроде картинка рисовалась но в каких-то непонятных масштабах и непонятно как располагалась на сцене.  Может кто сведущ в OpenGL и может помочь?
Либо есть еще способы или я что-то делал не так. Буду рад любому совету! Прикреплю файл с последним тестовым проектом с OpenGL.
 
Записан
_OLEGator_
Гость
« Ответ #1 : Апрель 22, 2013, 12:31 »

Порекомендовал бы задействовать фильтрацию видимой информации. На маленьких масштабах точки могут сливаться и рисовать их всех не имеет смысла, нужно прореживать. Соответственно на больших масштабах не вся информация попадает на экран и фильтровать надо данные, попадающие за экран.
« Последнее редактирование: Апрель 22, 2013, 12:32 от _OLEGator_ » Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #2 : Апрель 22, 2013, 12:39 »

Порекомендовал бы задействовать фильтрацию видимой информации. На маленьких масштабах точки могут сливаться и рисовать их всех не имеет смысла, нужно прореживать. Соответственно на больших масштабах не вся информация попадает на экран и фильтровать надо точки, попадающие за экран.

Согласен. Это правильно. Но какими средствами рисовать эти точки и матрицу? При максимальном масштабе (скорее минимальном, когда видна вся область отрисовки) спокойно отображется более 10 тыс точек.. в облати видимости размером 900х900, это без секторов, зон и т.д. и уже начинает тормозить, если рисовать отдельными items на сцене.
« Последнее редактирование: Апрель 22, 2013, 12:40 от Vladimir » Записан
_OLEGator_
Гость
« Ответ #3 : Апрель 22, 2013, 12:43 »

Одним элементом рисовать все точки.
Я пока не понимаю необходимости использования QGraphicsScene. Я бы переопределил отрисовку QWidget (QGLWidget), а манипуляции с масштабом и перемещением делаются легко.
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #4 : Апрель 22, 2013, 12:57 »

Одним элементом рисовать все точки.
Я пока не понимаю необходимости использования QGraphicsScene. Я бы переопределил отрисовку QWidget (QGLWidget), а манипуляции с масштабом и перемещением делаются легко.

Так а есть принципиальная разница, ведь в  QGraphicsScene тоже контекст рисования QGLWidget?! ну может и так попробовать, тогда как быстрее всего отрисовать матрицу на QGLWidget? Понятно, что точки  glVertex2f рисуются быстро.. но OpenGL капризная штука, в зависимости от установленных дров на видеокарту.. даже qt-е 40 000 чипов очень по разному рисуются на разных машинах в режиме OpenGL, поэтому склонялся больше к QGraphicsScene.
Записан
_OLEGator_
Гость
« Ответ #5 : Апрель 22, 2013, 15:31 »

QGraphicsScene массивный слишком, если не требуется его функциональности, кроме как отрисовать, передвинуть, масштабировать - я бы воспользовался ручной отрисовкой. На счет QGLWidget все верно, это скорее не от видеокарты зависит - сейчас они вполне мощные даже встроенные. Зависит от дров, потому что на винде под OpenGL стоят самые простейшие, из-за которых все медленно.
Я проводил тесты - на QGLWidget'e простой QPainter рисует быстрее, при условии обновленных дров под OpenGL.
Данные то какие у тебя? Матрица это что такое, просто сетка, таблица?
Прикрепил бы скрин чтоли, чтобы понятнее было.
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #6 : Апрель 22, 2013, 16:16 »

QGraphicsScene массивный слишком, если не требуется его функциональности, кроме как отрисовать, передвинуть, масштабировать - я бы воспользовался ручной отрисовкой. На счет QGLWidget все верно, это скорее не от видеокарты зависит - сейчас они вполне мощные даже встроенные. Зависит от дров, потому что на винде под OpenGL стоят самые простейшие, из-за которых все медленно.
Я проводил тесты - на QGLWidget'e простой QPainter рисует быстрее, при условии обновленных дров под OpenGL.
Данные то какие у тебя? Матрица это что такое, просто сетка, таблица?
Прикрепил бы скрин чтоли, чтобы понятнее было.

В том то и дело, что программу предполагается юзать под двумя ОС Linux и Win и как обстоят дела с настройкой дров под Linux под максимальную производительность OpenGL я малопредставляю. Но это нужно тестить и проверять, для начала хотелось бы сделать кросплатформенный метод отрисовки вышеописанного.
Что касается матрицы, то это массив цветовых значений по ширине 4096 и высотой 2400, каждые 12 ms приходят данные data[2400] и заполняют постепенно весь прямоугольник от 0 до 4096. На скрине данные заполняются рандомом(по яркости) зеленым цветом. Эти данные нужно писать в некий битмап (либо еще как-то..) и раз в 50-60 ms отрисовывать на экране в виде подложки.. как это реализовать на QGLWidget'e?

Как было описано, я пробовал рисовать в QImage(2400,4096), а потом сценой масштабировать данную подложку.. сначала уменьшал, чтобы она влазила в область просмотра, а если нужно уточнить данные приближал(увеличивал)! И сцена делает это достаточно шустро без отрисовки всего остального, тобишь меток.. с выводом меток все начинает тормозить! Грустный
« Последнее редактирование: Апрель 22, 2013, 16:22 от Vladimir » Записан
_OLEGator_
Гость
« Ответ #7 : Апрель 22, 2013, 16:23 »

Все равно эти данные в картинку преобразовывать надо (возможно в потоке, чтобы не морозить интерфейс). Либо вручную, либо напрямую:
Код
C++ (Qt)
QImage::fromData( ... )
QPixmap::loadFromData( ... )
А дальше рисуй, картинка QPainter'ом рисуется быстро, 30 fps должна держать.
По поводу QGLWIdget'a еще раз повторю - та же самая отрисовка QPainter'ом на QGLWidget'e идет с аппаратным ускорением, т.е. это не тоже самое что рисовать на QWidget. Условие - что дрова стоят не самые древние и примитивные, на винде по умолчанию идут древние дрова.
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #8 : Апрель 22, 2013, 16:30 »

Все равно эти данные в картинку преобразовывать надо (возможно в потоке, чтобы не морозить интерфейс). Либо вручную, либо напрямую:
Код
C++ (Qt)
QImage::fromData( ... )
QPixmap::loadFromData( ... )
А дальше рисуй, картинка QPainter'ом рисуется быстро, 30 fps должна держать.
По поводу QGLWIdget'a еще раз повторю - та же самая отрисовка QPainter'ом на QGLWidget'e идет с аппаратным ускорением, т.е. это не тоже самое что рисовать на QWidget. Условие - что дрова стоят не самые древние и примитивные, на винде по умолчанию идут древние дрова.

Т.е. Вы предлагаете на QGLWIdget данную матрицу отрисовывать painter->drawImage(), а метки рисовать glVertex2f(i,j); как точка? Это все можно отрисовывать в paintGL()?
Записан
_OLEGator_
Гость
« Ответ #9 : Апрель 22, 2013, 16:43 »

Нет, я для начала предлагаю отрисовать все с помощью QPainter на QWidget с фильтрацией, потом посмотреть на скорость. Просто изменить с QWidget на QGLWidget и посмотреть скорость. Механизм отрисовки не изменяется, вообще после фильтрации должно все быстро рисоваться, вся загвоздка в избыточном количестве точек на экране.
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #10 : Апрель 22, 2013, 17:02 »

Нет, я для начала предлагаю отрисовать все с помощью QPainter на QWidget с фильтрацией, потом посмотреть на скорость. Просто изменить с QWidget на QGLWidget и посмотреть скорость. Механизм отрисовки не изменяется, вообще после фильтрации должно все быстро рисоваться, вся загвоздка в избыточном количестве точек на экране.

Так их действительно много и они вполне могут не перекрываться. Точки образуют трассы, которые могут рисоваться разными зигзагами и вполне не перекрывать друг друга. Понятно, что 50 000 это перебор и его нужно фильтровать, но отрисовка даже 10 тыс на минимальном масштабе вполне может быть.. это потенциально возрастающий цикл + проверка на нужно/ненужно рисовать.
Понятно, что нужно тестировать смотреть. И не последний момент какими средствами отрисовывать в paintEvent(): drawPoint() и drawImage(), какими методами рисовать быстрее?
« Последнее редактирование: Апрель 22, 2013, 17:06 от Vladimir » Записан
_OLEGator_
Гость
« Ответ #11 : Апрель 22, 2013, 17:11 »

Точки гарантированно поверх матрицы попадают?
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #12 : Апрель 22, 2013, 17:19 »

Точки гарантированно поверх матрицы попадают?

Да. Матрица меняется/заполняется данными(заполняет весь прямоугольник, затем сначала пишет новые данные), точки появляются удаляются над этой подложкой(матрицей).
Записан
_OLEGator_
Гость
« Ответ #13 : Апрель 22, 2013, 17:23 »

У меня больше идей нету. Разумным кажется рисовать матрицу через картинку, только я бы заполнял картинку напрямую из сырых данных, а не через setPixel и также точки через картинку.
Прикрепи минимальный проект с такой реализацией, чтобы погонять и посмотреть что там за тормоза при масштабировании.
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #14 : Апрель 22, 2013, 17:27 »

У меня больше идей нету. Разумным кажется рисовать матрицу через картинку, только я бы заполнял картинку напрямую из сырых данных, а не через setPixel и также точки через картинку.
Прикрепи минимальный проект с такой реализацией, чтобы погонять и посмотреть что там за тормоза при масштабировании.

Хорошо повырезаю все лишнее и сегодня/завтра скину проект, чтобы было более нагляднее! Спасибо, что откликнулся Улыбающийся
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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