やっと、ポリゴンを表示できるようになります。 とりあえず、3角形ポリゴンを表示します。
次のソースを、ダウンロードしてください。
今回は、描画専用に draw.cpp, draw.h のファイルを追加しました。
HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDEV); // 初期化 void Render(LPDIRECT3DDEVICE8 lpD3DDEV); // 描画 void CleanRender(); // 後片付けです。
// 頂点の定義
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);
}
// 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;