(python)pygame opengl比blitting慢得多

时间:2014-06-09 01:08:40

标签: opengl pygame

我刚刚在我的pygame应用程序中实现了基本的opengl渲染,认为硬件加速会使程序运行得更快。它反而慢得多。

看起来问题是绘图功能。

这是我的opengl绘图功能

    def draw(self, screen):
        rect = self.texture.imagerect.copy()
        rect.x += self.xoffset
        rect.y += self.yoffset

        halfWidth = self.getWidth()/2
        halfHeight = self.getHeight()/2

        glEnable(GL_TEXTURE_2D)

        glBindTexture(GL_TEXTURE_2D, self.texture.getTexID()) 

        self.color.setGLColor()

        glPushMatrix()

        glTranslatef(rect.x,rect.y,0)

        glRotatef(self.angle, 0, 0, 1);

        glBegin(GL_QUADS)

        glTexCoord2d(0,0)
        glVertex2f(-halfWidth + self.pivot.x, -halfHeight + self.pivot.y)

        glTexCoord2d(0,1)
        glVertex2f(-halfWidth + self.pivot.x,-halfHeight + self.getHeight() + self.pivot.y)

        glTexCoord2d(1,1) 
        glVertex2f(-halfWidth + self.getWidth() + self.pivot.x,-halfHeight + self.getHeight() + self.pivot.y)

        glTexCoord2d(1,0)
        glVertex2f(-halfWidth + self.getWidth() + self.pivot.x,-halfHeight + self.pivot.y)

        glEnd()

        glPopMatrix()

我的探查器为绘制函数提供的内容

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
312792   20.395    0.000   34.637    0.000 image.py:61(draw)

我的其他探查者文字:( 1个月后到期)

http://pastebin.com/ApfiCQzw

我的源代码

https://bitbucket.org/claysmithr/warbots/src

注意:当我将它设置为不绘制任何瓷砖时,我得到60 fps!如果我限制只绘制出现在屏幕上的图块,我也会获得20 fps,但这仍然比blitting慢得多

我想要绘制的图块数量(64x64):15,625

有没有办法测试我是否真的是硬件加速?

我应该回到blitting吗?

编辑:blitting是否自动不会绘制不在屏幕上的图块?这可能是为什么opengl如此缓慢的原因!

1 个答案:

答案 0 :(得分:1)

如果我理解正确,你需要每帧绘制数千个纹理四边形。减速来自您为每个四边形进行的多个OpenGL调用 - 在上面的代码中至少有16个。

您需要做的是分批绘制,一次绘制更多基元。

首先,您可以将瓷砖合并为更大的单元吗?在过去十年中制造的任何显卡都可以处理16K x 16K纹理贴图。你可以在不必绑定新纹理的情况下绘制的四边形越多越好。

用顶点数组替换glBegin .. glEnd块。即使在最糟糕的情况下仍然一次绘制一个四边形,你可以用2,glVertexPointer和glTexCoordPointer替换当前的10个OpenGL调用。

然后开始将tile quads合并到更大的顶点数组中。不要使用glTranslatef,而是将rect.x和rect.y值直接添加到每个顶点。

glRotatef是一个问题,如果每个瓷砖确实必须有所不同。如果它被限制在90度的倍数,那么你不需要它,而只需交换纹理坐标。对于其他值,请研究如何使用sin和cos直接旋转纹理坐标。

一旦你消除了平移和旋转每个平铺,你就可以将所有计算出的四边形顶点和纹理坐标都粘贴到巨大的顶点数组中,只用两次调用绘制整个地图。

希望这有帮助。

(对于真正的超级性能,你可能想要使用GPU侧顶点缓冲区对象和着色器,但是根据你的编码风格我假设你想要坚持使用OpenGL 1/2。)