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();
}
}