This is a simplified code snippet to show the issue (epilepsy warning):
from panda3d.core import *
loadPrcFileData("", "fullscreen #t")
loadPrcFileData("", "sync-video #t")
loadPrcFileData("", "show-frame-rate-meter #t")
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
base = ShowBase()
state = 0
cm1 = CardMaker('card')
cm1.setFrame(-1, 1, -1, 1)
redcard = NodePath(cm1.generate())
redcard.setColor(1,0,0,1)
redcard.reparentTo(base.render2d)
redcard.hide()
cm2 = CardMaker('card')
cm2.setFrame(-1, 1, -1, 1)
bluecard = NodePath(cm2.generate())
bluecard.setColor(0,0,1,1)
bluecard.reparentTo(base.render2d)
bluecard.hide()
def myTaskFunc(task):
global state
if state == 0:
bluecard.show()
redcard.hide()
state = 1
elif state == 1:
redcard.show()
bluecard.hide()
state = 0
return task.cont
myTask = base.taskMgr.add(myTaskFunc, 'myTask')
base.run()
It should show red one frame, blue the next, repeat. Due to persistence of vision, you should be seeing violet.
The issue is once every 5 seconds or so, you get red or blue frames reused at least once, which results in a flicker/popping artifact due to displaying two red or two blue frames in a sequence. Even when vsync is on.
The real code I have is for a device which does optical pixel shifting. My program syncs with the optical pixel shifter, and Panda provides only even or odd rows of pixels each frame.
I’d be very surprised if this was normal behavior even when vsync is on, as any 3d camera movement would produce noticeable jitter due to some frames being reused, and more specific uses like VR would become nauseating due to reused frames when you move your head around.
The FPS meter never shows true 60 or 120 fps, it is always off by 0.1 or less. I had always assumed it was just a bug/limitation of the fps counter, but maybe it shows the issue that is causing this problem.