MascotCapsuleで立方体の3D描画に挑戦:“BREW”アプリケーション開発入門(9)(1/2 ページ)
「MascotCapsule eruption」を用いたBREW上での3Dプログラミングについて解説。今回は、立方体の3D描画にチャレンジする!!
前回は、エイチアイ社が提供する3D描画エンジン「MascotCapsule® eruption(以下、eruption)」を用いたBREW上での3Dプログラミングを行うための環境構築を行いました。
今回はこの環境を使って、実際に3D描画を行いたいと思います。プロジェクトは、前回のものを引き続き利用し、連載第7回で紹介した立方体の3D描画を行いたいと思います。
3D描画のセットアップ
まず、eruptionでの3D描画を行うための準備を行います。ここで行うeruptionの主な処理は以下のとおりです。
- 描画コンテキストの生成
- フレームバッファサイズの設定
- ビューポートの設定
- クリッピング領域の設定
- カメラ設定
- 3Dデータのロード
それでは、3D描画のセットアップに関するソースコードを確認してみましょう(ソース1)。
boolean setup(eruption1* pMe){
hi_bool isCreate; // 初期化判定
hi_exception exception; // 例外判定
hi_sint32 WWidth; // 画面サイズ幅
hi_sint32 WHeight; // 画面サイズ縦
pMe->pIMC = NULL; // eruptionのインスタンス格納
// eruptionのインスタンス生成
ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_ERUPTION_A31, (void **)&pMe->pIMC);
isCreate = mceGraphics3D_initializeContext(&pMe->a); // 描画コンテキストの初期化
if (isCreate != HI_TRUE){
return FALSE;
}
pMe->G3d = mceGraphics3D_create (&exception); // 描画コンテキストの生成
if ((pMe->G3d == NULL) || (exception != hi_NoException)){
return FALSE;
}
ISHELL_GetDeviceInfo(pMe->a.m_pIShell, &pMe->DeviceInfo); // 画面サイズの取得
WWidth = pMe->DeviceInfo.cxScreen;
WHeight = pMe->DeviceInfo.cyScreen;
mceGraphics3D_setContextSize(pMe->G3d, WWidth, WHeight); // フレームバッファのサイズを指定
exception = mceGraphics3D_setViewport(pMe->G3d, 0, 0, WWidth, WHeight); // ビューポートの設定
if(exception != hi_NoException){
return FALSE;
}
exception = mceGraphics3D_setClip(pMe->G3d, 0, 0, WWidth, WHeight); // クリッピング領域の設定
if(exception != hi_NoException){
return FALSE;
}
pMe->Camera = mceCamera_create (&exception); // カメラオブジェクト生成
if ((pMe->Camera == NULL) || (exception != hi_NoException)){
return FALSE;
}
// カメラの初期値設定
pMe->AspectRate = MCE_DIV((hi_coord)WWidth, (hi_coord)WHeight);
pMe->ViewAngle = MCE_F2C(45.0f);
pMe->NearClip = MCE_F2C(1.0f);
pMe->FarClip = MCE_F2C(100.0f);
if (!dataLoad(pMe, “data\\test_model01.mcm”)){ // データロード
return FALSE;
}
pMe->Figure = (mceFigure *)pMe->Obj3d [0];
FREE (pMe->Obj3d);
// MCMデータ内のmceFigureを検索し、取得
pMe->Fig_model =
(mceNodeDeformerNode*)mceObject3D_findObject3D((mceObject3D*)pMe->Figure, ClassId_Figure, 0);
if (pMe->Fig_model == NULL){
return FALSE;
}
// モデル回転量の初期化
pMe->ObjRx = MCE_F2C(0.0f);
pMe->ObjRy = MCE_F2C(0.0f);
return TRUE;
}
| ソース1 3D描画のセットアップに関するソースコード |
次に、構造体に以下のメンバを追加します。eruption特有のデータ型については、「mce」および「hi_」の接頭辞が付きます。この中でも「hi_coord」型は、固定小数点を扱う型で、前回解説した“高速化”を行うための機能になります。hi_coord型を利用することにより浮動小数点、固定小数点の変換や計算が容易に行えるため、浮動小数点と固定小数点を意識しない演算が可能になります。
Imc* pIMC; // エクステンションインスタンスの格納
mceGraphics3D *G3d; // MceGraphics3Dオブジェクトの格納
mceCamera *Camera; // カメラオブジェクト
hi_coord AspectRate; // アスペクト比
hi_coord ViewAngle; // 視野角
hi_coord NearClip; // ニアクリップ
hi_coord FarClip; // ファークリップ
mceObject3D **Obj3d; // Object3Dオブジェクト格納
mceFigure *Figure; // シーングラフのルートとなるmceFigure
mceNodeDeformerNode *Fig_model; // mceFigure内のモデル
hi_coord ObjRx; // モデルX軸回転量
hi_coord ObjRy; // モデルY軸回転量
関数宣言を追加します。
boolean setup(eruption1* pMe);
さらに、以下のマクロを定義します。前回、接頭辞を省略できるとして「convert.h」をインクルードしましたが、さらにeruptionのインスタンスを「GPIMC」として定義する必要があります。これは、convert.h内で接頭辞を省略するためにeruptionのインスタンスが必要で、それがGPIMCと定義してあることを前提にしているためです。
#define GPIMC pMe->pIMC
では、ソースの主要な部分を確認してみましょう。まず、「ISHELL_CreateInstance()」によるextentionのインスタンス化ですが、eruptionのクラスIDである「AEECLSID_ERUPTION_A31」を指定して、extentionのインスタンス化を行っています。これによりeruptionの各関数が使用可能になります。これ以降からeruptionの処理に入っていきます。
描画コンテキストの生成
「mceGraphics3D_initializeContext()」は、「mceGraphics3D」というeruptionが3D描画を行う際に利用するオブジェクトの生成およびOpenGL ESの初期化を行います。mceGraphics3Dの実体は、eruption内部に隠蔽(ぺい)されているOpenGL ESの状態管理オブジェクトで、このオブジェクトに対してさまざまな描画設定を行うことにより、その設定がOpenGL ESの描画に反映されます。そして、「mceGraphics3D_create()」により、mceGraphics3Dが生成され、利用可能な状態になります。mceGraphics3D_create()は、引数にエラーチェックを設定でき、例外が発生した場合には、この中に例外情報がセットされます。定義されている例外には、以下があります。
| 例外 | 内容 |
|---|---|
| hi_NoException | 例外なし |
| hi_IllegalArgumentException | 引数不正 |
| hi_NullPointerException | 引数がNULL |
| hi_IndexOutOfBoundsException | インデックス範囲外 |
| hi_IllegalStateException | 異常な内部状態 |
| hi_NotEnoughMemory | メモリ不足 |
| hi_ArithmeticException | 演算エラー |
| hi_IOException | I/Oエラー |
| hi_IllegalDataException | データエラー |
| 表1 定義されている例外 | |
フレームバッファのサイズ設定
「mceGraphics3D_setContextSize()」は、描画ターゲットであるフレームバッファの領域サイズを指定する関数です。ここでは画面サイズを取得して全画面表示を行うようにしていますが、アプリケーションによっては、一部しか3D描画領域を使用しない場合もあります。このような場合にmceGraphics3D_setContextSize()で、任意のサイズを指定することにより、描画バッファを調整して描画リソースをコントロールできます。
ビューポート、クリッピング領域の設定
「mceGraphics3D_setViewport()」でビューポートの設定を行います。これは、前回のOpenGL ESの際にも設定した内容と同様のものです。「mceGraphics3D_setClip()」では、クリッピング領域を設定します。クリッピング領域とは、描画結果を最終的にディスプレイに表示する領域で、ここで指定した領域がディスプレイに表示されます。例えば、画面全体に描画バッファを取っていても、クリッピング領域で100×100の領域設定をすると、この部分しかディスプレイには表示されません(図1)。
カメラ設定
カメラの設定は、描画処理の部分で設定しますが、ここでは「mceCamera_create()」でカメラオブジェクトの生成を行っておきます。設定する値については、Applet構造体に「AspectRate」「ViewAngle」「NearClip」「FarClip」を追加して標準視野角の値をセットしておきます(設定は後ほど行います)。
ここで使われている「MCE_DIV」と「MCE_F2C」のマクロですが、これはeruptionが提供するマクロで「eruption_a31.h」をインクルードすることで利用可能になります。なお、それぞれの機能についてですが、MCE_DIVは固定小数点の除算を行い、MCE_F2Cは浮動小数点を固定小数点に変換します。
3Dデータのロード
前回説明した「dataLoad()」で3Dオブジェクトのデータをロードします。eruptionの3Dのモデルデータは「mcmデータ」といい、3Dオーサリングツールで作成します。ここでは、事前に用意した立方体のデータをロードしますので、以下のデータ「sample_cube.mcm」をダウンロードして、プロジェクトフォルダ内にdataフォルダを作成し、そこにデータを格納します。
| ダウンロード: | |
|---|---|
| ⇒ | 「sample_cube.mcm」のダウンロード |
dataLoad()内では、「mceLoader_load()」によりロードされたモデルデータがApplet構造体に追加した「mceObject3D」型の「Obj3d」メンバにセットされるようになっています。ロードされたデータはその種類により操作するためのオブジェクトが異なるのですが、ここではモデルデータをコントロールするため「mceFigure」型にキャストしています。
そして、「mceObject3D_findObject3D()」でロードしたmcmデータの中から立方体のオブジェクトを取り出します。詳細は次回以降で解説しますが、eruptionのmcmデータから取り出した「mcmFigureオブジェクト」は「シーングラフ」になっています。シーングラフとは、各オブジェクトをツリー構造で構成させ、描画を実現するグラフィックスのモデルです。つまり、mcmFigureオブジェクトには、複数のオブジェクトが連なっており、そこから対象をクラス種別とIDで探し出すのがmceObject3D_findObject3D()の機能です。ここでは「ClassId_Figure」と「ID 0」を指定することにより、立方体のオブジェクトを取り出しています。
Copyright © ITmedia, Inc. All Rights Reserved.
