透明色を設定したテクスチャを貼り付ける

矩形に透明色を設定したテクスチャを貼り付けて表示します。
ColorKey(透明色)を設定するときは DirectX の D3DXCreateTextureFromFileEx() を使います。

【メモ】
ColorKey を設定しなくても、透明色を指定して PNG 形式で保存すると、透明になるようです。
「カリングモードと座標系」の説明は Windows Guid を参照して下さい。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. 背景を黒(0,0,0)に設定した適当な画像を調達してきて下さい。
    画像に黒が使われているときは 8,8,8 ぐらいに設定して下さい。
    JPG 画像は透明色には向かないので BMP 画像を使っています。
  2. DirectX の Global Area です。
    myd3d は MyD3D Object Class の定義です。
    g_pTexture はテクスチャのオブジェクトです。
    ViewForm() はカメラ座標です。
    "c:\\data\\test\\kishi.bmp" がテクスチャに使った画像ファイルです。
    //Global Area
    MyD3D                   *myd3d     = NULL;
    HWND                    g_hWnd     = NULL;
    LPDIRECT3DDEVICE9       g_pDEV     = NULL;
    LPDIRECT3DTEXTURE9      g_pTexture = NULL;
    bool                    g_bActive  = false;
    D3DXVECTOR3             ViewForm(0.0f, 0.0f, -30.0f);
    char                    imgfile[]= "c:\\data\\test\\kishi.bmp";
    
  3. 頂点フォーマットの設定です。
    三角形を組み合わせた矩形(TRIANGLESTRIP)を定義します。
    矩形の描画サイズは3Dのオブジェクトと同じように、描画環境の設定で幾らでも変わります。
    tu,tv がテクスチャ座標の定義です。
    テクスチャ座標は「左上=0.0f, 0.0f, 右下=1.0f, 1.0f」とした float タイプで設定します。

    ViewForm や vtx の順序が変わるとポリゴンが裏向いて描画されないことがあります。
    詳細はページ後部の【NOTE】を参照して下さい。
    #define D3DFVF_VERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
    typedef struct
    {   float       x,y,z;    // The position
        D3DCOLOR    color;    // The color
        FLOAT       tu, tv;   // The texture coordinates
    }   D3DMYVERTEX;
    D3DMYVERTEX vtx[4]=
    { { -6,    6,    0,   0xffffffff, 0,   0    },  //左上
      {  6,    6,    0,   0xffffffff, 1.0, 0    },  //右上
      { -6,   -6,    0,   0xffffffff, 0,   1.0  },  //左下
      {  6,   -6,    0,   0xffffffff, 1.0, 1.0  },  //右下
    };
    
  4. WinMain() はいつもと同じです。
    InitD3D() でデバイスを設定します。
    Draw() 関数は WM_PAINT: から呼んでいるので、メッセージループにはありません。
    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int)
    {   MSG     msg;
    
        WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,MsgProc,0L,0L,hInst,
                          NULL,NULL,NULL,NULL,NAME,NULL };
        if (RegisterClassEx(&wc)==0)    return FALSE;
        g_hWnd = CreateWindowEx(0,NAME,NAME,WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
                       NULL,NULL,hInst,NULL);
        if (!g_hWnd)                return FALSE;
        if (FAILED(InitD3D()))      return FALSE;
    
        ShowWindow(g_hWnd,SW_SHOWDEFAULT);
        UpdateWindow(g_hWnd);
        ZeroMemory(&msg,sizeof(msg));
        while(msg.message!=WM_QUIT)
        {   if (PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))
            {   TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            //else    Draw();
        }
        Cleanup();
        UnregisterClass(NAME,wc.hInstance);
        return TRUE;
    }
    
  5. CALLBACK 関数です。
    ESCAPEキーまたは F12キーを押すと終了します。
    今回のような静止した画像は Windows と同じように WM_PAINT: で描画することもできます。
    LRESULT WINAPI MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
    {
        switch(msg)
        {   case WM_ACTIVATE:
                g_bActive= (LOWORD(wParam)!=0);
                break;
            case WM_PAINT:
                Draw();
                return 0;
            case WM_KEYDOWN:
                switch(wParam)
                {   case VK_ESCAPE:
                    case VK_F12:
                        PostMessage(hWnd,WM_CLOSE,0,0);
                        return 0L;
                }
                break;
            case WM_DESTROY:
                PostQuitMessage(0);
                return 0L;
        }
        return DefWindowProc(hWnd,msg,wParam,lParam);
    }
    
  6. MyD3D Object Class をインスタンス化して、インターフェースを取得します。
    デバイスが設定できるとテクスチャ読み込みます。
    ColorKey(透明色)を設定するときは myd3d->LoadTextureBlack() を使います。
    LoadTextureBlack() のソースコードは MyD3D Object Class を参照して下さい。
    HRESULT InitD3D()
    {
        myd3d= new MyD3D(g_hWnd);
        myd3d->InitD3D(&g_pDEV);
        // テクスチャ読み込み
        g_pTexture= myd3d->LoadTextureBlack(imgfile);
        return S_OK;
    }
    
  7. 描画を行う Draw(void) 関数です。
    SetupMatrices() で描画環境を設定して g_pDEV->DrawPrimitiveUP() で矩形を描画します。
    void Draw(void)
    {
        if (!g_pDEV || !g_bActive)  return;
        g_pDEV->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,100,80),1.0,0);
        if (SUCCEEDED(g_pDEV->BeginScene()))
        {   SetupMatrices();
            // 頂点フォーマットの設定
            g_pDEV->SetFVF(D3DFVF_VERTEX);
            // 描画処理
            g_pDEV->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,vtx,sizeof(D3DMYVERTEX));
            g_pDEV->EndScene();
        }
        g_pDEV->Present(NULL,NULL,NULL,NULL);
    }
    
  8. 描画環境を設定する SetupMatrices() です。
    テクスチャを貼り付けるときは TextureStageState を設定して下さい。
    テクスチャに透明色を使うときは、カラーキー用アルファテストを設定して下さい。
    void  SetupMatrices(void)
    {   D3DXMATRIX      matView;
        D3DXMATRIX      matProj;
        RECT            rect;
    
        GetClientRect(g_hWnd,&rect);
        //View 座標の設定
        D3DXMatrixLookAtLH(&matView,&ViewForm,
                           //&D3DXVECTOR3(0.0f,0.0f,0.0f),&D3DXVECTOR3(0.0f,-1.0f,0.0f));
                           &D3DXVECTOR3(0.0f,0.0f,0.0f),&D3DXVECTOR3(0.0f,1.0f,0.0f));
        g_pDEV->SetTransform(D3DTS_VIEW,&matView);
        //透視変換の設定
        D3DXMatrixPerspectiveFovLH(&matProj,D3DXToRadian(45.0f),(float)rect.right/(float)rect.bottom,1,50);
        g_pDEV->SetTransform(D3DTS_PROJECTION,&matProj);
        //Zバッファの設定
        g_pDEV->SetRenderState(D3DRS_ZENABLE,D3DZB_FALSE);
        g_pDEV->SetRenderState(D3DRS_LIGHTING,FALSE);
        // テクスチャ設定
        g_pDEV->SetTexture(0,g_pTexture);
        g_pDEV->SetTextureStageState(0,D3DTSS_COLOROP,  D3DTOP_MODULATE);
        g_pDEV->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
        g_pDEV->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);
        //カラーキー用アルファテスト
        g_pDEV->SetRenderState(D3DRS_ALPHATESTENABLE,TRUE);
        g_pDEV->SetRenderState(D3DRS_ALPHAREF,0x80);
        g_pDEV->SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL);
    }
    

【課題】

  1. 0xffffffff は色の設定ですが、次のように定義すると「赤色が減色」するので試して下さい。
        D3DMYVERTEX vtx[4]=
        { { -6,    6,    0,   0xff40ffff, 0,   0    },  //左上
          {  6,    6,    0,   0xff40ffff, 1.0, 0    },  //右上
          { -6,   -6,    0,   0xff40ffff, 0,   1.0  },  //左下
          {  6,   -6,    0,   0xff40ffff, 1.0, 1.0  },  //右下
        };
        
  2. テクスチャ座標を次のように設定すると表示はどうなるでしょう。
        D3DMYVERTEX vtx[4]=
        { { -6,    6,    0,   0xffffffff, 0,   0    },  //左上
          {  6,    6,    0,   0xffffffff, 3.0, 0    },  //右上
          { -6,   -6,    0,   0xffffffff, 0,   2.0  },  //左下
          {  6,   -6,    0,   0xffffffff, 3.0, 2.0  },  //右下
        };
        

超初心者の方のために全ソースコードを掲載します。 (^_^;)
全ソースコード

前田稔(Maeda Minoru)の超初心者のプログラム入門

超初心者のプログラム入門(DirectX9 game program)

超初心者のプログラム入門(DirectX10 game program)