ディスプレイのリフレッシュレートと表示画像
PCのディスプレイは、リフレッシュレートで書き換えられる。スクリーン(キャンバス)での描画が、即、画面に表示されるのではなく、flip関数などで転送されて表示されるが、転送された画像が表示されるのは、画面がリフレッシュされた後である。このため、flipとリフレッシュとの時間関係で、先にflipした画像が表示されずに、後からflipされた画像に上書きされることが起こる。
図1において、A(i)でflipされた画像は、後のA(i+1)においてflipされた画像に上書きされて、表示画面のリフレッシュ(i)においてはA(i+1)においてflipされた画像が表示される。
図1
例として、図2と図3の画像を交互に表示するスクリプト、リスト1とリスト2を用意した。スクリプトファイルは、まとめて圧縮ファイルscriptfiles.zipとした。
図2
図3
リスト1では、flipの間隔は、使用PCのリフレッシュレート1/60秒に合わせて、画像がリフレッシュ間に1回だけflipされるようにしている。スクリプトを以下に示す。
t2 = t1
while t2 < t1 +
d_time:
# flipの間隔をd_timeに調整
t2 =
time.perf_counter_ns()
pygame.display.flip()
t1 = t2
d_timeは、次のコードで与えられている。時間の単位はナノ秒である。
d_time = (10**9) / 60
表示画面のリフレッシュの間に、flipは1回だけであるので、図2と図3の図形は交互に提示される。
リスト2では、flipの時間間隔はリフレッシュ間隔の半分に設定されている。
d_time = (10**9) / 60
d_time /= 2
# リフレッシュ間に2回のflip
したがって、リフレッシュの間にflipが2回行われ、先にflipされた画像は、後からflipされた画像で上書きされる。そのため、表示画像は、図2あるいは図3のみとなる。
import pygame
import time
import matplotlib.pyplot as plt
pygame.init()
screen = pygame.display.set_mode((700, 700))
pygame.display.set_caption('Check-Display')
screen.fill((255,255,255))
pygame.display.flip()
#
# リフレッシュレート60Hzの場合のリフレッシュ間隔: ナノ秒/回
#
d_time = (10**9) / 60
state_id = 0
# 提示画像の切り替え用
t1 = time.perf_counter_ns() # t1の初期値
while True:
if state_id == 0:
state_id = 1
else:
state_id = 0
screen.fill((255,255,255))
if state_id == 0:
pygame.draw.line(screen, (0,0,0), (10, 350), (690, 350), width=10)
else:
pygame.draw.line(screen, (0,0,0), (350,10), (350, 690), width=10)
t2 = t1
while t2 < t1 +
d_time:
# flipの間隔をd_timeに調整
t2 =
time.perf_counter_ns()
pygame.display.flip()
t1 = t2
ck = False
for e in pygame.event.get():
if
e.type == pygame.QUIT:
# Windowのcloseボタンがクリックされたか
ck = True
if ck:
break
pygame.quit()
import pygame
import time
import matplotlib.pyplot as plt
pygame.init()
screen = pygame.display.set_mode((700, 700))
pygame.display.set_caption('Check-Display')
screen.fill((255,255,255))
pygame.display.flip()
#
#
リフレッシュレート60Hzの場合のリフレッシュ間隔: ナノ秒/回
#
d_time = (10**9) / 60
d_time /= 2
# リフレッシュ間に2回のflip
state_id = 0
# 提示画像の切り替え用
t1 = time.perf_counter_ns() # t1の初期値
while True:
if state_id == 0:
state_id = 1
else:
state_id = 0
screen.fill((255,255,255))
if state_id == 0:
pygame.draw.line(screen, (0,0,0), (10, 350), (690, 350), width=10)
else:
pygame.draw.line(screen, (0,0,0), (350,10), (350, 690), width=10)
t2 = t1
while t2 < t1 +
d_time:
# flipの間隔をd_timeに調整
t2 =
time.perf_counter_ns()
pygame.display.flip()
t1 = t2
ck = False
for e in pygame.event.get():
if
e.type == pygame.QUIT:
# Windowのcloseボタンがクリックされたか
ck = True
if ck:
break
pygame.quit()