www.pudn.com > Win32DirectX9.rar > Win32DirectX9.cpp


// Win32DirectX9.cpp : 定义应用程序的入口点。 
// 
 
#include "stdafx.h" 
#include "Win32DirectX9.h" 
 
#define MAX_LOADSTRING 100 
 
// 全局变量: 
HINSTANCE hInst;								// 当前实例 
TCHAR szTitle[MAX_LOADSTRING];					// 标题栏文本 
TCHAR szWindowClass[MAX_LOADSTRING];			// 主窗口类名 
 
 
// g_全局变量 
HINSTANCE g_hInst; 
HWND g_hWnd; 
IDirect3D9 *g_pD3D; 
IDirect3DDevice9 *g_pd3dDevice; 
IDirect3DVertexBuffer9 *g_pVB; 
 
struct CUSTOMVERTEX 
{ 
	D3DVECTOR pos; 
	D3DVECTOR normal; 
}; 
 
//TCHAR szTitle[MAX_LOADSTRING]; 
//TCHAR szWindowClass[MAX_LOADSTRING]; 
ATOM MyRegisterClass(HINSTANCE hInstance); 
BOOL InitInstance(HINSTANCE, int); 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); 
void OnIdle( void ); 
void OnCreate( HWND hWnd ); 
HRESULT InitD3D( void ); 
HRESULT CreateObject( void ); 
void ReleaseD3D( void ); 
HRESULT SetModalMatrix( void ); 
HRESULT SetProjMatrix( WORD wWidth, WORD wHeight ); 
void BeforePaint( void ); 
 
 
// 此代码模块中包含的函数的前向声明: 
ATOM				MyRegisterClass(HINSTANCE hInstance); 
BOOL				InitInstance(HINSTANCE, int); 
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM); 
LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM); 
 
 
void CalcNormal( const D3DVECTOR *pVertices, D3DVECTOR *pNormal ) 
{ 
	 D3DVECTOR v1, v2; 
	 v1.x = pVertices[0].x - pVertices[1].x; 
	 v1.y = pVertices[0].y - pVertices[1].y; 
	 v1.z = pVertices[0].z - pVertices[1].z; 
	 v2.x = pVertices[1].x - pVertices[2].x; 
	 v2.y = pVertices[1].y - pVertices[2].y; 
	 v2.z = pVertices[1].z - pVertices[2].z; 
 
	 D3DXVECTOR3 Temp( v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z,v1.x * v2.y - v1.y * v2.x ); 
	 D3DXVec3Normalize( (D3DXVECTOR3*)pNormal, &Temp ); 
} 
 
class CTimer 
{ 
private: 
	LARGE_INTEGER m_Frequency; 
	LARGE_INTEGER m_StartCount; 
 
public: 
	CTimer()  
	{ 
		QueryPerformanceFrequency(&m_Frequency);  
		Start(); 
	} 
	void Start() 
	{ 
		QueryPerformanceCounter(&m_StartCount); 
	} 
    double End()  
	{ 
		LARGE_INTEGER CurrentCount;QueryPerformanceCounter(&CurrentCount); 
		return double(CurrentCount.LowPart - m_StartCount.LowPart)/(double)m_Frequency.LowPart; 
	} 
 
}; 
 
 
int APIENTRY _tWinMain(HINSTANCE hInstance, 
                     HINSTANCE hPrevInstance, 
                     LPTSTR    lpCmdLine, 
                     int       nCmdShow) 
{ 
 	// TODO: 在此放置代码。 
	MSG msg; 
	HACCEL hAccelTable; 
 
	// 初始化全局字符串 
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 
	LoadString(hInstance, IDC_WIN32DIRECTX9, szWindowClass, MAX_LOADSTRING); 
	MyRegisterClass(hInstance); 
 
	// 执行应用程序初始化: 
	if (!InitInstance (hInstance, nCmdShow))  
	{ 
		return FALSE; 
	} 
 
	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WIN32DIRECTX9); 
 
	// 主消息循环:(原始) 
	//while (GetMessage(&msg, NULL, 0, 0))  
	//{ 
	//	if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))  
	//	{ 
	//		TranslateMessage(&msg); 
	//		DispatchMessage(&msg); 
	//	} 
	//} 
	 
	// 主消息循环:(修改后) 
	 
	while(true) 
	{ 
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
		{ 
			if(!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
			{ 
				TranslateMessage(&msg); 
				DispatchMessage(&msg); 
			} 
			continue; 
		} 
		if(WM_QUIT == msg.message) 
		{ 
			break; 
		} 
		OnIdle(); 
	} 
	UnregisterClass(szWindowClass, g_hInst); 
 
	return (int) msg.wParam; 
} 
 
 
 
// 
//  函数: MyRegisterClass() 
// 
//  目的: 注册窗口类。 
// 
//  注释:  
// 
//    仅当希望在已添加到 Windows 95 的 
//    “RegisterClassEx”函数之前此代码与 Win32 系统兼容时, 
//    才需要此函数及其用法。调用此函数 
//    十分重要,这样应用程序就可以获得关联的 
//   “格式正确的”小图标。 
// 
ATOM MyRegisterClass(HINSTANCE hInstance) 
{ 
	WNDCLASSEX wcex; 
 
	wcex.cbSize = sizeof(WNDCLASSEX);  
 
	wcex.style			= CS_HREDRAW | CS_VREDRAW; 
	wcex.lpfnWndProc	= (WNDPROC)WndProc; 
	wcex.cbClsExtra		= 0; 
	wcex.cbWndExtra		= 0; 
	wcex.hInstance		= hInstance; 
	wcex.hIcon			= LoadIcon(hInstance, (LPCTSTR)IDI_WIN32DIRECTX9); 
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW); 
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1); 
	wcex.lpszMenuName	= (LPCTSTR)IDC_WIN32DIRECTX9; 
	wcex.lpszClassName	= szWindowClass; 
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); 
 
	return RegisterClassEx(&wcex); 
} 
 
// 
//   函数: InitInstance(HANDLE, int) 
// 
//   目的: 保存实例句柄并创建主窗口 
// 
//   注释:  
// 
//        在此函数中,我们在全局变量中保存实例句柄并 
//        创建和显示主程序窗口。 
// 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 
{ 
   HWND hWnd; 
 
   hInst = hInstance; // 将实例句柄存储在全局变量中 
 
   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, 
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); 
 
   if (!hWnd) 
   { 
      return FALSE; 
   } 
 
   ShowWindow(hWnd, nCmdShow); 
   UpdateWindow(hWnd); 
 
   return TRUE; 
} 
 
// 
//  函数: WndProc(HWND, unsigned, WORD, LONG) 
// 
//  目的: 处理主窗口的消息。 
// 
//  WM_COMMAND	- 处理应用程序菜单 
//  WM_PAINT	- 绘制主窗口 
//  WM_DESTROY	- 发送退出消息并返回 
// 
// 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	int wmId, wmEvent; 
	PAINTSTRUCT ps; 
	HDC hdc; 
 
	switch (message)  
	{ 
	case WM_CREATE: // 建立时 执行 
		//MessageBox(NULL, "Hello , Gavin", "WM_CREATE", MB_OK); 
		OnCreate(hWnd); 
		break; 
	case WM_COMMAND: 
		wmId    = LOWORD(wParam);  
		wmEvent = HIWORD(wParam);  
		// 分析菜单选择: 
		switch (wmId) 
		{ 
		case ID_D3D_BEGIN: 
			break; 
		case ID_D3D_END: 
			break; 
		case IDM_ABOUT: 
			DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); 
			break; 
		case IDM_EXIT: 
			DestroyWindow(hWnd); 
			break; 
		default: 
			return DefWindowProc(hWnd, message, wParam, lParam); 
		} 
		break; 
	case WM_PAINT: 
		hdc = BeginPaint(hWnd, &ps); 
		// TODO: 在此添加任意绘图代码... 
		EndPaint(hWnd, &ps); 
		break; 
	case WM_DESTROY: 
 
		ReleaseD3D(); 
		PostQuitMessage(0); 
		break; 
	default: 
		return DefWindowProc(hWnd, message, wParam, lParam); 
	} 
	return 0; 
} 
 
// “关于”框的消息处理程序。 
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	switch (message) 
	{ 
	case WM_INITDIALOG: 
		return TRUE; 
 
	case WM_COMMAND: 
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)  
		{ 
			EndDialog(hDlg, LOWORD(wParam)); 
			return TRUE; 
		} 
		break; 
	} 
	return FALSE; 
} 
 
 
 
void OnCreate( HWND hWnd ) 
{ 
	g_hWnd = hWnd; 
	InitD3D(); 
	CreateObject(); 
} 
 
void ReleaseD3D( void ) 
{ 
	if(g_pVB != NULL) g_pVB->Release(); 
	if(g_pd3dDevice != NULL) g_pd3dDevice->Release(); 
	if(g_pD3D != NULL) g_pD3D->Release(); 
} 
 
HRESULT InitD3D( void ) 
{ 
	g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ); 
	if(g_pD3D == NULL) return E_FAIL; 
 
	D3DPRESENT_PARAMETERS d3dpp; 
	ZeroMemory( &d3dpp, sizeof(d3dpp)); 
 
	d3dpp.Windowed = TRUE; 
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 
	d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; 
 
	g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,  
		D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE,  
		&d3dpp, &g_pd3dDevice); 
     
	g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE ); 
	g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_COLORVALUE( 0.3f, 0.3f, 0.3f, 1.0 )); 
	g_pd3dDevice->LightEnable(0, TRUE); 
 
	D3DMATERIAL9 mtrl; 
	ZeroMemory( &mtrl, sizeof(mtrl)); 
 
	mtrl.Diffuse.r = mtrl.Ambient.r = 140.0f/255.0f ; 
	mtrl.Diffuse.g = mtrl.Ambient.g = 200.0f/255.0f ; 
	mtrl.Diffuse.b = mtrl.Ambient.b = 255.0f/255.0f ; 
	mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f; 
    g_pd3dDevice->SetMaterial(&mtrl); 
 
	return S_OK; 
} 
 
void BeforePaint( void ) 
{ 
	D3DLIGHT9 light; 
	ZeroMemory(&light, sizeof(light)); 
	light.Position = D3DXVECTOR3(30.0f, 30.0f, 30.0f); 
	light.Attenuation1 = 0.05f; 
	light.Diffuse.r = 1.0f; 
	light.Diffuse.g = 1.0f; 
	light.Diffuse.b = 1.0f; 
	light.Range = 1000.0f; 
	light.Type = D3DLIGHT_POINT; 
	g_pd3dDevice->SetLight(0, &light); 
	g_pd3dDevice->LightEnable(0, TRUE); 
} 
 
HRESULT CreateObject( void ) 
{ 
	D3DVECTOR SrcBox[] = { 
		{ 5.0f, 5.0f, 0.0f },{ 5.0f, 5.0f, 10.0f }, 
		{ 5.0f,-5.0f, 0.0f },{ 5.0f,-5.0f, 10.0f }, 
		{-5.0f,-5.0f, 0.0f },{-5.0f,-5.0f, 10.0f }, 
		{-5.0f, 5.0f, 0.0f },{-5.0f, 5.0f, 10.0f } 
	 
	}; 
 
	WORD wIndex[] = { 
		0, 4, 6, 0, 2, 4, 
		0, 6, 7, 0, 7, 1, 
		0, 3, 2, 0, 1, 3, 
		5, 2, 3, 5, 4, 2, 
		5, 6, 4, 5, 7, 6, 
		5, 1, 7, 5, 3, 1 
	}; 
 
	CUSTOMVERTEX ExpandBox[sizeof(wIndex)/sizeof(WORD)]; 
	 
	for(int i = 0; i < 36; i++) ExpandBox[i].pos = SrcBox[ wIndex[i] ]; 
	for(i = 0; i < 12; i++) 
	{ 
		D3DVECTOR Tri[3]; 
		Tri[0] = ExpandBox[i * 3 + 0].pos ; 
		Tri[1] = ExpandBox[i * 3 + 1].pos ; 
		Tri[2] = ExpandBox[i * 3 + 2].pos ; 
 
		ExpandBox[i * 3 + 0].normal.x = 0.0f ; 
		ExpandBox[i * 3 + 0].normal.y = 0.0f ; 
		ExpandBox[i * 3 + 0].normal.z = 1.0f ; 
 
		CalcNormal(Tri, &(ExpandBox[i * 3 + 0].normal )); 
		ExpandBox[i * 3 + 1].normal = ExpandBox[i * 3 + 0].normal ; 
		ExpandBox[i * 3 + 2].normal = ExpandBox[i * 3 + 0].normal ; 
	} 
 
	g_pd3dDevice->CreateVertexBuffer(sizeof(ExpandBox), 0, /*D3DFVF_CUSTOMVERTEX*/ 0, D3DPOOL_DEFAULT, &g_pVB, NULL); 
 
	VOID* pVertices; 
	g_pVB->Lock( 0, sizeof(ExpandBox), (void**)&pVertices, 0) ; 
	MoveMemory(pVertices, ExpandBox, sizeof(ExpandBox)) ; 
	g_pVB->Unlock() ;  
	return S_OK; 
} 
 
void OnIdle( void ) 
{ 
	static CTimer t; 
	static double dt = t.End(); 
	double temp = t.End(); 
	double szValue[256]; 
	double ZhenLv = 1 / (temp - dt); // 当前帧率 
	 
	//sprintf(szValue,"%f", ZhenLv); 
	//sprintf(szValue , "当前帧率 : %f ", ZhenLv); 
	SetWindowText(g_hWnd, "当前帧率:"); 
	dt = temp; 
	if(g_pd3dDevice != NULL) 
	{ 
		g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 200), 1.0f, 0); 
		if(SUCCEEDED(g_pd3dDevice->BeginScene())) 
		{ 
			BeforePaint(); 
			if(FAILED(SetModalMatrix())) return; 
			g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX)); 
			g_pd3dDevice->SetFVF(/*D3DFVF_CUSTOMVERTEX*/0); 
			g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 12); 
			g_pd3dDevice->EndScene(); 
			g_pd3dDevice->Present(NULL, NULL, NULL, NULL); 
		} 
	} 
} 
 
HRESULT SetModalMatrix( void ) 
{ 
	static float fRadius = 0.5f; 
	fRadius -= 0.003f; 
	if(fRadius < 0) fRadius = D3DX_PI * 2; 
	D3DXMATRIX matWorld; 
	D3DXMatrixRotationZ( &matWorld, 0.0f); 
	if(FAILED(g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld))) return E_FAIL; 
	D3DXMATRIX matView; 
	D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3(cosf(fRadius) * 40.0f,  
	sinf(fRadius) * 40.0f, 30.0), &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3(0.0f, 0.0f, 1.0f)); 
	g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView); 
	return S_OK; 
} 
 
HRESULT SetProjMatrix( WORD wWidth, WORD wHeight ) 
{ 
	D3DXMATRIX matProj; 
	D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, (float)wWidth/(float)wHeight, 1.0f,100.0f); 
	return g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj); 
}