3Dモデルの描画
ここでは、3Dモデルの基本的な描画方法について説明します。
目次
1.モデルの構成要素
3Dモデルは以下の3つの要素から構成されています。
- モデルデータ( Figure )
3Dモデルの骨組みとなる部分です。MBACデータを読み込むことで取得します。 - テクスチャデータ( Texture )
モデルに貼り付けるテクスチャや背景などです。BMP(ビットマップ)データを読み込むことで取得します。 - アクションデータ( ActTable )
モデルのアニメーションについての情報です。MTRAデータを読み込むことで取得します。
2.モデルの描画手順
ここではサンプルコードを用いて3Dモデルを描画する手順を説明します。
2.1. データオブジェクトのバイトデータの作成
WIPIでは各データオブジェクト(Figure, Texture, ActionTable)の作成をそれぞれ対応するMBAC、BMP、MTRAファイルのバイトデータを読むことで行います。そのため、各ファイルのバイト配列を用意しておく必要があります。また、データを読み込む際にはそのファイルのバイト配列のサイズも分かっている必要があります。
0xeb ,0x0 ,0x28 ,0x1 ,0x41 ,0x0 ,0x6 ,0x0 ,0xa ,0x0 ,
0x2 ,0x0 ,0x1 ,0x0 ,0x1 ,0x0 ,0x6 ,0x0 ,0xa ,0x0 ,
0xd5 ,0x23 ,0x1c ,0xe9 ,0x64 ,0x92 ,0x64 ,0x92 ,0x64 ,0x92
};
const ByteData dragon_mbac = { _dragon_mbac, sizeof( _dragon_mbac ) };
const ByteData dragon_bmp = { _dragon_bmp, sizeof( _dragon_bmp ) };
const ByteData dragon_bg = { _dragon_bg, sizeof( _dragon_bg ) };
const ByteData dragon_mtra = { _dragon_mtra, sizeof( _dragon_mtra ) };
2.2. 3D関連オブジェクトの初期化
3Dモデルを描画するための各データを読み込むための初期化処理を行い、使用するオブジェクトとメモリアロケータの関連付けを行います。なお、各データは3Dモデルの構造体のメンバとして保持しておくと分かりやすくなります。このサンプルではヘッダファイル内でモデルの構造体を定義しています。
* 初期化処理
*/
hi_bool M3DTest_initialize( int id )
{
hi_bool rval;
g_vram_image = 0;
g_IAllocator = 0;
g_dif_time = 0;
g_key_mask = 0;
/* アロケータを初期化、VRAMの確保など */
if ( M3DTest_machInitialize() == HI_FALSE )
/* 3D描画関連オブジェクトの初期化 */
OEMC_Micro3D_Figure_initialize( &dragon.fig, g_IAllocator );
OEMC_Micro3D_Texture_initialize( &dragon.tex, g_IAllocator );
OEMC_Micro3D_Texture_initialize( &dragon.bg, g_IAllocator );
OEMC_Micro3D_ActTable_initialize( &dragon.act, g_IAllocator );
OEMC_Micro3D_Render_initialize( &render, g_IAllocator );
2.3.データの読み込み
使用するデータオブジェクト(Figure, Texture, ActTable)にモデルデータ、テクスチャデータ、アクションデータをインプットストリームを使用して読み込みます。インプットストリームはこの処理が行われるまでに使用できる状態である必要があります。
また、1つのモデルデータに対して複数のテクスチャを使用する場合、それらのデータのポインタを格納した配列 texArray を用意しておく必要があります。
MemIstream_initialize( &mis, dragon_mbac.addr, dragon_bmp.size );
rval = OEMC_Micro3D_Figure_loadMbacData(
/* テクスチャデータを読み込む */
MemIstream_initialize( &mis, dragon_bmp.addr, dragon_bmp.size );
rval = OEMC_Micro3D_Texture_loadBmpData(
MemIstream_getIIstream( &mis ), TEXTURE_TYPE_NORMAL );
rval = OEMC_Micro3D_Texture_loadBmpData(
MemIstream_getIIstream( &mis ), TEXTURE_TYPE_NORMAL );
/* テクスチャ配列の作成 */
dragon.texArray.num = 2;
dragon.texArray.texture[0] = &dragon.tex;
dragon.texArray.texture[1] = &dragon.bg;
/* アクションデータを読み込む */
MemIstream_initialize( &mis, dragon_mtra.addr, dragon_mtra.size );
rval = OEMC_Micro3D_ActTable_loadMtraData(
2.4.ライトとカメラの初期化
ライトとカメラの初期化を行います。ライトについては、使用するライトそれぞれについて明るさや方向などを設定します。カメラについては、位置・視点方向・upベクトル・ニアクリップ・ファークリップ・画角を設定し、カメラ座標への変換行列を作成します。
amb_light_intensity = 4096*50/100;
OEMC_Micro3D_Render_setAmbientLight(&render, amb_light_intensity );
/* 視点設定 */
/* 位置 */
cam_frame.pos.x = 0;
cam_frame.pos.y = 1024;
cam_frame.pos.z = 7000;
/* 視点方向 */
cam_frame.dir.x = 0;
cam_frame.dir.y = 0;
cam_frame.dir.z = -4096;
/* up ベクトル */
cam_frame.up.x = 0;
cam_frame.up.y = 4096;
cam_frame.up.z = 0;
/* near_crip, far_crip, 画角の設定 */
cam_frame.z_near = NEAR_CLIP;
cam_frame.z_far = FAR_CLIP;
cam_frame.angle = ANGLE;
/* カメラ座標への変換 */
OEMC_Micro3D_Atrans3i_setViewTrans( &view_trans, &cam_frame.pos,
2.5.描画環境の設定
描画環境の設定を行います。具体的には
- フレームバッファの設定
- スクリーン中央位置の設定
- 投影方法の設定
などを行います。
これらの各設定については、変更されない限り Render に設定されたままになりますので、同じ設定を使用する場合は、最初の一度でかまいません。
投影方法については、透視投影と平行投影の2種類があります。
-
透視投影の場合は、
- OEMC_Micro3D_Render_serPerspectiveFov(
Render* render, hi_sint32 z_near, hi_sint32 z_far, hi_sint32 angle )
- OEMC_Micro3D_Render_serPerspectiveWH(
Render* render, hi_sint32 z_near, hi_sint32 z_far, hi_sint32 vw, hi_sint32 vh )
- OEMC_Micro3D_Render_serPerspectiveW( Render* render, hi_sint32 z_near, hi_sint32 z_far, hi_sint32 vw )
- OEMC_Micro3D_Render_serPerspectiveFov(
Render* render, hi_sint32 z_near, hi_sint32 z_far, hi_sint32 angle )
-
平行投影の場合は、
- OEMC_Micro3D_Render_serOrthographicScale( Render* render, hi_sint32 sx, hi_sint32 sy )
- OEMC_Micro3D_Render_serOrthographicWH( Render* render, hi_sint32 vw, hi_sint32 vh )
- OEMC_Micro3D_Render_serOrthographicW( Render* render, hi_sint32 vw )
- OEMC_Micro3D_Render_serOrthographicScale( Render* render, hi_sint32 sx, hi_sint32 sy )
OEMC_Micro3D_Render_setVram( &render, VRAM_WIDTH,
/* スクリーン中央位置の設定 */
OEMC_Micro3D_Render_setScreenCenter( &render,
/* 透視投影の設定 */
OEMC_Micro3D_Render_setPerspectiveFov( &render, cam_frame.z_near, cam_frame.z_far, cam_frame.angle );
return HI_TRUE;
}
2.6. モデルのアクションの設定
モデルにアニメーションが設定されている場合、対象となる描画時刻におけるモデルの姿勢を設定します。モデルの姿勢はOEMC_Micro3D_Figure_setPosture( Figure* figure, struct ActTable* act, hi_sint32 act_idx, hi_sint32 frame ) で描画するフレームを設定することにより行います。アクションデータの最大フレーム数はOEMC_Micro3D_ActTable_getNumFrames( const ActTable* act, hi_sint32 act_idx ) で取得できます。
* アクション設定
*/
static void setAction( void )
{
if ( maxframe != 0 ) {
}
}
/* モデルにアクションを設定 */
OEMC_Micro3D_Figure_setPosture( &dragon.fig , &dragon.act , dragon.actID, dragon.currentFrame);
2.7. モデルの描画
取得した各オブジェクトをレンダリングし、VRAMに転送します。レンダリングは描画登録しか行いませんので、これだけではフレームバッファへの描画処理は実行されません。最後にOEMC_Micro3D_Render_flush( Render* render ) を呼び出すことで、それまで登録されていたオブジェクトの描画処理が行われます。
なお、1つのFigureに対し、複数のテクスチャを使用する場合は、それらのテクスチャのポインタを格納した配列を設定するOEMC_Micro3D_Render_setTextureArray( Render* render, TextureArray* texArray ) を使用してください。
* 描画処理
*/
static void draw_( void )
{
setAction();
/* Texture を設定 */
OEMC_Micro3D_Render_setTextureArray( &render, &dragon.texArray );
/* 視点変換行列設定 */
OEMC_Micro3D_Render_setViewTrans( &render, &view_trans );
/* Figure を設定 */
OEMC_Micro3D_Render_drawFigure( &render, &dragon.fig );
/* VRAMへ転送 */
OEMC_Micro3D_Render_flush( &render );
}

Sample 描画結果
2.8.終了処理
使用しなくなったオブジェクトの終了処理関数を呼び出して、リソースを解放します。終了処理の呼び出しが必要なオブジェクトは
- ActTable
- Atrans3iArray
- Figure
- Texture
- Render
の5種類です。
* 終了処理
*/
void M3DTest_terminate( void )
{
OEMC_Micro3D_Render_finalize( &render );
/* ActTable 終了処理 */
OEMC_Micro3D_ActTable_finalize( &dragon.act );
/* Texture 終了処理 */
OEMC_Micro3D_Texture_finalize( &dragon.bg );
OEMC_Micro3D_Texture_finalize( &dragon.tex );
/* Figure 終了処理 */
OEMC_Micro3D_Figure_finalize( &dragon.fig );
M3DTest_machTerminate();

