サンプル

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;
}

描画結果 モデルとテクスチャの関連付け あり 描画結果 モデルとテクスチャの関連付け なし
モデルとテクスチャの関連付け あり モデルとテクスチャの関連付け なし
描画結果


このページの先頭へ戻る