たくさんの刺激を書かないといけない場合は描画に時間がかかります。
サイコパイは裏でGLが働いているので、displaylistを使うと大分描画時間を短縮できいます。
BufferImageStimがdisplaylistのラッパになっているので、これを使えばいいんですが、
描画前にposとか変えても反映されないので、動かすことができません。
以下の様なworkaroundでGL関数直接呼び出すと使えます。
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()
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!!