0

I asked a similar question some time ago but I think I might be able to formulate it better now.

The code below (which I am adapting, not writing from scratch) plots a white bar in the correct place and with a correct angle, pictured below. It uses OpenGL commands in Psychtoolbox (running on Matlab). Psychtoolbox coordinates are very simple and pixel-based: (0,0) is on the top left. Y increases downwards and x increases rightwards.

I am having trouble understanding the mapping between OpenGL and Psychtoolbox coordinates. In particular, the line glTranslatef( SkitSet.xLever, SkitSet.yLever, 0 ); translates the white bar 1.5 units downwards. What are these units? Where am I telling matlab that 1.5 units in OpenGL are roughly half the vertical screen?

%% Psychtoolbox settings
whichScreen  = 0;
Screen('Preference', 'SkipSyncTests', 1); %1->without testing
inScreenRect = [0 0 500 500];


% Open window and specify some OpenGL settings
InitializeMatlabOpenGL( [], [], [], 0 );
[win , winRect] = PsychImaging( 'OpenWindow', whichScreen, 0, inScreenRect, [], [], 0, 0 );
Screen( 'BeginOpenGL', win );
aspectRatio = winRect( 4 ) / winRect( 3 );                       %% Get the aspect ratio of the screen
[winCenter.x, winCenter.y] = RectCenter(winRect);        %find the center of the screen
glMatrixMode( GL.PROJECTION );
glLoadIdentity;
gluPerspective( 25, 1 / aspectRatio, 0.1, 100 );
glMatrixMode( GL.MODELVIEW );
glLoadIdentity;
gluLookAt( 0, 0, 8, 0, 0, 0, 0, 1, 0);          %Set view point, center and direction
glClearColor( 0, 0, 0, 0 );
Screen( 'EndOpenGL', win );

SkitSet.xLever          = 0;        
SkitSet.yLever          = -1.5000;
SkitSet.LeverLength     = 0.4000;
SkitSet.LeverWidth      = 0.0400;


Screen( 'BeginOpenGL', win );
glClear;
glPushMatrix;
glTranslatef( SkitSet.xLever, SkitSet.yLever, 0 );
glRotatef( -45, 0.0, 0.0, 1.0 );                                         
glRectf( -SkitSet.LeverLength, -SkitSet.LeverWidth / 2, 0, SkitSet.LeverWidth / 2 );
glPopMatrix;
Screen( 'EndOpenGL', win );
Screen( 'Flip', win, [], [], 0 );                                   

Result of minimal code

Community
  • 1
  • 1
elisa
  • 965
  • 9
  • 27

1 Answers1

0

This is more of an OpenGL question than anything Psychtoolbox specific. You are setting up projection frustum. So any stimulus you draw will be projected using that projection and modelview that you set up. The units are arbitrary, but its helpfull to think of them in, e.g., meters. If zNear and zFar in gluPerspective are in meters, then all the other calls such as glTranslatef and glRectf also take input parameters in that same unit. If you want to move things down half the screen, you'll have to compute where that is in Y and Z, given the FOV you specified in gluPerspective. If you are just drawing a lever, are you sure you want to set up your own projection and modelview matrix? The Psychtoolbox default will do the trick for you and then you can address individual pixels, also in OpenGL mode. If PTB defaults don't work, then set up a gluortho2d using the window rect as the four vertices.