На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела *nix / gcc / Eclipse / Qt / wxWidgets / GTK+
  • При создании темы ОБЯЗАТЕЛЬНО указывайте версию тулкита / библиотеки / компилятора.
  • Перед тем как задать вопрос, сформулируйте его правильно, чтобы вас могли понять.
  • Нарушение Правил может повлечь наказание со стороны модераторов.


Полезные ссылки:
user posted image Boost по-русски
user posted image Qt по-русски
Модераторы: archimed7592
  
> Qt OpenGL VS "чистый openGL" , оценка производительности
    Добрый вечер. Вашему вниманию новая серия моих приключений в чудном мире WinCE.

    Кратко опишу задачу: на вход передается массив точек для отображения трека заданной и фиксированной ширины средствами OpenGL, конкретно нужно строить этот трек средствами TRIANGLE_STRIP. А чтобы жизнь не казалась сказкой этот трек нужно вращать в произвольном направлении (вокруг произвольно заданной оси вращения, со всеми вытекающими преобразованиями координат), масштабировать, перемещать, про такие мелочи как изменение цвета, ширины пера я умалчиваю. Ну и для полного счастья и максимального использования возможностей openGL будем применять шейдеры. Правда что это такое я узнал чуть более недели назад.
    Ладно, это не суть. В чем вопрос: имеется "эталонная программа", написанная на "голом openGL", демонстрирующая следующие результаты:
    ExpandedWrap disabled
      10k - 48 fps
      50k - 35 fps
      300k - 13 fps (масштаб по умолчанию), 8-9 fps масштаб, при котором все точки находятся в видимой области
      для 10k/50k масштаб значения не имеет

    Я предпринял две попытки реализации поставленной задачи на Qt.
    1) в QGraphicsView подсунул QGLWidget, в котором трек рисовал обычным QPainter в PaintGL. Для этого случая у меня все хорошо с построением самого трека, а также дополнительными плюшками, которые дает использование QGraphicsView/QGraphicsScene, но очень плохо с производительностью, возможно я избрал не самый верный подход - я брал несчастный QGraphicsPolygonItem и пихал в него силой все 300 000 точек. От чего ему, естественно, плохело. Ну и о производительности говорить не приходилось в этом случае. Для чистоты эксперимента запрещено думать об интерполяции, построении вместо полигона на 100 точек, лежащих на одной прямой этой самой прямой по двум точкам (я проводил эксперимент, у меня вместо 300 000 точек получилось около 800, ну и производительность, естественно выросла до космических скоростей). Я сейчас не понимаю что я курил, когда писал этот код, но не суть. Выглядит он, примерно, так:
    ExpandedWrap disabled
          void SnowWindow::populateScene()
          {
              m_trackScene = new QGraphicsScene(this);
              QString filename = QFileDialog::getOpenFileName(this, tr("open CSV data"), tr(""), tr("*.csv"));
              PointArray points = get_points(filename);
              // Populate scene
              QGraphicsPolygonItem *polygon_item = new QGraphicsPolygonItem;
              QPolygonF polygon;
              QVector2D point;
              int idx = 0;
              foreach (point, points) {
                  if((++idx % 100) == 0) {
                      QGraphicsSimpleTextItem *textItem = new QGraphicsSimpleTextItem;
                      textItem->setText("T");
                      textItem->setPos(point.toPointF());
                      textItem->setZValue(0.35);
                      m_trackScene->addItem(textItem);
                  }
                  polygon << point.toPointF();
              }
              polygon_item->setPolygon(polygon);
              QPen pen;  // creates a default pen
              pen.setStyle(Qt::SolidLine);
              pen.setWidth(3);
              pen.setBrush(QBrush(Qt::green, Qt::DiagCrossPattern));
              polygon_item->setPen(pen);
              polygon_item->setZValue(0.25);
              m_trackScene->addItem(polygon_item);
          }

    но на 300к точек выдает не более 4 fps. Есть ненулевая вероятность, что даже для этого варианта можно существенно повысить производительность, правда я не знаю как.
    Еще один вариант -уже с использованием шейдеров. Честно скажу, я долго курил этот мануал точнее весь курс, но видимо особых успехов не добился, ибо моя реализация выдает следующие результаты:
    10 000 точек - 48-70 FPS;
    50 000 - 17-25 FPS;
    100 000 - 11-15 FPS;
    200 000 - 7-11 FPS:
    300 000 - 4-5 FPS - во всех случаях независимо от масштаба. Весь код приводить не буду, скажу только, что после заполнения вершинами метод draw выглядит так:
    ExpandedWrap disabled
          void SnowTrack::drawTrueData()
          {
              m_program->setAttributeArray(m_vertexAttr, m_trueVertices.data(), 3);
              m_program->setAttributeArray(m_colorAttr, m_trueColors.data(), 3);
              m_program->enableAttributeArray(m_vertexAttr);
              m_program->enableAttributeArray(m_colorAttr);
              glDrawArrays(GL_TRIANGLE_STRIP, 0, m_trueVertices.size() / 3);
              m_program->disableAttributeArray(m_vertexAttr);
              m_program->disableAttributeArray(m_colorAttr);
          }

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

    ExpandedWrap disabled
      attribute highp vec4 vertexAttr;
      uniform mediump mat4 matrix;
      attribute lowp vec4 colorAttr;
      varying lowp vec4 color;
       
      void main()
      {
          gl_Position = matrix * vertexAttr;
          color = colorAttr;
      }

    в "эталонной" программе он сильно другой, но я так понимаю, что это влияет на положение вершин в пространстве, но никак не на производительность. Если я не прав, то тогда все совсем плохо. Хотя может и наоборот - все хорошо и я смогу догнать и перегнать америку.
    ExpandedWrap disabled
          const char* pszFragmentShader = "\
                                              precision mediump float;\
                                              varying vec4 trifragmentColor;\
                                              vec4 tricolor;\
                                              void main()\
                                              {\
                                                  gl_FragColor = trifragmentColor;\
                                          }";
       
          const char* pszVertexShader =   "\
                                              attribute vec3 trianglePosition_modelspace;\
                                              attribute vec3 triangleColor;\
                                              varying vec4 trifragmentColor;\
                                              uniform mat4 MVP;\
                                              void main()\
                                              {\
                                                  gl_Position = MVP * vec4(trianglePosition_modelspace, 1.0);\
                                                  trifragmentColor = vec4(triangleColor, 1.0);\
                                          }";


    Ну и отсюда вопрос к знающим людям: насколько реально получить средствами связки Qt OpenGL производительность аналогичную "голому OpenGL". По умолчанию предполагаем, что мой код, мягко говоря, не оптимален. Собственно для чего все это затевалось - показать, что средствами Qt можно обеспечить аналогичную производительность, а вместе с ней и все вкусности самого(ой?) Qt. Ибо писать на 03 стандарте меня не особо прельщает, да и сочинение очередной козы на лисапеде точно не добавит производительности приложению, будь оно даже на ассемблере написано. О скорости разработки и количестве багов даже подумать страшно. Но реалии таковы, что приходится выбирать. Сроки по доказательству производительности Qt стремительно мчатся к точке невозврата, а потому надеюсь на ваши мудрые советы, кои спасали меня здесь неоднократно.
      C qt5.4 вроде как с QGLWidget на QOpenGLWidget, QOpenGLWindow перекат был (сам мучился), https://doc.qt.io/archives/qt-5.5/examples-...ets-opengl.html https://doc.qt.io/qt-5.12/examples-widgets-opengl.html.
      Сообщение отредактировано: xVekx -
        в общем, как и предполагалось - дело было не в бобине. производительность удалось получить вполне вменяемую.
          Цитата kotmatroskin55 @
          kotmatroskin55

          Тема очень актуальная , подскажите ваше решение .
          Пробую QOpenGLWindow - Qt обрезает до 60 fps как не крути
          если через QGraphicsView/QGraphicsScene - тоже максимум 60 fps , но сильно падает при сложной отрисовке.
          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0569 ]   [ 16 queries used ]   [ Generated: 19.03.24, 05:32 GMT ]