Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.208.203.36] |
|
Сообщ.
#1
,
|
|
|
Добрый вечер. Вашему вниманию новая серия моих приключений в чудном мире WinCE.
Кратко опишу задачу: на вход передается массив точек для отображения трека заданной и фиксированной ширины средствами OpenGL, конкретно нужно строить этот трек средствами TRIANGLE_STRIP. А чтобы жизнь не казалась сказкой этот трек нужно вращать в произвольном направлении (вокруг произвольно заданной оси вращения, со всеми вытекающими преобразованиями координат), масштабировать, перемещать, про такие мелочи как изменение цвета, ширины пера я умалчиваю. Ну и для полного счастья и максимального использования возможностей openGL будем применять шейдеры. Правда что это такое я узнал чуть более недели назад. Ладно, это не суть. В чем вопрос: имеется "эталонная программа", написанная на "голом openGL", демонстрирующая следующие результаты: 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, ну и производительность, естественно выросла до космических скоростей). Я сейчас не понимаю что я курил, когда писал этот код, но не суть. Выглядит он, примерно, так: 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 выглядит так: 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); } а вершинный шейдер настолько примитивен, что даже самому грустно. attribute highp vec4 vertexAttr; uniform mediump mat4 matrix; attribute lowp vec4 colorAttr; varying lowp vec4 color; void main() { gl_Position = matrix * vertexAttr; color = colorAttr; } в "эталонной" программе он сильно другой, но я так понимаю, что это влияет на положение вершин в пространстве, но никак не на производительность. Если я не прав, то тогда все совсем плохо. Хотя может и наоборот - все хорошо и я смогу догнать и перегнать америку. 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 стремительно мчатся к точке невозврата, а потому надеюсь на ваши мудрые советы, кои спасали меня здесь неоднократно. |
Сообщ.
#2
,
|
|
|
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.
|
Сообщ.
#3
,
|
|
|
в общем, как и предполагалось - дело было не в бобине. производительность удалось получить вполне вменяемую.
|
Сообщ.
#4
,
|
|
|
Цитата kotmatroskin55 @ kotmatroskin55 Тема очень актуальная , подскажите ваше решение . Пробую QOpenGLWindow - Qt обрезает до 60 fps как не крути если через QGraphicsView/QGraphicsScene - тоже максимум 60 fps , но сильно падает при сложной отрисовке. |