やっと、ポリゴンを表示できるようになります。 とりあえず、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;