#pragma comment(lib, "d3d9")
#pragma comment(lib, "d3dx9")
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#define SAFE_RELEASE(p) if(p){p->Release();p=NULL;}
struct CUSTOM_VTX {
float x, y, z;
DWORD color;
};
#define CUSTOM_FVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)
// 外部変数
LPDIRECT3D9 pD3D;
LPDIRECT3DDEVICE9 pD3DDev;
LPD3DXEFFECT pEffect;
IDirect3DVertexBuffer9* pVertex;
IDirect3DVertexDeclaration9* pDecl;
float t = 0;
// 関数プロトタイプ宣言
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
HWND InitWindow(HINSTANCE hInstance, int nCmdShow);
HRESULT InitD3D(HWND hWnd);
void Cleanup();
void Render();
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int nCmdShow)
{
HWND hWnd = InitWindow(hInstance, nCmdShow);
if (!hWnd) return -1;
HRESULT hr = InitD3D(hWnd);
if (FAILED(hr)) {
Cleanup();
return -1;
}
ShowWindow(hWnd, nCmdShow);
MSG msg = { 0 };
while (msg.message != WM_QUIT) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
Render();
}
}
Cleanup();
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
HWND InitWindow(HINSTANCE hInstance, int nCmdShow)
{
WNDCLASSEX wc = { sizeof WNDCLASSEX };
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hbrBackground = HBRUSH(COLOR_WINDOW + 1);
wc.lpszClassName = L"dx9sample2";
if (!RegisterClassEx(&wc)) return NULL;
DWORD deStyle = WS_OVERLAPPEDWINDOW ^ WS_MAXIMIZEBOX ^ WS_THICKFRAME;
RECT rc = { 0, 0, 400, 400 };
AdjustWindowRect(&rc, deStyle, FALSE);
HWND hWnd = CreateWindow(
wc.lpszClassName, L"dx9sample2", deStyle,
CW_USEDEFAULT, 0, rc.right - rc.left, rc.bottom - rc.top,
NULL, NULL, hInstance, NULL);
return hWnd;
}
HRESULT InitD3D(HWND hWnd)
{
HRESULT hr;
pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if (!pD3D) return E_FAIL;
D3DPRESENT_PARAMETERS d3dpp = { 0 };
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
hr = pD3D->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp,
&pD3DDev);
if (FAILED(hr)) return hr;
// ファイルからシェーダを作成
LPD3DXBUFFER pError;
hr = D3DXCreateEffectFromFile(
pD3DDev,
L"effect.fx",
NULL, NULL, D3DXSHADER_DEBUG, 0,
&pEffect, &pError);
if (FAILED(hr)) {
if (pError) {
OutputDebugStringA((LPCSTR)pError->GetBufferPointer());
}
SAFE_RELEASE(pError);
return hr;
}
SAFE_RELEASE(pError);
// x, y, z, ARGB
CUSTOM_VTX vtx[] = {
{ 0, 0, 1, 0xff0000ff },
{ 0, 1, 0, 0xff00ff00 },
{ 1, 0, 0, 0xffff0000 },
};
// 頂点バッファの作成
hr = pD3DDev->CreateVertexBuffer(
sizeof vtx,
D3DUSAGE_WRITEONLY,
CUSTOM_FVF,
D3DPOOL_MANAGED,
&pVertex,
NULL);
void* pData;
hr = pVertex->Lock(0, 0, &pData, 0);
memcpy(pData, vtx, sizeof vtx);
hr = pVertex->Unlock();
// 頂点宣言の作成
D3DVERTEXELEMENT9 ve[] = {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
D3DDECL_END()
};
hr = pD3DDev->CreateVertexDeclaration(ve, &pDecl);
return S_OK;
}
void Cleanup()
{
SAFE_RELEASE(pDecl);
SAFE_RELEASE(pVertex);
SAFE_RELEASE(pEffect);
SAFE_RELEASE(pD3DDev);
SAFE_RELEASE(pD3D);
}
void Render()
{
pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1, 0);
pD3DDev->BeginScene();
D3DXMATRIX mat;
D3DXMatrixRotationZ(&mat, t);
pEffect->SetMatrix("mat", &mat);
t += 0.01f;
pEffect->SetTechnique("T0");
UINT pass;
pEffect->Begin(&pass, 0);
pEffect->BeginPass(0);
pD3DDev->SetStreamSource(0, pVertex, 0, sizeof CUSTOM_VTX);
pD3DDev->SetVertexDeclaration(pDecl);
pD3DDev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
pEffect->EndPass();
pD3DDev->EndScene();
pD3DDev->Present(NULL, NULL, NULL, NULL);
}