とりあえずポリゴン表示

#include <windows.h>
#include <d3d9.h>
 
#pragma comment(lib, "d3d9.lib")
 
//定数いろいろ
const LPCTSTR WIN_CLASS_NAME = TEXT("RDD");
const LPCTSTR WINDOW_NAME = TEXT("RozenMaidenDuoDectet!!");
const LPCTSTR TEXT_OUTPUT = TEXT("Under Constructions...");
 
//関数のプロトタイプ宣言
HWND createWindow(HINSTANCE hInstance, LPCTSTR className);
int resisterWindowClass(HINSTANCE hInstance,  LPCTSTR className);
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);
HRESULT initD3D(HWND hWnd);
 
//グローバル変数
IDirect3D9* pDirect3D;			//Direct3Dインターフェース。デバイスの作成、情報の取得などを担当
IDirect3DDevice9* pD3Device;	//Direct3Dデバイスインターフェース。
D3DPRESENT_PARAMETERS d3dpp;	//DirectXをどのように初期化するかのパラメータを格納するとこ
 
IDirect3DVertexBuffer9* pVertex; //頂点バッファ、VRAM上に作られる
 
//FVF設定で使う構造体の定義。これは決まってるので順番変えたりしちゃダメ
typedef struct tag_D3DVERTEX{
	float x, y, z;			//頂点座標
	float rhw;				//除算数、スケール変換の値。
	DWORD dwColor;			//頂点の色
	float u, v;				//テクスチャ座標
} D3DVERTEX;
 
//FVF設定で使うフラグの定義、D3DFVFを参照
#define FVF_CUSTOM (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)
 
//定数で三角形の頂点を定義しておく
//三角形の頂点の定義順は反時計回り。裏は描画しない
//スクリーン座標から見ると時計回り
const D3DVERTEX v[] = {
	{600, 200, 0.0f, 1.0f, 0xFFFF0000, 0.0f, 0.0f},//右上赤色
	{500, 400, 0.0f, 1.0f, 0xFF00FF00, 0.0f, 1.0f},//右下緑
	{100, 100, 0.0f, 1.0f, 0xFFFF00FF, 1.0f, 0.0f},//左上紫
	{200, 400, 0.0f, 1.0f, 0xFF0000FF, 1.0f, 0.0f} //左下青
};
 
////////////////////////////////////////////////////////////////////////////
// ウィンドウプロシージャ
////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){
	HDC hdc;
	PAINTSTRUCT ps;
 
	switch(msg){
		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
		case WM_PAINT:
			if(pD3Device == NULL)
				return 0;
			//白で塗りつぶす
			pD3Device->Clear(0, NULL, D3DCLEAR_TARGET,
							 D3DCOLOR_XRGB(0xFF, 0xFF, 0xFF), 1.0, 0);
			pD3Device->BeginScene(); //描画開始
 
			//ストリームソースに頂点バッファをセットする
			pD3Device->SetStreamSource(0,					//ストリーム番号、今は0を指定
									   pVertex,				//頂点バッファコンポーネントへのポインタ
									   0,					//頂点データの書き始めを指定、ヘッダ分ずらせる
									   sizeof(D3DVERTEX));	//1頂点分のサイズを指定
            //頂点バッファのフォーマットをセット
			pD3Device->SetFVF(FVF_CUSTOM);
			//描画
			pD3Device->DrawPrimitive(D3DPT_TRIANGLESTRIP,	//ポリゴンの頂点の結び方を指定、D3DPRIMITIVETYPE参照
									 0,						//描画を開始する最初の頂点番号
									 2);					//描画するポリゴン数
 
			pD3Device->EndScene(); //描画終了
			pD3Device->Present(NULL, NULL, NULL, NULL);
 
			return 0;
 
		case WM_SIZE:
			if(!pD3Device)
				return 0;
			d3dpp.BackBufferWidth = LOWORD(lp);
			d3dpp.BackBufferHeight = HIWORD(lp);
			pD3Device->Reset(&d3dpp);
			return 0;
	}
	return DefWindowProc(hWnd, msg, wp, lp);
}
 
/////////////////////////////////////////////////////////////////////////
// エントリポイント
/////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
				   PSTR lpCmdLine, int nCmdShow)
{
	HWND hWnd;		//ウィンドウのIDを保持するとこ
	MSG msg;		//メッセージを保持するとこ
 
 
	if(!resisterWindowClass(hInstance,WIN_CLASS_NAME))
		return 0;
 
	if((hWnd = createWindow(hInstance, WIN_CLASS_NAME)) == NULL)
		return 0;
 
	//DirectXの初期化
	if(initD3D(hWnd) != D3D_OK){
		MessageBox(hWnd, TEXT("DirectXの初期化に失敗しました!"), TEXT("Error"), MB_ICONINFORMATION);
		return 0;
	}
 
	////////////////////////////////////////////////////////////////
	//頂点バッファの作成
	////////////////////////////////////////////////////////////////
	HRESULT hr;
	//pVertexの先に頂点バッファ操作コンポーネント生成
	hr = pD3Device->CreateVertexBuffer(sizeof(D3DVERTEX)*4,	//頂点バッファのサイズ
									   D3DUSAGE_WRITEONLY,	//リソースの使用方法指定
									   FVF_CUSTOM,			//頂点フォーマットの型指定、D3DFVF参照
									   D3DPOOL_MANAGED,		//バッファをどこに作るか指定、MANAGEDで適切な場所に作ってくれる
									   &pVertex,			//頂点バッファコンポーネントへのポインタのアドレス。これを使ってバッファの操作を行う
									   NULL);				//工事中?NULLでおk
	if(hr != D3D_OK){
		MessageBox(hWnd, TEXT("頂点バッファの作成に失敗しました!"), TEXT("Error"), MB_ICONINFORMATION);
		return 0;
	}
 
	//頂点バッファを書き込む
	void *pData;
	//VRAMをロックする
	hr = pVertex->Lock(0,					//ロックするメモリの範囲開始点
					   sizeof(D3DVERTEX)*4, //ロックするメモリの範囲終点
					   (void**)&pData,		//ロックされたメモリの先頭アドレスへのポインタ
					   0);					//オプションフラグ、D3DLOCKを参照
 
	if(hr == D3D_OK){
		//ロックしたVRAMに頂点情報を流し込む
		memcpy(pData, v, sizeof(D3DVERTEX)*4);
		//ロックを外す
		pVertex->Unlock();
	}
	else{
		MessageBox(hWnd, TEXT("頂点バッファのロックに失敗しました!"), TEXT("Error"), MB_ICONINFORMATION);
		return 0;
	}
 
	////////////////////////////////////////////////////////////////////
 
	while(GetMessage(&msg, NULL, 0, 0)){//MSG構造体にメッセージをゲットだぜ
		TranslateMessage(&msg);
		DispatchMessage(&msg);			//メッセージをウィンドウプロシージャにお裾分けする
	}
 
	pVertex->Release();
	pDirect3D->Release();
	pD3Device->Release();
	return msg.wParam;
}
 
////////////////////////////////////////////////////////////////////////////
//DirectXを初期化
////////////////////////////////////////////////////////////////////////////
HRESULT initD3D(HWND hWnd){
	D3DDISPLAYMODE d3ddm;			//ディスプレイモードを格納するとこ
 
	//D3Dインタフェースの取得、ここから色んな準備を行う
	if((pDirect3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
		return FALSE;
 
	//バッファのサーフェイスフォーマットを指定するために、ディスプレイモードを取得する。
	pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
 
	ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));	//動的確保~
	d3dpp.BackBufferFormat = d3ddm.Format;				//バッファのサーフェスフォーマット。D3DFORMATを参照
	d3dpp.BackBufferCount = 1;							//確保するバッファ数、1ならダブルバッファ
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;			//ダブルバッファリングのスワップ動作指定。D3DSWAPEFFECTを参照
	d3dpp.Windowed = TRUE;								//FALSEでフルスクリーン
 
	//D3Dデバイスを取得する
	return pDirect3D->CreateDevice( D3DADAPTER_DEFAULT,		//使用するグラフィックアダプタの指定
									D3DDEVTYPE_HAL,			//デバイスタイプ指定、D3DDEVTYPE参照
									hWnd,					//アプリのウィンドウハンドラ
									D3DCREATE_SOFTWARE_VERTEXPROCESSING,	//デバイスの動作を指定するフラグ 
									&d3dpp,					//先ほど初期化したD3DPRESENT_PARAMETERSを指定
									&pD3Device);			//デバイスインターフェースを格納するポインタを指定
}
 
////////////////////////////////////////////////////////////////////////////
//ウィンドウ作成
////////////////////////////////////////////////////////////////////////////
HWND createWindow(HINSTANCE hInstance, LPCTSTR className){
	return CreateWindow(className,
						WINDOW_NAME,
						WS_OVERLAPPEDWINDOW | WS_VISIBLE,
						CW_USEDEFAULT, CW_USEDEFAULT,	//初期位置x,y
						640, 480,	//横幅、縦幅
						NULL, NULL,
						hInstance,
						NULL);
}
 
////////////////////////////////////////////////////////////////////////////
//ウィンドウクラス登録
////////////////////////////////////////////////////////////////////////////
int resisterWindowClass(HINSTANCE hInstance, LPCTSTR className){
	WNDCLASS winc;
 
	winc.style			=CS_HREDRAW | CS_VREDRAW;
	winc.lpfnWndProc	= WndProc;
	winc.cbClsExtra		= winc.cbWndExtra = 0;
	winc.hInstance		= hInstance;
	winc.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	winc.hCursor		= LoadCursor(NULL, IDC_ARROW);
	winc.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	winc.lpszClassName	= className;
	//ウィンドウクラスを登録して使えるようにします
	return RegisterClass(&winc);
}

タグ:

+ タグ編集
  • タグ:
最終更新:2008年07月28日 02:16
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。