在 Raspberry Pi 上使用 pygame 进行屏幕撕裂
Screen tearing using pygame on Raspberry Pi
我被屏幕撕裂问题困扰了大约一个星期。
这是我的问题:我想制作一个可以非常快地显示 PNG 图片序列的程序(以 30 fps 或更高的速率)。为此,我使用 pygame 库,尤其是 pygame.display.blit
和 pygame.display.flip
.
下面是代码示例(带有自制延迟功能):
import time
import pygame
screen=pygame.display.set_mode(size, pygame.FULLSCREEN)
nbPicturesToLoad=12
pictures=range(nbPicturesToLoad)
for i in range(nbPicturesToLoad):
pictures[i]=pygame.image.load(pictureName).convert() //Here pictureName depends on the value of i
(...)
for i in range(nbPicturesToLoad):
timer1=time.time()
screen.blit(pictures[i], (0,0))
pygame.display.flip()
timer2=time.time()
timer=timer2-timer1
while(timer<0.03333):
timer2=time.time()
timer=timer2-timer1
计时器允许我在屏幕上有相同的刷新率。
我的问题是亲眼所见是画面撕裂的问题(https://en.wikipedia.org/wiki/Screen_tearing)。
在 pygame 文档中,他们建议为屏幕初始化使用其他标志(pygame.HWSURFACE and pygame.DOUBLEBUF
、http://www.pygame.org/docs/ref/display、y.set_mode
)。显然这些可以帮助纠正屏幕撕裂问题。但是当我使用这些标志时,我看不到屏幕撕裂校正。
我在某处看到 pygame 无法处理 X11 上的垂直同步,这可以解释为什么我看不出 HWSURFACE 和 DOUBLEBUF 标志有什么不同。
有没有人在 Raspberry Pi 上遇到过这个 vsync 问题? "config.txt" 文件中是否有参数?
有没有人有办法获得真正的 vsync 信息来避免这些屏幕撕裂效果?
我已经看到 pyglet 可以在创建的 windows 中处理垂直同步,但由于未知原因我无法在 pyglet window 中显示图像,我真的不确定它是否会解决这个问题,特别是如果 Raspberry 现在无法处理 vsync。
尝试使用 Pygame 时钟来处理计时,它更容易实现和理解,并且可能会解决问题。
如下所示:
import pygame as py
py.init()
WINDOW = (400,400)
screen = py.display.set_mode(WINDOW)
nbPicturesToLoad=12
pictures = range(nbPicturesToLoad)
for i in range(nbPicturesToLoad):
pictures[i]=py.image.load(pictureName).convert()
FPS = 30
clock = py.time.Clock() # Create a clock object
done = False
while not done:
for event in py.event.get():
if event.type == py.QUIT:
done = True
for i in range(nbPicturesToLoad):
screen.fill((255,255,255))
screen.blit(pictures[i],(0,0))
py.display.flip()
clock.tick(FPS) # use pygame.time.Clock to wait 1/30th of a second
py.quit()
但是,由于这是一个屏幕撕裂问题,解决方案可能是完全停止使用 Pygame。 How to avoid tearing with pygame on Linux/X11
这个问题似乎涵盖了您可能正在寻找的内容。
祝你好运。
我被屏幕撕裂问题困扰了大约一个星期。
这是我的问题:我想制作一个可以非常快地显示 PNG 图片序列的程序(以 30 fps 或更高的速率)。为此,我使用 pygame 库,尤其是 pygame.display.blit
和 pygame.display.flip
.
下面是代码示例(带有自制延迟功能):
import time
import pygame
screen=pygame.display.set_mode(size, pygame.FULLSCREEN)
nbPicturesToLoad=12
pictures=range(nbPicturesToLoad)
for i in range(nbPicturesToLoad):
pictures[i]=pygame.image.load(pictureName).convert() //Here pictureName depends on the value of i
(...)
for i in range(nbPicturesToLoad):
timer1=time.time()
screen.blit(pictures[i], (0,0))
pygame.display.flip()
timer2=time.time()
timer=timer2-timer1
while(timer<0.03333):
timer2=time.time()
timer=timer2-timer1
计时器允许我在屏幕上有相同的刷新率。
我的问题是亲眼所见是画面撕裂的问题(https://en.wikipedia.org/wiki/Screen_tearing)。
在 pygame 文档中,他们建议为屏幕初始化使用其他标志(pygame.HWSURFACE and pygame.DOUBLEBUF
、http://www.pygame.org/docs/ref/display、y.set_mode
)。显然这些可以帮助纠正屏幕撕裂问题。但是当我使用这些标志时,我看不到屏幕撕裂校正。
我在某处看到 pygame 无法处理 X11 上的垂直同步,这可以解释为什么我看不出 HWSURFACE 和 DOUBLEBUF 标志有什么不同。
有没有人在 Raspberry Pi 上遇到过这个 vsync 问题? "config.txt" 文件中是否有参数? 有没有人有办法获得真正的 vsync 信息来避免这些屏幕撕裂效果?
我已经看到 pyglet 可以在创建的 windows 中处理垂直同步,但由于未知原因我无法在 pyglet window 中显示图像,我真的不确定它是否会解决这个问题,特别是如果 Raspberry 现在无法处理 vsync。
尝试使用 Pygame 时钟来处理计时,它更容易实现和理解,并且可能会解决问题。
如下所示:
import pygame as py
py.init()
WINDOW = (400,400)
screen = py.display.set_mode(WINDOW)
nbPicturesToLoad=12
pictures = range(nbPicturesToLoad)
for i in range(nbPicturesToLoad):
pictures[i]=py.image.load(pictureName).convert()
FPS = 30
clock = py.time.Clock() # Create a clock object
done = False
while not done:
for event in py.event.get():
if event.type == py.QUIT:
done = True
for i in range(nbPicturesToLoad):
screen.fill((255,255,255))
screen.blit(pictures[i],(0,0))
py.display.flip()
clock.tick(FPS) # use pygame.time.Clock to wait 1/30th of a second
py.quit()
但是,由于这是一个屏幕撕裂问题,解决方案可能是完全停止使用 Pygame。 How to avoid tearing with pygame on Linux/X11 这个问题似乎涵盖了您可能正在寻找的内容。
祝你好运。