/*
[構成プロパティ]-[VC++ ディレクトリ]
[インクルード ディレクトリ]
C:\Program Files\Microsoft DirectX SDK (February 2010)\Include
[ライブラリ ディレクトリ]
C:\Program Files\Microsoft DirectX SDK (February 2010)\Lib\x86
Unicode文字セット
*/
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#include <d3d9.h>
#include <d3dx9.h>
#include <stdio.h>
#include "comptr.h"
#include <crtdbg.h>
using namespace IKD;
#define SAFE_RELEASE(x) { if (x) { x->Release(); x = NULL; } }
#define CLASS_NAME TEXT("Shader2")
#define WINDOW_NAME TEXT("Shader2")
// 頂点定義
struct CUSTOMVTX {
float x, y, z; // 頂点位置
DWORD color; // 頂点カラー
float u, v; // テクスチャ座標
};
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
// 関数プロトタイプ宣言
void Trace(LPCTSTR format, ...);
HWND CreateWnd(HINSTANCE hInstance);
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//==============================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
// アプリケーションの初期化
MSG msg;
msg.wParam = 0;
// ウィンドウの作成
HWND hWnd = CreateWnd(hInstance);
if (hWnd == NULL) {
return 0;
}
// Direct3Dの初期化
LPDIRECT3D9 pD3D;
LPDIRECT3DDEVICE9 pD3DDev;
HRESULT hr;
pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if (pD3D == NULL) return 0;
Com_ptr<IDirect3D9> spD3D(pD3D);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof d3dpp);
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; // 0
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; // 0
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // 1
d3dpp.Windowed = TRUE; // windowed / full-screen
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; // 75
d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL; // 2
d3dpp.FullScreen_RefreshRateInHz= D3DPRESENT_RATE_DEFAULT; // 0
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; // 0
hr = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pD3DDev);
if (FAILED(hr)) return 0;
Com_ptr<IDirect3DDevice9> cpDev(pD3DDev);
// Xファイルオブジェクト読み込み
Com_ptr<ID3DXBuffer> cpMatBuf;
Com_ptr<ID3DXMesh> cpMesh;
DWORD dwMatNum;
D3DXMATERIAL *pMatAry;
hr = D3DXLoadMeshFromX(TEXT("Cube2.x"), D3DXMESH_MANAGED, cpDev.GetPtr(), NULL,
cpMatBuf.ToCreator(), NULL, &dwMatNum, cpMesh.ToCreator());
pMatAry = (D3DXMATERIAL *)cpMatBuf->GetBufferPointer();
// エフェクトの読み込み
Com_ptr<ID3DXEffect> cpEffect;
hr = D3DXCreateEffectFromFile(cpDev.GetPtr(), TEXT("Effect00.fx"), NULL, NULL,
D3DXSHADER_DEBUG, NULL, cpEffect.ToCreator(), NULL);
// ビュー変換・射影変換
D3DXMATRIX View, Proj;
D3DXMatrixPerspectiveFovLH(&Proj, D3DXToRadian(45), 640.0f / 480.0f, 1.0f, 10000.0f);
// ウィンドウ表示
ShowWindow(hWnd, nCmdShow);
// メッセージループ
float f = 0.0f;
DWORD i;
do {
// Sleep(1);
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
f += 0.025f;
pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(10,150,190), 1.0f, 0);
pD3DDev->BeginScene();
// エフェクト内のワールドビュー射影変換行列を設定
D3DXMATRIX mat;
D3DXMatrixLookAtLH(&View, &D3DXVECTOR3(30*sin(f),20,-30*cos(f)),
&D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,1,0));
D3DXMatrixIdentity(&mat);
mat = mat * View * Proj;
cpEffect->SetMatrix("matWorldViewProj", &mat);
// 描画開始
cpEffect->SetTechnique("BasicTec");
UINT numPass;
cpEffect->Begin(&numPass, 0);
cpEffect->BeginPass(0);
for (i = 0; i < dwMatNum; i++) {
cpDev->SetMaterial(&(pMatAry[i].MatD3D));
cpMesh->DrawSubset(i);
}
cpEffect->EndPass();
cpEffect->End();
pD3DDev->EndScene();
pD3DDev->Present(NULL, NULL, NULL, NULL);
}
} while (msg.message != WM_QUIT);
return msg.wParam;
}
//------------------------------------------------------------------------------
void Trace(LPCTSTR format, ...)
{
va_list arg_ptr;
TCHAR buffer[256];
int size;
va_start(arg_ptr, format);
size = _vsnwprintf_s(buffer, _TRUNCATE, format, arg_ptr);
va_end(arg_ptr);
OutputDebugString(buffer);
if (size < 0) {
OutputDebugString(L"...\n");
}
}
//------------------------------------------------------------------------------
HWND CreateWnd(HINSTANCE hInstance)
{
// ウィンドウクラスの登録
WNDCLASSEX wcx;
ZeroMemory(&wcx, sizeof wcx);
wcx.cbSize = sizeof wcx;
wcx.style = CS_HREDRAW | CS_VREDRAW;
wcx.lpfnWndProc = MainWndProc;
wcx.hInstance = hInstance;
wcx.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
// wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcx.lpszClassName = CLASS_NAME;
if (RegisterClassEx(&wcx) == 0) {
return NULL;
}
// ウィンドウの作成
DWORD dwStyle = WS_OVERLAPPEDWINDOW & ~(WS_MAXIMIZEBOX | WS_SIZEBOX);
RECT rc = {0, 0, 800, 600};
AdjustWindowRect(&rc, dwStyle, FALSE);
HWND hWnd = CreateWindow(
CLASS_NAME, WINDOW_NAME,
dwStyle,
CW_USEDEFAULT, 0,
rc.right - rc.left, rc.bottom - rc.top,
NULL, NULL, hInstance, NULL);
return hWnd;
}
//------------------------------------------------------------------------------
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}