「ビルボード」の編集履歴(バックアップ)一覧はこちら
「ビルボード」(2009/03/08 (日) 18:11:34) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
<p>ビルボード処理です。<br />
主に樹木などポリゴン数が多く、背景であまり目立たない部分にあるケースの時に<br />
ポリゴン数を抑える目的で使われます。</p>
<table cellspacing="1" cellpadding="1" width="600" border="2"><tbody><tr><td>
<p><font size="2">#include <d3d9.h><br />
#include <d3dx9.h></font></p>
<p><font size="2">#define SAFE_RELEASE(p)
{if(p){(p)->Release();(p)=NULL;}}//安全に解放する</font></p>
<p><font size="2">LPDIRECT3D9 g_pD3D = NULL;//Direct3D9<br />
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;//レンダリングデバイス<br />
LPD3DXFONT g_pFont = NULL; //フォント<br />
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;//頂点バッファ<br />
LPDIRECT3DTEXTURE9 pTexture = NULL;<br />
float angle=0.0f;<br />
bool billflag=false;</font></p>
<p><font size="2">struct THING<br />
{ <br />
LPD3DXMESH pMesh;<br />
D3DMATERIAL9* pMeshMaterials;<br />
LPDIRECT3DTEXTURE9* pMeshTextures ;<br />
DWORD dwNumMaterials;<br />
D3DXVECTOR3 vecPosition;<br />
D3DXMATRIX matRotation;<br />
THING()<br />
{<br />
ZeroMemory(this,sizeof(THING));<br />
}<br />
};</font></p>
<p><font size="2">THING Thing[3];</font></p>
<p><font size="2">//テキスト描画<br />
void TextDraw(LPD3DXFONT pFont,char* text,int X,int Y)<br />
{<br />
RECT rect={X,Y,0,0};//描画位置<br />
//スプライトポインタ(無くても良し),描画文字,文字数(-1で全部),描画範囲,フォーマット,色<br />
pFont->DrawText(NULL, text, -1, &rect, DT_LEFT | DT_NOCLIP,
D3DCOLOR_ARGB(255, 255, 255, 255));<br />
}</font></p>
<p><font size="2">//レンダー<br />
VOID RenderThing(THING* pThing,int bill)<br />
{<br />
D3DXMATRIXA16 matWorld,matCurrentView,matPosition,matScale;<br />
if((bill==1)&&(billflag==true)){//ワールドトランスフォーム(絶対座標変換)<br />
pThing->pMeshMaterials->Emissive.a=1.0f;<br />
pThing->pMeshMaterials->Emissive.r=1.0f;<br />
pThing->pMeshMaterials->Emissive.g=1.0f;<br />
pThing->pMeshMaterials->Emissive.b=1.0f;<br />
D3DXMatrixIdentity(&matWorld);<br />
D3DXMatrixTranslation(&matPosition,pThing->vecPosition.x,pThing->vecPosition.y,<br />
pThing->vecPosition.z+0.01f);<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matPosition);<br />
D3DXMatrixScaling(&matScale,0.2f,0.2f,1.0f);<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matScale);</font></p>
<p><font size="2"> //現在のビュー行列を得て、、<br />
g_pd3dDevice->GetTransform(D3DTS_VIEW,&matCurrentView);<br />
// それを逆行列にして、、<br />
D3DXMatrixInverse(&matCurrentView,NULL,&matCurrentView);<br />
// ワールド行列に掛け合わせると、ビュー変換を打ち消すことになる<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matCurrentView);</font></p>
<p><font size="2"> g_pd3dDevice->SetTransform( D3DTS_WORLD,
&matWorld );</font></p>
<p><font size="2"> }else{<br />
//ワールドトランスフォーム(絶対座標変換)<br />
D3DXMatrixIdentity(&matWorld);<br />
D3DXMatrixTranslation(&matPosition,pThing->vecPosition.x,pThing->vecPosition.y,<br />
pThing->vecPosition.z);<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&pThing->matRotation);<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matPosition);<br />
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );<br />
}<br />
// ビュートランスフォーム(視点座標変換)<br />
D3DXVECTOR3 vecEyePt( 0.0f, 3.0f,-2.5f ); //カメラ(視点)位置<br />
D3DXVECTOR3 vecLookatPt( 0.0f, 0.0f, 0.0f );//注視位置<br />
D3DXVECTOR3 vecUpVec( 0.0f, 1.0f, 0.0f );//上方位置<br />
D3DXMATRIXA16 matView,matHeading,matCameraPos;<br />
D3DXMatrixIdentity(&matView);<br />
D3DXMatrixRotationY(&matHeading,angle);<br />
D3DXMatrixLookAtLH( &matCameraPos, &vecEyePt, &vecLookatPt,
&vecUpVec );<br />
D3DXMatrixMultiply(&matView,&matView,&matHeading);<br />
D3DXMatrixMultiply(&matView,&matView,&matCameraPos);<br />
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );<br />
// プロジェクショントランスフォーム(射影変換)<br />
D3DXMATRIXA16 matProj;<br />
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f
);<br />
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); <br />
// ライトをあてる 白色で鏡面反射ありに設定<br />
D3DXVECTOR3 vecDirection(-1,-1,1);<br />
D3DLIGHT9 light;<br />
ZeroMemory( &light, sizeof(D3DLIGHT9) );<br />
light.Type = D3DLIGHT_DIRECTIONAL;<br />
light.Diffuse.r = 1.0f;<br />
light.Diffuse.g = 1.0f;<br />
light.Diffuse.b = 1.0f; <br />
light.Specular.r=1.0f;<br />
light.Specular.g=1.0f;<br />
light.Specular.b=1.0f;<br />
D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDirection
);<br />
light.Range = 200.0f;<br />
g_pd3dDevice->SetLight( 0, &light );<br />
g_pd3dDevice->LightEnable( 0, TRUE );<br />
// レンダリング <br />
for( DWORD i=0; i<pThing->dwNumMaterials; i++ )<br />
{<br />
g_pd3dDevice->SetMaterial( &pThing->pMeshMaterials[i] );<br />
g_pd3dDevice->SetTexture( 0,pThing->pMeshTextures[i] );<br />
pThing->pMesh->DrawSubset( i );<br />
} <br />
}</font></p>
<p><font size="2">//初期化<br />
HRESULT InitThing(THING *pThing,LPSTR szXFileName,D3DXVECTOR3*
pvecPosition)<br />
{<br />
// メッシュの初期位置<br />
memcpy(&pThing->vecPosition,pvecPosition,sizeof(D3DXVECTOR3));<br />
// メッシュの初期回転行列<br />
D3DXMatrixIdentity(&pThing->matRotation);<br />
// Xファイルからメッシュをロードする <br />
LPD3DXBUFFER pD3DXMtrlBuffer = NULL;</font></p>
<p><font size="2"> if( FAILED( D3DXLoadMeshFromX( szXFileName,
D3DXMESH_SYSTEMMEM,<br />
g_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL,<br />
&pThing->dwNumMaterials, &pThing->pMesh ) ) )<br />
{<br />
MessageBox(NULL, "Xファイルの読み込みに失敗しました",szXFileName, MB_OK);<br />
return E_FAIL; <br />
}<br />
D3DXMATERIAL* d3dxMaterials =
(D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();<br />
pThing->pMeshMaterials = new D3DMATERIAL9[pThing->dwNumMaterials];<br />
pThing->pMeshTextures = new
LPDIRECT3DTEXTURE9[pThing->dwNumMaterials];</font></p>
<p><font size="2"> for( DWORD i=0; i<pThing->dwNumMaterials; i++ )<br />
{<br />
pThing->pMeshMaterials[i] = d3dxMaterials[i].MatD3D;<br />
pThing->pMeshMaterials[i].Ambient =
pThing->pMeshMaterials[i].Diffuse;<br />
pThing->pMeshTextures[i] = NULL;<br />
if( d3dxMaterials[i].pTextureFilename != NULL &&<br />
lstrlen(d3dxMaterials[i].pTextureFilename) > 0 )<br />
{ <br />
if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice,<br />
d3dxMaterials[i].pTextureFilename,<br />
&pThing->pMeshTextures[i] ) ) )<br />
{ <br />
MessageBox(NULL, "テクスチャの読み込みに失敗しました", NULL, MB_OK);<br />
}<br />
}<br />
}<br />
pD3DXMtrlBuffer->Release();<br />
<br />
return S_OK;<br />
}</font></p>
<p><font size="2">//Direct3D初期化<br />
HRESULT InitD3D( HWND hWnd )<br />
{<br />
//Direct3Dを生成する<br />
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION))){return E_FAIL;}</font></p>
<p><font size="2"> //デバイス生成用のパラメーター<br />
D3DPRESENT_PARAMETERS d3dpp;//パラメーター構造体<br />
ZeroMemory( &d3dpp, sizeof(d3dpp) );//ゼロで初期化<br />
d3dpp.Windowed = TRUE;//ウインドウモードで起動<br />
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;//バックバッファのスワップエフェクト
Direct3Dにスワップエフェクトをまかせる<br />
d3dpp.BackBufferFormat =
D3DFMT_UNKNOWN;//バックバッファのフォーマット今表示されているモニタの設定と同じ<br />
d3dpp.BackBufferCount = 1;//バックバッファの数<br />
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;//マルチサンプリングは行わない<br />
d3dpp.MultiSampleQuality = 0;//マルチサンプリングは行わないので0<br />
d3dpp.EnableAutoDepthStencil = TRUE;//Direct3Dに深度バッファの管理をまかせる<br />
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;//深度バッファのフォーマット(通常はこの値で問題ない)<br />
d3dpp.hDeviceWindow = hWnd;//カバーウィンドウ=アプリケーションのウィンドウ<br />
d3dpp.Flags = 0;//フラグは使わない<br />
d3dpp.FullScreen_RefreshRateInHz =
D3DPRESENT_RATE_DEFAULT;//今のリフレッシュレートをそのまま使う<br />
d3dpp.PresentationInterval =
D3DPRESENT_INTERVAL_DEFAULT;//モニタの垂直回帰を待つ</font></p>
<p><font size="2"> //Direct3Dデバイスの生成 HAL(ハードウェアアクセラレーション)<br />
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice))){<br />
//HALが駄目ならHEL(ソフトウェアエミュレーション)<br />
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice))){<br />
//駄目なら終了<br />
return(E_FAIL);<br />
}<br />
}</font></p>
<p><font size="2"> // カリングはしない<br />
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);<br />
// Zバッファー処理を有効にする<br />
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); </font></p>
<p><font size="2"> // Xファイル毎にメッシュを作成する<br />
InitThing(&Thing[0],"tail.x",&D3DXVECTOR3(0,0,0));<br />
InitThing(&Thing[1],"Center.x",&D3DXVECTOR3(0,0,0));<br />
InitThing(&Thing[2],"bill.x",&D3DXVECTOR3(0,1,1));</font></p>
<p><font size="2"> return S_OK;<br />
}</font></p>
<p><font size="2">//フォントの初期化<br />
HRESULT InitFont(HWND hWnd)<br />
{<br />
//フォントの生成 MSゴシック<br />
//デバイス,文字高さ,文字幅,フォントスタイル,ミップマップのレベル,斜体にするかどうか,文字セット,出力精度,出力品質,フォントピッチとファミリ,フォント名,フォントポインタ<br />
HRESULT hr = D3DXCreateFont( g_pd3dDevice, 24, 0, FW_HEAVY, 1, false,
SHIFTJIS_CHARSET, OUT_TT_ONLY_PRECIS,<br />
ANTIALIASED_QUALITY, FF_DONTCARE, "MS ゴシック", &g_pFont );<br />
if FAILED(hr){return(E_FAIL);}<br />
return S_OK;<br />
}</font></p>
<p><font size="2">//終了時解放処理<br />
VOID Cleanup()<br />
{<br />
SAFE_RELEASE(pTexture);<br />
SAFE_RELEASE(g_pVB);<br />
SAFE_RELEASE(g_pFont);<br />
SAFE_RELEASE(g_pd3dDevice);<br />
SAFE_RELEASE(g_pD3D);<br />
}</font></p>
<p><font size="2">//レンダリング<br />
VOID Render()<br />
{<br />
//デバイスが無いなら終了<br />
if(NULL==g_pd3dDevice){return;}<br />
angle+=0.01f;</font></p>
<p><font size="2"> //バックバッファのクリア<br />
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET| D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(200,200, 255), 1.0f, 0 );<br />
<br />
//シーンの開始<br />
if(SUCCEEDED(g_pd3dDevice->BeginScene()))<br />
{<br />
//ここに処理内容を書く<br />
for(DWORD i=0;i<3;i++)<br />
{ <br />
if(i==2){RenderThing(&Thing[i],1);}else{<br />
RenderThing(&Thing[i],0);<br />
}<br />
} <br />
TextDraw(g_pFont,"ビルボード処理:スペースキーでON/OFF",0,0);</font></p>
<p><br /><font size="2"> <br />
//シーンの終了<br />
g_pd3dDevice->EndScene();<br />
}</font></p>
<p><font size="2"> //バックバッファを表画面に反映させる<br />
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );<br />
}</font></p>
<p><font size="2">//メッセージプロシージャ<br />
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )<br />
{<br />
switch( msg )<br />
{<br />
case WM_DESTROY://終了時<br />
Cleanup();<br />
PostQuitMessage(0);<br />
return 0;</font></p>
<p><font size="2"> case WM_PAINT://ウインドウ描画時<br />
Render();<br />
return 0;<br />
case WM_SIZE://ウインドウサイズ変更時<br />
InvalidateRect(hWnd,NULL,true);//画面更新<br />
return 0;<br />
case WM_KEYDOWN:<br />
switch((CHAR)wParam)<br />
{<br />
case VK_SPACE:<br />
billflag== false ? billflag=true : billflag=false;<br />
break;<br />
case VK_ESCAPE:<br />
PostQuitMessage(0);<br />
break;<br />
case VK_LEFT:<br />
Thing[2].vecPosition.x-=0.01f; <br />
break;<br />
case VK_RIGHT:<br />
Thing[2].vecPosition.x+=0.01f;<br />
break; <br />
case VK_UP:<br />
Thing[2].vecPosition.y+=0.01f; <br />
break; <br />
case VK_DOWN:<br />
Thing[2].vecPosition.y-=0.01f;<br />
break; <br />
}<br />
break;<br />
}</font></p>
<p><font size="2"> return DefWindowProc( hWnd, msg, wParam, lParam );<br />
}</font></p>
<p><font size="2">//メイン関数<br />
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )<br />
{<br />
//ウインドウクラスの登録<br />
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,<br />
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,<br />
"Window1", NULL };<br />
RegisterClassEx( &wc );</font></p>
<p><font size="2"> //タイトルバーとウインドウ枠の分を含めてウインドウサイズを設定<br />
RECT rect;<br />
SetRect(&rect,0,0,640,480);<br />
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);<br />
rect.right=rect.right-rect.left;<br />
rect.bottom=rect.bottom-rect.top;<br />
rect.top=0;<br />
rect.left=0;</font></p>
<p><font size="2"> //ウインドウの生成<br />
HWND hWnd = CreateWindow( "Window1", "Hello DirectX9 World !!",<br />
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rect.right,
rect.bottom,<br />
NULL, NULL, wc.hInstance, NULL );</font></p>
<p><font size="2"> //Direct3D初期化<br />
if(SUCCEEDED(InitD3D(hWnd)))<br />
{<br />
InitFont(hWnd);<br />
//ウインドウ表示<br />
ShowWindow(hWnd,SW_SHOWDEFAULT);<br />
UpdateWindow(hWnd);</font></p>
<p><font size="2"> //メッセージループ<br />
MSG msg;<br />
while( GetMessage(&msg,NULL,0,0))<br />
{<br />
TranslateMessage(&msg);<br />
DispatchMessage(&msg);<br />
}<br />
}</font></p>
<p><font size="2"> UnregisterClass("Window1",wc.hInstance);<br />
return 0;<br />
}<br /></font></p>
</td>
</tr></tbody></table>
<p>ビルボード処理です。<br />
主に樹木などポリゴン数が多く、背景であまり目立たない部分にあるケースの時に<br />
ポリゴン数を抑える目的で使われます。</p>
<p><img alt="" src="http://www36.atwiki.jp/directx?cmd=upload&act=open&pageid=30&file=dxb.PNG" /></p>
<table cellspacing="1" cellpadding="1" width="600" border="2"><tbody><tr><td>
<p><font size="2">#include <d3d9.h><br />
#include <d3dx9.h></font></p>
<p><font size="2">#define SAFE_RELEASE(p)
{if(p){(p)->Release();(p)=NULL;}}//安全に解放する</font></p>
<p><font size="2">LPDIRECT3D9 g_pD3D = NULL;//Direct3D9<br />
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;//レンダリングデバイス<br />
LPD3DXFONT g_pFont = NULL; //フォント<br />
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;//頂点バッファ<br />
LPDIRECT3DTEXTURE9 pTexture = NULL;<br />
float angle=0.0f;<br />
bool billflag=false;</font></p>
<p><font size="2">struct THING<br />
{ <br />
LPD3DXMESH pMesh;<br />
D3DMATERIAL9* pMeshMaterials;<br />
LPDIRECT3DTEXTURE9* pMeshTextures ;<br />
DWORD dwNumMaterials;<br />
D3DXVECTOR3 vecPosition;<br />
D3DXMATRIX matRotation;<br />
THING()<br />
{<br />
ZeroMemory(this,sizeof(THING));<br />
}<br />
};</font></p>
<p><font size="2">THING Thing[3];</font></p>
<p><font size="2">//テキスト描画<br />
void TextDraw(LPD3DXFONT pFont,char* text,int X,int Y)<br />
{<br />
RECT rect={X,Y,0,0};//描画位置<br />
//スプライトポインタ(無くても良し),描画文字,文字数(-1で全部),描画範囲,フォーマット,色<br />
pFont->DrawText(NULL, text, -1, &rect, DT_LEFT | DT_NOCLIP,
D3DCOLOR_ARGB(255, 255, 255, 255));<br />
}</font></p>
<p><font size="2">//レンダー<br />
VOID RenderThing(THING* pThing,int bill)<br />
{<br />
D3DXMATRIXA16 matWorld,matCurrentView,matPosition,matScale;<br />
if((bill==1)&&(billflag==true)){//ワールドトランスフォーム(絶対座標変換)<br />
pThing->pMeshMaterials->Emissive.a=1.0f;<br />
pThing->pMeshMaterials->Emissive.r=1.0f;<br />
pThing->pMeshMaterials->Emissive.g=1.0f;<br />
pThing->pMeshMaterials->Emissive.b=1.0f;<br />
D3DXMatrixIdentity(&matWorld);<br />
D3DXMatrixTranslation(&matPosition,pThing->vecPosition.x,pThing->vecPosition.y,<br />
pThing->vecPosition.z+0.01f);<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matPosition);<br />
D3DXMatrixScaling(&matScale,0.2f,0.2f,1.0f);<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matScale);</font></p>
<p><font size="2"> //現在のビュー行列を得て、、<br />
g_pd3dDevice->GetTransform(D3DTS_VIEW,&matCurrentView);<br />
// それを逆行列にして、、<br />
D3DXMatrixInverse(&matCurrentView,NULL,&matCurrentView);<br />
// ワールド行列に掛け合わせると、ビュー変換を打ち消すことになる<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matCurrentView);</font></p>
<p><font size="2"> g_pd3dDevice->SetTransform( D3DTS_WORLD,
&matWorld );</font></p>
<p><font size="2"> }else{<br />
//ワールドトランスフォーム(絶対座標変換)<br />
D3DXMatrixIdentity(&matWorld);<br />
D3DXMatrixTranslation(&matPosition,pThing->vecPosition.x,pThing->vecPosition.y,<br />
pThing->vecPosition.z);<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&pThing->matRotation);<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matPosition);<br />
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );<br />
}<br />
// ビュートランスフォーム(視点座標変換)<br />
D3DXVECTOR3 vecEyePt( 0.0f, 3.0f,-2.5f ); //カメラ(視点)位置<br />
D3DXVECTOR3 vecLookatPt( 0.0f, 0.0f, 0.0f );//注視位置<br />
D3DXVECTOR3 vecUpVec( 0.0f, 1.0f, 0.0f );//上方位置<br />
D3DXMATRIXA16 matView,matHeading,matCameraPos;<br />
D3DXMatrixIdentity(&matView);<br />
D3DXMatrixRotationY(&matHeading,angle);<br />
D3DXMatrixLookAtLH( &matCameraPos, &vecEyePt, &vecLookatPt,
&vecUpVec );<br />
D3DXMatrixMultiply(&matView,&matView,&matHeading);<br />
D3DXMatrixMultiply(&matView,&matView,&matCameraPos);<br />
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );<br />
// プロジェクショントランスフォーム(射影変換)<br />
D3DXMATRIXA16 matProj;<br />
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f
);<br />
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); <br />
// ライトをあてる 白色で鏡面反射ありに設定<br />
D3DXVECTOR3 vecDirection(-1,-1,1);<br />
D3DLIGHT9 light;<br />
ZeroMemory( &light, sizeof(D3DLIGHT9) );<br />
light.Type = D3DLIGHT_DIRECTIONAL;<br />
light.Diffuse.r = 1.0f;<br />
light.Diffuse.g = 1.0f;<br />
light.Diffuse.b = 1.0f; <br />
light.Specular.r=1.0f;<br />
light.Specular.g=1.0f;<br />
light.Specular.b=1.0f;<br />
D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDirection
);<br />
light.Range = 200.0f;<br />
g_pd3dDevice->SetLight( 0, &light );<br />
g_pd3dDevice->LightEnable( 0, TRUE );<br />
// レンダリング <br />
for( DWORD i=0; i<pThing->dwNumMaterials; i++ )<br />
{<br />
g_pd3dDevice->SetMaterial( &pThing->pMeshMaterials[i] );<br />
g_pd3dDevice->SetTexture( 0,pThing->pMeshTextures[i] );<br />
pThing->pMesh->DrawSubset( i );<br />
} <br />
}</font></p>
<p><font size="2">//初期化<br />
HRESULT InitThing(THING *pThing,LPSTR szXFileName,D3DXVECTOR3*
pvecPosition)<br />
{<br />
// メッシュの初期位置<br />
memcpy(&pThing->vecPosition,pvecPosition,sizeof(D3DXVECTOR3));<br />
// メッシュの初期回転行列<br />
D3DXMatrixIdentity(&pThing->matRotation);<br />
// Xファイルからメッシュをロードする <br />
LPD3DXBUFFER pD3DXMtrlBuffer = NULL;</font></p>
<p><font size="2"> if( FAILED( D3DXLoadMeshFromX( szXFileName,
D3DXMESH_SYSTEMMEM,<br />
g_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL,<br />
&pThing->dwNumMaterials, &pThing->pMesh ) ) )<br />
{<br />
MessageBox(NULL, "Xファイルの読み込みに失敗しました",szXFileName, MB_OK);<br />
return E_FAIL; <br />
}<br />
D3DXMATERIAL* d3dxMaterials =
(D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();<br />
pThing->pMeshMaterials = new D3DMATERIAL9[pThing->dwNumMaterials];<br />
pThing->pMeshTextures = new
LPDIRECT3DTEXTURE9[pThing->dwNumMaterials];</font></p>
<p><font size="2"> for( DWORD i=0; i<pThing->dwNumMaterials; i++ )<br />
{<br />
pThing->pMeshMaterials[i] = d3dxMaterials[i].MatD3D;<br />
pThing->pMeshMaterials[i].Ambient =
pThing->pMeshMaterials[i].Diffuse;<br />
pThing->pMeshTextures[i] = NULL;<br />
if( d3dxMaterials[i].pTextureFilename != NULL &&<br />
lstrlen(d3dxMaterials[i].pTextureFilename) > 0 )<br />
{ <br />
if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice,<br />
d3dxMaterials[i].pTextureFilename,<br />
&pThing->pMeshTextures[i] ) ) )<br />
{ <br />
MessageBox(NULL, "テクスチャの読み込みに失敗しました", NULL, MB_OK);<br />
}<br />
}<br />
}<br />
pD3DXMtrlBuffer->Release();<br />
<br />
return S_OK;<br />
}</font></p>
<p><font size="2">//Direct3D初期化<br />
HRESULT InitD3D( HWND hWnd )<br />
{<br />
//Direct3Dを生成する<br />
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION))){return E_FAIL;}</font></p>
<p><font size="2"> //デバイス生成用のパラメーター<br />
D3DPRESENT_PARAMETERS d3dpp;//パラメーター構造体<br />
ZeroMemory( &d3dpp, sizeof(d3dpp) );//ゼロで初期化<br />
d3dpp.Windowed = TRUE;//ウインドウモードで起動<br />
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;//バックバッファのスワップエフェクト
Direct3Dにスワップエフェクトをまかせる<br />
d3dpp.BackBufferFormat =
D3DFMT_UNKNOWN;//バックバッファのフォーマット今表示されているモニタの設定と同じ<br />
d3dpp.BackBufferCount = 1;//バックバッファの数<br />
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;//マルチサンプリングは行わない<br />
d3dpp.MultiSampleQuality = 0;//マルチサンプリングは行わないので0<br />
d3dpp.EnableAutoDepthStencil = TRUE;//Direct3Dに深度バッファの管理をまかせる<br />
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;//深度バッファのフォーマット(通常はこの値で問題ない)<br />
d3dpp.hDeviceWindow = hWnd;//カバーウィンドウ=アプリケーションのウィンドウ<br />
d3dpp.Flags = 0;//フラグは使わない<br />
d3dpp.FullScreen_RefreshRateInHz =
D3DPRESENT_RATE_DEFAULT;//今のリフレッシュレートをそのまま使う<br />
d3dpp.PresentationInterval =
D3DPRESENT_INTERVAL_DEFAULT;//モニタの垂直回帰を待つ</font></p>
<p><font size="2"> //Direct3Dデバイスの生成 HAL(ハードウェアアクセラレーション)<br />
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice))){<br />
//HALが駄目ならHEL(ソフトウェアエミュレーション)<br />
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice))){<br />
//駄目なら終了<br />
return(E_FAIL);<br />
}<br />
}</font></p>
<p><font size="2"> // カリングはしない<br />
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);<br />
// Zバッファー処理を有効にする<br />
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); </font></p>
<p><font size="2"> // Xファイル毎にメッシュを作成する<br />
InitThing(&Thing[0],"tail.x",&D3DXVECTOR3(0,0,0));<br />
InitThing(&Thing[1],"Center.x",&D3DXVECTOR3(0,0,0));<br />
InitThing(&Thing[2],"bill.x",&D3DXVECTOR3(0,1,1));</font></p>
<p><font size="2"> return S_OK;<br />
}</font></p>
<p><font size="2">//フォントの初期化<br />
HRESULT InitFont(HWND hWnd)<br />
{<br />
//フォントの生成 MSゴシック<br />
//デバイス,文字高さ,文字幅,フォントスタイル,ミップマップのレベル,斜体にするかどうか,文字セット,出力精度,出力品質,フォントピッチとファミリ,フォント名,フォントポインタ<br />
HRESULT hr = D3DXCreateFont( g_pd3dDevice, 24, 0, FW_HEAVY, 1, false,
SHIFTJIS_CHARSET, OUT_TT_ONLY_PRECIS,<br />
ANTIALIASED_QUALITY, FF_DONTCARE, "MS ゴシック", &g_pFont );<br />
if FAILED(hr){return(E_FAIL);}<br />
return S_OK;<br />
}</font></p>
<p><font size="2">//終了時解放処理<br />
VOID Cleanup()<br />
{<br />
SAFE_RELEASE(pTexture);<br />
SAFE_RELEASE(g_pVB);<br />
SAFE_RELEASE(g_pFont);<br />
SAFE_RELEASE(g_pd3dDevice);<br />
SAFE_RELEASE(g_pD3D);<br />
}</font></p>
<p><font size="2">//レンダリング<br />
VOID Render()<br />
{<br />
//デバイスが無いなら終了<br />
if(NULL==g_pd3dDevice){return;}<br />
angle+=0.01f;</font></p>
<p><font size="2"> //バックバッファのクリア<br />
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET| D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(200,200, 255), 1.0f, 0 );<br />
<br />
//シーンの開始<br />
if(SUCCEEDED(g_pd3dDevice->BeginScene()))<br />
{<br />
//ここに処理内容を書く<br />
for(DWORD i=0;i<3;i++)<br />
{ <br />
if(i==2){RenderThing(&Thing[i],1);}else{<br />
RenderThing(&Thing[i],0);<br />
}<br />
} <br />
TextDraw(g_pFont,"ビルボード処理:スペースキーでON/OFF",0,0);</font></p>
<p><br /><font size="2"> <br />
//シーンの終了<br />
g_pd3dDevice->EndScene();<br />
}</font></p>
<p><font size="2"> //バックバッファを表画面に反映させる<br />
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );<br />
}</font></p>
<p><font size="2">//メッセージプロシージャ<br />
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )<br />
{<br />
switch( msg )<br />
{<br />
case WM_DESTROY://終了時<br />
Cleanup();<br />
PostQuitMessage(0);<br />
return 0;</font></p>
<p><font size="2"> case WM_PAINT://ウインドウ描画時<br />
Render();<br />
return 0;<br />
case WM_SIZE://ウインドウサイズ変更時<br />
InvalidateRect(hWnd,NULL,true);//画面更新<br />
return 0;<br />
case WM_KEYDOWN:<br />
switch((CHAR)wParam)<br />
{<br />
case VK_SPACE:<br />
billflag== false ? billflag=true : billflag=false;<br />
break;<br />
case VK_ESCAPE:<br />
PostQuitMessage(0);<br />
break;<br />
case VK_LEFT:<br />
Thing[2].vecPosition.x-=0.01f; <br />
break;<br />
case VK_RIGHT:<br />
Thing[2].vecPosition.x+=0.01f;<br />
break; <br />
case VK_UP:<br />
Thing[2].vecPosition.y+=0.01f; <br />
break; <br />
case VK_DOWN:<br />
Thing[2].vecPosition.y-=0.01f;<br />
break; <br />
}<br />
break;<br />
}</font></p>
<p><font size="2"> return DefWindowProc( hWnd, msg, wParam, lParam );<br />
}</font></p>
<p><font size="2">//メイン関数<br />
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )<br />
{<br />
//ウインドウクラスの登録<br />
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,<br />
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,<br />
"Window1", NULL };<br />
RegisterClassEx( &wc );</font></p>
<p><font size="2"> //タイトルバーとウインドウ枠の分を含めてウインドウサイズを設定<br />
RECT rect;<br />
SetRect(&rect,0,0,640,480);<br />
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);<br />
rect.right=rect.right-rect.left;<br />
rect.bottom=rect.bottom-rect.top;<br />
rect.top=0;<br />
rect.left=0;</font></p>
<p><font size="2"> //ウインドウの生成<br />
HWND hWnd = CreateWindow( "Window1", "Hello DirectX9 World !!",<br />
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rect.right,
rect.bottom,<br />
NULL, NULL, wc.hInstance, NULL );</font></p>
<p><font size="2"> //Direct3D初期化<br />
if(SUCCEEDED(InitD3D(hWnd)))<br />
{<br />
InitFont(hWnd);<br />
//ウインドウ表示<br />
ShowWindow(hWnd,SW_SHOWDEFAULT);<br />
UpdateWindow(hWnd);</font></p>
<p><font size="2"> //メッセージループ<br />
MSG msg;<br />
while( GetMessage(&msg,NULL,0,0))<br />
{<br />
TranslateMessage(&msg);<br />
DispatchMessage(&msg);<br />
}<br />
}</font></p>
<p><font size="2"> UnregisterClass("Window1",wc.hInstance);<br />
return 0;<br />
}<br /></font></p>
</td>
</tr></tbody></table>