【问题标题】:Screen tearing using pygame on Raspberry Pi在 Raspberry Pi 上使用 pygame 进行屏幕撕裂
【发布时间】:2016-05-24 07:40:40
【问题描述】:

我被屏幕撕裂问题困扰了大约一周。

这是我的问题:我想制作一个程序,可以非常快速地显示一系列 PNG 图片(以 30 fps 或更高的速度)。为此,我使用了 pygame 库,尤其是 pygame.display.blitpygame.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.DOUBLEBUFhttp://www.pygame.org/docs/ref/displayy.set_mode)。显然,这些可以帮助纠正屏幕撕裂问题。但是当我使用这些标志时,我看不到屏幕撕裂校正。

我在某处看到 pygame 无法在 X11 上处理 vsync,这可以解释为什么我认为 HWSURFACE 和 DOUBLEBUF 标志没有区别。

有人在 Raspberry Pi 上遇到过这个 vsync 问题吗?是否有要放入“config.txt”文件的参数? 有没有人有办法获得真正的 vsync 信息来避免这些屏幕撕裂效果?

我已经看到 pyglet 可以在创建的窗口中处理 vsync,但由于未知原因,我无法在 pyglet 窗口中显示图像,我真的不确定它是否能解决问题,特别是如果 Raspberry 可以'现在不处理 vsync。

【问题讨论】:

  • 作为一个癫痫患者,我需要问你为什么要这样做,而且你知道这种显示的闪烁会给像我这样的人带来问题,对吧?
  • 我完全清楚这一点;)。它不是一个游戏或任何人都可以下载的东西,它是一个个人项目,仅供我自己使用:我正在使用投影仪和相机开发 3D 扫描仪。相机捕捉投影仪显示的帧。

标签: python raspberry-pi pygame vsync


【解决方案1】:

尝试使用 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 这个问题似乎涵盖了您可能正在寻找的内容。

祝你好运。

【讨论】:

  • 是的,它更容易实现和理解,但它并没有解决问题。我会调查的,谢谢。
  • 问题解决了,你的回答给了我一些其他的想法!
  • 请问您是如何解决的?有类似的问题
猜你喜欢
  • 2015-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-09
  • 1970-01-01
  • 2012-12-26
  • 2012-10-27
相关资源
最近更新 更多