www.pudn.com > DirectX source.zip > main.cpp


/*! 
	@file : main.cpp 
	The main file of the application. Contains all the global functions and 
	variables. 
 
	@author Sarmad Kh. Abdulla 
*/ 
//------------------------------------------------------------------------------ 
 
//////////////////////////////////////////////////////////////////////////////// 
// Headers 
#include "stdafx.h" 
 
//////////////////////////////////////////////////////////////////////////////// 
// Constants 
#define SCREENWIDTH		800 
#define SCREENHEIGHT	600 
 
//////////////////////////////////////////////////////////////////////////////// 
// Global variables 
HWND				g_hWnd			= NULL; 
LPDIRECT3D8			g_pD3D			= NULL; 
LPDIRECT3DDEVICE8	g_pD3DDevice	= NULL; 
bool				g_bWait			= false; 
D3DXMATRIX			g_WorldMat; 
CSkinMesh			g_SkinMesh; 
 
//////////////////////////////////////////////////////////////////////////////// 
// Global functions 
void Initialize( HINSTANCE hinstance ); 
void Terminate( void ); 
void InitDevice( void ); 
void LoadSkinMesh( void ); 
bool ProcessMessages( void ); 
void Run( void ); 
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ); 
 
 
//////////////////////////////////////////////////////////////////////////////// 
// Entry point 
int APIENTRY WinMain(HINSTANCE hInstance, 
                     HINSTANCE hPrevInstance, 
                     LPSTR     lpCmdLine, 
                     int       nCmdShow) 
{ 
	try 
	{ 
		Initialize( hInstance ); 
		InitDevice(); 
		LoadSkinMesh(); 
		Run(); 
	} 
	catch( CException * pe ) 
	{ 
		pe->ShowMessage( g_hWnd ); 
		delete pe; 
	} 
	Terminate(); 
 
	return 0; 
} 
 
 
/*! 
 * Initialize the main D3D objects of the application and create the main window. 
 * 
 * @param hinstance : The handle of the instance 
 * 
 * @return void  :  
 */ 
void Initialize( HINSTANCE hinstance ) 
{ 
	// create the D3D object 
    if( NULL == ( g_pD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) ) 
        throw new CCustomException( "Couldn't create D3D object" ); 
 
	// register the window class 
	WNDCLASS wndclass; 
	wndclass.style         = CS_HREDRAW | CS_VREDRAW; 
	wndclass.lpfnWndProc   = WndProc; 
	wndclass.cbClsExtra    = 0; 
	wndclass.cbWndExtra    = 0; 
	wndclass.hInstance     = hinstance; 
	wndclass.hIcon         = NULL; 
	wndclass.hCursor       = LoadCursor( NULL, IDC_ARROW ); 
	wndclass.hbrBackground = NULL; 
	wndclass.lpszMenuName  = NULL; 
	wndclass.lpszClassName = "SKINMESHWINDOW"; 
 
	if( !RegisterClass( &wndclass ) ) 
	{ 
		SAFERELEASE( g_pD3D ); 
		throw new CCustomException( "Couldn't register window class" ); 
	} 
 
	// create the window 
	g_hWnd = CreateWindow( "SKINMESHWINDOW", "Skin Mesh Sample",  
		WS_OVERLAPPEDWINDOW, 0, 0, SCREENWIDTH, SCREENHEIGHT,  
		NULL, NULL, hinstance, NULL ); 
	if( !g_hWnd ) 
	{ 
		SAFERELEASE( g_pD3D ); 
		throw new CCustomException( "Couldn't create window" ); 
	} 
	ShowWindow( g_hWnd, SW_NORMAL ); 
 
	// prepare to create the device 
	D3DPRESENT_PARAMETERS d3dpp;  
	ZeroMemory( &d3dpp, sizeof(d3dpp) ); 
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 
	d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; 
	d3dpp.Windowed = TRUE; 
 
	// Get the current desktop display mode 
	D3DDISPLAYMODE d3ddm; 
	HRESULT result = g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ); 
	if( FAILED( result ) ) 
	{ 
		SAFERELEASE( g_pD3D ); 
		DestroyWindow( g_hWnd ); 
		g_hWnd = NULL; 
		throw new CDXException( "Couldn't get desktop display mode", result ); 
	} 
	d3dpp.BackBufferFormat = d3ddm.Format; 
	d3dpp.BackBufferCount = 1; 
	d3dpp.hDeviceWindow = g_hWnd; 
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
	d3dpp.EnableAutoDepthStencil = TRUE; 
 
	// create the device 
	result = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT,  
		D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
		&d3dpp, &g_pD3DDevice ); 
	if( FAILED( result ) ) 
	{ 
		SAFERELEASE( g_pD3D ); 
		DestroyWindow( g_hWnd ); 
		g_hWnd = NULL; 
		throw new CDXException( "Couldn't create D3D device", result ); 
	} 
} 
 
 
/*! 
 * Destroy all the objects 
 * 
 * @param void :  
 * 
 * @return void  :  
 */ 
void Terminate( void ) 
{ 
	g_SkinMesh.Destroy(); 
	SAFERELEASE( g_pD3DDevice ); 
	SAFERELEASE( g_pD3D ); 
	if( g_hWnd ) 
	{ 
		DestroyWindow( g_hWnd ); 
		g_hWnd = NULL; 
	} 
} 
 
 
/*! 
 * The window procedure. 
 */ 
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) 
{ 
	switch( message ) 
	{ 
	case WM_CLOSE: 
		PostQuitMessage( 0 ); 
		return 0; 
 
	case WM_PAINT: 
		if( g_pD3DDevice ) 
			g_pD3DDevice->Present( NULL, NULL, NULL, NULL ); 
		ValidateRect( hwnd, NULL ); 
		return 0; 
 
	case WM_ACTIVATE: 
		if( LOWORD( wparam ) == WA_INACTIVE ) 
			g_bWait = true; 
		else 
			g_bWait = false; 
		break; 
	} 
	return DefWindowProc( hwnd, message, wparam, lparam ); 
} 
 
 
/*! 
 * Render a new frame 
 * 
 * @param void :  
 * 
 * @return void  :  
 */ 
void Render( void ) 
{ 
	// check if the window is created 
	if( !g_pD3DDevice ) return; 
 
    // Clear the z buffer if necessary 
	g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET,  
		D3DCOLOR_XRGB(0,0,255), 1.0f, 0 ); 
     
    // Begin the scene 
    g_pD3DDevice->BeginScene(); 
 
	// Render the skin object 
	g_SkinMesh.Render( g_pD3DDevice, &g_WorldMat ); 
 
    // End the scene 
    g_pD3DDevice->EndScene(); 
 
	// present to the window 
	g_pD3DDevice->Present( NULL, NULL, NULL, NULL ); 
} 
 
 
/*! 
 * Initialize the states of the D3D device. 
 * 
 * @param void :  
 * 
 * @return void  :  
 */ 
void InitDevice( void ) 
{ 
	// set the states of the device 
	g_pD3DDevice->SetRenderState( D3DRS_LIGHTING, TRUE ); 
	g_pD3DDevice->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE ); 
	g_pD3DDevice->LightEnable( 0, TRUE ); 
	// set the view matrix 
	D3DXMATRIX viewmat; 
	D3DXMatrixTranslation( &viewmat, 0, -1.2f, 4 ); 
	g_pD3DDevice->SetTransform( D3DTS_VIEW, &viewmat ); 
	// set the projection matrix 
	D3DXMATRIX projmat; 
	D3DXMatrixPerspectiveFovLH( &projmat, D3DX_PI/4, 1.33f, 1.0f, 10.0f ); 
	g_pD3DDevice->SetTransform( D3DTS_PROJECTION, &projmat ); 
	// initialize the world mat 
	D3DXMatrixRotationX( &g_WorldMat, -1.4f ); 
	D3DXMATRIX mat; 
	D3DXMatrixRotationY( &mat, -D3DX_PI ); 
	D3DXMatrixMultiply( &g_WorldMat, &g_WorldMat, &mat ); 
	D3DXMatrixScaling( &mat, 0.005f, 0.005f, 0.005f ); 
	D3DXMatrixMultiply( &g_WorldMat, &g_WorldMat, &mat ); 
} 
 
 
/*! 
 * Load the skin mesh. 
 * 
 * @param void :  
 * 
 * @return void  :  
 */ 
void LoadSkinMesh( void ) 
{ 
	g_SkinMesh.Create( "tiny.x", g_pD3DDevice ); 
} 
 
 
/*! 
 * The message loop processed here 
 * 
 * @param void :  
 * 
 * @return bool : false if a quit message is received, true otherwise 
 */ 
bool ProcessMessages( void ) 
{ 
	MSG msg; 
	// loop until s_bWait is false 
	do{ 
		if( !g_bWait ) 
		{ 
			// if g_bWait is false do not wait in the loop, so check the 
			// existance of messages and processes them if available 
			if( PeekMessage( &msg, NULL, 0, 0, 0 ) ) 
			{ 
				if( !GetMessage( &msg, NULL, 0, 0 ) ) 
				{ 
					return false; 
				} 
				else 
				{ 
					TranslateMessage( &msg ); 
					DispatchMessage( &msg ); 
				} 
			} 
		} 
		else 
		{ 
			// if g_bWait is true use GetMessage to return control to 
			// the operating system 
			if( !GetMessage( &msg, NULL, 0, 0 ) ) 
			{ 
				return false; 
			} 
			else 
			{ 
				TranslateMessage( &msg ); 
				DispatchMessage( &msg ); 
			} 
		} 
	} while( g_bWait ); 
	// all messages are processed and no quit message was recieved so 
	// return true 
	return true; 
} 
 
 
/*! 
 * The main loop of the app 
 * 
 * @param void :  
 * 
 * @return void  :  
 */ 
void Run( void ) 
{ 
	while( ProcessMessages() ) 
	{ 
		g_SkinMesh.SetTime( timeGetTime()*5 ); 
		Render(); 
	} 
}