Japanese | English | Korean

Samples

3Dモデルの描画

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

目次



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

1. モデルの構成要素

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

  • モデルデータ ( Figure )
    3Dモデルの骨組みとなる部分です。MBACデータを読み込むことで取得します。

  • テクスチャデータ ( Texture )
    モデルに貼り付けるテクスチャや背景などです。BMP(ビットマップ)データを読み込むことで取得します。

  • アクションデータ ( ActTable )
    モデルのアニメーションについての情報です。MTRAデータを読み込むことで取得します。





2. モデルの描画手順

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

2.1. MascotCapsule V4(V3互換)インターフェースの生成

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

  [ brewmain.c 内 ]
/* インターフェースの作成 */
pMe -> pIM3D = NULL;
ISHELL_CreateInstance( pMe -> m_applet.m_pIShell, AEECLSID_IM3DES_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. MascotCapsule V4(V3互換)内で BREWの OpenGL ESを使用可能にするための処理をコール

IMICRO3D_mcext_Start()を使用して、MascotCapsule内でBREWのOpenGL ES( AEECLSID_GLとAEECLSID_ELG )の初期化を行います。

  [ brewmain.c 内 ]
/* OpenGL ESの初期化 */
IMICRO3D_mcext_Start( pMe -> pIM3D, &pMe -> applet );

2.3. Figure, Texture, ActionTable オブジェクトの初期化

使用するデータオブジェクト(Figure, Texture, ActionTable)を初期化します。使用するオブジェクトとアロケータとの関連付けを必要な数だけ行います。

  [ sample3d_v4v3.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.4. データの読み込み

使用するオブジェクト(Figure, Texture, ActionTable)にモデルデータ、テクスチャデータ、アクションデータを読み込みます。

例 : Figureデータ読み込み


  [ sample3d_v4v3.c 内 ]
/* データへのパス指定 */
STRCPY( pMe -> mc_data.mbactraFile [ 0 ] , "\\data\\v3_sample.mbac" );

/* FileIstream オブジェクト 初期化 */
FileIstream_initialize( &fis, pMe -> m_pIFileMgr, mc_data.mbactraFile [ 0 ] );

/* モデルデータ読み込み */
IMICRO3D_Figure_loadMbacData( pMe -> pIM3D, &pMe -> mc_data.figure, FileIstream_getIIstream( &fis ) );

/* FileIstream オブジェクト 終了 */
IFILE_Release( &fis );

2.5. カメラの初期化

カメラの初期化を行います。位置・視点方向・upベクトル・ニアクリップ・ファークリップ・画角を設定し、カメラ座標への変換行列を作成します。

  [ sample3d_v4v3.c, sample3d_v4v3.h 内 ]
/* ニアクリップ、ファークリップ、画角の設定 */
#define CAM_NEAR       2048
#define CAM_FAR         32000
#define CAM_ANGLE     228

/* 視点設定 */
/* 位置 */
position.x = 0;
position.y = 1365;
position.z = 12288;

/* 視点方向 */
look.x       = 0;
look.y       = 0;
look.z       = -4096;

/* upベクトル */
up.x         = 0;
up.y         = 4096;
up.z         = 0;

/* 視点変換行列取得 */
IMICRO3D_Atrans3i_setViewTrans( pMe -> pIM3D,
        &pMe -> mc_data.view_trans,
        & position,
        & look,
        & up );

2.6. 描画時の環境設定

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

  • 描画対象となるフレームバッファの設定
  • スクリーンの設定
  • 投影方法の設定

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

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

  • IMICRO3D_Render_setPerspectiveFov()
  • IMICRO3D_Render_setPerspectiveWH()   あるいは、IMICOR3D_Render_setPerspectiveW()

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

  • IMICRO3D_Render_setOrthographicScale()
  • IMICRO3D_Render_setOrthographicWH()   あるいは、IMICRO3D_Render_setOrthographicW()

を使用して設定します。

  [ sample3d_v4v3.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.7. モデルのアクションの設定

モデルにアニメーションが設定されている場合、対象となる描画時におけるモデルの姿勢を設定します。モデルの姿勢は、IMICRO3D_Figure_setPosture()で描画するフレームを設定することにより行います。アクションデータの最大フレーム数はIMICRO3D_ActTable_getNumFrames()で取得できます。

  [ sample3d_v4v3.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.8. モデルの描画

取得した各オブジェクトをレンダリングし、VRAMに転送します。レンダリングにはIMICRO3D_Render_drawFigure()を使用します。ただし、レンダリングは描画登録しか行いませんので、これだけではフレームバッファへの描画処理は実行されません。最後にIMICRO3D_Render_flush()を呼び出すことで、それまで登録されていたオブジェクトの描画処理が行われます。

  [ sample3d_v4v3.c 内 ]
/* 背景をクリア */
IMICRO3D_mcext_Clear( pMe -> pIM3D, M3D_COLOR_BUFFER_BIT );
/* 描画登録 */
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 -> pIM3D, &pMe -> mc_data.render );

Sample 描画結果

2.9. 終了処理

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

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

  [ sample3d_v4v3.c 内 ]
/* 3D関連オブジェクト 終了処理 */
IMICRO3D_Figure_finalize( pMe    -> pIM3D, &pMe   -> mc_data.figure );
IMICRO3D_Render_finalize( pMe   -> pIM3D, &pMe   -> mc_data.render );
IMICRO3D_Texture_finalize( pMe  -> pIM3D, &pMe   -> mc_data.texture [ 0 ] );
IMICRO3D_Texture_finalize( pMe  -> pIM3D, &pMe   -> mc_data.texture [ 1 ] );
IMICRO3D_ActTable_finalize( pMe -> pIM3D, &pMe  -> mc_data.act );
  [ brewmain.c 内 ]
if ( pMe -> pIM3D != NULL )
{
/* 新規API:OpenGL ES終了処理など */
IMICRO3D_mcext_End( pMe -> pIM3D );

/* Micro3Dの終了処理 */
IMICRO3D_Release( pMe -> pIM3D );
pMe -> pIM3D = NULL;
}