Проблема с производительностью при использовании QGLWidget с Qt5 - PullRequest
0 голосов
/ 19 ноября 2018

Я пытаюсь разработать приложение, которое будет использоваться для визуализации трехмерных объектов и их моделирования. В этом я должен нарисовать 'n' количество объектов (может быть треугольник, прямоугольник или некоторые другие невыпуклые многоугольники) с отдельными цветовыми оттенками. Для этого я использую QGLWidget в Qt5 (OS - Windows 7/8/10) ).

структура, используемая для заполнения информации об объектах:

typedef struct {
  QList<float> r,g,b;
  QList<double> x,y,z;
}objectData;

Количество объектов и соответствующие им значения координат будут считаны из файла.

функция paintGL:

void paintGL() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(25, GLWidget::width()/(float)GLWidget::height(), 0.1, 100);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0,0,5,   0,0,0,   0,1,0);
    glRotatef(140, 0.0, 0.0, 1.0);
    glRotatef(95, 0.0, 1.0, 0.0);
    glRotatef(50, 1.0, 0.0, 0.0);
    glTranslated(-1.0, 0.0, -0.6);
    drawObjects(objData, 1000)
}

Функция рисования объектов:

void drawObjects(objectData objData,int objCnt) {
    glPushMatrix();
    glBegin(GL_POLYGON);
    for(int i = 0; i < objCnt; i++) {
        glColor3f(objData.r[i],objData.g[i],objData.b[i] );
        glVertex3d(objData.x[i],objData.y[i],objData.z[i]);
    }
    glEnd();
    glFlush();
    glPopMatrix();
}

Проблема: Теперь, когда количество нарисованных объектов превышает определенное максимальное значение (например, скажем, n = 5000), скорость нанесения постепенно уменьшается. Я не могу использовать QThread, поскольку он уже наследует QGLWidget.

Подскажите, пожалуйста, как повысить производительность приложения, когда количество объектов больше. Я не знаю, где я делаю ошибку.

Скриншот этого образца:

Пример изображения, которое содержит количество объектов в виде сетки

Ответы [ 3 ]

0 голосов
/ 19 ноября 2018

Вы используете фиксированный конвейер вместо программируемого, где вы говорите каждому этапу процесса рендеринга, что должно быть сделано, и больше ничего.Среди других заметных отличий, которые я призываю вас исследовать (исследуйте «современный opengl», который приведет вас к выполнению работы OpenGL 3.3 и выше).

Старый фиксированный конвейер ужасно неэффективен, когда компьютер имеетразговаривать с видеокартой для каждой геометрии во время рендеринга.В отличие от этого, современный программируемый конвейер позволяет передавать данные моделей для рендеринга в VRAM, откуда они будут напрямую доступны во время рендеринга (очень быстрый доступ к памяти).

Вы также избавляетесь от общих способов «делать вещи», которые механически медленнее, чем индивидуальные.

Также я рекомендую вам использовать QOpenGLWidget вместо прежнего класса QGLWidget.Как уже упоминалось в http://doc.qt.io/qt-5/qglwidget.html,, этот класс устарел.

Современный быстрый запуск OpenGL:

http://www.opengl -tutorial.org /

Итак, вы не делаете ничего «неправильного».Вы просто не используете текущую технологию.Веселись!

0 голосов
/ 20 ноября 2018

Спасибо @dave и @ Zedka9. Это прекрасно работает для меня, когда я начал использовать промежуточный режим в openGL. Я изменил функцию drawObject следующим образом

Функция рисования объектов:

После организации и копирования вершин и цветов в эти буферы

GLfloat вершин [1024 * 1024], цвета [1024 * 1024];

int vertArrayCnt; // количество вершин

void drawObjects(void) {
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);
    glColorPointer(3, GL_FLOAT, 0, colors);
    glVertexPointer(3, GL_FLOAT, 0, vertices); 
    glPushMatrix();
    glDrawArrays(GL_TRIANGLES, 0, vertArrayCnt); 
    glPopMatrix();
    glDisableClientState(GL_VERTEX_ARRAY);  // disable vertex arrays
    glDisableClientState(GL_COLOR_ARRAY);
}
0 голосов
/ 19 ноября 2018

Вы используете OpenGL немедленный режим , который очень медленный для большого количества вершин и почти никогда не должен использоваться.Вместо этого используйте режим сохранения .Смотрите этот ответ для более подробной информации: https://stackoverflow.com/a/6734071

...