ポリゴンの表示


~とりあえずね~




■今回のファイルは

やっと、ポリゴンを表示できるようになります。 とりあえず、3角形ポリゴンを表示します。

次のソースを、ダウンロードしてください。

今回は、描画専用に draw.cpp, draw.h のファイルを追加しました。
draw.cpp にある関数は、
HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDEV); // 初期化
void Render(LPDIRECT3DDEVICE8 lpD3DDEV);        // 描画
void CleanRender();                             // 後片付け
です。

■頂点の定義

DirectX では、頂点の情報を自分で指定します。 今回は、頂点に色をつけたものを表示します。
情報は、各位置と色なので、次のようになります。
// 頂点の定義
typedef struct {
    FLOAT x, y, z, rhw;  // 位置
    DWORD color;         // 色
} CUSTOMVERTEX;

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
また、今後扱いやすいように、頂点フォーマットの構成に define 名 D3DFVF_CUSTOMVERTEX をつけました。

■各関数

ポリゴンを描画するのに必要なオブジェクトは LPDIRECT3DVERTEXBUFFER8 です。 頂点バッファの情報がここに格納されます。

LPDIRECT3DVERTEXBUFFER8 pVB = NULL; // 頂点バッファに使うオブジェクト

さて、初期化です。
CreateVertexBuffer で頂点バッファについての初期化をして、 書き込むメモリを一時的にロックした後、頂点の情報をコピーします。
CreateVertexBuffer の引数の一つ目は、頂点バッファのサイズ(数字の3は3頂点の意味である)、 2つ目は各種フラグ、3つ目は、頂点フォーマットの種類、4つめは、どのメモリに情報を置くかを指定します。 最後は、生成した情報を入れる場所です。
その後のメモリのロックは、『書き込むので、メモリの内容が変化する途中である』ことを、他のアプリケーションに伝えて、 使わせないようにします。
ロックした後に、ローカル変数として確保している vertices の内容を、memcpy でコピーします。 vertices は先ほど定義した順番で、並んでいます。

HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDEV)
{
    CUSTOMVERTEX vertices[] = {
        //     x,      y,    z,  rhw, color
        { 150.0f,  50.0f, 0.5f, 1.0f, D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), },
        { 250.0f, 250.0f, 0.5f, 1.0f, D3DCOLOR_RGBA(0x00, 0xff, 0x00, 0xff), },
        {  50.0f, 250.0f, 0.5f, 1.0f, D3DCOLOR_RGBA(0x00, 0xff, 0xff, 0xff), },
    };
    HRESULT hr;
    
    hr = lpD3DDEV->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),0,
                                   D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &pVB);
    if(FAILED(hr)) return E_FAIL;

    VOID* pVertices;
    hr = pVB->Lock( 0, sizeof(vertices), (BYTE**)&pVertices, 0);
    if(FAILED(hr)) return E_FAIL;
    memcpy( pVertices, vertices, sizeof(vertices) );
    pVB->Unlock();

    return S_OK;
}

次に実際の描画です。
SetStreamSource で、頂点情報を指定します。
あとは、SetVertexShader で、頂点フォーマットを指定したあと、 DrawPrimitive で描画します。

void Render(LPDIRECT3DDEVICE8 lpD3DDEV)
{
    lpD3DDEV->SetStreamSource( 0, pVB, sizeof(CUSTOMVERTEX) );
    lpD3DDEV->SetVertexShader( D3DFVF_CUSTOMVERTEX );
    lpD3DDEV->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
}

後片付けは、CreateVertexBuffer で確保したメモリを開放するだけです。

void CleanRender()
{
    RELEASE(pVB);
}

■組み込み

main.cpp から、draw.h の各関数を呼び出します。 次のプログラムは、WinMain のウィンドウの初期化が終わった後です。
// Direct3D の初期化
if(SUCCEEDED(InitD3D(hWnd))){
    
    if(FAILED(InitRender(s_lpD3DDEV))) s_end = true;// ★★★★★ ポリゴン描画の初期化

    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);

    // メインループ
    MSG msg;
    while (!s_end)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
            // メッセージの処理
        }else{
            // Direct3D の描画
            // バックバッファと Z バッファをクリア
            s_lpD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
            // シーン開始
            s_lpD3DDEV->BeginScene();
            
            // 描画などの処理
           Render(s_lpD3DDEV);// ★★★★★ ポリゴンの描画
            
            // シーン終了
            s_lpD3DDEV->EndScene();
            if (FAILED(s_lpD3DDEV->Present(NULL,NULL,NULL,NULL)))
                s_lpD3DDEV->Reset(&s_d3dpp);// バックバッファをプライマリバッファにコピー
        }
    }
}

初期化に失敗したときは、終了フラグを立ててメインループを通らないようにしました。

// 終了
CleanRender();    // ★★★★★ 描画の後かたずけ
RELEASE(s_lpD3DDEV);
RELEASE(s_lpD3D);

return 0;




もどる

imagire@gmail.com