【问题标题】:Drawing a pyglet batch increases memory usage?绘制 pyglet 批处理会增加内存使用量?
【发布时间】:2019-01-23 19:47:58
【问题描述】:

我正在尝试使用 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 使用的内存在动画持续期间稳步增加。

【问题讨论】:

  • 如果您将违规代码添加到问题中,人们在尝试回答您的问题时将有更多工作要做
  • @Gab。明白了。我试图避免这种情况,因为代码非常大并且可能令人困惑。不过,我会尽量补充。
  • 在这种情况下,我相信添加 minimal reproducible example 是正确的选择

标签: python animation opengl memory pyglet


【解决方案1】:

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

您创建了 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 个批次。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 2018-08-20
    • 2015-09-06
    • 2014-11-06
    • 1970-01-01
    相关资源
    最近更新 更多