2Dと3Dの合成時の処理

ここでは、BREW API を用いた 2D描画と3D描画との合成処理について解説します。




※ 開発環境によってダウンロードするサンプルデータが異なります。

目次



MascotCapsule V4 (V3互換)やV4 では 2D描画と 3D描画を同一のフレームバッファに描画する方法でのみ 2D3D 合成が実現可能ですが (詳細はこちらをご覧下さい)、この方法は、パフォーマンスに影響が出ることから eruption では推奨しておりません。
代わりに、任意のフレームバッファに 2D を描画し、そのフレームバッファから生成された mceTexture と 3Dモデルを描画することで 2D3D合成を実現する実装を推奨しております。 実装法は以下の順になります。

  1. アプリ側で 2D 描画用のフレームバッファを作成
  2. 2D をフレームバッファへ描画
  3. mceTexture の生成
  4. mceTexture と3D モデルの描画

各実装の詳細については以下で説明します。
なお、本サンプルでは2D描画に日本語文字列を用います。


1. 文字列描画用のフレームバッファを作成

文字列描画用の任意のフレームバッファを作成します。作成の際は IBITMAP_CreateCompatibleBitmap( po, ppIBITmap, w, h ) を用いてデバイスビットマップと互換性のあるフレームバッファを作成します。

#define REGION_W        (256)        /* 矩形転送X軸サイズ */
#define REGION_H        ( 64)        /* 矩形転送Y軸サイズ */

typedef struct tagWork
{
    (中略)

    AEEApplet Applet;                /* アプレット構造体 */

    (中略)
} WORK;
IDIB*       ComDib;
IBitmap*    Combitmap;                
IBitmap*    Devbitmap;               /* デバイスビットマップ */
int         i_ret;

    (中略)

/* デバイスビットマップの取得 */
i_ret = IDISPLAY_GetDeviceBitmap (work->Applet.m_pIDisplay,
                                        &Devbitmap);
if (i_ret != SUCCESS)
{
    return 1;
}

/* Devbitmap に互換性のあるビットマップの生成 */
i_ret = IBITMAP_CreateCompatibleBitmap (Devbitmap, &Combitmap,
                                        REGION_W, REGION_H);
if (i_ret != SUCCESS)
{
    return 1;
}    
IBITMAP_Release (Devbitmap);

/* CombitmapをDIBに変換 */
i_ret = IBITMAP_QueryInterface (Combitmap, AEECLSID_DIB,
                                (void **)&ComDib);
if (i_ret != SUCCESS)
{
    return 1;
}


2. 文字列をフレームバッファへ描画

文字列をフレームバッファに描画する際には、描画前に IDISPLAY_SetDestination( po, pDst ) を用いて作成したフレームバッファをレンダリングターゲットに設定する必要があります。また描画後には、IDISPLAY_SetDestination( po, pDst ) の第 2 引数を NULL に指定し、フレームバッファをレンダリングターゲットから外します。

#define REGION_W        (256)        /* 矩形転送X軸サイズ */
#define REGION_H        ( 64)        /* 矩形転送Y軸サイズ */

typedef struct tagWork
{
    (中略)

    AEEApplet Applet;                /* アプレット構造体 */

    (中略)
} WORK;
IBitmap    *Combitmap;
AECHAR      AEtext[18];
AEERect     rect;
Int         i_ret;

    (中略)

/* 描画範囲の設定 */
rect.x  =         0;
rect.y  =         0;
rect.dx =  REGION_W;
rect.dy =  REGION_H;

    (中略)

/* レンダリングターゲットの設定 */
i_ret = IDISPLAY_SetDestination (work->Applet.m_pIDisplay,
                                                 Combitmap);
if (i_ret != SUCCESS)
{
    return 1;
}

IDISPLAY_FillRect (work->Applet.m_pIDisplay, &rect, 0x00000000);
i_ret = IDISPLAY_DrawText (work->Applet.m_pIDisplay,
        AEE_FONT_BOLD, AEtext, -1, NULL, NULL, &rect, 
        IDF_ALIGN_CENTER | IDF_ALIGN_MIDDLE | IDF_TEXT_TRANSPARENT);
if (i_ret != SUCCESS)
{
    return 1;
}

/* フレームバッファをレンダリングターゲットから外す */
i_ret = IDISPLAY_SetDestination (work->Applet.m_pIDisplay, NULL);
if (i_ret != SUCCESS)
{
    return 1;
}

3. mceTexture の生成

文字列を描画したフレームバッファから mceTexture を生成します。
mceTexture_create( gID, format, width, height, useMipmap, exception ) で mceTexture を生成し、mceTexture_setImage( This, format, level, xp, yp, width, height, image ) を用いて生成した mceTexture にフレームバッファのピクセル情報を設定します。

#define REGION_W        (256)        /* 矩形転送X軸サイズ */
#define REGION_H        ( 64)        /* 矩形転送Y軸サイズ */

typedef struct tagWork
{
    (中略)

    AEEApplet      Applet;           /* アプレット構造体 */

    (中略)

    mceTexture*    RegionTexture;    /* RegionTexture    */

    (中略)
} WORK;
IDIB*           ComDib;
IBitmap*        Combitmap;
hi_uint32       format;
hi_exception    exception;
Int             i_ret;

    (中略)

format = mcePixelFormat_RGB565;        /* ピクセルフォーマット */

    (中略)

/* 2D描画用テクスチャの生成 */
work->RegionTexture = mceTexture_create (0, format, REGION_W, REGION_H,
                                         HI_FALSE, &exception);
if (exception != hi_NoException)
{
    return 1;
}

/*フレームバッファのピクセル情報を2D描画用テクスチャに設定*/
exception = mceTexture_setImage (work->RegionTexture, format, 0, 0, 0,
                                 REGION_W, REGION_H, (hi_sint8*)ComDib->pBmp);
if (exception != hi_NoException)
{
    return 1;
}

IBITMAP_Release (Combitmap);
IQI_Release ((IQueryInterface *)ComDib);
ComDib = NULL;

4. mceTexture と 3Dモデルの描画

作成した mceTexture と 3Dモデルを描画します。
mceTexture の描画はリージョン機能である mceGraphics3D_drawRect( This, x, y, width, height, roll, abgr, appearance, regions, regionNum ) で行い、3Dモデルの描画は mceGraphics3D_drawFigure( This, figure, transform, param ) で行います。
また、mceTexture は 3Dモデルの背面と前に描画しますが、mceGraphics3D_drawRect() を使用すると mceTexture はデフォルトで最前に描画されてしまいます。そのため、3Dモデルの背面に mceTexture を描画する場合には、mceTexture を先に描画した後に、mceGraphics3D_clear( This, flag, abgr ) の第2引数に MCE_GRAPHICS3D_CLEAR_DEPTH を指定し、デプス値をクリアしてから 3Dモデルを描画するようにしてください。

なお、リージョン機能や 3Dモデルの描画については、それぞれ「リージョン」、「3Dモデルの描画」のドキュメントページを参照してください。

#define COORD_SHIFT        (16)    /* int→hi_coordのシフト */

    (中略)

#define ANGLE              (360)   /* 角度 */

    (中略)

#define REGION_W           (256)   /* 矩形転送X軸サイズ */
#define REGION_H           ( 64)   /* 矩形転送Y軸サイズ */

#define HEGHT_OFFSET       ( 10)   /* 矩形描画位置のオフセット値 */

typedef struct tagWork
{
    (中略)

    AEEApplet    Applet;           /* アプレット構造体 */

    (中略)

    mceGraphics3D *G3d;            /* Graphics3D */

    (中略)

    hi_uint16 WindowWidth;         /* 画面幅   */
    hi_uint16 WindowHeight;        /* 画面高さ */

    (中略)

    mceAppearance* RegionAppe;     /* RegionAppearance */
    mceRegionF     Region;         /* Region           */

    hi_coord ReZoom;               /* 矩形転送拡縮率 */
    hi_coord ReRotate;             /* 矩形転送回転値 */

    hi_coord ObjRy;                /* オブジェクトY軸回転 */

    (中略)
} WORK;
hi_exception exception;

mceTransform matrix;
mceTransform matrix2;
mceVector3D  rotate;

hi_sint16     x, y, w, h;

    (中略)

/*------ 2D描画 Back ------*/

/* 描画範囲設定 */
w = ((REGION_W * work->ReZoom) >> COORD_SHIFT);
h = ((REGION_H * work->ReZoom) >> COORD_SHIFT);
x = (work->WindowWidth  / 2) - (w / 2);
y = HEGHT_OFFSET;

/* テクスチャ描画 */
exception = mceGraphics3D_drawRect (work->G3d, x, y, w, h,
                                    work->ReRotate / ANGLE, 0xffffffff, 
                                    work->RegionAppe, &work->Region, 2);
if (exception != hi_NoException)
{
    return 1;
}

/* デプス値のクリア */
exception = mceGraphics3D_clear (work->G3d,
                                 MCE_GRAPHICS3D_CLEAR_DEPTH, 0x00808080);
if (exception != hi_NoException)
{
    return 1;
}

/*------ 3D描画 ------*/

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

/*------ 2D描画 Front ------*/

/* 描画範囲指定 */
w = ((REGION_W * work->ReZoom) >> COORD_SHIFT);
h = ((REGION_H * work->ReZoom) >> COORD_SHIFT);
x = (work->WindowWidth / 2) - (w / 2);
y =  work->WindowHeight - (REGION_H + HEGHT_OFFSET);

/* テクスチャの描画 */
exception = mceGraphics3D_drawRect (work->G3d, x, y, w, h,
                                    work->ReRotate / ANGLE, 0xffffffff,
                                    work->RegionAppe, NULL, 0);
if (exception != hi_NoException)
{
    return 1;
}

/*------ 描画処理 ------*/

exception = mceGraphics3D_flush (work->G3d);
if (exception != hi_NoException)
{
    return 1;
}
描画結果



このページの先頭へ戻る