I’ve got a Twisted program which does some things. One of those things is to, 60 times per second, perform a bunch of low-CPU networking and data processing tasks. At the same time, it drives Panda, by calling Task.step() periodically.
This sometimes creates a problem. Since my other code can’t run while Panda is running, if Panda takes too long to draw a frame, my other tasks get short shrift.
My attempt to solve the problem was to use Twisted’s deferToThread() to call Panda’s Task.step(). Since the rest of my code doesn’t touch Panda while a frame is being rendered, I expected this to work.
However, I ran into two problems.
First, Python doesn’t like it when you call signal.signal(signal.SIGINT, blah) while not on the main thread. Task.step() does this in two places to correctly handle a KeyboardInterrupt. But KeyboardInterrupts are for people without hammers, right? I commented those out.
Second, all I got was a black rendering window. I verified that Task.step() was being called periodically as designed, sounds were running, etc. But no graphics were produced.
So my question is, is it even possible to run Panda off the main thread?
I found out that if I use any one of the following threading methods in Config.prc, I can run my little Panda program off the main thread.
Of course, I still needed to comment out the KeyboardInterrupt stuff as noted above.
I’d prefer not to do this – the input latency becomes darn noticeable under Cull/Draw. However, my App consumes very little time so /Draw was a decent compromise.
I know this is over a year old, but I had a similar problem and came across this page.
I was lucky to come across an even older post about VisionEgg with the same issue.
The first suggestion worked for me: Initialize and load the renderer in the secondary thread where the render stepping will take place.
from direct.showbase.ShowBase import ShowBase
from direct.actor.Actor import Actor
base = ShowBase()
#Setup your scene
#time.sleep(0.001) #I don't know if this is necessary.
myThread = pandaThread()
myThread.daemon = True