最初に、MinimalisticOpenGLDemo を見たことがない方は、先にそちらをご覧ください。
ここでは、GLUTによる「手抜き」OpenGL入門「三次元図形を描く」で解説されている内容をPTBのプログラムの中で行う方法について解説します。またPTBとどのように連動させるのかに重きを置いているので、OpenGLに関する詳細な説明はリンク元をご覧ください。
y軸を中心に25度回転(回転というよりは水平方向の幅が狭まったように見えます)
clear all;AssertOpenGL;ListenChar(2);bgColor = [128 128 128]; % 背景色screenWidth = 500; % OpenGLで描画する領域(正方形)の幅。screenNumber=max(Screen('Screens'));InitializeMatlabOpenGL;try [windowPtr, windowRect] = Screen('OpenWindow', screenNumber, bgColor); % スクリーンの中心座標 [centerPos(1), centerPos(2)] = RectCenter(windowRect); % OpenGL関数で描画する領域 myRect = CenterRectOnPoint([0 0 screenWidth screenWidth], centerPos(1), centerPos(2)); % OpenGL関数を使い始めるという宣言 Screen('BeginOpenGL', windowPtr); % PTBの座標系では画面の左上が原点だが、OpenGLでは画面の左下が原点であることに注意。 glViewport(myRect(1), myRect(2), screenWidth, screenWidth); glMatrixMode(GL.PROJECTION); % アンダーバーがドットになっていることに注意。 glLoadIdentity; glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glClearColor(1,1,1,1); % 背景色 glClear; glRotated(25.0, 0.0, 1.0, 0.0); glBegin(GL.POLYGON); % アンダーバーがドットになっていることに注意。 glColor3d(1.0, 0.0, 0.0); % 赤 glVertex2d(-0.9, -0.9); glColor3d(0.0, 1.0, 0.0); % 緑 glVertex2d(0.9, -0.9); glColor3d(0.0, 0.0, 1.0); % 青 glVertex2d(0.9, 0.9); glColor3ub(255, 255, 0); % 黄色(0から255の値で指定したいときは、glColor3ubを使います) glVertex2d(-0.9, 0.9); glEnd(); % OpenGL関数の使用を終わります。 Screen('EndOpenGL', windowPtr); % この段階で、PTBの機能を使って図形を描画することも可能です。 Screen('FillRect', windowPtr, [255 0 0], [200 300 400 400]); Screen('Flip', windowPtr); KbWait; Screen('CloseAll'); ShowCursor; ListenChar(0);catch Screen('CloseAll'); ShowCursor; ListenChar(0); psychrethrow(psychlasterror);end線画を表示する。
clear all;AssertOpenGL;ListenChar(2);bgColor = [128 128 128]; % 背景色screenWidth = 500; % OpenGLで描画する領域(正方形)の幅。screenNumber=max(Screen('Screens'));InitializeMatlabOpenGL;% 頂点の情報vertex = [ 0, 0, 0 % A (1) 1, 0, 0 % B (2) 1, 1, 0 % C (3) 0, 1, 0 % D (4) 0, 0, 1 % E (5) 1, 0, 1 % F (6) 1, 1, 1 % G (7) 0, 1, 1 % H (8) ];% 2つの頂点を結ぶ線分の情報% MATLABでは行列の参照が0からではなく、1からであることに注意。edge = [ 1, 2 % ア(A-B) 2, 3 % イ(B-C) 3, 4 % ウ(C-D) 4, 1 % エ(D-A) 5, 6 % オ(E-F) 6, 7 % カ(F-G) 7, 8 % キ(G-H) 8, 5 % ク(H-E) 1, 5 % ケ(A-E) 2, 6 % コ(B-F) 3, 7 % サ(C-G) 4, 8 % シ(D-H) ];try [windowPtr, windowRect] = Screen('OpenWindow', screenNumber, bgColor); % スクリーンの中心座標 [centerPos(1), centerPos(2)] = RectCenter(windowRect); % OpenGL関数で描画する領域 myRect = CenterRectOnPoint([0 0 screenWidth screenWidth], centerPos(1), centerPos(2)); % OpenGL関数を使い始めるという宣言 Screen('BeginOpenGL', windowPtr); % PTBの座標系では画面の左上が原点だが、OpenGLでは画面の左下が原点であることに注意。 glViewport(myRect(1), myRect(2), screenWidth, screenWidth); glMatrixMode(GL.PROJECTION); % アンダーバーがドットになっていることに注意。 glLoadIdentity; glOrtho(-2, 2, -2, 2, -2, 2); glClearColor(1,1,1,1); % 背景色 glClear; glColor3d(0.0, 0.0, 0.0); glBegin(GL.LINES); % アンダーバーがドットになっていることに注意。 for i = 1:12 % 12本の線分を描く glVertex3dv(vertex(edge(i,1),:)); glVertex3dv(vertex(edge(i,2),:)); end; glEnd(); % OpenGL関数の使用を終わります。 Screen('EndOpenGL', windowPtr); % この段階で、PTBの機能を使って図形を描画することも可能です。 Screen('FillRect', windowPtr, [255 0 0], [200 300 400 400]); Screen('Flip', windowPtr); KbWait; Screen('CloseAll'); ShowCursor; ListenChar(0);catch Screen('CloseAll'); ShowCursor; ListenChar(0); psychrethrow(psychlasterror);end透視投影する。
clear all;AssertOpenGL;ListenChar(2);bgColor = [128 128 128]; % 背景色screenWidth = 500; % OpenGLで描画する領域(正方形)の幅。screenNumber=max(Screen('Screens'));InitializeMatlabOpenGL;% 頂点の情報vertex = [ 0, 0, 0 % A (1) 1, 0, 0 % B (2) 1, 1, 0 % C (3) 0, 1, 0 % D (4) 0, 0, 1 % E (5) 1, 0, 1 % F (6) 1, 1, 1 % G (7) 0, 1, 1 % H (8) ];% 2つの頂点を結ぶ線分の情報% MATLABでは行列の参照が0からではなく、1からであることに注意。edge = [ 1, 2 % ア(A-B) 2, 3 % イ(B-C) 3, 4 % ウ(C-D) 4, 1 % エ(D-A) 5, 6 % オ(E-F) 6, 7 % カ(F-G) 7, 8 % キ(G-H) 8, 5 % ク(H-E) 1, 5 % ケ(A-E) 2, 6 % コ(B-F) 3, 7 % サ(C-G) 4, 8 % シ(D-H) ];try [windowPtr, windowRect] = Screen('OpenWindow', screenNumber, bgColor); % スクリーンの中心座標 [centerPos(1), centerPos(2)] = RectCenter(windowRect); % OpenGL関数で描画する領域 myRect = CenterRectOnPoint([0 0 screenWidth screenWidth], centerPos(1), centerPos(2)); % OpenGL関数を使い始めるという宣言 Screen('BeginOpenGL', windowPtr); % PTBの座標系では画面の左上が原点だが、OpenGLでは画面の左下が原点であることに注意。 % 透視投影のときは、glViewportは不要。有効にすると表示が変わる。 %glViewport(myRect(1), myRect(2), screenWidth, screenWidth); glMatrixMode(GL.PROJECTION); % アンダーバーがドットになっていることに注意。 glLoadIdentity; gluPerspective(30.0, windowRect(3)/windowRect(4), 1.0, 100.0); glTranslated(0.0, 0.0, -5.0); glClearColor(1,1,1,1); % 背景色 glClear; glColor3d(0.0, 0.0, 0.0); glBegin(GL.LINES); % アンダーバーがドットになっていることに注意。 for i = 1:12 % 12本の線分を描く glVertex3dv(vertex(edge(i,1),:)); glVertex3dv(vertex(edge(i,2),:)); end; glEnd(); % OpenGL関数の使用を終わります。 Screen('EndOpenGL', windowPtr); % この段階で、PTBの機能を使って図形を描画することも可能です。 Screen('FillRect', windowPtr, [255 0 0], [200 300 400 400]); Screen('Flip', windowPtr); KbWait; Screen('CloseAll'); ShowCursor; ListenChar(0);catch Screen('CloseAll'); ShowCursor; ListenChar(0); psychrethrow(psychlasterror);end視点の位置を変更する。
clear all;AssertOpenGL;ListenChar(2);bgColor = [128 128 128]; % 背景色screenWidth = 500; % OpenGLで描画する領域(正方形)の幅。screenNumber=max(Screen('Screens'));InitializeMatlabOpenGL;% 頂点の情報vertex = [ 0, 0, 0 % A (1) 1, 0, 0 % B (2) 1, 1, 0 % C (3) 0, 1, 0 % D (4) 0, 0, 1 % E (5) 1, 0, 1 % F (6) 1, 1, 1 % G (7) 0, 1, 1 % H (8) ];% 2つの頂点を結ぶ線分の情報% MATLABでは行列の参照が0からではなく、1からであることに注意。edge = [ 1, 2 % ア(A-B) 2, 3 % イ(B-C) 3, 4 % ウ(C-D) 4, 1 % エ(D-A) 5, 6 % オ(E-F) 6, 7 % カ(F-G) 7, 8 % キ(G-H) 8, 5 % ク(H-E) 1, 5 % ケ(A-E) 2, 6 % コ(B-F) 3, 7 % サ(C-G) 4, 8 % シ(D-H) ];try [windowPtr, windowRect] = Screen('OpenWindow', screenNumber, bgColor); % スクリーンの中心座標 [centerPos(1), centerPos(2)] = RectCenter(windowRect); % OpenGL関数で描画する領域 myRect = CenterRectOnPoint([0 0 screenWidth screenWidth], centerPos(1), centerPos(2)); % OpenGL関数を使い始めるという宣言 Screen('BeginOpenGL', windowPtr); % PTBの座標系では画面の左上が原点だが、OpenGLでは画面の左下が原点であることに注意。 % 透視投影のときは、glViewportは不要。有効にすると表示が変わる。
%glViewport(myRect(1), myRect(2), screenWidth, screenWidth); glMatrixMode(GL.PROJECTION); % アンダーバーがドットになっていることに注意。 glLoadIdentity; gluPerspective(30.0, windowRect(3)/windowRect(4), 1.0, 100.0); gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glClearColor(1,1,1,1); % 背景色 glClear; glColor3d(0.0, 0.0, 0.0); glBegin(GL.LINES); % アンダーバーがドットになっていることに注意。 for i = 1:12 % 12本の線分を描く glVertex3dv(vertex(edge(i,1),:)); glVertex3dv(vertex(edge(i,2),:)); end; glEnd(); % OpenGL関数の使用を終わります。 Screen('EndOpenGL', windowPtr); % この段階で、PTBの機能を使って図形を描画することも可能です。 Screen('FillRect', windowPtr, [255 0 0], [200 300 400 400]); Screen('Flip', windowPtr); KbWait; Screen('CloseAll'); ShowCursor; ListenChar(0);catch Screen('CloseAll'); ShowCursor; ListenChar(0); psychrethrow(psychlasterror);end