2012年3月13日火曜日

OpenGL事始め1

OpenGLを弄るのに毎回調べ直している気がするので,まとめておこうかと.

仕様を手に入れる

ちょこちょこと気になると本当にそうなの,と調べてしまうので最初から仕様を手に入れておく.幸いOpenGLは仕様が公開されている.

OpenGL最新仕様
OpenGL Shader Language仕様
GLUT仕様

一通り揃えてiPadへ.

とりあえず,最小の部分から始めていこうかと.環境は,Mac OS X Lionで.Windowsでの手順もそのうち書こうかな.寒く無くなって,デスクトップに向かう気が起きたら.

OpenGLでウィンドウを表示する場合,基本的にはGLUTを利用することになる.まずは,このヘッダファイルを開けるかの確認.
// main.cpp
#include <GLUT/glut.h>

int main(int argc, char * argv[])
{
    return 0;
}

このコードをビルドしてみる.

$ g++ -o main main.cpp

特に何もしなくても,Lionの場合開発環境さえ入っていればGLUTまで入っているみたい.で,GLUTの初期化をする.

// main.cpp
#include <GLUT/glut.h>

int main(int argc, char * argv[])
{
    glutInit(&argc, argv);
    return 0;
}

そして,ビルド.

$ g++ -o main main.cpp

今度は失敗.GLUTライブラリをリンクしていないから仕方無い.で,Mac OS Xの場合便利なのが,-frameworkオプションで名前指定するだけで色々よしなにしてくれるってところ.

$ g++ -o main main.cpp -framework GLUT

これでビルドが通る.実行してみてもちゃんと特に何も起きずに終わる.GLUTの仕様によれば,glutInit()を実行する前に,glutInit系(glutInitWindowSizeなど)以外のglutの関数や,OpenGLの関数を呼び出してはいけない,とのこと.で,glutInitにargcとargvを渡す理由としては,いくつかのコマンドライン引数をGLUT側で処理してくれるから,ということ.例えば、-iconicでアイコン化(最小化?)で表示される,とか.

で,次はウィンドウを作ってみる.
// main.cpp
#include <GLUT/glut.h>

int main(int argc, char * argv[])
{
    glutInit(&argc, argv);
    glutCreateWindow("hello");
    return 0;
}

ビルドして実行すると,何事も無かったかのように終わる.GLUT仕様曰く,glutMainLoop()に入るまではウィンドウの表示状態が変わらない,とのこと.ということで,glutMainLoop()を追加する.

// main.cpp
#include <GLUT/glut.h>

int main(int argc, char * argv[])
{
    glutInit(&argc, argv);
    glutCreateWindow("hello");
    glutMainLoop();
    return 0;
}

すると,ウィンドウを描画するための関数が設定されていないよ,と文句を言われる.このウィンドウを描画するための関数は,glutDisplayFunc()で設定する.というわけで,さっそく登録してみる.仕様を見ながら関数の型だけ合わせて空の関数を作って登録する.

// main.cpp
#include <GLUT/glut.h>

void display();

int main(int argc, char * argv[])
{
    glutInit(&argc, argv);
    glutDisplayFunc(display);
    glutCreateWindow("hello");
    glutMainLoop();
    return 0;
}

void display()
{}

しかし,これをビルドして実行しても,さっきと同じ文句を言われる.仕様を読むと,ウィンドウが作成されたときには,描画関数が設定されておらず,表示するまでに設定するのがプログラマの責任,と書いてある.つまり,glutCreateWindow()で作成してから,glutMainLoop()に入るまでの間にglutDisplayFunc()で描画関数を登録する必要がある,ということ.というわけで,順番を修正する.

// main.cpp
#include <GLUT/glut.h>

void display();

int main(int argc, char * argv[])
{
    glutInit(&argc, argv);
    glutCreateWindow("hello");
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}

void display()
{}

とりあえず,これでビルドして実行すると,無事ウィンドウが表示される.
今日はこんなところかな.

0 件のコメント:

コメントを投稿