LoginSignup
0
0

More than 5 years have passed since last update.

PsychoPyでBufferImageStimを動かす how to move BufferImageStim object in PsychoPy

Posted at

たくさんの刺激を書かないといけない場合は描画に時間がかかります。
サイコパイは裏で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!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0