有没有更快的方法用pyglet和线程在屏幕上画画?

问题描述 投票:1回答:1

下面的三个函数显示了我是如何使用pyglet库在屏幕上绘制正方形的。代码运行良好。但我想让它运行得更快。

以我对线程的新手理解,我认为在 draw_grid() 可以通过使用线程使速度更快,因为它等待一个方块来绘制,使用 pos 然后画一个新的方块。由于 all_positions 已经提供了,有没有办法同时绘制所有的方块?

def draw_square(single_location):
    # draws a single square
    pyglet.graphics.draw_indexed(4, pyglet.graphics.gl.GL_TRIANGLES,
                             [0,1,2,1,2,3],
                             ('v2i', single_location))

def position_array():
    # returns an 2D array with each row representing the coordinates of the rectangle to draw
    ...relevant code...
    return all_positions

def draw_grid(all_positions):
    # uses draw_square function and all_positions to draw multiple squares at the specified locations.
    for pos in all_positions:
        draw_square(pos)

在查找了一些关于穿线的视频后,我发现了关于 concurrent.futures 库。所以我试着去实现它,但它却给了我错误。所以现在我被卡住了。

下面是我如何使用 concurrent.futures.ThreadPoolExecutor() 里面 draw_grid()

def draw_grid(all_positions):
    # uses draw_square function and all_positions to draw multiple squares at the specified locations.
    with concurrent.futures.ThreadPoolExecutor as executor:
        for pos in all_positions:
        f1 = executor.submit(draw_square, pos)
        f1.result()
python multithreading pyglet concurrent.futures
1个回答
2
投票

一般来说,千万不要把线程和图形渲染混在一起。这是个灾难的接受者。利用线程与渲染(GL)相结合是可能的。但同样 不建议.

相反,你可能想看看的是批量渲染。有很大的 关于Batched渲染的文档 你可能会觉得很容易理解。

只需要记住,如果你在将顶点添加到补丁后想要修改它们,你需要存储它们并修改批处理的返回,不要试图直接操作批处理。

vertex_list = batch.add(2, pyglet.gl.GL_POINTS, None,
    ('v2i', (10, 15, 30, 35)),
    ('c3B', (0, 0, 255, 0, 255, 0))
)
# vertex_list.vertices <-- Modify here

之所以不想使用线程,是因为几乎有99.9%的保证,你最终会因为竞赛条件而出现分割故障。在那里,有东西试图更新屏幕,而你正在渲染你试图操作的东西。

更多信息在这里的评论中。更新和On_Draw Pyglet在线程中的应用

所以,把所有的方块加到一个批次,然后做 batch.draw() 它将模拟一次绘制所有的方块,而不是浪费CPU周期,每次调用函数重新创建方块,然后再逐个渲染。而不是浪费CPU周期,每次都要调用函数重新创建方块,然后再一个一个地渲染。

batch = pyglet.graphics.Batch()
batch.add(2, pyglet.gl.GL_TRIANGLES, None,
    ('v2i', [0,1,2,1,2,3])
)

def on_draw():
    batch.draw()

类似于这样。但很明显,你需要在不同的位置创建正方形,等等。但作为一个指导原则,在渲染逻辑之外创建批处理和方块,然后调用 .draw() 在渲染周期中的批次上。

© www.soinside.com 2019 - 2024. All rights reserved.