「HLSL:フォン鏡面反射」の編集履歴(バックアップ)一覧はこちら
「HLSL:フォン鏡面反射」(2009/06/02 (火) 22:14:33) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
<p>よく磨きこまれた反射率の高い物体に光が当たると表面が光り輝いているように見えます。<br />
俗に言うハイライトですが、それを表現するのがこのフォン鏡面反射(フォンスペキュラー)です。</p>
<p><img alt="" src="http://www36.atwiki.jp/directx?cmd=upload&act=open&pageid=39&file=pn4.PNG" /></p>
<p><img alt="" src="http://www36.atwiki.jp/directx?cmd=upload&act=open&pageid=39&file=fn.PNG" /></p>
<p>HLSL.cpp</p>
<table cellspacing="1" cellpadding="1" width="600" border="2"><tbody><tr><td>
<p><font size="2">#include <d3dx9.h><br />
#include <string><br />
#define WINDOW_WIDTH 640 //ウインドウの幅<br />
#define WINDOW_HEIGHT 480 //ウインドウの高さ<br />
#define SAFE_RELEASE(x) if(x){x->Release();} </font></p>
<p><font size="2">using namespace std;</font></p>
<p><font size="2">LPDIRECT3D9 g_pD3D = NULL;//Direct3D9<br />
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;//レンダリングデバイス<br />
LPD3DXEFFECT m_pEffect; // ★シェーダ<br />
D3DXHANDLE m_hTechnique;// ★テクニック<br />
D3DXHANDLE m_hmWVP; // ★ワールド~射影行列<br />
D3DXHANDLE m_hvLightDir;<br />
D3DXHANDLE m_hvColor;<br />
D3DXHANDLE m_hvEyePos;<br />
LPDIRECT3DVERTEXDECLARATION9 m_pDecl; // 頂点宣言</font></p>
<p><font size="2">class MODEL{<br />
public:<br />
LPD3DXMESH Mesh;//メッシュ<br />
D3DMATERIAL9* Material;//マテリアル<br />
LPDIRECT3DTEXTURE9* Texture;//テクスチャ<br />
DWORD PartsNumber;//マテリアル数<br />
void LoadXFile(string);<br />
void XFileDraw(float,float,float,float,float,float,float,float,float);<br />
};</font></p>
<p><font size="2">//Xファイル描画<br />
void MODEL::XFileDraw(float XSize,float YSize,float ZSize,float XRot,float
YRot,float ZRot,float XTran,float YTran,float ZTran)<br />
{<br />
D3DXMATRIXA16
m,matWorld,matView,matScale,matRotation,matProj,matPosition[4],matPos;<br />
D3DXMatrixIdentity(&matWorld);<br />
D3DXMatrixScaling(&matScale,XSize,YSize,ZSize);<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matScale);<br />
//ワールドトランスフォーム(絶対座標変換)<br />
D3DXMatrixIdentity(&matRotation);</font></p>
<p><font size="2"> D3DXMatrixRotationY( &matRotation, YRot );<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matRotation);<br />
D3DXMatrixRotationX( &matRotation, XRot );<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matRotation);<br />
D3DXMatrixRotationZ( &matRotation, ZRot );</font></p>
<p><font size="2"> D3DXMatrixMultiply(&matWorld,&matWorld,&matRotation);<br />
D3DXMatrixTranslation(&matPos,XTran,YTran,ZTran);<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matPos);</font></p>
<p><font size="2"> // ビュートランスフォーム(視点座標変換)<br />
D3DXVECTOR3 vecEyePt( 0.0f, 7.0f,-3.5f ); //カメラ(視点)位置<br />
D3DXVECTOR3 vecLookatPt( 0.0f, 0.0f, 0.0f );//注視位置<br />
D3DXVECTOR3 vecUpVec( 0.0f, 1.0f, 0.0f );//上方位置<br />
D3DXMatrixLookAtLH( &matView, &vecEyePt, &vecLookatPt,
&vecUpVec );<br />
// プロジェクショントランスフォーム(射影変換)<br />
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 1000.0f
);<br />
m = (matWorld * matView * matProj);</font></p>
<p><font size="2"> m_pEffect->SetMatrix( m_hmWVP, &m );</font></p>
<p><font size="2"> D3DXVECTOR4 v;<br />
//light<br />
D3DXVECTOR4 light_pos = D3DXVECTOR4(-0.577f,-0.577f,-0.577f,0);<br />
D3DXMatrixInverse(&m,NULL,&matWorld);<br />
D3DXVec4Transform(&v,&light_pos,&m);<br />
D3DXVec3Normalize((D3DXVECTOR3 *)&v,(D3DXVECTOR3 *)&v);// 正規化<br />
v.w = -0.3f;// 環境光の強さ<br />
m_pEffect->SetVector(m_hvLightDir,&v);</font></p>
<p><font size="2"> // 視点<br />
m = matWorld * matView;<br />
D3DXMatrixInverse( &m, NULL, &m);<br />
v = D3DXVECTOR4( 0, 0, 0, 1);<br />
D3DXVec4Transform( &v, &v, &m );<br />
m_pEffect->SetVector( m_hvEyePos, &v );</font></p>
<p><font size="2"> //-------------------------------------------------<br />
// ★シェーダの設定<br />
//-------------------------------------------------<br />
m_pEffect->SetTechnique( m_hTechnique );<br />
m_pEffect->Begin( NULL, 0 );<br />
m_pEffect->BeginPass( 0 );</font></p>
<p><font size="2"> g_pd3dDevice->SetFVF( D3DFVF_XYZ |
D3DFVF_NORMAL);</font></p>
<p><font size="2"> m_pEffect->SetTexture("Tex", Texture[0]);<br />
//-------------------------------------------------<br />
// 描画<br />
//-------------------------------------------------<br />
g_pd3dDevice->SetVertexDeclaration( m_pDecl );</font></p>
<p><font size="2"> D3DMATERIAL9 *pMtrl = &Material[0];<br />
for( DWORD i=0; i<PartsNumber; i++ )<br />
{<br />
v.x=pMtrl->Diffuse.r/1.3f;<br />
v.y=pMtrl->Diffuse.g/1.3f;<br />
v.z=pMtrl->Diffuse.b/1.3f;<br />
m_pEffect->SetVector( m_hvColor, &v );</font></p>
<p><font size="2"> g_pd3dDevice->SetTexture( 0,Texture[i] );<br />
Mesh->DrawSubset( i );<br />
pMtrl++;<br />
}<br />
m_pEffect->EndPass();<br />
m_pEffect->End();<br />
}<br />
//Xファイル読み込み<br />
void MODEL::LoadXFile(string FileName)<br />
{<br />
// Xファイルからメッシュをロードする<br />
LPD3DXBUFFER pD3DXMtrlBuffer = NULL;</font></p>
<p><font size="2"> D3DXLoadMeshFromXA( FileName.c_str(),
D3DXMESH_SYSTEMMEM,g_pd3dDevice, NULL, &pD3DXMtrlBuffer,
NULL,&PartsNumber, &Mesh);<br />
D3DXMATERIAL* d3dxMaterials =
(D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();<br />
Material = new D3DMATERIAL9[PartsNumber];<br />
Texture = new LPDIRECT3DTEXTURE9[PartsNumber];</font></p>
<p><font size="2"> for( DWORD i=0; i<PartsNumber; i++ )<br />
{<br />
Material[i] = d3dxMaterials[i].MatD3D; <br />
Material[i].Ambient = Material[i].Diffuse;<br />
Texture[i] = NULL;<br />
if( d3dxMaterials[i].pTextureFilename != NULL
&&lstrlenA(d3dxMaterials[i].pTextureFilename) > 0)<br />
{ <br />
D3DXCreateTextureFromFileA(g_pd3dDevice,d3dxMaterials[i].pTextureFilename,&Texture[i]);<br />
}<br />
}<br />
pD3DXMtrlBuffer->Release();<br />
}</font></p>
<p><br /><font size="2"> MODEL Model[2];//モデル用</font></p>
<p><font size="2"> HWND hwnd;</font></p>
<p><font size="2">HRESULT Init()<br />
{<br />
HRESULT hr;</font></p>
<p><font size="2"> // ★シェーダの読み込み<br />
LPD3DXBUFFER pErr=NULL;<br />
if( FAILED( hr = D3DXCreateEffectFromFileA(<br />
g_pd3dDevice, "hlsl.fx", NULL, NULL,<br />
0 , NULL, &m_pEffect, &pErr ))){</font></p>
<p><font size="2"> // シェーダの読み込みの失敗<br />
MessageBoxA( NULL, (LPCSTR)pErr->GetBufferPointer()<br />
, "ERROR", MB_OK);<br />
}else{<br />
m_hTechnique = m_pEffect->GetTechniqueByName( "TShader" );<br />
m_hmWVP = m_pEffect->GetParameterByName( NULL, "mWVP" );<br />
//m_hmWIT = m_pEffect->GetParameterByName( NULL, "mWIT" );<br />
m_hvLightDir = m_pEffect->GetParameterByName( NULL, "vLightDir" );<br />
m_hvColor = m_pEffect->GetParameterByName( NULL, "vColor" );<br />
m_hvEyePos = m_pEffect->GetParameterByName( NULL, "vEyePos" );<br />
}<br />
SAFE_RELEASE(pErr);</font></p>
<p><font size="2"> return true;<br />
}<br />
void FrameUpDate()<br />
{</font></p>
<p><font size="2">}<br />
void ScreenDraw()<br />
{</font></p>
<p><font size="2">// 画面をクリアする<br />
g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,<br />
0x000000ff, 1.0f, 0L );<br />
//シーンの開始<br />
if(SUCCEEDED(g_pd3dDevice->BeginScene()))<br />
{</font></p>
<p><font size="2"> Model[0].XFileDraw(1.0f,1.0f,1.0f,0.5f,timeGetTime()/10000.0f,0.0f,0.0f,0.0f,0.0f);<br />
Model[1].XFileDraw(1.0f,1.0f,1.0f,0.5f,timeGetTime()/300.0f,0.0f,0.0f,0.0f,3.0f);<br />
<br />
//シーンの終了<br />
g_pd3dDevice->EndScene();<br />
}</font></p>
<p><font size="2"> //バックバッファを表画面に反映させる<br />
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );</font></p>
<p> </p>
<p><font size="2">}<br />
void GetFPS()<br />
{<br />
FrameUpDate();<br />
ScreenDraw();<br />
Sleep(16);<br />
}<br />
DWORD WINAPI MainLoop(LPVOID vdParam)<br />
{<br />
while(TRUE){<br />
GetFPS();<br />
}<br />
return 0;<br />
}<br />
HRESULT InitD3D( HWND hWnd )<br />
{<br />
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION))){return E_FAIL;}</font></p>
<p><font size="2"> D3DPRESENT_PARAMETERS d3dpp;<br />
ZeroMemory( &d3dpp, sizeof(d3dpp) );<br />
d3dpp.Windowed = TRUE;<br />
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;<br />
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;<br />
d3dpp.BackBufferCount = 1;<br />
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;<br />
d3dpp.MultiSampleQuality = 0;<br />
d3dpp.EnableAutoDepthStencil = TRUE;<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_IMMEDIATE ;</font></p>
<p><font size="2"> if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp,
&g_pd3dDevice))){<br />
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice))){<br />
return(E_FAIL);<br />
}<br />
}</font></p>
<p><font size="2"> // Xファイルからメッシュをロードする<br />
Model[0].LoadXFile("land.x");<br />
Model[1].LoadXFile("ufo.x");</font></p>
<p><br /><font size="2"> Init();<br />
return S_OK;<br />
}<br />
LRESULT CALLBACK MsgProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {<br />
switch (msg) {<br />
case WM_DESTROY:<br />
PostQuitMessage(0);<br />
return 0;<br />
}<br />
return DefWindowProc(hwnd , msg , wp , lp);<br />
}</font></p>
<p><font size="2">int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE
hPrevInstance ,PSTR lpCmdLine , int nCmdShow )<br />
{<br />
MSG msg;<br />
DWORD dwID;</font></p>
<p><br /><font size="2"> WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc,
0L, 0L,<br />
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,<br />
L"Window1", NULL };<br />
RegisterClassEx( &wc );</font></p>
<p><font size="2"> RECT rect;<br />
SetRect(&rect,0,0,WINDOW_WIDTH,WINDOW_HEIGHT);<br />
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);<br />
SetRect(&rect,0,0,rect.right-rect.left,rect.bottom-rect.top);</font></p>
<p><font size="2"> hwnd = CreateWindow( L"Window1", L"HLSL",<br />
WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, rect.right, rect.bottom,<br />
NULL, NULL, wc.hInstance, NULL );</font></p>
<p><font size="2"> if (hwnd == NULL) return 0;</font></p>
<p><font size="2"> timeBeginPeriod(1);</font></p>
<p><font size="2"> if(SUCCEEDED(InitD3D(hwnd))){<br />
ShowWindow(hwnd,SW_SHOWDEFAULT);<br />
UpdateWindow(hwnd);</font></p>
<p><font size="2"> CreateThread(NULL , 0 , MainLoop , (LPVOID)hwnd , 0 ,
&dwID);<br />
while (GetMessage(&msg , NULL , 0 , 0 )) {<br />
TranslateMessage(&msg);<br />
DispatchMessage(&msg);<br />
}</font></p>
<p><font size="2"> }<br />
UnregisterClass(L"Window1",wc.hInstance);<br />
timeEndPeriod(1);</font></p>
<p><font size="2"> SAFE_RELEASE( m_pEffect ); // シェーダ<br />
SAFE_RELEASE( m_pDecl ); // 頂点宣言<br />
SAFE_RELEASE(g_pd3dDevice);<br />
SAFE_RELEASE(g_pD3D);<br />
return 0;<br />
}<br /></font></p>
</td>
</tr></tbody></table><p>hlsl.fx</p>
<table cellspacing="1" cellpadding="1" width="600" border="2"><tbody><tr><td>
<p><font size="2">//グローバル変数<br />
float4x4 mWVP;//ローカルから射影空間への座標変換</font></p>
<p><font size="2">//テクスチャ<br />
texture Tex;<br />
sampler Samp = sampler_state<br />
{<br />
Texture =<Tex>;<br />
MinFilter =LINEAR;<br />
MagFilter =LINEAR;<br />
MipFilter =NONE;</font></p>
<p><font size="2"> AddressU =Clamp;<br />
AddressV =Clamp;<br />
};</font></p>
<p><font size="2">float4 vLightDir; // ライトの方向<br />
float4 vColor; // ライト*メッシュの色<br />
float3 vEyePos; //カメラの位置<br />
// 光の強さ<br />
float4 I_a = { 0.3f, 0.3f, 0.3f, 0.0f }; // ambient<br />
float4 I_d = { 0.7f, 0.7f, 0.7f, 0.0f }; // diffuse</font></p>
<p><font size="2">// 反射率<br />
float4 k_a = { 1.0f, 1.0f, 1.0f, 1.0f }; // ambient<br />
float4 k_d = { 1.0f, 1.0f, 1.0f, 1.0f }; // diffuse</font></p>
<p><font size="2">// 頂点シェーダからピクセルシェーダに渡すデータ<br />
struct VS_OUTPUT<br />
{<br />
float4 Pos : POSITION;<br />
float4 Color : COLOR0;<br />
float2 Tex : TEXCOORD0;<br />
};</font></p>
<p><font size="2">//頂点シェーダプログラム<br />
VS_OUTPUT VS(<br />
float4 Pos : POSITION, // ローカル位置座標<br />
float4 Normal : NORMAL, // 法線ベクトル<br />
float2 Tex:TEXCOORD<br />
){<br />
VS_OUTPUT Out = (VS_OUTPUT)0; // 出力データ<br />
<br />
// 座標変換<br />
Out.Pos = mul(Pos, mWVP);</font></p>
<p><font size="2"> // 頂点色<br />
float amb = -vLightDir.w;//環境光の強さ<br />
float3 eye = normalize(vEyePos -Pos.xyz);<br />
float3 L = -vLightDir;//ライトベクトル<br />
float3 N = Normal.xyz;<br />
float3 R = -eye +2.0f*dot(N,eye)*N;//反射ベクトル</font></p>
<p><font size="2"> Out.Color =vColor * max(amb,dot(Normal, -vLightDir))<br />
+pow(max(0,dot(L,R)),10);</font></p>
<p><font size="2"> return Out;<br />
}<br />
// -------------------------------------------------------------<br />
float4 PS(VS_OUTPUT In) : COLOR<br />
{ <br />
return In.Color;<br />
}</font></p>
<p><font size="2">//
-------------------------------------------------------------<br />
// テクニック<br />
// -------------------------------------------------------------<br />
technique TShader<br />
{<br />
pass P0<br />
{<br />
VertexShader = compile vs_2_0 VS();<br />
PixelShader = compile ps_2_0 PS();<br />
}<br />
}<br /></font></p>
</td>
</tr></tbody></table>
<p>よく磨きこまれた反射率の高い物体に光が当たると表面が光り輝いているように見えます。<br />
俗に言うハイライトですが、それを表現するのがこのフォン鏡面反射(フォンスペキュラー)です。</p>
<p><img alt="" src="http://www36.atwiki.jp/directx?cmd=upload&act=open&pageid=39&file=pn4.PNG" /></p>
<p><img alt="" src="http://www36.atwiki.jp/directx?cmd=upload&act=open&pageid=39&file=fn.PNG" /></p>
<p>HLSL.cpp</p>
<table cellspacing="1" cellpadding="1" width="600" border="2"><tbody><tr><td>
<p><font size="2">#include <d3dx9.h><br />
#include <string><br />
#define WINDOW_WIDTH 640 //ウインドウの幅<br />
#define WINDOW_HEIGHT 480 //ウインドウの高さ<br />
#define SAFE_RELEASE(x) if(x){x->Release();} </font></p>
<p><font size="2">using namespace std;</font></p>
<p><font size="2">LPDIRECT3D9 g_pD3D = NULL;//Direct3D9<br />
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;//レンダリングデバイス<br />
LPD3DXEFFECT m_pEffect; // ★シェーダ<br />
D3DXHANDLE m_hTechnique;// ★テクニック<br />
D3DXHANDLE m_hmWVP; // ★ワールド~射影行列<br />
D3DXHANDLE m_hvLightDir;<br />
D3DXHANDLE m_hvColor;<br />
D3DXHANDLE m_hvEyePos;<br />
LPDIRECT3DVERTEXDECLARATION9 m_pDecl; // 頂点宣言</font></p>
<p><font size="2">class MODEL{<br />
public:<br />
LPD3DXMESH Mesh;//メッシュ<br />
D3DMATERIAL9* Material;//マテリアル<br />
LPDIRECT3DTEXTURE9* Texture;//テクスチャ<br />
DWORD PartsNumber;//マテリアル数<br />
void LoadXFile(string);<br />
void XFileDraw(float,float,float,float,float,float,float,float,float);<br />
};</font></p>
<p><font size="2">//Xファイル描画<br />
void MODEL::XFileDraw(float XSize,float YSize,float ZSize,float XRot,float
YRot,float ZRot,float XTran,float YTran,float ZTran)<br />
{<br />
D3DXMATRIXA16
m,matWorld,matView,matScale,matRotation,matProj,matPosition[4],matPos;<br />
D3DXMatrixIdentity(&matWorld);<br />
D3DXMatrixScaling(&matScale,XSize,YSize,ZSize);<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matScale);<br />
//ワールドトランスフォーム(絶対座標変換)<br />
D3DXMatrixIdentity(&matRotation);</font></p>
<p><font size="2"> D3DXMatrixRotationY( &matRotation, YRot );<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matRotation);<br />
D3DXMatrixRotationX( &matRotation, XRot );<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matRotation);<br />
D3DXMatrixRotationZ( &matRotation, ZRot );</font></p>
<p><font size="2"> D3DXMatrixMultiply(&matWorld,&matWorld,&matRotation);<br />
D3DXMatrixTranslation(&matPos,XTran,YTran,ZTran);<br />
D3DXMatrixMultiply(&matWorld,&matWorld,&matPos);</font></p>
<p><font size="2"> // ビュートランスフォーム(視点座標変換)<br />
D3DXVECTOR3 vecEyePt( 0.0f, 7.0f,-3.5f ); //カメラ(視点)位置<br />
D3DXVECTOR3 vecLookatPt( 0.0f, 0.0f, 0.0f );//注視位置<br />
D3DXVECTOR3 vecUpVec( 0.0f, 1.0f, 0.0f );//上方位置<br />
D3DXMatrixLookAtLH( &matView, &vecEyePt, &vecLookatPt,
&vecUpVec );<br />
// プロジェクショントランスフォーム(射影変換)<br />
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 1000.0f
);<br />
m = (matWorld * matView * matProj);</font></p>
<p><font size="2"> m_pEffect->SetMatrix( m_hmWVP, &m );</font></p>
<p><font size="2"> D3DXVECTOR4 v;<br />
//light<br />
D3DXVECTOR4 light_pos = D3DXVECTOR4(-0.577f,-0.577f,-0.577f,0);<br />
D3DXMatrixInverse(&m,NULL,&matWorld);<br />
D3DXVec4Transform(&v,&light_pos,&m);<br />
D3DXVec3Normalize((D3DXVECTOR3 *)&v,(D3DXVECTOR3 *)&v);// 正規化<br />
v.w = -0.3f;// 環境光の強さ<br />
m_pEffect->SetVector(m_hvLightDir,&v);</font></p>
<p><font size="2"> // 視点<br />
m = matWorld * matView;<br />
D3DXMatrixInverse( &m, NULL, &m);<br />
v = D3DXVECTOR4( 0, 0, 0, 1);<br />
D3DXVec4Transform( &v, &v, &m );<br />
m_pEffect->SetVector( m_hvEyePos, &v );</font></p>
<p><font size="2"> //-------------------------------------------------<br />
// ★シェーダの設定<br />
//-------------------------------------------------<br />
m_pEffect->SetTechnique( m_hTechnique );<br />
m_pEffect->Begin( NULL, 0 );<br />
m_pEffect->BeginPass( 0 );</font></p>
<p><font size="2"> g_pd3dDevice->SetFVF( D3DFVF_XYZ |
D3DFVF_NORMAL);</font></p>
<p><font size="2"> m_pEffect->SetTexture("Tex", Texture[0]);<br />
//-------------------------------------------------<br />
// 描画<br />
//-------------------------------------------------<br />
g_pd3dDevice->SetVertexDeclaration( m_pDecl );</font></p>
<p><font size="2"> D3DMATERIAL9 *pMtrl = &Material[0];<br />
for( DWORD i=0; i<PartsNumber; i++ )<br />
{<br />
v.x=pMtrl->Diffuse.r/1.3f;<br />
v.y=pMtrl->Diffuse.g/1.3f;<br />
v.z=pMtrl->Diffuse.b/1.3f;<br />
m_pEffect->SetVector( m_hvColor, &v );</font></p>
<p><font size="2"> g_pd3dDevice->SetTexture( 0,Texture[i] );<br />
Mesh->DrawSubset( i );<br />
pMtrl++;<br />
}<br />
m_pEffect->EndPass();<br />
m_pEffect->End();<br />
}<br />
//Xファイル読み込み<br />
void MODEL::LoadXFile(string FileName)<br />
{<br />
// Xファイルからメッシュをロードする<br />
LPD3DXBUFFER pD3DXMtrlBuffer = NULL;</font></p>
<p><font size="2"> D3DXLoadMeshFromXA( FileName.c_str(),
D3DXMESH_SYSTEMMEM,g_pd3dDevice, NULL, &pD3DXMtrlBuffer,
NULL,&PartsNumber, &Mesh);<br />
D3DXMATERIAL* d3dxMaterials =
(D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();<br />
Material = new D3DMATERIAL9[PartsNumber];<br />
Texture = new LPDIRECT3DTEXTURE9[PartsNumber];</font></p>
<p><font size="2"> for( DWORD i=0; i<PartsNumber; i++ )<br />
{<br />
Material[i] = d3dxMaterials[i].MatD3D; <br />
Material[i].Ambient = Material[i].Diffuse;<br />
Texture[i] = NULL;<br />
if( d3dxMaterials[i].pTextureFilename != NULL
&&lstrlenA(d3dxMaterials[i].pTextureFilename) > 0)<br />
{ <br />
D3DXCreateTextureFromFileA(g_pd3dDevice,d3dxMaterials[i].pTextureFilename,&Texture[i]);<br />
}<br />
}<br />
pD3DXMtrlBuffer->Release();<br />
}</font></p>
<p><br /><font size="2"> MODEL Model[2];//モデル用</font></p>
<p><font size="2"> HWND hwnd;</font></p>
<p><font size="2">HRESULT Init()<br />
{<br />
HRESULT hr;</font></p>
<p><font size="2"> // ★シェーダの読み込み<br />
LPD3DXBUFFER pErr=NULL;<br />
if( FAILED( hr = D3DXCreateEffectFromFileA(<br />
g_pd3dDevice, "hlsl.fx", NULL, NULL,<br />
0 , NULL, &m_pEffect, &pErr ))){</font></p>
<p><font size="2"> // シェーダの読み込みの失敗<br />
MessageBoxA( NULL, (LPCSTR)pErr->GetBufferPointer()<br />
, "ERROR", MB_OK);<br />
}else{<br />
m_hTechnique = m_pEffect->GetTechniqueByName( "TShader" );<br />
m_hmWVP = m_pEffect->GetParameterByName( NULL, "mWVP" );<br />
//m_hmWIT = m_pEffect->GetParameterByName( NULL, "mWIT" );<br />
m_hvLightDir = m_pEffect->GetParameterByName( NULL, "vLightDir" );<br />
m_hvColor = m_pEffect->GetParameterByName( NULL, "vColor" );<br />
m_hvEyePos = m_pEffect->GetParameterByName( NULL, "vEyePos" );<br />
}<br />
SAFE_RELEASE(pErr);</font></p>
<p><font size="2"> return true;<br />
}<br />
void FrameUpDate()<br />
{</font></p>
<p><font size="2">}<br />
void ScreenDraw()<br />
{</font></p>
<p><font size="2">// 画面をクリアする<br />
g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,<br />
0x000000ff, 1.0f, 0L );<br />
//シーンの開始<br />
if(SUCCEEDED(g_pd3dDevice->BeginScene()))<br />
{</font></p>
<p><font size="2"> Model[0].XFileDraw(1.0f,1.0f,1.0f,0.5f,timeGetTime()/10000.0f,0.0f,0.0f,0.0f,0.0f);<br />
Model[1].XFileDraw(1.0f,1.0f,1.0f,0.5f,timeGetTime()/300.0f,0.0f,0.0f,0.0f,3.0f);<br />
<br />
//シーンの終了<br />
g_pd3dDevice->EndScene();<br />
}</font></p>
<p><font size="2"> //バックバッファを表画面に反映させる<br />
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );</font></p>
<p> </p>
<p><font size="2">}<br />
void GetFPS()<br />
{<br />
FrameUpDate();<br />
ScreenDraw();<br />
Sleep(16);<br />
}<br />
DWORD WINAPI MainLoop(LPVOID vdParam)<br />
{<br />
while(TRUE){<br />
GetFPS();<br />
}<br />
return 0;<br />
}<br />
HRESULT InitD3D( HWND hWnd )<br />
{<br />
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION))){return E_FAIL;}</font></p>
<p><font size="2"> D3DPRESENT_PARAMETERS d3dpp;<br />
ZeroMemory( &d3dpp, sizeof(d3dpp) );<br />
d3dpp.Windowed = TRUE;<br />
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;<br />
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;<br />
d3dpp.BackBufferCount = 1;<br />
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;<br />
d3dpp.MultiSampleQuality = 0;<br />
d3dpp.EnableAutoDepthStencil = TRUE;<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_IMMEDIATE ;</font></p>
<p><font size="2"> if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp,
&g_pd3dDevice))){<br />
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice))){<br />
return(E_FAIL);<br />
}<br />
}</font></p>
<p><font size="2"> // Xファイルからメッシュをロードする<br />
Model[0].LoadXFile("land.x");<br />
Model[1].LoadXFile("ufo.x");</font></p>
<p><br /><font size="2"> Init();<br />
return S_OK;<br />
}<br />
LRESULT CALLBACK MsgProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {<br />
switch (msg) {<br />
case WM_DESTROY:<br />
PostQuitMessage(0);<br />
return 0;<br />
}<br />
return DefWindowProc(hwnd , msg , wp , lp);<br />
}</font></p>
<p><font size="2">int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE
hPrevInstance ,PSTR lpCmdLine , int nCmdShow )<br />
{<br />
MSG msg;<br />
DWORD dwID;</font></p>
<p><br /><font size="2"> WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc,
0L, 0L,<br />
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,<br />
L"Window1", NULL };<br />
RegisterClassEx( &wc );</font></p>
<p><font size="2"> RECT rect;<br />
SetRect(&rect,0,0,WINDOW_WIDTH,WINDOW_HEIGHT);<br />
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);<br />
SetRect(&rect,0,0,rect.right-rect.left,rect.bottom-rect.top);</font></p>
<p><font size="2"> hwnd = CreateWindow( L"Window1", L"HLSL",<br />
WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, rect.right, rect.bottom,<br />
NULL, NULL, wc.hInstance, NULL );</font></p>
<p><font size="2"> if (hwnd == NULL) return 0;</font></p>
<p><font size="2"> timeBeginPeriod(1);</font></p>
<p><font size="2"> if(SUCCEEDED(InitD3D(hwnd))){<br />
ShowWindow(hwnd,SW_SHOWDEFAULT);<br />
UpdateWindow(hwnd);</font></p>
<p><font size="2"> CreateThread(NULL , 0 , MainLoop , (LPVOID)hwnd , 0 ,
&dwID);<br />
while (GetMessage(&msg , NULL , 0 , 0 )) {<br />
TranslateMessage(&msg);<br />
DispatchMessage(&msg);<br />
}</font></p>
<p><font size="2"> }<br />
UnregisterClass(L"Window1",wc.hInstance);<br />
timeEndPeriod(1);</font></p>
<p><font size="2"> SAFE_RELEASE( m_pEffect ); // シェーダ<br />
SAFE_RELEASE( m_pDecl ); // 頂点宣言<br />
SAFE_RELEASE(g_pd3dDevice);<br />
SAFE_RELEASE(g_pD3D);<br />
return 0;<br />
}<br /></font></p>
</td>
</tr></tbody></table><p>hlsl.fx</p>
<table cellspacing="1" cellpadding="1" width="600" border="2"><tbody><tr><td>
<p><font size="2">//
-------------------------------------------------------------<br />
// グローバル変数<br />
// -------------------------------------------------------------</font></p>
<p><font size="2">float4x4 mWVP;</font></p>
<p><font size="2">float4 vLightDir; // ライトの方向<br />
float4 vColor; // ライト*メッシュの色<br />
float3 vEyePos; // カメラの位置(ローカル座標系)</font></p>
<p><font size="2">//
-------------------------------------------------------------<br />
// 頂点シェーダからピクセルシェーダに渡すデータ<br />
// -------------------------------------------------------------<br />
struct VS_OUTPUT<br />
{<br />
float4 Pos : POSITION;<br />
float4 Color : COLOR0;<br />
float3 N : TEXCOORD0;<br />
float3 Eye : TEXCOORD1;<br />
float2 Tex : TEXCOORD2;<br />
};<br />
//テクスチャ<br />
texture Tex;<br />
sampler Samp = sampler_state<br />
{<br />
Texture =<Tex>;<br />
MinFilter =LINEAR;<br />
MagFilter =LINEAR;<br />
MipFilter =NONE;</font></p>
<p><font size="2"> AddressU =Clamp;<br />
AddressV =Clamp;<br />
};<br />
// -------------------------------------------------------------<br />
// シーンの描画<br />
// -------------------------------------------------------------<br />
VS_OUTPUT VS(<br />
float4 Pos : POSITION, // ローカル位置座標<br />
float4 Normal : NORMAL, // 法線ベクトル<br />
float2 Tex : TEXCOORD<br />
){<br />
VS_OUTPUT Out = (VS_OUTPUT)0; // 出力データ<br />
<br />
// 座標変換<br />
Out.Pos = mul(Pos, mWVP);<br />
<br />
// 拡散光+環境光<br />
float amb = -vLightDir.w; // 環境光の強さ<br />
float3 L = -vLightDir; // ローカル座標系でのライトベクトル<br />
Out.Color = vColor * max(amb, dot(Normal, -vLightDir));<br />
<br />
// 鏡面反射用のベクトル<br />
Out.N = Normal.xyz;<br />
Out.Eye = vEyePos - Pos.xyz;<br />
Out.Tex = Tex;//テクスチャ座標<br />
<br />
return Out;<br />
}<br />
// -------------------------------------------------------------<br />
float4 PS(VS_OUTPUT In) : COLOR<br />
{ <br />
float3 L = -vLightDir.xyz;<br />
float3 H = normalize(L + normalize(In.Eye)); // ハーフベクトル<br />
float3 N = normalize(In.N);<br />
<br />
// return (In.Color+ pow(max(0,dot(N, H)), 10))*tex2D( Samp, In. Tex);//
拡散光+環境光<br />
return In.Color*1.5*tex2D( Samp, In. Tex)+ pow(max(0,dot(N, H)), 40); <br />
//+ pow(max(0,dot(N, H)), 10); // 鏡面反射光<br />
}</font></p>
<p><font size="2">//
-------------------------------------------------------------<br />
// テクニック<br />
// -------------------------------------------------------------<br />
technique TShader<br />
{<br />
pass P0<br />
{<br />
VertexShader = compile vs_2_0 VS();<br />
PixelShader = compile ps_2_0 PS();<br />
}<br />
}<br /></font></p>
</td>
</tr></tbody></table>