PyOpenGL 渲染优化

1 投票
1 回答
648 浏览
提问于 2025-04-18 07:36

我正在寻找一种方法来优化我的代码,这段代码是用来显示一个行星的。实际上,我想旋转我的相机,以便查看行星的不同部分,但这个过程非常慢,耗时很长。

以下是我使用pyOpenGL的代码的一部分,它用来绘制我的不同对象:

def _DrawGLScene(self):
    if not self.printed:
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glLoadIdentity()
    # Camera movements
    glTranslatef(0.0, 0.0, self.move_z)
    glRotatef(self.rx, 1.0, 0.0, 0.0)
    glRotatef(self.ry, 0.0, 1.0, 0.0)
    glRotatef(self.rz, 0.0, 0.0, 1.0)
    # Print objects
    if not self.printed:
        self.planet.draw()
        self.printed = True
    glutSwapBuffers()

这个方法 self.planet.draw() 只是用它自己的 draw_triangle 方法来绘制一个三角形对象列表,定义如下:

def draw_triangle(self):
    glBegin(GL_POLYGON)
    glColor3f(self.color_a[0], self.color_a[1], self.color_a[2])
    glVertex3f(self.point_a[0], self.point_a[1], self.point_a[2])
    glColor3f(self.color_b[0], self.color_b[1], self.color_b[2])
    glVertex3f(self.point_b[0], self.point_b[1], self.point_b[2])
    glColor3f(self.color_c[0], self.color_c[1], self.color_c[2])
    glVertex3f(self.point_c[0], self.point_c[1], self.point_c[2])
    glEnd()
    return

当我旋转相机时,我必须重新绘制所有的三角形,这对于大约100,000个三角形来说真的很慢。我该如何优化OpenGL的使用呢?

1 个回答

1

你可以使用不同层次的优化方法。

一个非常简单的改动,可能会对你有很大帮助,就是不要在每个三角形周围都加上glBegin(..)glEnd()。另外,使用GL_TRIANGLES代替GL_POLYGON作为基本图形类型也可能会更好。听起来你现在的代码结构大概是这样的:

draw_triangle
    glBegin(GL_POLYGON)
    // specify colors, vertices
    glEnd()

draw
    loop over triangles
        draw_triangle

你应该改成这样:

draw_triangle
    // specify colors, vertices

draw
    glBegin(GL_TRIANGLES)
    loop over triangles
        draw_triangle
    glEnd()

如果想把事情提升到一个新层次,你需要了解一些更现代的方法。你现在使用的像glBeginglEndglVertex这样的调用方式,通常被称为“即时模式”绘图,这在更新版的OpenGL中已经不推荐使用了。

如果你搜索“顶点缓冲对象”(通常缩写为“VBO”)和“顶点数组对象”(“VAO”),你应该能找到一些很好的教程,教你如何使用这些功能。你将会使用像glGenBuffersglBindBufferglGenVertexArraysglBindVertexArrayglVertexAttribPointer等调用。这些方法可以让你的绘图效率大大提高。

撰写回答