function DriftWaitDemo(movieDurationSecs, waitframes) % DriftWaitDemo([movieDurationSecs=10][, waitframes=1]) % ___________________________________________________________________ % % Display an animated grating using the new Screen('DrawTexture') command. % In Psychtoolbox-3 Screen('DrawTexture') replaces Screen('CopyWindow'). % % This demo illustrates on how to emulate the old Screen('WaitBlanking'...) % behaviour: If you set waitframes > 1 then the screen is only updated % every waitframes'th monitor refresh interval. % % Optional parameters: % % movieDurationSecs == Requested total duration of movie in seconds. % waitframes == Number of monitor refresh intervals to wait before each % frame is drawn. % % CopyWindow vs. DrawTexture: % % In the OS 9 Psychtoolbox, Screen ('CopyWindow") was used for all % time-critical display of images, in particular for display of the movie % frames in animated stimuli. In contrast, Screen('DrawTexture') should not % be used for display of all graphic elements, but only for display of % MATLAB matrices. For all other graphical elements, such as lines, rectangles, % and ovals we recommend that these be drawn directly to the display % window during the animation rather than rendered to offscreen windows % prior to the animation. % % _________________________________________________________________________ % % see also: PsychDemos, MovieDemo, DriftDemo % HISTORY % 6/28/04 awi Adapted from Denis Pelli's DriftDemo.m for OS 9 % 7/18/04 awi Added Priority call. Fixed. % 9/8/04 awi Added Try/Catch, cosmetic changes to comments and see also. % 4/23/05 mk Added Priority(0) in catch section, moved Screen('OpenWindow') % before first call to Screen('MakeTexture') in % preparation of future improvements to 'MakeTexture'. % 5/10/05 mk Added demo-code for WaitBlanking - emulation. % 2/28/09 mk Smallish refinements, cleanups, updated comments. % 12/30/16 mk Cleanup this formatting mess. if nargin < 2 waitframes = 1; end if nargin < 1 movieDurationSecs = []; end if isempty(movieDurationSecs) movieDurationSecs = 10; end try % This script calls Psychtoolbox commands available only in OpenGL-based % versions of the Psychtoolbox. (So far, the OS X Psychtoolbox is the % only OpenGL-base Psychtoolbox.) The Psychtoolbox command AssertPsychOpenGL will issue % an error message if someone tries to execute this script on a computer without % an OpenGL Psychtoolbox AssertOpenGL; % Get the list of screens and choose the one with the highest screen number. % Screen 0 is, by definition, the display with the menu bar. Often when % two monitors are connected the one without the menu bar is used as % the stimulus display. Chosing the display with the highest dislay number is % a best guess about where you want the stimulus displayed. screens=Screen('Screens'); screenNumber=max(screens); % Find the color values which correspond to white and black: Usually % black is always 0 and white 255, but this rule is not true if one of % the high precision framebuffer modes is enabled via the % PsychImaging() commmand, so we query the true values via the % functions WhiteIndex and BlackIndex: white=WhiteIndex(screenNumber); black=BlackIndex(screenNumber); % Round gray to integral number, to avoid roundoff artifacts with some % graphics cards: gray=round((white+black)/2); % This makes sure that on floating point framebuffers we still get a % well defined gray. It isn't strictly neccessary in this demo: if gray == white gray=white / 2; end % Contrast 'inc'rement range for given white and gray values: inc=white-gray; % Open a double buffered fullscreen window and set default background % color to gray: w = Screen('OpenWindow',screenNumber, gray); % compute each frame of the movie and convert the those frames, stored in % MATLAB matices, into Psychtoolbox OpenGL textures using 'MakeTexture'; numFrames=12; % temporal period, in frames, of the drifting grating for i=1:numFrames phase=(i/numFrames)*2*pi; %phase=mod(i,2)*pi+pi/2; % grating [x,y]=meshgrid(-200:200,-200:200); angle=30*pi/180; % 30 deg orientation. f=0.05*2*pi; % cycles/pixel %f=0; a=cos(angle)*f; b=sin(angle)*f; m=exp(-((x/90).^2)-((y/90).^2)).*sin(a*x+b*y+phase); tex(i)=Screen('MakeTexture', w, round(gray+inc*m)); %#ok end % Run the movie animation for a fixed period. frameRate=Screen('FrameRate',screenNumber); % If MacOSX does not know the frame rate the 'FrameRate' will return 0. % That usually means we run on a flat panel with 60 Hz fixed refresh % rate: if frameRate == 0 frameRate=60; end movieDurationFrames=round(movieDurationSecs * frameRate / waitframes); movieFrameIndices=mod(0:(movieDurationFrames-1), numFrames) + 1; priorityLevel=MaxPriority(w); Priority(priorityLevel); Screen('TextSize', w, 24); Screen('DrawText', w, 'Measuring monitor refresh interval... This can take up to 20 seconds...', 10, 10, 255); Screen('Flip', w); ifi = Screen('GetFlipInterval', w); % Perform initial Flip to sync us to the VBL and for getting an initial % VBL-Timestamp for our "WaitBlanking" emulation: vbl=Screen('Flip', w); for i=1:movieDurationFrames % Draw image: Screen('DrawTexture', w, tex(movieFrameIndices(i))); % NEW: We only flip every 'waitframes' monitor refresh intervals: % For this, we calculate a point in time after which Flip should flip % at the next possible VBL. % This should happen waitframes * ifi seconds after the last flip % has happened (=vbl). ifi is the monitor refresh interval % duration. We subtract 0.5 frame durations, so we have some % headroom to take possible timing jitter or roundoff-errors into % account. % This is basically the old Screen('WaitBlanking', w, waitframes) % as known from the old PTB... vbl = Screen('Flip', w, vbl + (waitframes - 0.5) * ifi); end Priority(0); % Close all textures. This is not strictly needed, as % Screen('CloseAll') would do it anyway. However, it avoids warnings by % Psychtoolbox about unclosed textures. The warnings trigger if more % than 10 textures are open at invocation of Screen('CloseAll') and we % have 12 textues here: Screen('Close'); % Close window: sca; catch %this "catch" section executes in case of an error in the "try" section %above. Importantly, it closes the onscreen window if its open. sca; Priority(0); psychrethrow(psychlasterror); end %try..catch..