COM
ATL版DirectXにSphereを表示してみる
(2009. 7. 20)
前章でATL版のDirectXの画面が出てしまった(感動)ので、さっそくSphereを出してみる事にします。
ヘッダーファイルに球を作成するメソッドを追加です:
DXWindow.h class CDXWindow {
... // なんか色々ある部分ですよ
public:
ID3DXMesh sphere;
private:
void createSphere();
};
前章からの差分ですよ。Sphereの生成は簡単です:
CDXWindow::createSphere void CDXWindow::createSphere() {
D3DXCreateSphere( pD3DDev, 2, 20, 20, &sphere, 0 );
}
続いてOnDrawメソッド内を次のように拡張です:
CDXWindow::OnDraw() HRESULT CDXWindow::OnDraw(ATL_DRAWINFO& di)
{
if ( pD3DDev ) {
// ライト
D3DLIGHT9 light;
ZeroMemory(&light, sizeof(D3DLIGHT9) );
light.Direction = D3DXVECTOR3(-1, -1, 1);
light.Type = D3DLIGHT_DIRECTIONAL;
light.Diffuse.r = 1.0f;
light.Diffuse.g = 1.0f;
light.Diffuse.b = 1.0f;
light.Range = 1000;
// マテリアル
D3DMATERIAL9 material = {
{1.0f, 1.0f, 1.0f, 1.0f},
{0.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 0.0f},
50.0f
};
// ビュー変換
D3DXMATRIX View;
D3DXMatrixLookAtLH(
&View,
&D3DXVECTOR3(0.0f, 0.0f, -10.0f),
&D3DXVECTOR3(0, 0, 0),
&D3DXVECTOR3(0, 1, 0)
);
// 射影変換
D3DXMATRIX Proj;
float w = (float)(wndRect.right - wndRect.left);
float h = (float)(wndRect.bottom - wndRect.top);
D3DXMatrixPerspectiveFovLH( &Proj, D3DXToRadian(45), w/h, 1.0f, 10000.0f);
pD3DDev->SetLight( 0, &light );
pD3DDev->LightEnable( 0, true );
pD3DDev->SetRenderState( D3DRS_LIGHTING, TRUE );
pD3DDev->SetRenderState( D3DRS_AMBIENT, 0x00808080 ); // アンビエントライト
pD3DDev->SetMaterial( &material );
pD3DDev->SetTransform( D3DTS_VIEW, &View );
pD3DDev->SetTransform( D3DTS_PROJECTION, &Proj );
pD3DDev->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
pD3DDev->BeginScene();
sphere->DrawSubset(0);
pD3DDev->EndScene();
pD3DDev->Present( NULL, NULL, NULL, NULL );
}
return S_OK;
}
ライトとマテリアル、そしてビュー変換行列と射影変換行列を追加して、デバイスにセットしてSphereを描画しています。もうほとんどATL色はありませんね。これでコンパイルしてATLコントロールを作成し、VBに貼り付けると・・・よっしゃです(^-^)v
さて、COM+Direct3Dが実現で来ちゃったという事は、実質これでDirect3Dの色々な事がCOM(ATL)を通してVB上で出来てしまうことになります。これはとても楽しい状況が生まれました(依頼された仕事的にも大きな進歩・・・駄目かと思っただけに泣きそう(涙))。で、喜び勇んで上のビュー変換行列を使ってカメラを回してみたのですが・・・画像が変わりません。そりゃ当然で、更新となるOnDrawが呼ばれていないためです。このビューのOnDrawを定期的に呼び出すにはどうしたらよいか・・・。とりあえずタイマーかな。