ページ 11

(とても長いです)基礎的な3Dプログラミングで、例外が発生する

Posted: 2013年7月23日(火) 15:53
by dic
基礎的な3Dプログラミングをしています。
そこで、本に書いているとおりソースコードを入れましたが、
今やっているところからは、サンプルがCDに付属されていなくて、コンパイルはできたのですが、
実行すると例外が発生して、なおかつ予測していた、立方体が描画されません。

本に付属していたサンプルでは、この章のひとつまえまでがあり、いまのところはなく、
どこに処理を入れればいいのかが、自分なりにいれました。
どこに入れればいいのか迷っているのは コメントの 8-2 ~ 8-6です。
そこで、この8-2 ~ 8-6を適切な場所に入れてくれると助かります。

上のとおり、2つ質問があります。
ひとつは例外が発生するので、どこがまずいのか。
ふたつめは、8-2 ~ 8-6 をどこの処理に入れればいいのかをアドバイスしてください。


以下、ソースコード全部となり、とてもながいです。

コード:

// [2013 07 16] DirectX 3D.cpp : アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#include "[2013 07 16] DirectX 3D.h"


/*----------------------------------------------------------
	DirectX9実践プログラミング
		DirectX Graphicsサンプル

	DXGSample01.cpp
		「基本的なウインドウ・アプリケーション」

	(C) 2003 NARITA, Takuro
		E-Mail	narita@a1.mbn.or.jp
--------------------------------------------------------------*/

#define WIN32_LEAN_AND_MEAN	// ヘッダーからあまり使われない関数を省く

#include <windows.h>
#include <tchar.h>
#include <d3dx9.h>
#include <dxerr9.h>

#include "resource.h"

#define RELEASE(x)	if(x){x->Release();x=NULL;}

/*-------------------------------------------
	グローバル変数(アプリケーション関連)
--------------------------------------------*/
HINSTANCE	g_hInstance		= NULL;	// インスタンス・ハンドル
HWND		g_hWindow		= NULL;	// ウインドウ・ハンドル
HMENU		g_hMenu			= NULL;	//	メニュー・ハンドル

TCHAR		g_szAppTitle[]	= _T("DirectX 9.0 Graphics Sample01");
TCHAR		g_szWndClass[]	= _T("DX9GS01");

RECT		g_rectWindow;

// 起動時の描画領域サイズ
bool		g_bWindow = true;	//	true:ウィンドウモード false:フルスクリーンモード

SIZE		g_sizeWindowMode	= { 640, 480 };		// ウインドウ・モード
SIZE		g_sizeFullMode		= { 1024, 768 };	//	フルスクリーン・モード
D3DFORMAT	g_formatFull		= D3DFMT_X8R8G8B8;	//	ディスプレイ(バック・バッファ)・フォーマット


// デバイス設定の希望値
D3DFORMAT	g_fmtDisplay[] = 						// 希望するディスプレイ・フォーマット
	{ D3DFMT_X8R8G8B8, D3DFMT_X1R5G5B5, D3DFMT_R5G6B5 };
D3DFORMAT	g_fmtRendTexter[] = 					// 希望するレンダリング・テクスチャのフォーマット
	{ D3DFMT_X8R8G8B8, D3DFMT_X1R5G5B5, D3DFMT_R5G6B5 };
D3DFORMAT	g_fmtDepthStencil = D3DFMT_D24S8;		// 希望する深度/ステンシルバッファのフォーマット(D3DFMT_UNKNOWNで未使用)
D3DMULTISAMPLE_TYPE g_MultiSampleType[] =
		{ D3DMULTISAMPLE_4_SAMPLES, D3DMULTISAMPLE_NONMASKABLE };
													// 希望するマルチ・サンプリングのタイプ
UINT		g_Interval    = D3DPRESENT_INTERVAL_IMMEDIATE;		// 希望するPresent処理の実行レート


// アプリケーションの動作フラグ
bool		g_bActive		= false;	// アクティブ状態

/*-------------------------------------------
	グローバル変数(DirectX関連)
--------------------------------------------*/

// インターフェイス
LPDIRECT3D9				g_pD3D			= NULL; // Direct3Dインターフェイス
LPDIRECT3DDEVICE9		g_pD3DDevice	= NULL; // Direct3DDeviceインターフェイス
D3DPRESENT_PARAMETERS	g_D3DPP;				// D3DDeviceの設定

D3DPRESENT_PARAMETERS	g_D3DPPWindow;			// D3DDeviceの設定(ウインドウ・モード用)
D3DPRESENT_PARAMETERS	g_D3DPPFull;			// D3DDeviceの設定(フルスクリーン・モード用)

D3DFORMAT				g_fmtRendTexterWindow;	// レンダリング・テクスチャのフォーマット(ウインドウ用)
D3DFORMAT				g_fmtRendTexterFull;	// レンダリング・テクスチャのフォーマット(フルスクリーン用)

bool g_bDeviceLost = false;						// デバイスの消失フラグ

// スプライト機能
LPD3DXSPRITE			g_pD3DXSprite = NULL;	// スプライト
LPDIRECT3DTEXTURE9		g_pD3DTexture = NULL;	// スプライトに使うテクスチャ
TCHAR g_szSpriteFile[] = _T("canvas.png");		// スプライトに使う画像ファイル

// フォント機能
LPD3DXFONT				g_pD3DXFont = NULL;		// D3DXFontインターフェイス

// マウス・カーソル機能
TCHAR g_szCursorFile[] = _T("Cursor.dds");		// カーソルに使う画像ファイル 

// 画面キャプチャ機能
TCHAR g_szFontBufferFile[] = _T("save.bmp");	// キャプチャ画面の画像ファイル


//	8.基本的な3Dグラフィックスのプログラミング
struct	XYZBuffer
{
	FLOAT	x,y,z;
};

struct	ColBuffer
{
	D3DCOLOR	color;
};

D3DVERTEXELEMENT9	decl[] =
{
	{ 0, 0, D3DDECLTYPE_FLOAT3,		D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
	{ 1, 0, D3DDECLTYPE_D3DCOLOR,	D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,	  0 },
	D3DDECL_END()
};

	LPDIRECT3DVERTEXDECLARATION9	g_pVertexDeclaration;
	LPDIRECT3DVERTEXBUFFER9	g_pD3DVBXYZBuffer;	//	XYZBuffer の頂点バッファ
	LPDIRECT3DVERTEXBUFFER9	g_pD3DVBColBuffer;	//	ColBuffer の頂点バッファ
	LPDIRECT3DINDEXBUFFER9	g_pD3DIBuffer;
	LPDIRECT3DVERTEXSHADER9	g_pVertexShader;	//	頂点シェーダを受け取る変数
	LPDIRECT3DPIXELSHADER9	g_pPixelShader;	//	ピクセルシェーダを受け取る変数

/*-------------------------------------------
	関数定義
--------------------------------------------*/

LRESULT CALLBACK MainWndProc(HWND hWnd,UINT msg,UINT wParam,LONG lParam);

/*-------------------------------------------
	アプリケーション初期化(最初に一度だけ呼ばれる)
--------------------------------------------*/
HRESULT InitApp(HINSTANCE hInst)
{
	// アプリケーションのインスタンス・ハンドルを保存
	g_hInstance = hInst;

	// IMEを禁止する
//	ImmDisableIME(-1);

	// ウインドウ・クラスの登録
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= MainWndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= g_hInstance;
	wcex.hIcon			= LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_MY20130716DIRECTX3D));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_MY20130716DIRECTX3D);
	wcex.lpszClassName	= g_szWndClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	if (!RegisterClassEx(&wcex))
		return DXTRACE_ERR("InitApp", GetLastError());

	// メイン・ウインドウ作成(ウインドウ・モード用)
	g_rectWindow.top	= 0;
	g_rectWindow.left	= 0;
	g_rectWindow.right	= g_sizeWindowMode.cx;
	g_rectWindow.bottom	= g_sizeWindowMode.cy;
	AdjustWindowRect( &g_rectWindow, WS_OVERLAPPEDWINDOW, TRUE);
	g_rectWindow.right = g_rectWindow.right - g_rectWindow.left;
	g_rectWindow.bottom = g_rectWindow.bottom - g_rectWindow.top;
	g_rectWindow.top = 0;
	g_rectWindow.left = 0;

	RECT	rect;
	if( g_bWindow )
	{
		//	(ウィンドウモード用)
		rect.top	= CW_USEDEFAULT;
		rect.left	= CW_USEDEFAULT;
		rect.right	= g_rectWindow.right;
		rect.bottom	= g_rectWindow.bottom;
	}
	else
	{
		//	(フクスクリーン・モード用)
		rect.top	= 0;
		rect.left	= 0;
		rect.right	= g_sizeFullMode.cx;
		rect.bottom	= g_sizeFullMode.cy;

		g_hMenu = LoadMenu( g_hInstance, MAKEINTRESOURCE(IDR_MENU1) );
	}
	g_hWindow = CreateWindow(g_szWndClass, g_szAppTitle,
			g_bWindow ? WS_OVERLAPPEDWINDOW : WS_POPUP,
			rect.left, rect.top, rect.right, rect.bottom,
			NULL, NULL, hInst, NULL);
	if (g_hWindow == NULL)
		return DXTRACE_ERR("InitApp", GetLastError());

	// ウインドウ表示
	ShowWindow(g_hWindow, SW_SHOWNORMAL);
	UpdateWindow(g_hWindow);

	return S_OK;
}


/*-------------------------------------------
	適切なDirect3DDeviceやフォーマットの選択
--------------------------------------------*/
HRESULT CheckDeviceCaps(D3DCAPS9 *Caps);							// デバイス能力のチェック
HRESULT SelectAdapterFormat(UINT Adapter, D3DDEVTYPE Device, D3DDISPLAYMODE dmode);			// ディスプレイとバック・バッファのフォーマットの調査
HRESULT SelectDepthStencilFormat(UINT Adapter, D3DDEVTYPE Device, D3DDISPLAYMODE dmode);	// 深度/ステンシル・バッファのフォーマットを調べる
HRESULT SelectRenderTexterFormat(UINT Adapter, D3DDEVTYPE Device, D3DDISPLAYMODE dmode);	// レンダリング・テクスチャのフォーマットを調べる
HRESULT SelectMultiSampleType(UINT Adapter, D3DDEVTYPE Device);		// フルシーン・アンチエイリアシングを調べる
HRESULT SelectDisplayMode(UINT Adapter);							// ディスプレイ・モードを調べる

HRESULT SelectD3DDevice(UINT &Adapter, D3DDEVTYPE &Device)
{
	// アダプタの選択
	Adapter = D3DADAPTER_DEFAULT;	// プライマリ・ディスプレイ・アダプタ

	// デバイス能力の取得
	D3DCAPS9 Caps; // 能力を受け取るD3DCAPS9構造体

	HRESULT hr;
	Device = D3DDEVTYPE_HAL;	// HALデバイスをチェック
	hr = g_pD3D->GetDeviceCaps(Adapter, Device, &Caps);
	if (FAILED(hr) || FAILED(CheckDeviceCaps(&Caps)))
	{
		DXTRACE_ERR("SelectD3DDevice CheckDeviceCaps HAL", E_FAIL);

		Device = D3DDEVTYPE_REF;	// REFデバイスをチェック
		hr = g_pD3D->GetDeviceCaps(Adapter, Device, &Caps);
		if (FAILED(hr) || FAILED(CheckDeviceCaps(&Caps)))
			return DXTRACE_ERR("SelectD3DDevice CheckDeviceCaps REF", E_FAIL);
	}

	// 現在のディスプレイのフォーマットなどを取得しておく
	D3DDISPLAYMODE dmode;
	hr = g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dmode);
	if (FAILED(hr))
		return DXTRACE_ERR("SelectD3DDevice GetAdapterDisplayMode", hr);

	// ディスプレイとバック・バッファのフォーマットの調査
	hr = SelectAdapterFormat(Adapter, Device, dmode);
	if (FAILED(hr))
		return DXTRACE_ERR("SelectD3DDevice SelectAdapterFormat", hr);

	// 深度/ステンシル・バッファのフォーマットの調査
	if (g_fmtDepthStencil != D3DFMT_UNKNOWN)
	{
		hr = SelectDepthStencilFormat(Adapter, Device, dmode);
		if (FAILED(hr))
			return DXTRACE_ERR("SelectD3DDevice SelectDepthStencilFormat", hr);
	}

	// レンダリング・テクスチャのフォーマットを調べる
	hr = SelectRenderTexterFormat(Adapter, Device, dmode);
	if (FAILED(hr))
		return DXTRACE_ERR("SelectD3DDevice SelectRenderTexterFormat", hr);

	// その他のフォーマットを調べる(なし)

	// フルシーン・アンチエイリアシングを調べる
	hr = SelectMultiSampleType(Adapter, Device);
	if (FAILED(hr))
		return DXTRACE_ERR("SelectD3DDevice SelectMultiSampleType", hr);

	// ディスプレイ・モードを調べる
	hr = SelectDisplayMode(Adapter);
	if (FAILED(hr))
		return DXTRACE_ERR("SelectD3DDevice SelectDisplayMode", hr);

	return S_OK;
}

// デバイス能力のチェック
HRESULT CheckDeviceCaps(D3DCAPS9 *Caps)
{
	if (Caps->MaxStreams < 3)				// 頂点ストリーム数
		return DXTRACE_ERR("CheckDeviceCaps MaxStreams < 3", E_FAIL);

	if (Caps->MaxPrimitiveCount < 0xFFFF)	// プリミティブ数
		return DXTRACE_ERR("CheckDeviceCaps MaxPrimitiveCount < 0xFFFF", E_FAIL);

	if (Caps->MaxVertexIndex < 0xFFFF)		// インデックス数
		return DXTRACE_ERR("CheckDeviceCaps MaxVertexIndex < 0xFFFF", E_FAIL);

//	if (Caps->VertexShaderVersion < D3DVS_VERSION(2, 0))	// 頂点シェーダ・バージョン
//		return DXTRACE_ERR("CheckDeviceCaps VertexShaderVersion < D3DVS_VERSION(2, 0)", E_FAIL);

//	if (Caps->PixelShaderVersion < D3DPS_VERSION(2, 0))	// ピクセル・シェーダ・バージョン
//		return DXTRACE_ERR("CheckDeviceCaps PixelShaderVersion < D3DPS_VERSION(2, 0)", E_FAIL);

	return S_OK;
}

// ディスプレイとバック・バッファのフォーマットの調査
HRESULT SelectAdapterFormat(UINT Adapter, D3DDEVTYPE Device, D3DDISPLAYMODE dmode)
{
	int	i;
	HRESULT hr = S_OK;

	// ウインドウ・モード
	ZeroMemory(&g_D3DPPWindow, sizeof(g_D3DPPWindow));
	g_D3DPPWindow.BackBufferCount			= 1;
	g_D3DPPWindow.SwapEffect				= D3DSWAPEFFECT_DISCARD;
	g_D3DPPWindow.hDeviceWindow				= g_hWindow;
	g_D3DPPWindow.Windowed					= TRUE;
	g_D3DPPWindow.PresentationInterval		= g_Interval;

	for (int i=0; i<sizeof(g_fmtDisplay)/sizeof(g_fmtDisplay[0]); i++)
	{
		hr = g_pD3D->CheckDeviceType(Adapter, Device, dmode.Format, g_fmtDisplay[i], TRUE);
		if (SUCCEEDED(hr))
		{
			g_D3DPPWindow.BackBufferFormat = g_fmtDisplay[i];
			break;
		}
	}
	if (FAILED(hr))
		return DXTRACE_ERR("SelectAdapterFormat CheckDeviceType Window", hr);

	// フルスクリーン・モード
	ZeroMemory(&g_D3DPPFull, sizeof(g_D3DPPFull));
	g_D3DPPFull.BackBufferCount				= 1;
	g_D3DPPFull.SwapEffect					= D3DSWAPEFFECT_DISCARD;
	g_D3DPPFull.hDeviceWindow				= g_hWindow;
	g_D3DPPFull.Windowed					= FALSE;
	g_D3DPPFull.PresentationInterval		= g_Interval;
	
	for (/*int */i=0; i<sizeof(g_fmtDisplay)/sizeof(g_fmtDisplay[0]); i++)
	{
		hr = g_pD3D->CheckDeviceType(Adapter, Device, g_fmtDisplay[i], g_fmtDisplay[i], FALSE);
		if (SUCCEEDED(hr))
		{
			g_D3DPPFull.BackBufferFormat = g_fmtDisplay[i];
			break;
		}
	}
	if (FAILED(hr))
		return DXTRACE_ERR("SelectAdapterFormat CheckDeviceType Full", hr);

	return S_OK;
}

// 深度/ステンシル・バッファのフォーマットを調べる
HRESULT SelectDepthStencilFormat(UINT Adapter, D3DDEVTYPE Device, D3DDISPLAYMODE dmode)
{
	HRESULT hr;

	// ウインドウ・モード
	hr = g_pD3D->CheckDeviceFormat(Adapter, Device,
				dmode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, g_fmtDepthStencil);
	if (FAILED(hr))
		return DXTRACE_ERR("SelectDepthStencilFormat CheckDeviceFormat DS Window", hr);

	hr = g_pD3D->CheckDepthStencilMatch(Adapter, Device,
				dmode.Format, g_D3DPPWindow.BackBufferFormat, g_fmtDepthStencil);
	if (FAILED(hr))
		return DXTRACE_ERR("SelectDepthStencilFormat CheckDepthStencilMatch DS Window", hr);

	g_D3DPPWindow.EnableAutoDepthStencil = TRUE;
	g_D3DPPWindow.AutoDepthStencilFormat = g_fmtDepthStencil;

	// フルスクリーン・モード
	hr = g_pD3D->CheckDeviceFormat(Adapter, Device,
				g_D3DPPFull.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, g_fmtDepthStencil);
	if (FAILED(hr))
		return DXTRACE_ERR("SelectDepthStencilFormat CheckDeviceFormat DS Full", hr);

	hr = g_pD3D->CheckDepthStencilMatch(Adapter, Device,
				g_D3DPPFull.BackBufferFormat, g_D3DPPFull.BackBufferFormat, g_fmtDepthStencil);
	if (FAILED(hr))
		return DXTRACE_ERR("SelectDepthStencilFormat CheckDepthStencilMatch DS Full", hr);

	g_D3DPPFull.EnableAutoDepthStencil = TRUE;
	g_D3DPPFull.AutoDepthStencilFormat = g_fmtDepthStencil;

	return S_OK;
}

// レンダリング・テクスチャのフォーマットを調べる
HRESULT SelectRenderTexterFormat(UINT Adapter, D3DDEVTYPE Device, D3DDISPLAYMODE dmode)
{
	HRESULT hr = S_OK;
	int	i;

	// ウインドウ・モード
	g_fmtRendTexterWindow = D3DFMT_UNKNOWN;
	for (int i=0; i<sizeof(g_fmtRendTexter)/sizeof(g_fmtRendTexter[0]); i++)
	{
		hr = g_pD3D->CheckDeviceFormat(Adapter, Device,
				dmode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, g_fmtRendTexter[i]);
		if (SUCCEEDED(hr))
		{
			hr = g_pD3D->CheckDepthStencilMatch(Adapter, Device,
						dmode.Format, g_fmtRendTexter[i], g_fmtDepthStencil);
			if (SUCCEEDED(hr))
			{
				g_fmtRendTexterWindow = g_fmtRendTexter[i];
				break;
			}
		}
	}
	if (FAILED(hr))
		return DXTRACE_ERR("SelectRenderTexterFormat Window", hr);

	// フルスクリーン・モード
	g_fmtRendTexterFull = D3DFMT_UNKNOWN;
	for (i=0; i<sizeof(g_fmtRendTexter)/sizeof(g_fmtRendTexter[0]); i++)
	{
		hr = g_pD3D->CheckDeviceFormat(Adapter, Device,
				g_D3DPPFull.BackBufferFormat,
				D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, g_fmtRendTexter[i]);
		if (SUCCEEDED(hr))
		{
			hr = g_pD3D->CheckDepthStencilMatch(Adapter, Device,
					g_D3DPPFull.BackBufferFormat, g_fmtRendTexter[i], g_fmtDepthStencil);
			if (SUCCEEDED(hr))
			{
				g_fmtRendTexterFull = g_fmtRendTexter[i];
				break;
			}
		}
	}
	if (FAILED(hr))
		return DXTRACE_ERR("SelectRenderTexterFormat Full", hr);

	return S_OK;
}

// フルシーン・アンチエイリアシングを調べる
HRESULT SelectMultiSampleType(UINT Adapter, D3DDEVTYPE Device)
{
	int	i;
	int mstCount = sizeof(g_MultiSampleType) / sizeof(g_MultiSampleType[0]);

	// ウインドウ・モード
	for (int i=0; i<mstCount; i++)
	{
		if (FAILED(g_pD3D->CheckDeviceMultiSampleType(Adapter, Device,
				g_D3DPPWindow.BackBufferFormat, TRUE, g_MultiSampleType[i], NULL)))
			continue;
		if (g_D3DPPWindow.EnableAutoDepthStencil == TRUE)
			if (FAILED(g_pD3D->CheckDeviceMultiSampleType(Adapter, Device,
					g_D3DPPWindow.AutoDepthStencilFormat, TRUE, g_MultiSampleType[i], NULL)))
				continue;
		g_D3DPPWindow.MultiSampleType	= g_MultiSampleType[i];
		g_D3DPPWindow.MultiSampleQuality = 0;
		break;
	}

	// フルスクリーン・モード
	for (/*int */i=0; i<mstCount; i++)
	{
		if (FAILED(g_pD3D->CheckDeviceMultiSampleType(Adapter, Device,
				g_D3DPPFull.BackBufferFormat, FALSE, g_MultiSampleType[i], NULL)))
			continue;
		if (g_D3DPPWindow.EnableAutoDepthStencil == TRUE)
			if (FAILED(g_pD3D->CheckDeviceMultiSampleType(Adapter, Device,
					g_D3DPPFull.AutoDepthStencilFormat, FALSE, g_MultiSampleType[i], NULL)))
				continue;
		g_D3DPPFull.MultiSampleType	= g_MultiSampleType[i];
		g_D3DPPFull.MultiSampleQuality = 0;
		break;
	}

	return S_OK;
}

// ディスプレイ・モードを調べる
HRESULT SelectDisplayMode(UINT Adapter)
{
	// ウインドウ・モード(調べる必要ない)

	// フルスクリーン・モード
	D3DDISPLAYMODE dmode = { 0, 0, 0, D3DFMT_UNKNOWN };
	int level = 1000000;
	int num = g_pD3D->GetAdapterModeCount(Adapter, g_D3DPPFull.BackBufferFormat);
	for (int i=0; i<num; i++)
	{
		// ディスプレイ・モードの列挙
		D3DDISPLAYMODE dm;
		g_pD3D->EnumAdapterModes(Adapter, g_D3DPPFull.BackBufferFormat, i, &dm);
		// 希望のモードとの誤差
		int l = abs(g_sizeFullMode.cx  - (LONG)dm.Width) + abs(g_sizeFullMode.cy  - (LONG)dm.Height);
		if (l < level)
		{
			// より適切なモードを選択
			dmode = dm;
			level = l;
		}
	}
	if (dmode.Format == D3DFMT_UNKNOWN)
		return DXTRACE_ERR("SelectDisplayMode EnumAdapterModes", E_FAIL);

	g_D3DPPFull.BackBufferWidth  = dmode.Width;
	g_D3DPPFull.BackBufferHeight = dmode.Height;

	return S_OK;
}

/*-------------------------------------------
	DirectX Graphics初期化
--------------------------------------------*/
HRESULT InitDXGraphics(void)
{
	// Direct3Dオブジェクトの作成
	g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	if (g_pD3D == NULL)
		return DXTRACE_ERR("InitDXGraphics Direct3DCreate9", E_FAIL);

	// デバイス設定の選択
	UINT Adapter;
	D3DDEVTYPE Device;
	HRESULT hr = SelectD3DDevice(Adapter, Device);
	if (FAILED(hr))
		return DXTRACE_ERR("InitDXGraphics SelectD3DDevice", hr);

	// D3DDeviceオブジェクトの作成
	if (g_bWindow)
		g_D3DPP = g_D3DPPWindow;
	else
		g_D3DPP = g_D3DPPFull;

	hr = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWindow,
						D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_D3DPP, &g_pD3DDevice);
	if (FAILED(hr))
	{
		hr = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, g_hWindow,
						D3DCREATE_SOFTWARE_VERTEXPROCESSING, &g_D3DPP, &g_pD3DDevice);
		if (FAILED(hr))
			return DXTRACE_ERR("InitDXGraphics CreateDevice", hr);
	}

	// ビューポートの設定
	D3DVIEWPORT9 vp;
	vp.X		= 0;
	vp.Y		= 0;
	vp.Width	= g_D3DPP.BackBufferWidth;
	vp.Height	= g_D3DPP.BackBufferHeight;
	vp.MinZ		= 0.0f;
	vp.MaxZ		= 1.0f;
	hr = g_pD3DDevice->SetViewport(&vp);
	if (FAILED(hr))
		return DXTRACE_ERR("InitDXGraphics SetViewport", hr);

	// スプライト機能の初期化
	hr = D3DXCreateTextureFromFile(g_pD3DDevice, g_szSpriteFile, &g_pD3DTexture);
	if (FAILED(hr))
		return DXTRACE_ERR("InitDXGraphics D3DXCreateTextureFromFile", hr);

	hr = D3DXCreateSprite(g_pD3DDevice, &g_pD3DXSprite);
	if (FAILED(hr))
		return DXTRACE_ERR("InitDXGraphics D3DXCreateSprite", hr);

	// フォントの準備
	LOGFONT logfont;
	logfont.lfHeight      = 16; // 高さ
	logfont.lfWidth       = 0;  // 平均文字幅
	logfont.lfEscapement  = 0;  // X角度
	logfont.lfOrientation = 0;  // Y角度
	logfont.lfWeight      = FW_NORMAL; // 太さ
	logfont.lfItalic      = FALSE;     // 斜体
	logfont.lfUnderline   = FALSE;     // 下線
	logfont.lfStrikeOut   = FALSE;     // 打ち消し線
	logfont.lfCharSet     = SHIFTJIS_CHARSET;      // キャラクタ・セット
	logfont.lfOutPrecision  = OUT_DEFAULT_PRECIS;         // 出力精度
	logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; // クリップ精度
	logfont.lfQuality        = DEFAULT_QUALITY;    // 品質
	logfont.lfPitchAndFamily = DEFAULT_PITCH || FF_DONTCARE; // ピッチ
	lstrcpy(logfont.lfFaceName, _T("")); // フォント名

//	hr = D3DXCreateFontIndirect( g_pD3DDevice, &logfont, &g_pD3DXFont);
//	if (FAILED(hr))
//		return DXTRACE_ERR("InitDXGraphics D3DXCreateFontIndirect", hr);

	//	8-2	頂点フォーマットの定義
	
	//	■頂点宣言オブジェクトを作る
	hr = g_pD3DDevice->CreateVertexDeclaration( decl, &g_pVertexDeclaration );
	if( FAILED(hr) )
		return false;

	//	8-3	頂点バッファとインデックスバッファの作成

	//	■頂点バッファの作成

	//	[XYZBuffer]を収める頂点バッファ1
	hr = g_pD3DDevice->CreateVertexBuffer(
		sizeof(XYZBuffer)*8,		//	バッファ・サイズ(立方体の頂点数)
		0,							//	使用法
		0,							//	非FVF頂点バッファ
		D3DPOOL_MANAGED,			//	Direct3Dでメモリを管理
		&g_pD3DVBXYZBuffer,			//	頂点バッファを受け取る変数
		NULL );
	if( FAILED(hr) )
		return false;

	//	[ColBuffer]を収める頂点バッファ2
	hr = g_pD3DDevice->CreateVertexBuffer(
		sizeof(ColBuffer)*8,		//	バッファ・サイズ
		0,							//	使用法
		0,							//	非FVF頂点バッファ
		D3DPOOL_MANAGED,			//	Direct3Dでメモリを管理
		&g_pD3DVBColBuffer,			//	頂点バッファを受け取る変数
		NULL );
	if( FAILED(hr) )
		return false;

	//	■頂点バッファへの書き込み

	//	XYZBufferを収める頂点バッファ1に書き込む
	XYZBuffer	*pXYZBuffer;
	hr = g_pD3DVBXYZBuffer->Lock(
		0, 0, //	全体をロックする
		(LPVOID*)&pXYZBuffer, 0 );
	if( FAILED(hr) )
		DXTRACE_ERR( "エラー", hr );

	//	立方体の頂点データを書き込み
	pXYZBuffer[0].x =  1.0f;	pXYZBuffer[0].y =   1.0f;	pXYZBuffer[0].z =  1.0f;
	pXYZBuffer[1].x =  1.0f;	pXYZBuffer[1].y =   1.0f;	pXYZBuffer[1].z = -1.0f;
	pXYZBuffer[2].x =  1.0f;	pXYZBuffer[2].y =  -1.0f;	pXYZBuffer[2].z =  1.0f;
	pXYZBuffer[3].x =  1.0f;	pXYZBuffer[3].y =  -1.0f;	pXYZBuffer[3].z = -1.0f;
	pXYZBuffer[4].x = -1.0f;	pXYZBuffer[4].y =   1.0f;	pXYZBuffer[4].z =  1.0f;
	pXYZBuffer[5].x = -1.0f;	pXYZBuffer[5].y =   1.0f;	pXYZBuffer[5].z = -1.0f;
	pXYZBuffer[6].x = -1.0f;	pXYZBuffer[6].y =  -1.0f;	pXYZBuffer[6].z =  1.0f;
	pXYZBuffer[7].x = -1.0f;	pXYZBuffer[7].y =  -1.0f;	pXYZBuffer[7].z = -1.0f;

	g_pD3DVBXYZBuffer->Unlock();	//	アンロック

	//	ColBufferを収める頂点バッファ2に書き込む
	ColBuffer	*pColBuffer;
	hr = g_pD3DVBColBuffer->Lock( 0, 0, (LPVOID*)&pColBuffer, 0 );
	if( FAILED(hr) )
		return false;

	//	頂点の色データを書き込む
	pColBuffer[0].color = D3DCOLOR_XRGB( 0xff, 0xff, 0xff );
	pColBuffer[1].color = D3DCOLOR_XRGB( 0xff, 0xff, 0x00 );
	pColBuffer[2].color = D3DCOLOR_XRGB( 0xff, 0x00, 0xff );
	pColBuffer[3].color = D3DCOLOR_XRGB( 0xff, 0x00, 0x00 );
	pColBuffer[4].color = D3DCOLOR_XRGB( 0x00, 0xff, 0xff );
	pColBuffer[5].color = D3DCOLOR_XRGB( 0x00, 0xff, 0x00 );
	pColBuffer[6].color = D3DCOLOR_XRGB( 0x00, 0x00, 0xff );
	pColBuffer[7].color = D3DCOLOR_XRGB( 0x00, 0x00, 0x00 );

	g_pD3DVBColBuffer->Unlock();

	//	■インデックス・バッファの作成

	hr = g_pD3DDevice->CreateIndexBuffer(
		36 * 2,			//	36頂点分の16ビット・インデックス・バッファ
		0,				//	使用法
		D3DFMT_INDEX16,	//	16ビット・インデックス・バッファ
		D3DPOOL_MANAGED,//	Direct3Dでメモリを管理する
		&g_pD3DIBuffer,	//	インデックス・バッファを受け取る変数
		NULL );
	if( FAILED(hr) )
		return false;

	//	■インデックス・バッファへの書き込み
	DWORD	*pIndex;
	hr = g_pD3DIBuffer->Lock( 0, 0, (LPVOID*)&pIndex, 0 );
	if( FAILED(hr) )
		return hr;

	//	インデックスの書き込み
	pIndex[0] = 0;	pIndex[1] = 3;	pIndex[2] = 1;
	pIndex[3] = 0;	pIndex[4] = 2;	pIndex[5] = 3;
	pIndex[6] = 0;	pIndex[7] = 5;	pIndex[8] = 4;
	pIndex[9] = 0;	pIndex[10] = 1;	pIndex[11] = 5;
	pIndex[12] = 4;	pIndex[13] = 2;	pIndex[14] = 0;
	pIndex[15] = 4;	pIndex[16] = 6;	pIndex[17] = 2;
	pIndex[18] = 5;	pIndex[19] = 6;	pIndex[20] = 4;
	pIndex[21] = 5;	pIndex[22] = 7;	pIndex[23] = 6;
	pIndex[24] = 3;	pIndex[25] = 6;	pIndex[26] = 7;
	pIndex[27] = 3;	pIndex[28] = 2;	pIndex[29] = 6;
	pIndex[30] = 1;	pIndex[31] = 7;	pIndex[32] = 5;
	pIndex[33] = 1;	pIndex[34] = 3;	pIndex[35] = 7;

	g_pD3DIBuffer->Unlock();

	//	8-4	プログラマブル・シェーダの作成

	//	頂点シェーダ・プログラムのアセンブル
	LPD3DXBUFFER	pCode;
	hr = D3DXAssembleShaderFromFile( _T("test.vs"), NULL, NULL, 0, &pCode, NULL );
	if( FAILED(hr) )
		return DXTRACE_ERR("8-4", hr);

	//	頂点シェーダを作る
	hr = g_pD3DDevice->CreateVertexShader( (DWORD*)pCode->GetBufferPointer(), &g_pVertexShader );
	RELEASE( pCode );
	if( FAILED(hr) )
		return false;
	//	■ピクセル・シェーダの作成

	//	ピクセルシェーダ・プログラムのアセンブル
	hr = D3DXAssembleShaderFromFile( _T("test.ps"), NULL, NULL, 0, &pCode, NULL );
	if( FAILED(hr) )
		return false;

	//	ピクセルシェーダを作る
	hr = g_pD3DDevice->CreatePixelShader( (DWORD*)pCode->GetBufferPointer(), &g_pPixelShader );
	RELEASE( pCode );
	if( FAILED(hr) )
		return false;

	//	8-5	レンダリング・ステートの設定

	//	■シェーディングモードの設定
	hr = g_pD3DDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT );
	if( FAILED(hr) )
		return false;

	//	■zバッファの設定
	hr = g_pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
	if( FAILED(hr) )
		return false;

	//	■背面のカリングの設定
	hr = g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
	if( FAILED(hr) )
		return false;

	//	■変換行列の設定
	D3DXMATRIX	matWorld;
	FLOAT	ry = 0.0f;

	D3DXMatrixRotationY( &matWorld, ry );

	//	ビュー変換行列
	D3DXMATRIX	matView;

	D3DXVECTOR3	vEye( 0.0f, 5.0f, -5.0f );
	D3DXVECTOR3	vAt( 0.0f, 0.0f, 0.0f );
	D3DXVECTOR3	vUp( 0.0f, 1.0f, 0.0f );
	D3DXMatrixLookAtLH( &matView, &vEye, &vAt, &vUp );

	//	透視変換行列
	D3DXMATRIX	matProj;

	D3DXMatrixPerspectiveFovLH( &matProj,
		3.1415926535 / 3.0f,	//	60度
		g_D3DPP.BackBufferWidth / g_D3DPP.BackBufferHeight,	//	画面のアスペクト比
		3.0f, 15.0f );

	D3DXMATRIX	mat;
	mat = matWorld * matView * matProj;
	D3DXMatrixTranspose( &mat, &mat );

	g_pD3DDevice->SetVertexShaderConstantF( 0, (float*)&mat, 4 );

	return S_OK;
}

/*-------------------------------------------
	D3Dに管理されないオブジェクトの初期化
--------------------------------------------*/
HRESULT InitD3DObject(void)
{
	HRESULT	hr;

	// レンダリング・ステートの設定
	// Zバッファの設定
	g_pD3DDevice->SetRenderState(D3DRS_ZENABLE,
		g_D3DPP.EnableAutoDepthStencil ? D3DZB_TRUE : D3DZB_FALSE);

	// マルチサンプリングの設定
	hr = g_pD3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE );
	if( FAILED(hr) )
		return DXTRACE_ERR( "error", hr );
//	hr = g_pD3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,
//		g_D3DPP.MultiSampleType != D3DMULTISAMPLE_NONE ? TRUE : FALSE);
//	if( FAILED(hr) )
//		return DXTRACE_ERR( "error", hr );

	// スプライトの処理
	g_pD3DXSprite->OnResetDevice();

	// フォントの処理
//	g_pD3DXFont->OnResetDevice();

	// マウス・カーソルの設定
	LPDIRECT3DSURFACE9 pCursorSurface = NULL;
	hr = g_pD3DDevice->CreateOffscreenPlainSurface(32, 32,
			D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pCursorSurface, NULL);
	if (FAILED(hr))
		return DXTRACE_ERR("InitD3DObject CreateOffscreenPlainSurface", hr);

	hr = D3DXLoadSurfaceFromFile(pCursorSurface, NULL, NULL,
			g_szCursorFile, NULL, D3DX_FILTER_NONE, 0, NULL);
	if (SUCCEEDED(hr))
		hr = g_pD3DDevice->SetCursorProperties(16, 10, pCursorSurface);
	RELEASE(pCursorSurface);
	if (FAILED(hr))
		return DXTRACE_ERR("InitD3DObject SetCursorProperties", hr);

	return S_OK;
}

/*--------------------------------------------
	画面の描画処理
--------------------------------------------*/
HRESULT Render(void)
{
	// シーンのクリア
	HRESULT	hr;
	hr = g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);

	// シーンの描画開始
//	if (SUCCEEDED(g_pD3DDevice->BeginScene()))
	hr = g_pD3DDevice->BeginScene();
	{
	//	8-6	3Dオブジェクトの描画

	//	頂点宣言オブジェクトの登録
	g_pD3DDevice->SetVertexDeclaration( g_pVertexDeclaration );

	//	頂点バッファとインデックスバッファの登録
	g_pD3DDevice->SetStreamSource( 0, g_pD3DVBXYZBuffer, 0, sizeof(XYZBuffer) );
	g_pD3DDevice->SetStreamSource( 1, g_pD3DVBColBuffer, 0, sizeof(ColBuffer) );

	hr = g_pD3DDevice->SetIndices( g_pD3DIBuffer );
	if( FAILED(hr) )
		return DXTRACE_ERR( "error", hr );

	//	プログラマブルシェーダの登録
	g_pD3DDevice->SetVertexShader( g_pVertexShader );
	g_pD3DDevice->SetPixelShader( g_pPixelShader );
		hr = g_pD3DDevice->DrawIndexedPrimitive(
			D3DPT_TRIANGLELIST,
			0,
			0,
			8,
			0,
			12 );
		if( FAILED(hr) )
			DXTRACE_ERR( "str", hr );

/*
		// シーンの描画(スプライトの描画)
		static int alpha=0;
		g_pD3DXSprite->Begin();
		g_pD3DXSprite->Draw(g_pD3DTexture, NULL, NULL, NULL, 0.0f, NULL,
				D3DCOLOR_ARGB(alpha>255?511-alpha:alpha,255,255,255));
		alpha++; alpha &= 0x1FF;
		g_pD3DXSprite->End();

		// フォントの描画
		g_pD3DXFont->Begin();

		// 文字列表示
		RECT rect1 = { 8, 32, 108, 50 }; //描画領域(8, 32)-(108, 50)
		g_pD3DXFont->DrawText(_T("文字列表示①"),
			-1,		// 文字数(NULL終端まで表示)
			&rect1,	// 描画領域
			DT_LEFT | DT_NOCLIP,       // 左揃え&クリップしない
			D3DCOLOR_XRGB(255, 255, 0)); // 文字色(R255,G255, B0)

		g_pD3DXFont->End();
*/
		// シーンの描画終了
		hr = g_pD3DDevice->EndScene();
		if( FAILED(hr) )
			DXTRACE_ERR( "error", hr );
	}

	// シーンの表示
	hr = g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
	if( FAILED(hr) )
		DXTRACE_ERR( "error", hr );

	return hr;
}

/*-------------------------------------------
	D3Dに管理されないオブジェクトの終了処理
--------------------------------------------*/
HRESULT CleanupD3DObject(void)
{
	// スプライトの処理
	if (g_pD3DXSprite)
		g_pD3DXSprite->OnLostDevice();

	// フォントの処理
	if (g_pD3DXFont)
		g_pD3DXFont->OnLostDevice();

	return S_OK;
}

/*-------------------------------------------
	ウインドウ・サイズの変更
--------------------------------------------*/
HRESULT ChangeWindowSize(void)
{
	// ウインドウのクライアント領域に合わせる
	CleanupD3DObject();

	HRESULT hr = g_pD3DDevice->Reset(&g_D3DPP);
	if (FAILED(hr))
	{
		if (hr == D3DERR_DEVICELOST)
			g_bDeviceLost = true;
		else
			DestroyWindow(g_hWindow);
		return DXTRACE_ERR("ChangeWindowSize Reset", hr);
	}
	hr = InitD3DObject();
	if (FAILED(hr))
	{
		DestroyWindow(g_hWindow);
		return DXTRACE_ERR("ChangeWindowSize InitD3DObject", hr);
	}

	// ビューポートの設定
	D3DVIEWPORT9 vp;
	vp.X		= 0;
	vp.Y		= 0;
	vp.Width	= g_D3DPP.BackBufferWidth;
	vp.Height	= g_D3DPP.BackBufferHeight;
	vp.MinZ		= 0.0f;
	vp.MaxZ		= 1.0f;
	hr = g_pD3DDevice->SetViewport(&vp);
	if (FAILED(hr))
	{
		DXTRACE_ERR("ChangeWindowSize SetViewport", hr);
		DestroyWindow(g_hWindow);
	}
	return hr;
}


/*-------------------------------------------
	画面モードの変更
--------------------------------------------*/
void ChangeDisplayMode(void)
{
	g_bWindow = !g_bWindow;

	CleanupD3DObject();

	if (g_bWindow)
	{
		g_D3DPP = g_D3DPPWindow;
	}
	else
	{
		g_D3DPP = g_D3DPPFull;
		GetWindowRect(g_hWindow, &g_rectWindow);
	}

	HRESULT hr = g_pD3DDevice->Reset(&g_D3DPP);
	if (FAILED(hr))
	{
		if (hr == D3DERR_DEVICELOST)
			g_bDeviceLost = true;
		else
			DestroyWindow(g_hWindow);
		DXTRACE_ERR("ChangeDisplayMode Reset", hr);
		return;
	}

	hr = InitD3DObject();
	if (FAILED(hr))
	{
		DXTRACE_ERR("ChangeDisplayMode InitD3DObject", hr);
		DestroyWindow(g_hWindow);
		return;
	}

	if (g_bWindow)
	{
		SetWindowLong(g_hWindow, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
		if(g_hMenu != NULL)
		{
			SetMenu(g_hWindow, g_hMenu);
			g_hMenu = NULL;
		}
		SetWindowPos(g_hWindow, HWND_NOTOPMOST,
				g_rectWindow.left, g_rectWindow.top,
				g_rectWindow.right - g_rectWindow.left,
				g_rectWindow.bottom - g_rectWindow.top,
				SWP_SHOWWINDOW);
	}
	else
	{
		SetWindowLong(g_hWindow, GWL_STYLE, WS_POPUP | WS_VISIBLE);
		if(g_hMenu == NULL)
		{
			g_hMenu = GetMenu(g_hWindow);
			SetMenu(g_hWindow, NULL);
		}
	}
}

/*-------------------------------------------
	DirectX Graphicsの終了処理(初期化に失敗したときも呼ばれる)
--------------------------------------------*/
bool CleanupDXGraphics(void)
{
	// 取得したオブジェクトの開放
	RELEASE(g_pD3DXFont);
	RELEASE(g_pD3DXSprite);
	RELEASE(g_pD3DTexture);
	RELEASE(g_pD3DDevice);
	RELEASE(g_pD3D);

	return true;
}

/*-------------------------------------------
	アプリケーションの終了処理(最後に呼ばれる)
--------------------------------------------*/
bool CleanupApp(void)
{
	//	メニュー・ハンドルの削除
	if( g_hMenu )
		DestroyMenu( g_hMenu );

	// ウインドウ・クラスの登録解除
	UnregisterClass(g_szWndClass, g_hInstance);
	return true;
}

/*-------------------------------------------
	ウィンドウ処理
--------------------------------------------*/
HRESULT SaveFrontBuffer(void);	// 画面キャプチャ

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam)
{
	HRESULT hr = S_OK;

	switch(msg)
	{
	case WM_ACTIVATE:
		g_bActive = (LOWORD(wParam) != 0);
		break;

	case WM_DESTROY:
		// D3Dに管理されないオブジェクトの終了処理
		CleanupD3DObject();
		// DirectX Graphicsの終了処理
		CleanupDXGraphics();
		// ウインドウを閉じる
		PostQuitMessage(0);
		g_hWindow = NULL;
		return 0;

	// ウインドウ・サイズの変更処理
	case WM_SIZE:
		if (g_D3DPP.Windowed != TRUE)
			break;
		if (!g_pD3DDevice || wParam == SIZE_MINIMIZED)
			break;
		g_D3DPP.BackBufferWidth  = LOWORD(lParam);
		g_D3DPP.BackBufferHeight = HIWORD(lParam);
		if(g_bDeviceLost)
			break;
		if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED)
			ChangeWindowSize();
		break;

	case WM_SETCURSOR:
		if (g_pD3DDevice)
		{
			if (LOWORD(lParam) == HTCLIENT)	// クライアント領域のみ
			{
				SetCursor(NULL);				// ウインドウの標準カーソルを消す
				g_pD3DDevice->ShowCursor(TRUE);	// DirectX Graphicsのカーソル機能を使う
				return TRUE;					// 設定を終えたことを通知
			}
		}
		break;

	case WM_MOUSEMOVE:
		if (g_pD3DDevice)
		{
			POINT ptCursor;
			GetCursorPos(&ptCursor);
			g_pD3DDevice->SetCursorPosition(ptCursor.x, ptCursor.y, 0L);
		}
		break;

	case WM_KEYDOWN:
		// キー入力の処理
		switch(wParam)
		{
		case VK_ESCAPE:	// [ESCAPE]キーでウインドウを閉じる
			PostMessage(hWnd, WM_CLOSE, 0, 0);
			break;
		case 'W':	// 画面モードの切り替え
			ChangeDisplayMode();
			break;
		case 'S':	// 画面キャプチャ
			SaveFrontBuffer();
			break;
		}
		break;

	case WM_COMMAND:
		// 選択されたメニューを実行
		switch (LOWORD(wParam))
		{
		case IDM_EXIT:
			DestroyWindow(hWnd);
			return 0;
		}
		break;
	}

	// デフォルト処理
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

// 画面キャプチャ
HRESULT SaveFrontBuffer(void)
{
	HRESULT hr;

	// 現在のディスプレイのフォーマットなどを取得
	D3DDISPLAYMODE dmode;
	hr = g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dmode);
	if (FAILED(hr))
		return DXTRACE_ERR("SaveFrontBuffer GetAdapterDisplayMode", hr);

	// キャプチャ用サーフェス作成
	LPDIRECT3DSURFACE9 pSurface; // サーフェス
	hr = g_pD3DDevice->CreateOffscreenPlainSurface(
			dmode.Width,
			dmode.Height,
			D3DFMT_A8R8G8B8,		// この場合、標準的な32ビット・フォーマット
			D3DPOOL_SCRATCH, &pSurface, NULL);
	if (FAILED(hr))
		return DXTRACE_ERR("SaveFrontBuffert CreateOffscreenPlainSurface", hr);

	// キャプチャ
	hr = g_pD3DDevice->GetFrontBufferData(0, pSurface);
	if (FAILED(hr))
	{
		RELEASE(pSurface);
		return DXTRACE_ERR("SaveFrontBuffert GetFrontBufferData", hr);
	}

	// サーフェスの保存
	RECT rect;
	if (g_D3DPP.Windowed)
	{
		POINT p = { 0, 0 };
		ClientToScreen(g_hWindow, &p);
		rect.left = p.x; rect.top = p.y;
		p.x = g_D3DPP.BackBufferWidth;
		p.y = g_D3DPP.BackBufferHeight;
		ClientToScreen(g_hWindow, &p);
		rect.right = p.x; rect.bottom = p.y;
	}
	hr = D3DXSaveSurfaceToFile(
			g_szFontBufferFile,	// 保存ファイル名
			D3DXIFF_BMP,		// BMP形式
			pSurface,			// 保存するサーフェス
			NULL,				// パレット
			g_D3DPP.Windowed ? &rect : NULL); // 保存領域
	RELEASE(pSurface);
	if (FAILED(hr))
		return DXTRACE_ERR("SaveFrontBuffert D3DXSaveSurfaceToFile", hr);

	return S_OK;

}


/*--------------------------------------------
	アイドル時の処理
--------------------------------------------*/
bool AppIdle(void)
{
	if (!g_pD3D || !g_pD3DDevice)
		return false;

	if (!g_bActive)
		return true;

	// 消失したデバイスの復元処理
	HRESULT hr;
	if (g_bDeviceLost)
	{
		Sleep(100);	// 0.1秒待つ

		// デバイス状態のチェック
		hr  = g_pD3DDevice->TestCooperativeLevel();
		if (FAILED(hr))
		{
			if (hr == D3DERR_DEVICELOST)
				return true;  // デバイスはまだ失われている

			if (hr != D3DERR_DEVICENOTRESET)
				return false; // 予期せぬエラー

			CleanupD3DObject(); // Direct3Dで管理していないリソースを開放
			hr = g_pD3DDevice->Reset(&g_D3DPP); // 復元を試みる
			if (FAILED(hr))
			{
				if (hr == D3DERR_DEVICELOST)
					return true; // デバイスはまだ失われている

				DXTRACE_ERR("AppIdle Reset", hr);
				return false; // デバイスの復元に失敗
			}
			hr = InitD3DObject();  // 開放したDirect3Dで管理していないリソースを再取得
			if (FAILED(hr))
			{
				DXTRACE_ERR("AppIdle InitD3DObject", hr);
				return false;
			}
		}
		// デバイスが復元した
		g_bDeviceLost = false;
	}

	// 画面の更新
	hr = Render();
	if (hr == D3DERR_DEVICELOST)
		g_bDeviceLost = true;	// デバイスの消失
	else if (FAILED(hr))
		return false;

	return true;
}

/*--------------------------------------------
	メイン
---------------------------------------------*/
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
	// アプリケーションに関する初期化
	HRESULT hr = InitApp(hInst);
	if (FAILED(hr))
	{
		DXTRACE_ERR("WinMain InitApp", hr);
		return 0;
	}

	// DirectX Graphicsの初期化
	hr = InitDXGraphics();
	if (FAILED(hr))
		DXTRACE_ERR("WinMain InitDXGraphics", hr);
	else
	{
		// D3Dに管理されないオブジェクトの初期化
		hr = InitD3DObject();
		if (FAILED(hr))
		{
			DXTRACE_ERR("WinMain InitD3DObject", hr);
			DestroyWindow(g_hWindow);
		}
	}

	// メッセージ・ループ
	MSG msg;
	do
	{
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			// アイドル処理
			if (!AppIdle())
				// エラーがある場合,アプリケーションを終了する
				DestroyWindow(g_hWindow);
		}
	} while (msg.message != WM_QUIT);

	// アプリケーションの終了処理
	CleanupApp();

	return msg.wParam;
}



Re: (とても長いです)基礎的な3Dプログラミングで、例外が発生する

Posted: 2013年7月23日(火) 16:34
by softya(ソフト屋)
このまま動くコードでしょうか?

#include "[2013 07 16] DirectX 3D.h"
これは?

 ↓

#include "resource.h"
は必須のようです。

Re: (とても長いです)基礎的な3Dプログラミングで、例外が発生する

Posted: 2013年7月27日(土) 10:39
by dic
>>softyaさん
いいえ、多少 #include やライブラリを追加設定する必要があります。

いろいろじっくり見ていたところ、バグの原因がわかりました。

651行目あたりの以下のソースコードの第一変数 36 * 2 を

コード:

hr = g_pD3DDevice->CreateIndexBuffer(
        36 * 2,         //  36頂点分の16ビット・インデックス・バッファ
        0,              //  使用法
        D3DFMT_INDEX16, //  16ビット・インデックス・バッファ
        D3DPOOL_MANAGED,//  Direct3Dでメモリを管理する
        &g_pD3DIBuffer, //  インデックス・バッファを受け取る変数
        NULL );

sizeof(DWOD)*36

に変更したところ、うまく動きました。
参考書が間違っていたようです。

Re: (とても長いです)基礎的な3Dプログラミングで、例外が発生する

Posted: 2013年7月27日(土) 15:46
by ISLe
DWORDを使うなら、D3DFMT_INDEX16をD3DFMT_INDEX32に変更する必要があるような?

662行目のDWORDが間違いで、WORDにするのが正しいのではないでしょうか。

どちらにせよ記述的にsizeofを使ったほうが良いですけど。