カメヲラボ

主にプログラミングとお勉強全般について書いてます

Stereo Graphics Programming(2)

ちょー簡単ステレオグラフィックス

Sharp Americaが公開しているステレオグラフィックスライブラリSGL/SPLを使うと、glutベースの3Dプログラムがあっという間にステレオ対応なのだ。ちょー簡単。どれくらいなのかというと、たとえばTeaPotを描くプログラムは


001 #include <GL/glut.h>
002 #include <iostream>
003 #include <SGLContext.h>
004
005 float nclip = 6.0, fclip = 12.0;
006 CSGLContext context;
007
008 void drawscene(){ glutSolidTeapot( 2.0 ); }
009
010 void draw()
011 {
012 glMatrixMode( GL_MODELVIEW );
013 glLoadIdentity();
014 glTranslatef(0.0, 0.0, -10.0);
015 glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
016
017 context.Begin( SGL_STEREO_FRAME );
018
019 context.Calculate();
020
021
022 context.Begin( SGL_DEPTH_FRAME );
023 drawscene();
024 context.End();
025
026 context.Begin( SGL_LEFT_FRAME );
027 drawscene();
028 context.End();
029
030 context.Begin( SGL_RIGHT_FRAME );
031 drawscene();
032 context.End();
033
034 context.End();
035
036 glutSwapBuffers();
037 }
038
039 void reshape( int w, int h )
040 {
041 glViewport( 0, 0, w, h );
042 glMatrixMode(GL_PROJECTION);
043 glLoadIdentity();
044 gluPerspective( 45.0, float(w)/float(h), nclip, fclip );
045
046 glutPostRedisplay();
047 }
048
049 int main(int argc, char* argv[])
050 {
051 CSGLDisplay display;
052 context.SetDisplay( display );
053 context.SetInterlacing( SGL_STENCIL );
054
055 glutInit(&argc, argv);
056 glutInitDisplayMode( GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE|GLUT_STENCIL );
057 glutCreateWindow(argv[0]);
058
059 glEnable(GL_DEPTH_TEST);
060 glEnable(GL_LIGHTING);
061 glEnable(GL_LIGHT0);
062
063 glutDisplayFunc( draw );
064 glutReshapeFunc( reshape );
065 glutMainLoop();
066
067 return 0;
068 }

これでおしまい。

CSGLContextというのがコントロールクラスで、そこにディスプレイ情報を格納したCSGLDisplayクラスのオブジェクトを登録するだけ。CSGLDisplayは、ディスプレイサイズ・ウィンドウサイズ・クリッピング距離・ディスプレイと視点との距離・両眼の間隔を設定しないといけないのだが、何も書かずにイケたのでデフォルト値で十分だということか。デフォルトの状態でうまく立体視できない人は、この辺の値を設定しないといけない。これは次回書こうかな。

draw関数内は、context.Begin(SGL_STEREO_FRAME)とcontext.End(SGL_STEREO_FRAME)で挟まれた部分にDEPTH_FRAME, LEFT_FRAME, RIGHT_FRAMEとして3回物体を書かなければならない。DEPTH_FRAMEは省略できるけど、省略すると立体感の精度がかなり落ちる。注意する点は、物体を描く前にcontext.Calculate()を呼んでビューボリューム計算をしておかないと全然意味が無いってこと。このcontext.Calculate()というヤツは、CSGLContextが持っている(隠蔽されているが・・・)CSPLCameraという、投影変換に必要な情報を持ったクラスに計算させるメソッドだ。計算方法が隠されているので、精度が気になる人はSGLライブラリ自体使わないほうが良いだろう。でもソースを見てわかるように、めちゃくちゃお手軽なのでお遊び程度ならこれで十分!!


ところで、ここに貼り付けたソースはid:santamartaさんの作ったCodeToHTML(http://smdn.invisiblefulmoon.net/)を使っている。コレ、大好き。ちなみにDのソースもこれでイケる。(キーワードは自分で登録しないとイカンけどな)