複雑な刺激(例えば幾何学的な模様が入り乱れているような)を使う場合、各試行で呈示する直前で描画を行っていると、そこで時間のロスが生じる可能性があります。それを防止するため、使用する刺激をあらかじめオフスクリーンウィンドウ(テクスチャ)に描画しておく方法があります。試行が始まると、事前に描画しておいたオフスクリーンウィンドウを画面に呈示するだけなので、時間のロスを抑えることができます。
Screen('OpenOffscreenWindow') も参照してください。
またデモのMullerLyerIllusionのなかにも、
% %an example of preparing an offScreenwindow (for repeated use and fast drawing) % [fixcross,rect2]=Screen('OpenOffscreenWindow',screenNumber,[],[0 0 20 20]); % Screen('drawline',fixcross,[0 0 0],10,0,10,20,2);%mx-10,my,mx+10,my % Screen('drawline',fixcross,[0 0 0],0,10,20,10,2);%mx,my-10,mx,my+10のように、オフスクリーンウィンドウの使用方法について記載があります。
Screen('MakeTexture') を使用してもよいのですが、刺激によっては行列を作るのが難しい場合があると思います(例えば円を描画するときなど)。もしくはアンチエイリアシングを行いたい場合も(おそらく)MakeTextureを使うのは難しいと思います。
少し話がそれますが描画速度に興味のあるかたは、/Applications/Psychtoolbox/PsychTests/ にある DrawingSpeedTest もご覧ください。
私の環境だとprimitivetypeとmodeの組み合わせによって、最適な描画方法が異なりますが、基本的にはmode=1(複数の座標を事前に指定しておき、for文などの繰り返しを使わない方法)で問題のない速度で描画ができています。
かなり複雑な刺激の描画でない限りは、mode=1 の方法でよさそうです。オフスクリーンウィンドウを使う場合より、シンプルなコードになります。
以下にオフスクリーンウィンドウを使ったサンプルプログラムを記します。
3秒ごとにオフスクリーンウィンドウを切り替えています。
最後の刺激はアンチエイリアシングの動作確認です。
function offscreenTest% 刺激を呈示する前にオフスクリーン(テクスチャ)に刺激を描画しておくことにより% 時間のロスをなくす方法%ListenChar(2);AssertOpenGL;WaitSecs(0.1);%OSで共通のキー配置にするKbName('UnifyKeyNames');%手作りfunction。必要に応じてコメントアウトしてください。%myKeyCheck;try bgColor = [128 128 128]; % 画面全体の背景色 bgColor2 = [0 0 0]; % 四角形領域の背景色 screenNumber=max(Screen('Screens')) %ウィンドウでの呈示 %[windowPtr, windowRect]=Screen('OpenWindow', screenNumber, bgColor, [100, 200, 800, 600]); %フルスクリーンでの呈示 [windowPtr, windowRect]=Screen('OpenWindow', screenNumber, bgColor); OvalColor = [255 255 255]; % 円の色 StimRect = [0 0 200 200]; % Stimulus Rect 円を描画する四角形領域 [centerX centerY] = RectCenter(StimRect); % 四角形の中心座標 radius = 20; % 円の半径 dist = 50; % 円と円のあいだの距離 %----------------------------------- % オフスクリーン(テクスチャ)の作成 (このサンプルでは4つのオフスクリーンを作成しています) % オフスクリーン1:中心に1つの円 OvalTex1 = Screen('OpenOffscreenWindow', screenNumber, bgColor2, StimRect); Screen('FillOval', OvalTex1, OvalColor, [centerX - radius, centerY - radius, centerX + radius, centerY + radius]); % オフスクリーン2:水平に並んだ2つの円 OvalTex2 = Screen('OpenOffscreenWindow', screenNumber, bgColor2, StimRect); Screen('FillOval', OvalTex2, OvalColor, [centerX - radius, centerY - radius, centerX + radius, centerY + radius]); Screen('FillOval', OvalTex2, OvalColor, [centerX - radius - dist, centerY - radius, centerX + radius - dist, centerY + radius]); % オフスクリーン3:水平に並んだ3つの円 OvalTex3 = Screen('OpenOffscreenWindow', screenNumber, bgColor2, StimRect); Screen('FillOval', OvalTex3, OvalColor, [centerX - radius, centerY - radius, centerX + radius, centerY + radius]); Screen('FillOval', OvalTex3, OvalColor, [centerX - radius - dist, centerY - radius, centerX + radius - dist, centerY + radius]); Screen('FillOval', OvalTex3, OvalColor, [centerX - radius + dist, centerY - radius, centerX + radius + dist, centerY + radius]); % オフスクリーン4:斜めの2本の線分 % アンチエイリアシングの確認 LineTex = Screen('OpenOffscreenWindow', screenNumber, bgColor2, StimRect); Screen(LineTex,'BlendFunction',GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); % アンチエイリアシングを有効に Screen('DrawLines', LineTex, [20, 150; 20, 40], 2, OvalColor, [], 0); % アンチエイリアシングなしの線分 Screen('DrawLines', LineTex, [20, 150; 60, 80], 2, OvalColor, [], 1); % アンチエイリアシングありの線分 % 呈示の開始 Screen('DrawTexture', windowPtr, OvalTex1); Screen('Flip', windowPtr); WaitSecs(3); Screen('DrawTexture', windowPtr, OvalTex2); Screen('Flip', windowPtr); WaitSecs(3); Screen('DrawTexture', windowPtr, OvalTex3); Screen('Flip', windowPtr); WaitSecs(3); Screen('DrawTexture', windowPtr, LineTex); Screen('Flip', windowPtr); KbWait; %終了処理 Screen('CloseAll'); ShowCursor; ListenChar(0); catch Screen('CloseAll'); ShowCursor; ListenChar(0); psychrethrow(psychlasterror);end