OpenGL関数で階層構造

最初に、MinimalisticOpenGLDemo を見たことがない方は、先にそちらをご覧ください。

ここでは、GLUTによる「手抜き」OpenGL入門「階層構造」で解説されている内容をPTBのプログラムの中で行う方法について解説します。またPTBとどのように連動させるのかに重きを置いているので、OpenGLに関する詳細な説明はリンク元をご覧ください。

実行するとアニメーションが開始されます。左矢印キーを押すたびに、アニメーションの有効と無効が切り替わります。アニメーションが無効な状態で右矢印キーを押すと、立方体が1度だけ回転します。エスケープキーで終了します。

オリジナルのデモと異なり、glutWireCube関数を使用しています。

clear all;
AssertOpenGL;
ListenChar(2);
screenNumber=max(Screen('Screens'));
InitializeMatlabOpenGL;
try
    [windowPtr, windowRect] = Screen('OpenWindow', screenNumber);
    % スクリーンの中心座標
    [centerPos(1), centerPos(2)] = RectCenter(windowRect);
        
    % OpenGL関数を使い始めるという宣言
    Screen('BeginOpenGL', windowPtr);
    glMatrixMode(GL.PROJECTION); % アンダーバーがドットになっていることに注意。
    glLoadIdentity;    
    gluPerspective(30.0, windowRect(3)/windowRect(4), 1.0, 100.0);
    
    glMatrixMode(GL.MODELVIEW);
    glLoadIdentity;
    gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); % 視点位置と視線方向
    
    r = 0; % 回転角の初期値
    flag = 1; % flagが1のときrが自動的に加算される。(アニメーション)
    
    while KbCheck; end; % いずれのキーも押していないことを確認
    while 1 % while 文の中をぐるぐる回ります。
        [ keyIsDown, keyTime, keyCode ] = KbCheck; % キーが押されたか、そのときの時間、どのキーか、の情報を取得する
        if keyIsDown
            if keyCode(KbName('ESCAPE')) % エスケープキーでプログラムを終了
                break;
            end
            if keyCode(KbName('LeftArrow'))
                flag = 1-flag; % アニメーションを有効にしたり、無効にしたり。
            end;
            
            if keyCode(KbName('RightArrow'))
                r = r + 1; % 手動で回転角度を増やす。
                if r >= 360
                    r = 0;
                end;
            end;
            while KbCheck; end;                    
        end;
        
        glClearColor(1,1,1,1); % 背景色
        glClear;
        glPushMatrix(); % モデルビュー変換行列の保存
        
        glRotated(r, 0, 1, 0); % 図形の回転
        
        % ひとつ目のキューブ
        glColor3d(0, 0, 1);
        glutWireCube(0.5);
        
        % ふたつ目のキューブ
        glPushMatrix();
        glTranslated(1, 1, 1);
        glRotated(2*r, 0.0, 1.0, 0.0);
        glColor3d(0, 1, 0);
        glutWireCube(0.5);
        glPopMatrix(); % モデルビュー変換行列の復帰
        
        glPopMatrix(); % モデルビュー変換行列の復帰
                
        % OpenGL関数の使用を終わります。
        Screen('EndOpenGL', windowPtr);
        % この段階で、PTBの機能を使って図形を描画することも可能です。
        Screen('FillRect', windowPtr, [255 0 0], [200 300 400 400]);
        Screen('Flip', windowPtr);
        
        % 次の繰り返しのために
        Screen('BeginOpenGL', windowPtr);
        
        if flag % flagが1のときはアニメーション
            r = r + 1;
            if r >= 360
                r = 0;
            end;
        end;
    end;
    
    % OpenGL関数の使用を終わります。
    Screen('EndOpenGL', windowPtr);
    Screen('CloseAll');
    ShowCursor;
    ListenChar(0);
catch
    Screen('CloseAll');
    ShowCursor;
    ListenChar(0);
    psychrethrow(psychlasterror);
end