サンプル

3Dモデルの描画

ここでは、3Dモデルの基本的な描画方法について説明します。

3Dモデルの描画

目次





サンプルプログラムは、処理内容から大きく2つのファイルに分かれています。
  • (SourceFilesフォルダ内) brewmain.c : BREW独自の処理をまとめたファイル
  • (Appフォルダ内) sample3d_v3.c : MascotCapsuleの処理をまとめたファイル
下記 文中では、[ ] でどちらのファイルに含まれているか記述してありますので、参考にしてください。

1. モデルの構成要素

3Dモデルは以下の3つの要素から構成されています。





2. モデルの描画手順

サンプルコードを用いて3Dモデルを描画する手順を説明します。

2.1. MascotCapsule V3インターフェースの生成

ISHELL_CreateInstance()を使用して、MascotCapsule V3 インターフェースを生成し、各関数を呼び出せるようにします。
また、使用するアロケータとインプットストリームの初期化も行います。

  [ brewmain.c 内 ]
/* インターフェースの作成 */
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 内 ]
/* 3D関連オブジェクトの初期化 */
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データ読み込み

  [ sample3d_v3.c 内 ]
/* データへのパス指定 */
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,
        &pMe -> mc_data.view_trans,
        & position,
        & look,
        & up );

2.5. 描画時の環境設定

描画するための環境を指定します。具体的には、

等を行います。これらの各設定については、変更されない限りRenderに設定されたままになります。 同じ設定を使用する場合には、各設定は最初の一度で構いません。

投影方法については、透視投影と平行投影の2種類があります。 透視投影の場合は、

を使用して設定します。平行投影の場合は、

を使用して設定します。

  [ sample3d_v3.c 内 ]
/* フレームバッファの設定 */
IMICRO3D_Render_setVram( pMe -> pIM3D,
 pMe -> mc_data.render,
 GetBitmapWidth( pMe ),
 GetBitmapHeight( pMe ),
 GetBitmapPitch( pMe ),
pMe -> pimage );

/* 透視投影の設定 */
IMICRO3D_Render_setPerspectiveFov( pMe  -> pIM3D,
  &pMe -> mc_data.render,
  CAM_NEAR,
  CAM_FAR,
  CAM_ANGLE );

/* スクリーン中央位置の設定 */
IMICRO3D_Render_setScreenCenter( pMe -> pIM3D,
&pMe -> mc_data.render,
( 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 )
{
if ( pMe -> mc_data.act_frame > maxfrm )
{
     pMe -> mc_data.act_frame -= maxfrm;
}
}
else
{
     pMe -> mc_data.act_frame = 0;
}

/* モデルの姿勢決定 */
IMICRO3D_Figure_setPosture( pMe  -> pIM3D,
   &pMe -> mc_data.figure,
   &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 ) )
{
DBGPRINTF(" [ ERR ] draw failed");
return HI_FALSE;
}

/* フレームバッファへ描画 */
IMICRO3D_Render_flush( pMe -> mpMicro3D, &pMe -> mc_data.render );
Sample 描画結果
Sample 描画結果

2.8. 終了処理

アプリケーションの終了時など、オブジェクトをすべて終了する場合は、以下の順序で終了処理を呼び出すことですべてのオブジェクトを終了し、リソースを解放することができます。

  1. Renderの終了処理
  2. すべてのActTableの終了処理
  3. すべてのTexture、Figure、Atrans3iの終了処理
  4. IMICRO3D_mcext_Endのコール
  5. IMICRO3D_Relleaseのコール

  [ sample3d_v3.c 内 ]
/* Render、ActTable、Texture、Figureの終了処理 */
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 ] );
  [ brewmain.c 内 ]
if ( pMe -> pIM3D != NULL )
{
/* Micro3Dの終了処理 */
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のアプリの修正方法を示します。

  [ brewmain.c 内 ]
/* 本処理にて正しい Pitchの値が取得可能。Ver.D以前を使う場合は、本処理が必須。 */
pMe->pitch = (pMe->pAEEDIB->nPitch / ( pMe->pAEEDIB->nDepth >> DIV_8 ));

この “pMe->pitch” をIMICRO3D_Render_setVramの第五引数に設定します。

  [ sample3d_v3.c 内 ]
/*----- VRAM情報を設定 -----*/
IMICRO3D_Render_setVram(pMe->pIM3D, &pMe->mc_data.render,
     GetBitmapWidth( pMe ),
     GetBitmapHeight( pMe ),
     GetBitmapPitch( pMe ),
     pMe->pimage);

なお、V3エンジン Ver.E を使用した場合、エンジン内部で自動的にpitchの値を設定しますが、pitchの値としては、上記処理にて算出した値をご使用頂くことを推奨いたします。

詳しい内容につきましては、以下のガイドラインをご参照願います。
MascotCapsule V3 BREW Extension Guideline



このページの先頭へ戻る