michtesar
3/23/2017 - 1:47 PM

MATLAB tutorial for accessing OpenGL with sphere textures in Psychtoolbox.

MATLAB tutorial for accessing OpenGL with sphere textures in Psychtoolbox.

function DrawScene2(position_1, position_2, target, debug)
% Draws scene aka arena for paradigm stimulation
%   of two spheres in arena with texture.
%
% position_1 (array if double) - sets x, y and z coordinates
%                                of first sphere in arena
% position_2 (array if double) - sets x, y and z coordinates
%                                of second sphere in arena
%
% Michael Tesar <michtesar@gmail.com>
% 2017 Prague
%
clear;

global GL;

KbName('UnifyKeyNames');
rightKey = KbName('RightArrow');
leftKey = KbName('LeftArrow');

if nargin < 1
    position_1 = [-2, 0, 0];
    position_2 = [4, 0, -3];
    target = 2;
    debug = true;
end

if ~debug
    stereo = 1;
else
    stereo = 0;
end

if target == 1
    color_1 = [1.0, 0.0, 0.0];
    color_2 = [1.0, 1.0, 1.0];
else
    color_1 = [1.0, 1.0, 1.0];
    color_2 = [1.0, 0.0, 0.0];
end
    

AssertOpenGL;
screenid=max(Screen('Screens'));

try
    InitializeMatlabOpenGL;
    PsychImaging('PrepareConfiguration');
    [win, winRect] = PsychImaging('OpenWindow', screenid, 0,...
        [], [], [], stereo, []);

    Screen('BeginOpenGL', win);
    ar = RectHeight(winRect) / RectWidth(winRect);

	glViewport(0, 0, RectWidth(winRect), RectHeight(winRect));
    glColor3f(0,0,1);
    glEnable(GL.LIGHT0);
    glEnable(GL.BLEND);
    glBlendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA);
    glMatrixMode(GL.PROJECTION);
    glLoadIdentity;
    gluPerspective(25, 1/ar, 0.1, 100);
    glMatrixMode(GL.MODELVIEW);
    glLoadIdentity;
    glLightfv(GL.LIGHT0,GL.POSITION,[ 1 2 3 0 ]);
    gluLookAt(0,0,10,0,0,0,0,1,0);
    glClearColor(0,0,0,0);
    glClear;

    Screen('EndOpenGL', win);
    ifi = Screen('GetFlipInterval', win);
    vbl = Screen('Flip', win);

    Screen('BeginOpenGL', win);

    glEnable(GL.LIGHTING);
    glEnable(GL.DEPTH_TEST);
    glLightfv(GL.LIGHT0,GL.POSITION,[ 1 2 3 0 ]);
    
    Screen('EndOpenGL', win);
    
    % Texture setting %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    glEnable(GL.TEXTURE_2D);
    glEnable(GL.DEPTH_TEST);
    glShadeModel(GL.SMOOTH);
    image = imread('grass.jpg');
    grassTexture = Screen('MakeTexture', win, image);
    glTexParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
    glTexParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
    sphere = gluNewQuadric();
    gluQuadricDrawStyle(sphere, GLU.FILL);
    gluQuadricNormals(sphere, GLU.SMOOTH);
    gluQuadricTexture(sphere, GL.TRUE);
    grassPointer = glGenTextures(1);
    glBindTexture(GL.TEXTURE_2D, grassPointer);
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    while true
        [keyIsDown, seconds, keyCode] = KbCheck;
        
        if KbCheck   
            if keyCode(rightKey)
                disp('Right key was pressed.');
                if target == 2
                    disp('Correct!');
                else
                    disp('Incorrect!');
                end
            elseif keyCode(leftKey)
                disp('Left key was pressed.');
                if target == 1
                    disp('Correct!');
                else
                    disp('Incorrect!');
                end
            else
                disp('Other key was pressed.');
            end
            
            disp(['Reaction time: ', num2str(seconds), ' sec']);
            
            break;
        end
        
        for view = 0:1
            Screen('SelectStereoDrawbuffer', win, view);
            Screen('BeginOpenGL', win);
            glMatrixMode(GL.MODELVIEW);
            glLoadIdentity;
            gluLookAt(-0.4 + view * 0.8 , 0, 10, 0, 0, 0, 0, 1, 0);
            glClear;
            
            % IMPORTANT: Enable changing color in materials
            glEnable(GL.COLOR_MATERIAL);
            
            % Left sphere
            glColor3f(color_1(1), color_1(2), color_1(3));
            glTranslatef(position_1(1), position_1(2), position_1(3));
            glutSolidSphere(1.0, 100, 5);
            
            % Right sphere WITH TEXTURE ON IT %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            glTexImage2D(GL.TEXTURE_2D, 0, GL.RGB, 270, 270,...
                0, GL.RGB, GL.UNSIGNED_BYTE, image);
            glTexParameterfv(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.REPEAT);
            glTexParameterfv(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.REPEAT);
            glTexParameterfv(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
            glTexParameterfv(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
            
            glTexEnvfv(GL.TEXTURE_ENV, GL.TEXTURE_ENV_MODE, GL.MODULATE);
            glTranslatef(position_2(1), position_2(2), position_2(3));
            gluSphere(sphere, 2.3, 100.0, 5.0);
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            
            % Wired arena
            glColor3f(0.0, 1.0, 0.0);
            glTranslatef(-2, 0, 0);
            glRotatef(-90, 1, 0, 0);
            glutWireSphere(15, 100, 5);
            
            glPushAttrib(GL.LIGHTING_BIT);
            glLightfv(GL.LIGHT0,GL.POSITION,[ 1 2 3 0 ]);
            glPopAttrib;
            
            
            Screen('EndOpenGL', win);
        end
        
        Screen('DrawingFinished', win, 2);
        vbl = Screen('Flip', win, vbl + 0.5 * ifi, 2);    
    end
    
    Screen('Flip', win);
    sca;
    
catch
    sca;
end

return