Springheadを利用するアプリケーションの作成を容易にするために,アプリケーションクラスFWAppが用意されています. 2.5にFWAppを使って簡単なアプリケーションを 作成する方法について説明しましたのでそちらも合わせて参考にしてください.
冒頭で説明した通り,Springheadのほとんどのオブジェクトは,親オブジェクトのCreate系関数を使って作成しますが, FWAppは例外的に,C++のクラス継承を用いてユーザのアプリケーションクラスを定義する方法をとります. この方が 仮想関数によって動作のカスタマイズがフレキシブルに行えるからです.
以下ではFWAppの機能やユーザが実装すべき仮想関数について順に見ていきます.
FWAppの初期化処理は仮想関数Initで行います.
FWApp |
|
virtual void Init(int argc, char* argv[]) |
|
以下にInit関数のデフォルトの実装を示します.
void FWApp::Init(int argc, char* argv[]){ // create SDK CreateSdk(); // create a single scene GetSdk()->CreateScene(); // initialize window manager GRInit(argc, argv); // create main window CreateWin(); // create timer CreateTimer(); }
はじめに
CreateSdk();
でSDKを作成します. つぎに
GRInit(argc, argv);
でウィンドウマネジャが作成されます. デフォルトではGLUTを用いるウィンドウマネジャが作成されます. さらに
GetSdk()->CreateScene();
でFWSceneを1つ作成します. つづいて
CreateWin();
でメインウィンドウを作成します. 最後に
CreateTimer();
でタイマを作成します.
この基本処理に追加してなんらかの処理を行う場合は
virtual void Init(int argc = 0, char* argv[] = 0){ // select GLUI window manager SetGRAdaptee(TypeGLUI); // call base Init FWApp::Init(argc, argv); // do extra initialization here }
のように,FWApp:Initを実行してから追加の処理を行うのが良いでしょう. 一方,以下に挙げるようなカスタマイズが必要な場合はInit関数の処理全体を派生クラスに記述する必要があります.
• シーン生成をカスタマイズしたい
• ウィンドウの初期サイズやタイトルを変更したい
• 異なる種類のタイマが使いたい
この場合は,上に載せたInitのデフォルト処理をもとに必要な部分に修正を加えるのが良いでしょう.
プログラムの全体の構造は通常以下のようになります.
MyApp app; int main(int argc, char* argv[]){ app.Init(argc, argv); app.StartMainLoop(); return 0; }
ここでMyAppはユーザが定義したFWAppの派生クラスです(もちろん他の名前でも構いません) . MyAppのインスタンスをグローバル変数として定義し, main関数でInit, StartMainLoopを順次実行します. StartMainLoop関数はアプリケーションのメインループを開始します.
タイマの作成にはCreateTimer関数を使います. 通常,CreateTimerはInitの中で呼びます.
FWApp |
|
UTTimerIf* CreateTimer(UTTimerIf::Mode mode) |
|
引数modeに指定できる値はUTTimerのSetModeと同じです. 5.4節を参照してください. 戻り値としてUTTimerのインタフェースが返されます. 周期などの 設定はこのインタフェースを介して行います.
シミュレーション用と描画用に2つのタイマを作成する例を以下に示します.
UTTimerIf *timerSim, *timerDraw; timerSim = CreateTimer(MULTIMEDIA); timerSim->SetInterval(10); timerDraw = CreateTimer(FRAMEWORK); timerDraw->SetInterval(50);
この例ではシミュレーション用には周期を[ms]のマルチメディアタイマを使い, 描画用には周期
[ms]のフレームワークタイマ(GLUTタイマ)を使っています.
タイマを始動すると,周期ごとに以下の仮想関数が呼ばれます.
FWApp |
|
virtual void TimerFunc(int id) |
|
タイマの判別は引数で行います.
TimerFuncのデフォルトの振る舞いでは, カレントウィンドウのシーンのStepを呼び,つぎにPostRedisplayで再描画要求を発行します (その結果,直後にDisplay関数が呼び出されます) イズしたい場合はTimerFunc関数をオーバライドします.
void TimerFunc(int id){ // proceed simulation of scene attached to current window if(id == timerSim->GetID()){ GetCurrentWin()->GetScene()->Step(); } // generate redisplay request else if(id == timerDraw->GetID()){ PostRedisplay(); } }
この例ではシミュレーションと描画に異なる2つのタイマを使用しています.
描画処理は次の仮想関数で行います.
FWApp |
|
virtual void Display() |
|
Displayは描画要求が発行されたときに呼び出されます. 描画要求はPostRedisplay関数で行います.
FWApp |
|
virtual void PostRedisplay() |
|
Display関数のデフォルトの振る舞いではカレントウィンドウのDisplay関数が呼ばれます.
FWAppは各ウィンドウに関連付けられた仮想キーボード・マウスデバイスDVKeyMouseにコールバック登録されています. したがって以下の仮想関数をオーバライドすることでキーボード・マウスイベントを処理できます.
FWApp |
virtual bool OnMouse(int button, int state, int x, int y) |
virtual bool OnDoubleClick(int button, int x, int y) |
virtual bool OnMouseMove(int state, int x, int y, int zdelta) |
virtual bool OnKey(int state, int key, int x, int y) |
各イベントハンドラの詳細については10.5節を参照して下さい.