半透明表示

この章では、テクスチャ表示における様々なテクニックのうち、キャラクタなどの画像を半透明にして表示する方法を紹介する。

半透明表示とは?

描画するテクスチャを半透明にして、後ろが透けるように描画することができる。このような効果を出すことをαブレンディングと呼ぶ。
古いビデオカードではαブレンディングをサポートしていないものがあるが、最近のビデオカードであればほぼ問題がないと思われる。

半透明を指定すると、上記のようにキャラクタが背景に透けて表示できるようになる。透け具合も自由に調整できる。
この技術を利用すれば、キャラクタを半透明で表示させることはもちろん、色付きガラスや煙の表現などにも利用できる。

半透明処理の宣言

半透明処理を行うには、描画設定処理を次のように修正しなければならない。

//-----------------------------------------------------------------------------
// 関数名 : InitRender()
// 機能概要: 描画の設定など
//-----------------------------------------------------------------------------
void InitRender(void)
{
    // テクスチャの設定
    gl_lpD3ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
    gl_lpD3ddev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    gl_lpD3ddev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);

    // アルファ・ブレンディングを行う
    gl_lpD3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    // 透過処理を行う
    gl_lpD3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    // 半透明処理を行う
    gl_lpD3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
}

SetTextureStageState関数の設定

SetRenderState関数の設定

※上記修正を行い、エラーが出ないことを確認する(実行結果は同じ)。

半透明処理の使用

半透明処理を行うことを宣言したら、後は半透明にしたいポリゴンに対して半透明処理の指定を行えばよい
例えば、約50%の透明度でテクスチャを描画するには、頂点情報(ポリゴン)の頂点色情報(color)を次のように設定すればよい。

//----------------------------------------------------------------------------------------
// 関数名 : InitVertex() 
// 機能概要: 頂点データを格納する
//----------------------------------------------------------------------------------------
void InitVertex(LPTLVERTEX v, float x1, float y1, float x2, float y2)
{
    //頂点配列をゼロクリア
    ZeroMemory(v, sizeof(TLVERTX));
    //---頂点A1のデータ定義
    v[0].x      =  x1;                          // 頂点X座標
    v[0].y      =  y1;                          // 頂点Y座標
    v[0].z      =  0.0f;                        // 頂点Z座標
    v[0].rhw    =  1.0f;                        // 2Dを扱うときの値
    v[0].tu     =  0.0f;                        // テクスチャのX座標
    v[0].tv     =  0.0f;                        // テクスチャのY座標
    v[0].color  =  D3DCOLOR_RGBA(255,255,255,128); // 頂点色
    //---頂点A2のデータ定義
    v[1].x      =  x2;
    v[1].y      =  y1;
    v[1].z      =  0.0f;
    v[1].rhw    =  1.0f;
    v[1].tu     =  0.2f;
    v[1].tv     =  0.0f;
    v[1].color  =  D3DCOLOR_RGBA(255,255,255,128);
    //---頂点A3のデータ定義
    v[2].x      =  x2;
    v[2].y      =  y2;
    v[2].z      =  0.0f;
    v[2].rhw    =  1.0f;
    v[2].tu     =  0.2f;
    v[2].tv     =  0.2f;
    v[2].color  =  D3DCOLOR_RGBA(255,255,255,128);
    //---頂点A4のデータ定義
    v[3].x      =  x1;
    v[3].y      =  y2;
    v[3].z      =  0.0f;
    v[3].rhw    =  1.0f;
    v[3].tu     =  0.0f;
    v[3].tv     =  0.2f;
    v[3].color  =  D3DCOLOR_RGBA(255,255,255,128);
}

《POINT》

※上記修正を行い、すべてのキャラクタが半透明で表示されることを確認する。

頂点情報初期化関数の改造

しかしこのやり方では、全てのテクスチャが半透明になってしまうので、現実的ではない。通常、特定のポリゴンのみを半透明にしたいはず。
よって、頂点情報初期化関数を修正し、半透明にするかどうかを指定できるようにする。

1.頂点情報初期化関数の修正

頂点情報初期化関数(InitVertex関数)に引数を追加し、半透明にするかどうかを判断できるように修正する。プロトタイプ宣言も修正すること。

//----------------------------------------------------------------------------------------
// 関数名 : InitVertex() 
// 機能概要: 頂点データを格納する
//----------------------------------------------------------------------------------------
void InitVertex(LPTLVERTEX v, float x1, float y1, float x2, float y2, int Alpha)
{
    D3DCOLOR    color;  // 頂点カラー

    // 半透明処理をするかどうかを判断し、頂点カラーを決定
    if ( Alpha == 255 ) color = D3DCOLOR_XRGB(255,255,255);
    else                color = D3DCOLOR_RGBA(255,255,255,Alpha);

	//頂点配列をゼロクリア
    ZeroMemory(v, sizeof(TLVERTX));
    //---頂点A1のデータ定義
    v[0].x      =  x1;                         // 頂点X座標
    v[0].y      =  y1;                         // 頂点Y座標
    v[0].z      =  0.0f;                       // 頂点Z座標
    v[0].rhw    =  1.0f;                       // 2Dを扱うときの値
    v[0].tu     =  0.0f;                       // テクスチャのX座標
    v[0].tv     =  0.0f;                       // テクスチャのY座標
    v[0].color  =  color;                      // 頂点色
    //---頂点A2のデータ定義
    v[1].x      =  x2;
    v[1].y      =  y1;
    v[1].z      =  0.0f;
    v[1].rhw    =  1.0f;
    v[1].tu     =  1.0f;
    v[1].tv     =  0.0f;
    v[1].color  =  color;
    //---頂点A3のデータ定義
    v[2].x      =  x2;
    v[2].y      =  y2;
    v[2].z      =  0.0f;
    v[2].rhw    =  1.0f;
    v[2].tu     =  1.0f;
    v[2].tv     =  1.0f;
    v[2].color  =  color;
    //---頂点A4のデータ定義
    v[3].x      =  x1;
    v[3].y      =  y2;
    v[3].z      =  0.0f;
    v[3].rhw    =  1.0f;
    v[3].tu     =  0.0f;
    v[3].tv     =  1.0f;
    v[3].color  =  color;
}

《POINT》

2.頂点情報初期化関数の呼び出しを修正

頂点情報初期化処理をこのように修正すれば、あとは実行時に透明度を指定して頂点情報初期化処理を実行すればよい。
例えば1つ目のキャラクタは通常通り表示し、2つ目のキャラクタは半透明で表示する場合、次のように頂点情報初期化処理を実行すればよい。

//-----------------------------------------------------------------------------
// 関数名 : StartInit()
// 機能概要: スタート画面初期化処理
//-----------------------------------------------------------------------------
void StartInit(void)
{
    HRESULT ret;

    //--------------------------------------------------- 各変数の初期化
    // スタート画面で使用するテクスチャの作成
    CreateStartTexture();
    // 頂点データを格納する
    InitVertex(VertexDataTbl1, 100.0, 100.0, 300.0, 300.0, 255); // 半透明処理を行わない
    InitVertex(VertexDataTbl2, 200.0, 200.0, 400.0, 400.0, 128); // 半透明処理を行う

    //--------------------------------------------------- フレームナンバーセット
    g_FrameNo = START_FRAME;

}

《POINT》

※上記修正を行い、1つ目のキャラクタはそのままで、2つ目のキャラクタのみ半透明で表示されることを確認する。


BACK(透過表示) NEXT(加算合成)