绘制pyglet批量会增加内存使用量?

时间:2018-01-19 16:39:35

标签: python animation opengl memory pyglet

我试图使用Pyglet的批量绘图功能来加速动画的渲染,主要包括使用GL_LINES每秒多次绘制一组大的顶点。速度方面,我成功了,因为之前的滞后动画现在可以达到60 fps的清晰度。但是,我注意到每次绘制一个新的动画帧时(通过在几个批次上调用batch.draw(),在计划由pyglet.clock.schedule_interval()每帧调用的函数内),程序使用的内存稳步上升。

我希望创建批次时内存使用量会大幅增加(而且确实如此),但我不明白为什么仅仅调用batch.draw()似乎也是如此导致它,或者至少为什么内存使用似乎在未来的帧上积累。每次需要重绘帧时,是否需要以某种方式手动删除以前从内存中绘制的图像?如果是这样,我在Pyglet文档中没有发现需要做这样的事情。

在我的程序中,我在每次新帧更新开始时调用pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)以清除前一帧,但也许前一帧仍然存在于内存中?

下面是一个独立的示例脚本,它展示了这种精确的行为:

import pyglet as pg
import random

currentFrame = 0
window = pg.window.Window(600,600)

# A list of lists of batches to be drawn at each frame.
frames = []

# Make 200 frames...
for frameCount in range(200):
    batches = []
    for n in range(3):
        batch = pg.graphics.Batch()

        # Generate a random set of vertices within the window space
        batch.add(1000, pg.gl.GL_LINES, None,
            ("v2f", tuple(random.random()*600 for i in range(2000))),
            ("c3B", (255,255,255)*1000))
        batches.append(batch)
    frames.append(batches)

# This function will be called every time the window is redrawn
def update(dt, frames=frames):
    global currentFrame
    if currentFrame >= len(frames):
        pg.clock.unschedule(update)
        print("Animation complete")
        return

    batches = frames[currentFrame]

    # Clear the previous frame
    pg.gl.glClearColor(0,0,0,1)  # Black background color
    pg.gl.glClear(pg.gl.GL_COLOR_BUFFER_BIT)

    # Define line width for this frame and draw the batches
    pg.gl.glLineWidth(5)
    for batch in batches:
        batch.draw()

    currentFrame += 1

# Call the update() function 30 times per second.
pg.clock.schedule_interval(update, 1.0/30)
pg.app.run()

当动画正在运行时,不应创建新的批次,但Python使用的内存会在动画持续时间内稳定增加。

1 个答案:

答案 0 :(得分:0)

很抱歉,这可能是一个非常晚的答案,但对于遇到此问题的任何人...

您已创建2个列表,它们是线性内存使用量增加的来源:

frames = []

batches = []

分别在第8行和第12行。

然后,在for循环中,将3个批次添加到“批次”列表中,然后将它们添加到“框架”列表中。

for frameCount in range(200):
    batches = []
    for n in range(3):
        batch = pg.graphics.Batch()

        # Generate a random set of vertices within the window space
        batch.add(1000, pg.gl.GL_LINES, None,
            ("v2f", tuple(random.random()*600 for i in range(2000))),
            ("c3B", (255,255,255)*1000))
        batches.append(batch)
    frames.append(batches)

幸运的是,您确实要覆盖此处“批处理”中的所有内容:

batches = frames[currentFrame]

但是仍然遗漏了“帧”,该帧永远不会重置,并且每帧都有3个批次。

如果从0帧开始到200帧结束,则此“帧”列表的内存使用量将从什么都存储到存储600个批次。

尝试在每帧之后首先重置“帧”,并使用简单的整数跟踪您的帧数。

我希望这至少对某人有帮助