Pyglet 闪烁,在两帧之间交替

Pyglet flickers, alternates between two frames

我正在尝试子类化 pyglet.window.Window 以可视化越来越多的随机放置的十字架。不幸的是,Pyglet 似乎不是将这些十字架存储在一个中,而是在两个不同的 交替 帧中。大约 50 次迭代后,请参阅以下 GIF。

下面是我使用的代码。

import random
import pyglet


class Canvas(pyglet.window.Window):
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.x = 0.
    self.y = 0.

    pyglet.clock.schedule_interval(self.update, .5)

  def update(self, dt: float) -> None:
    if self.has_exit:
      pyglet.app.exit()
    
    self.x = random.random() * self.width
    self.y = random.random() * self.height

  def on_draw(self) -> None:
    pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2f', (self.x - 10, self.y + 10., self.x + 10., self.y - 10.)))
    pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2f', (self.x - 10, self.y - 10., self.x + 10., self.y + 10.)))


def main() -> None:
  canvas = Canvas(width=1024, height=768)
  pyglet.app.run()


if __name__ == '__main__':
  main()

有人可以向我解释发生了什么,甚至可以提供解决方案吗?

编辑:我不想在帧之间清除屏幕。我想在最后一帧的顶部绘制以增加每次调用 self.update.

的交叉数

在您的编辑中:要在前一帧上绘制,请禁用双缓冲区:config = pyglet.gl.Config(double_buffer=False) 并将其传递到 Window 初始化中。


绘制前需要清屏,否则之前的帧会留在屏幕上。

  def on_draw(self) -> None:
    self.clear()
    pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2f', (self.x - 10, self.y + 10., self.x + 10., self.y - 10.)))
    pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2f', (self.x - 10, self.y - 10., self.x + 10., self.y + 10.)))

编辑:如果你想增加渲染的交叉数量,你需要增加渲染的东西的数量。这是一个例子:


import random
import pyglet

class Cross:
    def __init__(self, x, y, batch, size=10):
        self.size = size
        self._position = (x, y)
        self.verts = []
        self.create_vertices(x, y, batch)

    @property
    def position(self):
        return self._position
        
    @position.setter
    def position(self, value):
        x, y = value
        self.verts[0].vertices[:] = (x - self.size, y + self.size, x + self.size, y - self.size)
        self.verts[1].vertices[:] = (x - self.size, y - self.size, x + self.size, y + self.size)
        self._position = value
        
    def create_vertices(self, x, y, batch):
        diag1 = batch.add(2, pyglet.gl.GL_LINES, None,
                      ('v2f', (x - self.size, y + self.size, x + self.size, y - self.size)))
                      
        diag2 = batch.add(2, pyglet.gl.GL_LINES, None,
                          ('v2f', (x - self.size, y - self.size, x + self.size, y + self.size)))
                          
        self.verts.append(diag1)
        self.verts.append(diag2)
    
    def delete(self):
        for vert in self.verts:
            vert.delete()
            
        self.verts.clear()


class Canvas(pyglet.window.Window):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.crosses = []

        self.cross_batch = pyglet.graphics.Batch()

        pyglet.clock.schedule_interval(self.update, .5)
        pyglet.clock.schedule_interval(self.create_cross, 1)

    def update(self, dt: float) -> None:
        if self.has_exit:
            pyglet.app.exit()
        
        # If you want the stars to move constantly, then uncomment this.
        #for cross in self.crosses:
        #    cross.position = (random.random() * self.width, random.random() * self.height)

    def create_cross(self, dt):
        cross = Cross(random.random() * self.width, random.random() * self.height, self.cross_batch, random.randint(3,10))
        self.crosses.append(cross)

    def on_draw(self) -> None:
        self.clear()
        self.cross_batch.draw()
        
    def on_key_press(self, symbol, modifiers):
        if symbol == pyglet.window.key.SPACE:
            for cross in self.crosses:
                cross.delete()
                
            self.crosses.clear()


def main() -> None:
  canvas = Canvas(width=1024, height=768)
  pyglet.app.run()


if __name__ == '__main__':
  main()