開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 プロジェクト
プロジェクト名 Shader1
アプリケーションの種類 Windows アプリケーション
追加のオプション 空のプロジェクト
文字セット Unicode

Microsoft DirectX SDK (February 2010)

参考

Shader1.cpp
/*
[構成プロパティ]-[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>
 
#define SAFE_RELEASE(x) { if (x) { x->Release(); x = NULL; } }
 
#define CLASS_NAME TEXT("Shader1")
#define WINDOW_NAME TEXT("Shader1")
 
// 頂点定義
struct CUSTOMVTX {
	float x, y, z;	// 頂点位置
	DWORD color;	// 頂点カラー
};
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)
 
// 関数プロトタイプ宣言
void Trace(LPCTSTR format, ...);
HWND CreateWnd(HINSTANCE hInstance);
HRESULT InitDirect3D(HWND hWnd);
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
// 外部変数構造体
static struct {
	LPDIRECT3D9 pD3D;
	LPDIRECT3DDEVICE9 pD3DDev;
	IDirect3DVertexBuffer9 *pVertex;
	IDirect3DVertexDeclaration9 *pDec;
	IDirect3DVertexShader9 *pShaderHandler;
} g;
 
//==============================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
	MSG msg;
	msg.wParam = 0;
 
	// ウィンドウの作成
	HWND hWnd = CreateWnd(hInstance);
	if (hWnd == NULL) {
		return 0;
	}
 
	// Direct3Dの初期化
	HRESULT hr = InitDirect3D(hWnd);
	if (FAILED(hr)) {
		goto Exit;
	}
 
	ShowWindow(hWnd, nCmdShow);
 
	// メッセージループ
	float c = 0.0f;
	float addcolor[4];	// 頂点カラー(RGB)に足す値
	do {
		Sleep(1);
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
			DispatchMessage(&msg);
		} else {
			// Direct3Dの処理
			g.pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0);
			g.pD3DDev->BeginScene();
			// 描画
			c += 0.005f;	// 足す値
			addcolor[0] = addcolor[1] = addcolor[2] = c;
			g.pD3DDev->SetVertexShaderConstantF(4, addcolor, 1);
			g.pD3DDev->SetStreamSource(0, g.pVertex, 0, sizeof (CUSTOMVTX));
			g.pD3DDev->SetVertexDeclaration(g.pDec);
			g.pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
 
			g.pD3DDev->EndScene();
			g.pD3DDev->Present(NULL, NULL, NULL, NULL);
		}
	} while (msg.message != WM_QUIT);
Exit:
	SAFE_RELEASE(g.pShaderHandler);
	SAFE_RELEASE(g.pDec);
	SAFE_RELEASE(g.pVertex);
	SAFE_RELEASE(g.pD3DDev);
	SAFE_RELEASE(g.pD3D);
	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;
	}
 
	// ウィンドウの作成
	HWND hWnd = CreateWindow(
		CLASS_NAME, WINDOW_NAME,
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0,
		CW_USEDEFAULT, 0,
		NULL, NULL, hInstance, NULL);
	return hWnd;
}
 
//------------------------------------------------------------------------------
HRESULT InitDirect3D(HWND hWnd)
{
	// Direct3Dの初期化
	g.pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	HRESULT hr = (g.pD3D) ? S_OK : E_FAIL;
 
	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.AutoDepthStencilFormat	= D3DFMT_UNKNOWN;		// 0
	if (SUCCEEDED(hr)) {
		hr = g.pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
			D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g.pD3DDev);
	}
 
	// 頂点の設定(小さな長方形)
	static const CUSTOMVTX v[] = {
		{-1.0f, -1.0f, 0.0f, 0xff0000ff},
		{+1.0f, -1.0f, 0.0f, 0xffff0000},
		{+1.0f, +1.0f, 0.0f, 0xff00ff00},
		{-1.0f, +1.0f, 0.0f, 0xffffffff},
	};
 
	// 頂点バッファ作成と頂点情報の書き込み
	if (SUCCEEDED(hr)) {
		hr = g.pD3DDev->CreateVertexBuffer(sizeof v, D3DUSAGE_WRITEONLY, CUSTOMFVF,
			D3DPOOL_MANAGED, &g.pVertex, NULL);
	}
	VOID *pData;
	if (SUCCEEDED(hr)) {
		hr = g.pVertex->Lock(0, sizeof v, &pData, 0);
	}
	if (SUCCEEDED(hr)) {
		memcpy_s(pData, sizeof v, v, sizeof v);
		hr = g.pVertex->Unlock();
	}
 
	// 頂点データ宣言(シェーダに伝える)
	static const D3DVERTEXELEMENT9 VtxElem[] = {
		{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
		{0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
		D3DDECL_END()
	};
	if (SUCCEEDED(hr)) {
		hr = g.pD3DDev->CreateVertexDeclaration(VtxElem, &g.pDec);
	}
 
	// シェーダバージョンの確認
	if (SUCCEEDED(hr)) {
		D3DCAPS9 caps;
		hr = g.pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
		Trace(L"VertexShaderVersion=%#x\n", caps.VertexShaderVersion);
		Trace(L"PixelShaderVersion=%#x\n", caps.PixelShaderVersion);
	}
 
	// シェーダ命令配列定義
	static const char VShader[] =
		"vs_1_1\n"
		"dcl_position	v0\n"
		"dcl_color	v1\n"
		"m4x4		oPos, v0, c0\n"	// 頂点に変換行列を掛け算
		"add		oD0, v1, c4\n";	// 頂点カラーに定数を足し算して出力
 
	// シェーダ命令のコンパイル
	ID3DXBuffer *pShader = NULL;
	ID3DXBuffer *pError = NULL;
	if (SUCCEEDED(hr)) {
		hr = D3DXAssembleShader(VShader, sizeof VShader - 1,
			NULL, NULL, 0, &pShader, &pError);
	}
 
	// シェーダハンドラの生成
	if (SUCCEEDED(hr)) {
		hr = g.pD3DDev->CreateVertexShader(
			(DWORD *)(pShader->GetBufferPointer()), &g.pShaderHandler);
	}
	SAFE_RELEASE(pError);
	SAFE_RELEASE(pShader);
 
	// 変換行列の設定
	D3DXMATRIX mat, matView, matProj;
	D3DXMatrixLookAtLH(&matView,
		&D3DXVECTOR3(0,0,5), &D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,1,0));
	D3DXMatrixPerspectiveFovLH(&matProj, 0.785398163f, 480.0f / 640.0f, 0.1f, 10000.0f);
	D3DXMatrixMultiply(&mat, &matView, &matProj);
 
	// 変換行列を転置して定数レジスタc0~c3に登録する
	D3DXMatrixTranspose(&mat, &mat);
	if (SUCCEEDED(hr)) {
		hr = g.pD3DDev->SetVertexShaderConstantF(0, (float *)&mat, 4);
	}
 
	// 頂点シェーダに切り替え
	if (SUCCEEDED(hr)) {
		hr = g.pD3DDev->SetVertexShader(g.pShaderHandler);
	}
	return hr;
}
 
//------------------------------------------------------------------------------
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);
}
 
最終更新:2012年10月23日 22:11