将QGLWidget与Qt5一起使用时的性能问题

时间:2018-11-19 07:08:45

标签: qt opengl qglwidget

我正在尝试开发一个将用于3D对象及其模拟的可视化的应用程序。在这种情况下,我必须绘制具有单个颜色阴影的n个对象(可能是三角形,矩形或其他非凸多边形)。为此,我在Qt5(OS-Windows 7/8/10)中使用QGLWidget )。

用于填充对象信息的结构:

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 :(得分:2)

您使用的是固定管线,而不是可编程管线,您在管线中告知渲染过程的每个阶段,应该做什么,仅此而已。我鼓励您研究其他明显的差异(研究“现代opengl”,这将使您进行OpenGL 3.3及更高版本的工作)。

当计算机在渲染时必须为每个几何图形与图形卡通信时,旧的固定管道效率极低。相比之下,现代的可编程管线允许您将模型的数据推送到VRAM中,在渲染过程中可以从那里直接访问数据(非常快速的内存访问)。

您还摆脱了“做事”的一般方法,这些方法在机械上比自定义方法慢。

此外,我鼓励您使用QOpenGLWidget而不是以前的QGLWidget类。如http://doc.qt.io/qt-5/qglwidget.html中所述,该类已过时。

现代OpenGL快速入门:

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

因此,您没有做任何“错误”的事情。您只是没有使用当前技术。玩得开心!

答案 1 :(得分:1)

您正在使用OpenGLs 立即模式,这对于大量顶点来说非常慢,因此几乎永远不要使用。请使用保留模式。有关更多详细信息,请参见以下答案:https://stackoverflow.com/a/6734071

答案 2 :(得分:0)

谢谢@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);
}