% Clear the workspace and the screen sca; close all; clear; % Here we call some default settings for setting up Psychtoolbox PsychDefaultSetup(2); % Get the screen numbers screens = Screen('Screens'); % Draw to the external screen if avaliable screenNumber = max(screens); % Define black and white white = WhiteIndex(screenNumber); black = BlackIndex(screenNumber); % Open an on screen window. If we are on a mac we request native retina % resolution to avoid only part of the movie being recorded. if IsOSX [window, windowRect] = PsychImaging('OpenWindow', screenNumber, black,... [], [], [], [], [], kPsychNeedRetinaResolution); else [window, windowRect] = PsychImaging('OpenWindow', screenNumber, black); end % Set the blend funciton for the screen Screen('BlendFunction', window, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA'); % Get the size of the on screen window [screenXpixels, screenYpixels] = Screen('WindowSize', window); % Get the centre coordinate of the window [xCenter, yCenter] = RectCenter(windowRect); % Maximum priority level topPriorityLevel = MaxPriority(window); Priority(topPriorityLevel); % Query the frame duration ifi = Screen('GetFlipInterval', window); % Maximum priority level topPriorityLevel = MaxPriority(window); Priority(topPriorityLevel); % Our sqaures will have sides 150 pixels in length, as we are going to be % rotating these around the origin using OpenGL commands we use -150 to % +150 for the X and Y coordinates dim = 300 / 2; baseRect = [-dim -dim dim dim]; % For this Demo we will draw 3 squares numRects = 3; % We will randomise the intial rotation angles of the squares. OpenGL uses % Degrees (not Radians) in these commands, so our angles are in degrees angles = rand(1, numRects) .* 360; % We will set the rotations angles to increase by 1 degree on every frame degPerFrame = 1; % We position the squares in the middle of the screen in Y, spaced equally % scross the screen in X posXs = [screenXpixels * 0.25 screenXpixels * 0.5 screenXpixels * 0.75]; posYs = ones(1, numRects) .* (screenYpixels / 2); % Finally, we will set the colors of the sqaures to red, green and blue colors = [1 0 0; 0 1 0; 0 0 1]; % Sync us and get a time stamp vbl = Screen('Flip', window); waitframes = 1; % Here we set up a movie pointer, the string that you see at the end of % this command specifies the codec that we will use in recording our video. % Video recording is handled via GStreamer via PTB. I have found that this % codec plays nicely for my purposes. Note that the codec will determine % which players will be able to play the movie. This codec will not open in % macOS QuickTime, but does fin in VLC. moviePtr = Screen('CreateMovie', window, 'rotatingSquaresDemo.mp4', ... [], [], [], ':CodecType=avenc_mpeg4'); % For this demo we will record a 10 second movie numSecs = 10; numFrames = round(numSecs / ifi); % Animation loop for frame = 1:numFrames % With this basic way of drawing we have to translate each square from % its screen position, to the coordinate [0 0], then rotate it, then % move it back to its screen position. % This is rather inefficient when drawing many rectangles at high % refresh rates. But will work just fine for simple drawing tasks. % For a much more efficient way of drawing rotated squares and rectangles % have a look at the texture tutorials for i = 1:numRects % Get the current squares position ans rotation angle posX = posXs(i); posY = posYs(i); angle = angles(i); % Translate, rotate, re-tranlate and then draw our square Screen('glPushMatrix', window) Screen('glTranslate', window, posX, posY) Screen('glRotate', window, angle, 0, 0); Screen('glTranslate', window, -posX, -posY) Screen('FillRect', window, colors(i,:),... CenterRectOnPoint(baseRect, posX, posY)); Screen('glPopMatrix', window) end % Flip to the screen vbl = Screen('Flip', window, vbl + (waitframes - 0.5) * ifi); % Now that we have flipped to the screen we add this displayed window % to our movie Screen('AddFrameToMovie', window); % Increment the rotation angles of the sqaures now that we have drawn % to the screen angles = angles + degPerFrame; end % We are done with movie recording now so we finalise and save Screen('FinalizeMovie', moviePtr); % Clear the screen sca;