If you have to write a lot of stimuli, it will take time to draw. Since GL works behind the scenes of Psycho Pai, you can save a lot of drawing time by using display list. BufferImageStim is a wrapper for the display list, so you can use this. Even if you change pos before drawing, it will not be reflected, so you can not move it.
It can be used by calling the GL function directly in the following workaround.
BufferImageStim is useful for fast rendering, but at the moment pos
has no effect, so you cannot move the stimulus.
Here is workaround.
from psychopy import visual, core, event, monitors
import numpy as np
# need these lines to use GL functions
import pyglet
pyglet.options['debug_gl'] = False
GL = pyglet.gl
#create a window
mywin = visual.Window([800,600],monitor="testMonitor", units="pix")
N = 800
xs = np.random.rand(N)*800-400
ys = np.random.rand(N)*600-300
rs = np.random.rand(N)*10
slist = [visual.Circle(win=mywin, radius=r, pos=(x,y)) for x,y,r in zip(xs,ys,rs)]
stim = visual.BufferImageStim(mywin, stim=slist)
t0 = core.getTime()
while True: #this creates a never-ending loop
nw = core.getTime()
cx = np.sin(-nw*np.pi)
# stim.draw() # position doesn't change
stim._selectWindow(stim.win)
GL.glPushMatrix()
GL.glTranslated(cx, 0, 0) # NOTE: gl coordinate. by default, [-1 to 1, -1 to -1](probably)
GL.glScalef(stim.thisScale[0] * (1,-1)[stim.flipHoriz],
stim.thisScale[1] * (1,-1)[stim.flipVert], 1.0)
GL.glColor4f(stim.desiredRGB[0], stim.desiredRGB[1], stim.desiredRGB[2], stim.opacity)
GL.glCallList(stim._listID)
GL.glPopMatrix()
mywin.flip()
if len(event.getKeys())>0: break
event.clearEvents()
#cleanup
mywin.close()
core.quit()
Let's compare the version without BufferImageStim
Here is non-BufferImageStim version. Pretty slow.
from psychopy import visual, core, event, monitors
import numpy as np
#create a window
mywin = visual.Window([800,600],monitor="testMonitor", units="pix")
N = 800
xs = np.random.rand(N)*800-400
ys = np.random.rand(N)*600-300
rs = np.random.rand(N)*10
slist = [visual.Circle(win=mywin, radius=r) for x,y,r in zip(xs,ys,rs)]
t0 = core.getTime()
while True: #this creates a never-ending loop
nw = core.getTime()
cx = np.sin(-nw*np.pi)*400
for i in range(0, N):
slist[i].pos = (xs[i]+cx, ys[i])
slist[i].draw()
mywin.flip()
if len(event.getKeys())>0: break
event.clearEvents()
#cleanup
mywin.close()
core.quit()
Enjoy!!
Recommended Posts