#include <d3dx9.h>
#include <string>
#define WINDOW_WIDTH 640 //ウインドウの幅
#define WINDOW_HEIGHT 480 //ウインドウの高さ
#define SAFE_RELEASE(x) if(x){x->Release();}
using namespace std;
LPDIRECT3D9 g_pD3D = NULL;//Direct3D9
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;//レンダリングデバイス
LPD3DXEFFECT m_pEffect; // ★シェーダ
D3DXHANDLE m_hTechnique;// ★テクニック
D3DXHANDLE m_hmWVP; // ★ワールド~射影行列
D3DXHANDLE m_hvLightDir;
D3DXHANDLE m_hvColor;
D3DXHANDLE m_hvEyePos;
LPDIRECT3DVERTEXDECLARATION9 m_pDecl; // 頂点宣言
class MODEL{
public:
LPD3DXMESH Mesh;//メッシュ
D3DMATERIAL9* Material;//マテリアル
LPDIRECT3DTEXTURE9* Texture;//テクスチャ
DWORD PartsNumber;//マテリアル数
void LoadXFile(string);
void XFileDraw(float,float,float,float,float,float,float,float,float);
};
//Xファイル描画
void MODEL::XFileDraw(float XSize,float YSize,float ZSize,float XRot,float
YRot,float ZRot,float XTran,float YTran,float ZTran)
{
D3DXMATRIXA16
m,matWorld,matView,matScale,matRotation,matProj,matPosition[4],matPos;
D3DXMatrixIdentity(&matWorld);
D3DXMatrixScaling(&matScale,XSize,YSize,ZSize);
D3DXMatrixMultiply(&matWorld,&matWorld,&matScale);
//ワールドトランスフォーム(絶対座標変換)
D3DXMatrixIdentity(&matRotation);
D3DXMatrixRotationY( &matRotation, YRot );
D3DXMatrixMultiply(&matWorld,&matWorld,&matRotation);
D3DXMatrixRotationX( &matRotation, XRot );
D3DXMatrixMultiply(&matWorld,&matWorld,&matRotation);
D3DXMatrixRotationZ( &matRotation, ZRot );
D3DXMatrixMultiply(&matWorld,&matWorld,&matRotation);
D3DXMatrixTranslation(&matPos,XTran,YTran,ZTran);
D3DXMatrixMultiply(&matWorld,&matWorld,&matPos);
// ビュートランスフォーム(視点座標変換)
D3DXVECTOR3 vecEyePt( 0.0f, 7.0f,-3.5f ); //カメラ(視点)位置
D3DXVECTOR3 vecLookatPt( 0.0f, 0.0f, 0.0f );//注視位置
D3DXVECTOR3 vecUpVec( 0.0f, 1.0f, 0.0f );//上方位置
D3DXMatrixLookAtLH( &matView, &vecEyePt, &vecLookatPt,
&vecUpVec );
// プロジェクショントランスフォーム(射影変換)
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 1000.0f
);
m = (matWorld * matView * matProj);
m_pEffect->SetMatrix( m_hmWVP, &m );
D3DXVECTOR4 v;
//light
D3DXVECTOR4 light_pos = D3DXVECTOR4(-0.577f,-0.577f,-0.577f,0);
D3DXMatrixInverse(&m,NULL,&matWorld);
D3DXVec4Transform(&v,&light_pos,&m);
D3DXVec3Normalize((D3DXVECTOR3 *)&v,(D3DXVECTOR3 *)&v);// 正規化
v.w = -0.3f;// 環境光の強さ
m_pEffect->SetVector(m_hvLightDir,&v);
// 視点
m = matWorld * matView;
D3DXMatrixInverse( &m, NULL, &m);
v = D3DXVECTOR4( 0, 0, 0, 1);
D3DXVec4Transform( &v, &v, &m );
m_pEffect->SetVector( m_hvEyePos, &v );
//-------------------------------------------------
// ★シェーダの設定
//-------------------------------------------------
m_pEffect->SetTechnique( m_hTechnique );
m_pEffect->Begin( NULL, 0 );
m_pEffect->BeginPass( 0 );
g_pd3dDevice->SetFVF( D3DFVF_XYZ |
D3DFVF_NORMAL);
m_pEffect->SetTexture("Tex", Texture[0]);
//-------------------------------------------------
// 描画
//-------------------------------------------------
g_pd3dDevice->SetVertexDeclaration( m_pDecl );
D3DMATERIAL9 *pMtrl = &Material[0];
for( DWORD i=0; i<PartsNumber; i++ )
{
v.x=pMtrl->Diffuse.r/1.3f;
v.y=pMtrl->Diffuse.g/1.3f;
v.z=pMtrl->Diffuse.b/1.3f;
m_pEffect->SetVector( m_hvColor, &v );
g_pd3dDevice->SetTexture( 0,Texture[i] );
Mesh->DrawSubset( i );
pMtrl++;
}
m_pEffect->EndPass();
m_pEffect->End();
}
//Xファイル読み込み
void MODEL::LoadXFile(string FileName)
{
// Xファイルからメッシュをロードする
LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
D3DXLoadMeshFromXA( FileName.c_str(),
D3DXMESH_SYSTEMMEM,g_pd3dDevice, NULL, &pD3DXMtrlBuffer,
NULL,&PartsNumber, &Mesh);
D3DXMATERIAL* d3dxMaterials =
(D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
Material = new D3DMATERIAL9[PartsNumber];
Texture = new LPDIRECT3DTEXTURE9[PartsNumber];
for( DWORD i=0; i<PartsNumber; i++ )
{
Material[i] = d3dxMaterials[i].MatD3D;
Material[i].Ambient = Material[i].Diffuse;
Texture[i] = NULL;
if( d3dxMaterials[i].pTextureFilename != NULL
&&lstrlenA(d3dxMaterials[i].pTextureFilename) > 0)
{
D3DXCreateTextureFromFileA(g_pd3dDevice,d3dxMaterials[i].pTextureFilename,&Texture[i]);
}
}
pD3DXMtrlBuffer->Release();
}
MODEL Model[2];//モデル用
HWND hwnd;
HRESULT Init()
{
HRESULT hr;
// ★シェーダの読み込み
LPD3DXBUFFER pErr=NULL;
if( FAILED( hr = D3DXCreateEffectFromFileA(
g_pd3dDevice, "hlsl.fx", NULL, NULL,
0 , NULL, &m_pEffect, &pErr ))){
// シェーダの読み込みの失敗
MessageBoxA( NULL, (LPCSTR)pErr->GetBufferPointer()
, "ERROR", MB_OK);
}else{
m_hTechnique = m_pEffect->GetTechniqueByName( "TShader" );
m_hmWVP = m_pEffect->GetParameterByName( NULL, "mWVP" );
//m_hmWIT = m_pEffect->GetParameterByName( NULL, "mWIT" );
m_hvLightDir = m_pEffect->GetParameterByName( NULL, "vLightDir" );
m_hvColor = m_pEffect->GetParameterByName( NULL, "vColor" );
m_hvEyePos = m_pEffect->GetParameterByName( NULL, "vEyePos" );
}
SAFE_RELEASE(pErr);
return true;
}
void FrameUpDate()
{
}
void ScreenDraw()
{
// 画面をクリアする
g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
0x000000ff, 1.0f, 0L );
//シーンの開始
if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
Model[0].XFileDraw(1.0f,1.0f,1.0f,0.5f,timeGetTime()/10000.0f,0.0f,0.0f,0.0f,0.0f);
Model[1].XFileDraw(1.0f,1.0f,1.0f,0.5f,timeGetTime()/300.0f,0.0f,0.0f,0.0f,3.0f);
//シーンの終了
g_pd3dDevice->EndScene();
}
//バックバッファを表画面に反映させる
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
void GetFPS()
{
FrameUpDate();
ScreenDraw();
Sleep(16);
}
DWORD WINAPI MainLoop(LPVOID vdParam)
{
while(TRUE){
GetFPS();
}
return 0;
}
HRESULT InitD3D( HWND hWnd )
{
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION))){return E_FAIL;}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.hDeviceWindow = hWnd;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE ;
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp,
&g_pd3dDevice))){
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice))){
return(E_FAIL);
}
}
// Xファイルからメッシュをロードする
Model[0].LoadXFile("land.x");
Model[1].LoadXFile("ufo.x");
Init();
return S_OK;
}
LRESULT CALLBACK MsgProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd , msg , wp , lp);
}
int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE
hPrevInstance ,PSTR lpCmdLine , int nCmdShow )
{
MSG msg;
DWORD dwID;
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc,
0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
L"Window1", NULL };
RegisterClassEx( &wc );
RECT rect;
SetRect(&rect,0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
SetRect(&rect,0,0,rect.right-rect.left,rect.bottom-rect.top);
hwnd = CreateWindow( L"Window1", L"HLSL",
WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, rect.right, rect.bottom,
NULL, NULL, wc.hInstance, NULL );
if (hwnd == NULL) return 0;
timeBeginPeriod(1);
if(SUCCEEDED(InitD3D(hwnd))){
ShowWindow(hwnd,SW_SHOWDEFAULT);
UpdateWindow(hwnd);
CreateThread(NULL , 0 , MainLoop , (LPVOID)hwnd , 0 ,
&dwID);
while (GetMessage(&msg , NULL , 0 , 0 )) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
UnregisterClass(L"Window1",wc.hInstance);
timeEndPeriod(1);
SAFE_RELEASE( m_pEffect ); // シェーダ
SAFE_RELEASE( m_pDecl ); // 頂点宣言
SAFE_RELEASE(g_pd3dDevice);
SAFE_RELEASE(g_pD3D);
return 0;
}
|