サンプル
3Dモデルの描画
ここでは、3Dモデルの基本的な描画方法について説明します。
目次
- (SourceFilesフォルダ内) brewmain.c : BREW独自の処理をまとめたファイル
- (Appフォルダ内) sample3d_v3.c : MascotCapsuleの処理をまとめたファイル
1. モデルの構成要素
3Dモデルは以下の3つの要素から構成されています。
- モデルデータ ( Figure )
3Dモデルの骨組みとなる部分です。MBACデータを読み込むことで取得します。 -
テクスチャデータ ( Texture )
モデルに貼り付けるテクスチャや背景などです。BMP(ビットマップ)データを読み込むことで取得します。 -
アクションデータ ( ActTable )
モデルのアニメーションについての情報です。MTRAデータを読み込むことで取得します。
2. モデルの描画手順
サンプルコードを用いて3Dモデルを描画する手順を説明します。
2.1. MascotCapsule V3インターフェースの生成
ISHELL_CreateInstance()を使用して、MascotCapsule V3 インターフェースを生成し、各関数を呼び出せるようにします。
また、使用するアロケータとインプットストリームの初期化も行います。
pMe -> pIM3D = NULL;
ISHELL_CreateInstance( pMe -> applet.m_pIShell, AEECLSID_IM3D_D31, ( void ** ) &pMe -> pIM3D );
/* Allocator 初期化 */
pMe -> allocatorVtbl.alloc = _alloc;
pMe -> allocatorVtbl.free = _free;
pMe -> allocatorVtbl.realloc = _realloc;
/* FileIstream 初期化 */
pMe -> istreamVtbl.readSint8 = _readSint8;
pMe -> istreamVtbl.readSint16 = _readSint16;
pMe -> istreamVtbl.readSint32 = _readSint32;
pMe -> istreamVtbl.readBytes = _readBytes;
pMe -> istreamVtbl.skipBytes = _skipBytes;
pMe -> istreamVtbl.fail = _fail;
2.2. Figure, Texture, ActionTable オブジェクトの初期化
使用するデータオブジェクト(Figure, Texture, ActionTable)を初期化します。使用するオブジェクトとアロケータとの関連付けを必要な数だけ行います。
[ sample3d_v3.c 内 ]IMICRO3D_Figure_initialize( pMe -> pIM3D, &pMe -> mc_data.figure, pMe -> pAlc );
IMICRO3D_Texture_initialize( pMe -> pIM3D, &pMe -> mc_data.texture [ 0 ] , pMe -> pAlc );
IMICRO3D_Texture_initialize( pMe -> pIM3D, &pMe -> mc_data.texture [ 1 ] , pMe -> pAlc );
IMICRO3D_ActTable_initialize( pMe -> pIM3D, &pMe -> mc_data.act, pMe -> pAlc );
2.3. データの読み込み
使用するオブジェクト(Figure, Texture, ActionTable)にモデルデータ、テクスチャデータ、アクションデータを読み込みます。
例 : Figureデータ読み込み
STRCPY( pMe -> mc_data.mbactraFile [ 0 ] , "\\data\\v3_sample.mbac" );
/* FileIstream オブジェクト 初期化 */
FileIstream_initialize( &fis, pMe -> m_pIFileMgr, pMe -> mc_data.mbactraFile [ 0 ] );
/* モデルデータ読み込み */
IMICRO3D_Figure_loadMbacData( pMe -> pIM3D, &pMe -> mc_data.figure, FileIstream_getIIstream( &fis ) );
/* FileIstream オブジェクト 終了 */
IFILE_Release( &fis );
2.4. カメラの初期化
カメラの初期化を行います。位置・視点方向・upベクトル・ニアクリップ・ファークリップ・画角を設定し、カメラ座標への変換行列を作成します。
[ sample3d_v3.c, sample3d_v3.h 内 ]#define CAM_NEAR 2048
#define CAM_FAR 32000
#define CAM_ANGLE 228
/* 視点設定 */
/* 位置 */
position.x = 0;
position.y = 1024;
position.z = 12288;
/* 視点方向 */
look.x = 0;
look.y &n = 1365;
look.z = -4096;
/* upベクトル */
up.x = 0;
up.y = 4096;
up.z = 0;
/* 視点変換行列取得 */
IMICRO3D_Atrans3i_setViewTrans( pMe -> mpMicro3D,
& position,
& look,
& up );
2.5. 描画時の環境設定
描画するための環境を指定します。具体的には、
- 描画対象となるフレームバッファの設定
- スクリーンの設定
- 投影方法の設定
等を行います。これらの各設定については、変更されない限りRenderに設定されたままになります。 同じ設定を使用する場合には、各設定は最初の一度で構いません。
投影方法については、透視投影と平行投影の2種類があります。 透視投影の場合は、
- IMICRO3D_Render_setPerspectiveFov()
- IMICRO3D_Render_setPerspectiveWH() あるいは、IMICOR3D_Render_setPerspectiveW()
を使用して設定します。平行投影の場合は、
- IMICRO3D_Render_setOrthographicScale()
- IMICRO3D_Render_setOrthographicWH() あるいは、IMICRO3D_Render_setOrthographicW()
を使用して設定します。
[ sample3d_v3.c 内 ]IMICRO3D_Render_setVram( pMe -> pIM3D,
GetBitmapWidth( pMe ),
GetBitmapHeight( pMe ),
GetBitmapPitch( pMe ),
pMe -> pimage );
/* 透視投影の設定 */
IMICRO3D_Render_setPerspectiveFov( pMe -> pIM3D,
  CAM_NEAR,
  CAM_FAR,
  CAM_ANGLE );
/* スクリーン中央位置の設定 */
IMICRO3D_Render_setScreenCenter( pMe -> pIM3D,
( GetBitmapWidth( pMe ) >> 1 ),
( GetBitmapHeight( pMe ) >> 1) );
2.6. モデルのアクションの設定
モデルにアニメーションが設定されている場合、対象となる描画時におけるモデルの姿勢を設定します。モデルの姿勢は、IMICRO3D_Figure_setPosture()で描画するフレームを設定することにより行います。アクションデータの最大フレーム数はIMICRO3D_ActTable_getNumFrames()で取得できます。
[ sample3d_v3.c 内 ]maxfrm = IMICRO3D_ActTable_getNumFrames( pMe -> pIM3D, &pMe -> mc_data.act, pMe -> mc_data.act_idx );
/* アニメーションのループ設定*/
if ( maxfrm != 0 )
{
{
pMe -> mc_data.act_frame -= maxfrm;
}
else
{
/* モデルの姿勢決定 */
IMICRO3D_Figure_setPosture( pMe -> pIM3D,
&pMe -> mc_data.act,
pMe -> mc_data.act_idx,
pMe -> mc_data.act_frame );
/* スピードの設定 */
pMe -> mc_data.act_frame += 32768;
2.7. モデルの描画
取得した各オブジェクトをレンダリングし、VRAMに転送します。レンダリングにはIMICRO3D_Render_drawFigure()を使用します。ただし、レンダリングは描画登録しか行いませんので、これだけではフレームバッファへの描画処理は実行されません。最後にIMICRO3D_Render_flush()を呼び出すことで、それまで登録されていたオブジェクトの描画処理が行われます。
[ sample3d_v3.c 内 ]Util_fillRect( pMe, BG_COLOR, 0, 0, GetBitmapWidth( pMe ), GetBitmapHeight( pMe ) );
/* 描画登録 */
if( HI_TRUE != IMICRO3D_Render_drawFigure( pMe -> pIM3D, & pMe -> mc_data.render, & pMe -> mc_data.figure ) )
{
return HI_FALSE;
/* フレームバッファへ描画 */
IMICRO3D_Render_flush( pMe -> mpMicro3D, &pMe -> mc_data.render );

Sample 描画結果
2.8. 終了処理
アプリケーションの終了時など、オブジェクトをすべて終了する場合は、以下の順序で終了処理を呼び出すことですべてのオブジェクトを終了し、リソースを解放することができます。
- Renderの終了処理
- すべてのActTableの終了処理
- すべてのTexture、Figure、Atrans3iの終了処理
- IMICRO3D_mcext_Endのコール
- IMICRO3D_Relleaseのコール
[ sample3d_v3.c 内 ]
IMICRO3D_Figure_finalize( pMe -> pIM3D, &pMe -> mc_data.figure );
IMICRO3D_Render_finalize( pMe -> pIM3D, &pMe -> mc_data.render );
IMICRO3D_ActTable_finalize( pMe -> pIM3D, &pMe -> mc_data.act );
IMICRO3D_Texture_finalize( pMe -> pIM3D, &pMe -> mc_data.texture [ 0 ] );
IMICRO3D_Texture_finalize( pMe -> pIM3D, &pMe -> mc_data.texture [ 1 ] );
{
IMICRO3D_Release( pMe -> pIM3D );
pMe -> pIM3D = NULL;
2.9. pitch幅取得処理
弊社ではこれまで、BREW上でV3をご利用頂く際、IMICRO3D_Render_setVramの第五引数(pitch:VRAM上で1ラインに含まれるピクセル数)にLCDサイズの横幅を設定することを、ご案内しておりました。
BREW4.0までは、LCD描画用のバッファの横幅と、LCDサイズの横幅がたまたま一致していたので問題とはならず、想定した描画結果を得ることができました。
しかし、BMP1.0では、LCD描画用のバッファの横幅が、LCDサイズの横幅と異なる値となるため、描画結果が画面上半分のみに表示されるという現象が発生してしまいます。また、これ以外の不具合が起こることも確認されています。
このように、LCDとサイズの横幅をpitchの値として使用することは、本来間違いですので、SPICEの案内をご参考にご修正をお願いいたします。
以下にV3のアプリの修正方法を示します。
- IBITMAP_QueryInterfaceを用い、BREW のデバイス独立ビットマップ形式(AEECLSID_DIB)へのインタフェースを取得。
- 同インターフェースのメンバ”nDepth”の値(1ピクセルのビット数)をバイト数に変換。
- 同インターフェースのメンバ”nPitch”の値(次の行へのオフセット)を上記2 の値にて除算。
pMe->pitch = (pMe->pAEEDIB->nPitch / ( pMe->pAEEDIB->nDepth >> DIV_8 ));
この “pMe->pitch” をIMICRO3D_Render_setVramの第五引数に設定します。
[ sample3d_v3.c 内 ]IMICRO3D_Render_setVram(pMe->pIM3D, &pMe->mc_data.render,
GetBitmapHeight( pMe ),
GetBitmapPitch( pMe ),
pMe->pimage);
なお、V3エンジン Ver.E を使用した場合、エンジン内部で自動的にpitchの値を設定しますが、pitchの値としては、上記処理にて算出した値をご使用頂くことを推奨いたします。
詳しい内容につきましては、以下のガイドラインをご参照願います。
MascotCapsule V3 BREW Extension Guideline


