使用 VBO 时出现奇怪的性能问题

问题描述

我正在使用 pyopengl 库在屏幕上渲染 2D 四边形:

class RenderElement:
    def __init__(self,surf=None,coords=(0,0),scale=None,rect=None,id=None,width=0,height=0,texture_size=None):
        # Unnecessary code skipped

        self.buffer = glGenBuffers(1)
        self.set_coords(coords)

    def load_texture(self):
        if not self.surface:
            return 0
        if self.texture_id:
            glBindTexture(GL_TEXTURE_2D,self.texture_id)
            return self.texture_id
        return read_texture(self.surface,texture_id=self.texture_id)

    def set_coords(self,coords):
        if coords == self.coords:
            return
        self.coords = coords
        sw,sh = screen_width(),screen_height()

        x0 = 2 * coords[0] / sw - 1.0
        x1 = x0 + self.width / sw * 2

        y0 = 2 * (-self.height + sh -coords[1]) / sh - 1.0
        y1 = y0 + self.height / sh * 2

        self.vertices = [
            # Vertex         # Texture
            x0,y1,0.0,1.0,x0,y0,x1,0.0
        ]

        self.__set_vertices(self.vertices)

        return self

    def __set_vertices(self,vertices):
        glBindBuffer(GL_ARRAY_BUFFER,self.buffer)
        glBufferData(GL_ARRAY_BUFFER,len(vertices) * 4,(c_float*len(vertices))(*vertices),GL_STATIC_DRAW)

    def _bindTex(self):
        glBindTexture(GL_TEXTURE_2D,self.texture_id)

    def _bindBuff(self):
        glBindBuffer(GL_ARRAY_BUFFER,self.buffer)

    def _vertexPoint(self):
        glVertexPointer(3,GL_FLOAT,5 * 4,None)

    def _texCoordPoint(self):
        glTexCoordPointer(2,c_void_p(12))

    def _drawArrays(self):
        glDrawArrays(GL_TRIANGLES,6)

    def draw(self):
        self._bindTex()
        self._bindBuff()
        self._vertexPoint()
        self._texCoordPoint()
        self._drawArrays()

        # glBindTexture(GL_TEXTURE_2D,self.texture_id)
        # glBindBuffer(GL_ARRAY_BUFFER,self.buffer)

        # glVertexPointer(3,None)
        # glTexCoordPointer(2,c_void_p(12))
        # glDrawArrays(GL_TRIANGLES,6)
class Renderer:
    @classmethod
    def init(cls):
        print('GL display init')
        display = screen_width(),screen_height()
        pygame.display.set_mode(display,DOUBLEBUF | OPENGL)
        glViewport(0,display[0],display[1])

        glEnableClientState(GL_VERTEX_ARRAY)
        glEnableClientState(GL_TEXTURE_COORD_ARRAY)

        Renderer.run()
        pygame.display.flip()

    @classmethod
    def run(cls):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    @classmethod
    def draw(cls,elem):

        elem.load_texture()
        elem.draw()

     @staticmethod
     def update():
        pygame.display.flip()

代码在类似这样的循环中运行:

Renderer.init()
while True:
   Renderer.run()
   for e of render_elements:
      Renderer.draw(e)
   Renderer.update()

   # cap at 30 FPS
   clock.tick(30)

虽然我预计主要性能问题是由连续的 glDrawArrays 调用引起的,但实际上 glVertexPointerglTexCoordPointer 需要更长的时间才能完成(glDrawArrays 需要不到一半与 glVertexPointer) 相比的完成时间:

enter image description here

此时我对如何提高性能一无所知(总体而言,这与我在使用 glBeginglEnd 调用的即时模式下获得的结果几乎相同,所以我必须在我的代码中犯了一些严重的错误)。非常感谢任何帮助。

编辑:

看起来有很多与这两个相关的 python 绑定开销。安装 pyOpenGL-accelerate 后,这些特定调用的性能显着提高,但我怀疑它仍然可以更好。

enter image description here

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)