サンプル
3D モデルの描画
ここでは基本的な 3D 描画について解説します。
目次
3D モデルの描画方法として、いくつかの方法が用意されていますが、ここでは最も基本的な描画方法である MascotCapsule eruption 専用フォーマット mcm ファイル( モデルデータ )、mct ファイル( テクスチャデータ )、mca ファイル( アニメーションデータ )を利用しての描画処理を行います。
1. BREW Extension の初期化
BREW 版の MascotCapsule eruption は BREW Extension として提供されるため、まず BREW Extension の初期化を行います。
指定するクラス ID は、使用する eruption BREW Extension の種類によって変更してください。
下記のサンプルプログラムでは、BREW3.1 用のMascotCapsule eruption を用意しています。
/*------ error codes ------*/
#define _APP_NO_MSG (0x000000)
#define _APP_INIT_MSG (0x010000)
#define _APP_DRAW_MSG (0x010001)
(中略)
typedef struct tagWork
{
/*------ BREW ------*/
AEEApplet Applet; /* 先頭の要素は必ずAEEApplet */
hi_sint32 ExpCode; /* BREW例外処理 */
(中略)
Imc* pIMC; /* エクステンションインスタンス */
(中略)
} WORK;
int i_ret;
(中略)
/*------ MascotCapsuleインスタンス作成 ------*/
work->pIMC = NULL;
i_ret = ISHELL_CreateInstance (work->Applet.m_pIShell,
AEECLSID_ERUPTION_A31,
(void **)&work->pIMC);
if (i_ret != AEE_SUCCESS)
{
DBGPRINTF ("[ ERUPTION EX CreateInst ERROR ]:%d", i_ret);
work->ExpCode = _APP_INIT_MSG;
return FALSE;
}
2. グラフィックスコンテキストの用意
MascotCapsule eruption では OpenGL ES を利用して 3D グラフィックスの描画を行うため、OpenGL ES の処理も必要となります。
mceGraphics3D_initializeContext( wnd ) の引数は環境依存となっており、BREW では引数にアプレット構造体を指定します。
/*------ error codes ------*/
#define _APP_NO_MSG (0x000000)
#define _APP_INIT_MSG (0x010000)
#define _APP_DRAW_MSG (0x010001)
(中略)
typedef struct tagWork
{
(中略)
/*------ エンジン画像処理構造体 ------*/
mceGraphics3D *G3d; /* Graphics3D */
/*------ 画面 ------*/
IDIB *pAEEDIB; /* デバイス独立ビットマップ */
hi_uint16 WindowWidth; /* 画面幅 */
hi_uint16 WindowHeight; /* 画面高さ */
(中略)
} WORK;
hi_bool hb_ret;
(中略)
/* コンテキストの用意 */
hb_ret = mceGraphics3D_initializeContext (&work->Applet);
if (hb_ret != HI_TRUE)
{
DBGPRINTF ("[ mcext_Start ERROR ]");
work->ExpCode = _APP_INIT_MSG;
return FALSE;
}
hi_exception exception; /* 例外取得 */
(中略)
/*------ 画面サイズ ------*/
work->WindowWidth = work->pAEEDIB->cx; /* X軸サイズ */
work->WindowHeight = work->pAEEDIB->cy; /* Y軸サイズ */
/*------ カメラ ------*/
/* mceGraphics3Dを作成 */
work->G3d = mceGraphics3D_create (&exception);
if ((work->G3d == NULL) || (exception != hi_NoException))
{
return 1;
}
(中略)
/* GL描画領域を設定 */
mceGraphics3D_setContextSize (work->G3d,
(hi_sint32)work->WindowWidth,
(hi_sint32)work->WindowHeight);
/* ビューポートを設定 */
exception = mceGraphics3D_setViewport (work->G3d,
0, 0, work->WindowWidth, work->WindowHeight);
if (exception != hi_NoException)
{
return 1;
}
/* クリッピング領域を設定 */
exception = mceGraphics3D_setClip (work->G3d,
0, 0, work->WindowWidth, work->WindowHeight);
if (exception != hi_NoException)
{
return 1;
}
3. テクスチャ、アニメーションの設定
テクスチャやアニメーションは、それぞれのデータを用意した後に、対象となるモデルに関連付けを行う必要があります。
モデルにテクスチャとアニメーションを関連付けるには、mceFigure_bindTexture( This, textures ) と、mceFigure_bindAction( This, actions ) を使用します。
どちらの関数を使用する場合も、最初に 1 度だけモデルへの関連付けを行えば良く、描画時に毎回、関連付けする必要はありません。また、引数 textures 及び、actions に NULL を指定することでそれぞれの関連付けを解除することも可能です。
typedef struct tagWork
{
(中略)
/*------ データ ------*/
mceFigure *Figure; /* Figure */
mceTextureTable *Textbl; /* TextureTable */
mceActionTable *Acttbl; /* ActionTable */
(中略)
hi_coord AnimeCounter; /* オブジェクトアニメーションカウンター */
} WORK;
hi_exception exception; /* 例外取得 */
(中略)
/* テクスチャの関連付け */
exception = mceFigure_bindTexture (work->Figure, work->Textbl);
if (exception != hi_NoException)
{
return 1;
}
/* アニメーションの関連付け */
exception = mceFigure_bindAction (work->Figure, work->Acttbl);
if (exception != hi_NoException)
{
return 1;
}
モデルに関連付けたアニメーションの再生は、mceFigure_setFrame( This, frame ) を用いて再生したいフレームを設定することで行えます。
work->AnimeCounter = MCE_F2C (0.0f);
(中略)
hi_exception exception;
(中略)
/* アニメーションフレームを設定 */
exception = mceFigure_setFrame (work->Figure, work->AnimeCounter);
if (exception != hi_NoException)
{
return 1;
}
4. 外観の設定
外観の設定対象のモデルが使用する mceAppearance に対し、各種の設定を行うことで、光源やカリング、ブレンド、テクスチャの歪み補正など、モデルの外観に関わる部分を変更することができます。
下記のサンプルプログラムでは、mceAppearance の持つプロパティに MCE_APPEARANCE_PERSCORRECT ( テクスチャの歪み補正 )を追加しています。
まず、mceObject3D_findObject3D( This, type, userId, results, num ) を用いて、外観の設定対象のモデルが使用する mceFigure から mceAppearance を取得します。取得した mceAppearance のプロパティを mceAppearance_getProperties( This ) で取得することで、プロパティの変更を行うことができます。プロパティの変更後は mceAppearance_setProperties( This, properties ) でプロパティの設定を行います。
typedef struct tagWork
{
(中略)
mceAppearance *Appe; /* Appearance */
(中略)
} WORK;
hi_exception exception;
hi_sint32 data;
(中略)
/* mceAppearanceを取得 */
work->Appe = (mceAppearance *)mceObject3D_findObject3D (
(mceObject3D *)work->Figure,
ClassId_Appearance,
0);
if (work->Appe == NULL)
{
return 1;
}
/* プロパティの取得、再設定 */
data = mceAppearance_getProperties (work->Appe);
exception = mceAppearance_setProperties (work->Appe,
MCE_APPEARANCE_PERSCORRECT | data);
if (exception != hi_NoException)
{
return 1;
}
5. カメラの設定
mceCamera はモデルの描画に必須で、投影方法や投影範囲、フォグなどの情報を持ちます。
カメラの設定には 2 種類あり、個々の mceFigure に対して行う方法と、mceGraphics3D ( ワールド全体 )に対して行う方法があります。個々の mceFigure に対して設定する場合は mceFigure_setCamera( This, camera ) 、mceGraphics3D に対して設定する場合は mceGraphics3D_setCamera( This, camera, transform ) 及び、mceGraphics3D_setCamera_at( This, camera, pos, look, up ) を使用します。
#define ANGLE (360) /* 角度 */
typedef struct tagWork
{
(中略)
mceCamera *Camera; /* Camera */
hi_coord AspectRate; /* アスペクト比 */
hi_coord ViewAngle; /* 視野角 */
hi_coord NearClip; /* ニアクリップ */
hi_coord FarClip; /* ファークリップ */
hi_coord CameraTx; /* カメラワールドX軸 */
hi_coord CameraTy; /* カメラワールドY軸 */
hi_coord CameraTz; /* カメラワールドZ軸 */
hi_coord CameraRx; /* カメラX軸回転 */
hi_coord CameraRy; /* カメラY軸回転 */
hi_coord CameraRz; /* カメラZ軸回転 */
(中略)
} WORK;
hi_exception exception;
(中略)
/* カメラの生成 */
work->Camera = mceCamera_create (&exception);
if ((work->Camera == NULL) || (exception != hi_NoException))
{
return 1;
}
/* (画面横幅 / 画面縦幅)で、アスペクト比を設定 */
work->AspectRate = MCE_DIV ((hi_coord)work->WindowWidth,
(hi_coord)work->WindowHeight);
/* 視野角を設定 */
work->ViewAngle = MCE_F2C ( 45.0f);
/* ニアクリップ距離、ファークリップ距離を設定 */
work->NearClip = MCE_F2C ( 0.1f);
work->FarClip = MCE_F2C (100.0f);
work->CameraTx = MCE_F2C ( 0.0f);
work->CameraTy = MCE_F2C ( 4.0f);
work->CameraTz = MCE_F2C (25.0f);
work->CameraRx = MCE_F2C (0.0f);
work->CameraRy = MCE_F2C (0.0f);
work->CameraRz = MCE_F2C (0.0f);
(中略)
mceTransform matrix;
mceTransform matrix2;
mceVector3D rotate;
(中略)
/* 投影方法の設定 */
exception = mceCamera_setPerspectiveFov (work->Camera,
work->AspectRate,
work->ViewAngle / ANGLE,
work->NearClip, work->FarClip);
if (exception != hi_NoException)
{
return 1;
}
/* 平行移動 */
mceTransform_setTranslate (&matrix,
work->CameraTx, work->CameraTy, work->CameraTz);
/* X軸回転 */
mceVector3D_set (&rotate,
MCE_F2C (1.0f), MCE_F2C (0.0f), MCE_F2C (0.0f));
mceTransform_setRotate (&matrix2, &rotate, work->CameraRx / ANGLE);
mceTransform_multiply (&matrix, &matrix2);
/* Y軸回転 */
mceVector3D_set (&rotate,
MCE_F2C (0.0f), MCE_F2C (1.0f), MCE_F2C (0.0f));
mceTransform_setRotate (&matrix2, &rotate, work->CameraRy / ANGLE);
mceTransform_multiply (&matrix, &matrix2);
/* Z軸回転 */
mceVector3D_set (&rotate,
MCE_F2C (0.0f), MCE_F2C (0.0f), MCE_F2C (1.0f));
mceTransform_setRotate (&matrix2, &rotate, work->CameraRz / ANGLE);
mceTransform_multiply (&matrix, &matrix2);
/* mceGraphics3Dにデフォルトカメラを設定 */
exception = mceGraphics3D_setCamera (work->G3d, work->Camera, &matrix);
if (exception != hi_NoException)
{
return 1;
}
6. 描画処理
上記の設定が終了したら描画処理が可能となります。ここまでの設定は、変更がない限り、初期化時に 1 度行うだけで描画が可能です。
mceFigure の描画には mceGraphics3D_drawFigure( This, figure, transform, param ) を使用します。
画面への描画は mceGraphics3D_swapContext() を使用した時点で行います。また、サンプルプログラムでは描画に mceGraphics3D_flush( This ) を使用していますが、mceGraphics3D_drawFigure( This, figure, transform, param ) を使用して描画する場合は、mceGraphics3D_swapContext() で内部的に同様の処理が行われているため、使用する必要はありません。
/*------ error messages ------*/
#define APP_INIT_MSG "Init Error"
#define APP_DRAW_MSG "Draw Error"
#define UNKNOWN_MSG "Unknown Error"
(中略)
/*------ 時間制御 ------*/
#define FRAME_TIME (30) /* 描画更新間隔(ms) */
/*------ 角度 ------*/
#define ANGLE (360) /* 角度 */
(中略)
typedef struct tagWork
{
/*------ BREW ------*/
AEEApplet Applet; /* 先頭の要素は必ずAEEApplet */
hi_sint32 ExpCode; /* BREW例外処理 */
(中略)
hi_coord ObjRy; /* オブジェクトY軸回転 */
(中略)
} WORK;
(中略)
extern long MainProg (WORK *work);
long prog_ret;
(中略)
prog_ret = MainProg (work);
mceGraphics3D_swapContext ();
(中略)
if (prog_ret != 0)
{
/* 描画処理でエラー */
work->ExpCode = _APP_DRAW_MSG;
ISHELL_SetTimer (work->Applet.m_pIShell, FRAME_TIME,
(PFNNOTIFY)System_MsgDisp, work);
}
else
{
/* メインルーチンの再呼び出し */
(中略)
CALLBACK_Init (&work->Callback, (PFNNOTIFY)SystemFrame, work);
ISHELL_Resume (work->Applet.m_pIShell, &work->Callback);
(中略)
}
/*
long MainProg (WORK *work) 内部
*/
hi_exception exception;
mceTransform matrix;
mceTransform matrix2;
mceVector3D rotate;
(中略)
/*------ 背景クリア ------*/
exception = mceGraphics3D_clear (work->G3d,
MCE_GRAPHICS3D_CLEAR_DEPTH | MCE_GRAPHICS3D_CLEAR_COLOR,
0x00808080);
if (exception != hi_NoException)
{
return 1;
}
(中略)
/*------ 描画 ------*/
mceTransform_setTranslate (&matrix,
MCE_F2C (0.0f), MCE_F2C (0.0f), MCE_F2C (0.0f));
mceVector3D_set (&rotate,
MCE_F2C (0.0f), MCE_F2C (1.0f), MCE_F2C (0.0f));
mceTransform_setRotate (&matrix2, &rotate, work->ObjRy / ANGLE);
mceTransform_multiply (&matrix, &matrix2);
exception = mceGraphics3D_drawFigure (work->G3d,
work->Figure, &matrix, 0);
if (exception != hi_NoException)
{
return 1;
}
/*------ 描画処理 ------*/
exception = mceGraphics3D_flush (work->G3d);
if (exception != hi_NoException)
{
return 1;
}
![]() |
![]() |
| モデルとテクスチャの関連付け あり | モデルとテクスチャの関連付け なし |
| 描画結果 | |



