Pyglet/OpenGL 图像在鼠标移动时闪烁
Pyglet/OpenGL image flickering on mouse movement
我在 YouTube 上关注 "Pyglet Python and OpenGL - part 01 - Hello Triangle" tutorial by Attila Toth 以使用 Pyglet 绘制三角形,因为我以前从未使用过 Pyglet。据我所知,代码与视频中的相同,但是当我移动鼠标时,图像会闪烁,但没有错误消息。
作为参考,我的电脑有 4 GB 内存、i3 7020U 和集成显卡,DirectX 版本 12。我使用的是 Windows 10 build 18632。
代码:
import pyglet
from pyglet.gl import *
class Window(pyglet.window.Window):
def __init__(self, *args,**kwargs):
super().__init__(*args, **kwargs)
self.set_minimum_size(400, 300)
self.triangle = Triangle()
def ondraw(self):
self.triangle.vertices.draw(GL_TRIANGLES)
class Triangle():
def __init__(self):
self.vertices = pyglet.graphics.vertex_list(3, ('v3f', [-0.5,-0.5,0.0, 0.5,-0.5,0.0, 0.0,0.5,0.0]),
('c3B', [100,200,220, 200,110,100, 100,250,100]))
if __name__ == "__main__":
window = Window(800, 600, "The Game", resizable=True)
window.ondraw()
pyglet.app.run()
我无法重现问题,我的机器上没有闪烁。 (GTX 1070,6 年前的 i7 和 16GB 内存,windows 10 等)
但是,您的代码存在一些小问题。
首先,它是 on_draw
而不是 ondraw
,这在以后会变得很重要,因为它是 pyglet.window.Window.on_draw 函数的挂钩覆盖,在某些事件中被调用。
这里还有一个重要的功能就是设置glViewport
否则屏幕上什么也不会显示。所以你需要的最少代码是这样的:
import pyglet
from pyglet.gl import *
class Window(pyglet.window.Window):
def __init__(self, *args,**kwargs):
super().__init__(*args, **kwargs)
self.set_minimum_size(400, 300)
self.triangle = Triangle()
def on_draw(self):
self.clear()
self.triangle.vertices.draw(GL_TRIANGLES)
def on_resize(self, width, height):
glViewport(0, 0, width, height)
class Triangle():
def __init__(self):
self.vertices = pyglet.graphics.vertex_list(3, ('v3f', [-0.5,-0.5,0.0, 0.5,-0.5,0.0, 0.0,0.5,0.0]),
('c3B', [100,200,220, 200,110,100, 100,250,100]))
if __name__ == "__main__":
window = Window(800, 600, "The Game", resizable=True)
pyglet.app.run()
了解 on_***
事件是由 Pyglet 的内部机制触发的,而不是您应该手动调用的东西(就像您在 if __name__ ...
中所做的 window.ondraw()
), 这不是个好主意。
相反,如果您想强制执行一个 draw
事件,只需通过触发 Pyglet 事件来触发它,一些示例是:
- 鼠标移动
- 键盘输入(尝试点击 spacebar)
- 正在设置 clock/timer 以安排更新
闪烁可能来自您的显卡(或缺少适当的驱动程序),它根本无法处理您要求的刷新率。尝试快速点击 space bar 几次,这可能也会导致闪烁。在这种情况下,您可能无法从您期望的机器中获得性能。
解决方法可能是:batched rendering 这会显着缩短渲染时间,不过,对于一个简单的三角形,您应该不会遇到问题。
我在 YouTube 上关注 "Pyglet Python and OpenGL - part 01 - Hello Triangle" tutorial by Attila Toth 以使用 Pyglet 绘制三角形,因为我以前从未使用过 Pyglet。据我所知,代码与视频中的相同,但是当我移动鼠标时,图像会闪烁,但没有错误消息。
作为参考,我的电脑有 4 GB 内存、i3 7020U 和集成显卡,DirectX 版本 12。我使用的是 Windows 10 build 18632。
代码:
import pyglet
from pyglet.gl import *
class Window(pyglet.window.Window):
def __init__(self, *args,**kwargs):
super().__init__(*args, **kwargs)
self.set_minimum_size(400, 300)
self.triangle = Triangle()
def ondraw(self):
self.triangle.vertices.draw(GL_TRIANGLES)
class Triangle():
def __init__(self):
self.vertices = pyglet.graphics.vertex_list(3, ('v3f', [-0.5,-0.5,0.0, 0.5,-0.5,0.0, 0.0,0.5,0.0]),
('c3B', [100,200,220, 200,110,100, 100,250,100]))
if __name__ == "__main__":
window = Window(800, 600, "The Game", resizable=True)
window.ondraw()
pyglet.app.run()
我无法重现问题,我的机器上没有闪烁。 (GTX 1070,6 年前的 i7 和 16GB 内存,windows 10 等)
但是,您的代码存在一些小问题。
首先,它是 on_draw
而不是 ondraw
,这在以后会变得很重要,因为它是 pyglet.window.Window.on_draw 函数的挂钩覆盖,在某些事件中被调用。
这里还有一个重要的功能就是设置glViewport
否则屏幕上什么也不会显示。所以你需要的最少代码是这样的:
import pyglet
from pyglet.gl import *
class Window(pyglet.window.Window):
def __init__(self, *args,**kwargs):
super().__init__(*args, **kwargs)
self.set_minimum_size(400, 300)
self.triangle = Triangle()
def on_draw(self):
self.clear()
self.triangle.vertices.draw(GL_TRIANGLES)
def on_resize(self, width, height):
glViewport(0, 0, width, height)
class Triangle():
def __init__(self):
self.vertices = pyglet.graphics.vertex_list(3, ('v3f', [-0.5,-0.5,0.0, 0.5,-0.5,0.0, 0.0,0.5,0.0]),
('c3B', [100,200,220, 200,110,100, 100,250,100]))
if __name__ == "__main__":
window = Window(800, 600, "The Game", resizable=True)
pyglet.app.run()
了解 on_***
事件是由 Pyglet 的内部机制触发的,而不是您应该手动调用的东西(就像您在 if __name__ ...
中所做的 window.ondraw()
), 这不是个好主意。
相反,如果您想强制执行一个 draw
事件,只需通过触发 Pyglet 事件来触发它,一些示例是:
- 鼠标移动
- 键盘输入(尝试点击 spacebar)
- 正在设置 clock/timer 以安排更新
闪烁可能来自您的显卡(或缺少适当的驱动程序),它根本无法处理您要求的刷新率。尝试快速点击 space bar 几次,这可能也会导致闪烁。在这种情况下,您可能无法从您期望的机器中获得性能。
解决方法可能是:batched rendering 这会显着缩短渲染时间,不过,对于一个简单的三角形,您应该不会遇到问题。