www.pudn.com > bookcode.rar > main.cpp
//Example2_3 //main.cpp //Ernest Pazera //08OCT2001 //TGO-02-B, C, D //Libs: d3d8.lib #include//include windows stuff #include //standard input/output #include "D3D8.h" //include direct3d8 stuff #include "d3dfmtutils.h" //include format utility functions //constants //window class name const char* WINDOWCLASS = "3D42DGP" ; //window title const char* WINDOWTITLE = "Example 2.3 (TGO-02-B, C, D): Viewports and Presenting" ; //screen width and height const int SCREENWIDTH = 640 ; const int SCREENHEIGHT = 480 ; //cell columns and rows const int CELLCOLUMNS = 10 ; const int CELLROWS = 10 ; //cell width const int CELLWIDTH = SCREENWIDTH / CELLCOLUMNS ; //cell height const int CELLHEIGHT = SCREENHEIGHT / CELLROWS ; //globals //instance handle HINSTANCE g_hInstance = NULL ; //window handle HWND g_hWnd = NULL ; //IDirect3D8 pointer IDirect3D8* g_pd3d = NULL ; //device type in use D3DDEVTYPE g_devtype ; //device pointer IDirect3DDevice8* g_pd3ddev = NULL ; //main viewport D3DVIEWPORT8 g_vpmain ; //cell viewports D3DRECT g_rccells [ CELLCOLUMNS ] [ CELLROWS ] ; //game map bool g_map [ CELLCOLUMNS ] [ CELLROWS ] ; //function prototypes //winmain int WINAPI WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpCmdLine , int nShowCmd ) ; //window procedure LRESULT CALLBACK TheWindowProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam ) ; //initialization void Prog_Init ( ) ; //clean up void Prog_Done ( ) ; //redraw frame void RedrawFrame ( ) ; //clear the map void ClearMap ( ) ; //make a move void MakeMove ( int x , int y ) ; //window procedure LRESULT CALLBACK TheWindowProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam ) { //which message did we get? switch ( uMsg ) { case WM_KEYDOWN: //a key has been pressed { //if escape pressed, destroy window if ( wParam == VK_ESCAPE ) DestroyWindow ( hWnd ) ; //return 0 return ( 0 ) ; } break ; case WM_LBUTTONDOWN: //left mouse button press { //grab x and y coordinates int x = LOWORD ( lParam ) ; int y = HIWORD ( lParam ) ; //calulate cell x /= CELLWIDTH ; y /= CELLHEIGHT ; //make a move MakeMove ( x , y ) ; //refresh frame RedrawFrame ( ) ; //return 0 return ( 0 ) ; } break ; case WM_DESTROY : //window being destroyed { //quit PostQuitMessage ( 0 ) ; //message handled, return 0 return ( 0 ) ; } break ; default: //all other messages, send to default handler return ( DefWindowProc ( hWnd , uMsg , wParam , lParam ) ) ; } } //winmain int WINAPI WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpCmdLine , int nShowCmd ) { //grab instance handle g_hInstance = hInstance ; //redirect stderr and stdout output freopen ( "stdout.txt" , "w" , stdout ) ; //fill in window class WNDCLASSEX wc ; wc.cbClsExtra = 0 ; //no extra class information wc.cbSize = sizeof ( WNDCLASSEX ) ; //size of structure wc.cbWndExtra = 0 ; //no extra window information wc.hbrBackground = ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) ; //black brush wc.hCursor = LoadCursor ( NULL , MAKEINTRESOURCE ( IDC_ARROW ) ) ; //arrow cursor wc.hIcon = NULL ; //no icon wc.hIconSm = NULL ; //no small icon wc.hInstance = g_hInstance ; //instance handle wc.lpfnWndProc = TheWindowProc ; //window procedure wc.lpszClassName = WINDOWCLASS ; //name of class wc.lpszMenuName = NULL ; //no menu wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC ; //class styles //register window class RegisterClassEx ( &wc ) ; //create window g_hWnd = CreateWindowEx ( 0 , WINDOWCLASS , WINDOWTITLE , WS_POPUP , 0 , 0 , 640 , 480 , NULL , NULL , g_hInstance , NULL ) ; //show the window ShowWindow ( g_hWnd , nShowCmd ) ; //initialization Prog_Init ( ) ; MSG msg ; //message pump for ( ; ; ) { //check for a message if ( PeekMessage( &msg , NULL , 0 , 0 , PM_REMOVE ) ) { //message exists //check for quit message if ( msg.message == WM_QUIT ) break ; //translate the message TranslateMessage ( &msg ) ; //dispatch the message DispatchMessage ( &msg ) ; } } //clean up Prog_Done ( ) ; //exit return ( msg.wParam ) ; } //initialization void Prog_Init ( ) { //seed the random generator srand ( GetTickCount ( ) ) ; //create the IDirect3D8 object g_pd3d = Direct3DCreate8 ( D3D_SDK_VERSION ) ; //error check if ( g_pd3d ) { //success fprintf ( stdout , "IDirect3D8 object created successfully.\n" ) ; } else { //failure fprintf ( stdout , "IDirect3D8 object creation failed.\n" ) ; //cannot proceed, so return return ; } //find display mode D3DDISPLAYMODE mode ; UINT nDisplayModeCount = g_pd3d->GetAdapterModeCount ( D3DADAPTER_DEFAULT ) ; //loop through display modes for ( UINT nDisplayMode = 0 ; nDisplayMode < nDisplayModeCount ; nDisplayMode ++ ) { //check next display mode g_pd3d->EnumAdapterModes ( D3DADAPTER_DEFAULT , nDisplayMode , &mode ) ; //if it matches desired screen width, break out of loop if ( mode.Width == SCREENWIDTH && mode.Height == SCREENHEIGHT ) break ; } //check for proper sized mode if ( mode.Width != SCREENWIDTH || mode.Height != SCREENHEIGHT ) { //did not find mode //post quit message PostQuitMessage ( 0 ) ; //report fprintf ( stdout , "Did not find display mode!\n" ) ; //return return ; } else { //found mode //report fprintf ( stdout , "Found display mode.\n" ) ; } //set up presentation parameters D3DPRESENT_PARAMETERS parms; //back buffer information parms.BackBufferWidth = mode.Width ; //use mode width parms.BackBufferHeight = mode.Height ; //use mode height parms.BackBufferFormat = mode.Format ; //use format of mode parms.BackBufferCount = 1 ; //make one back buffer //multisampling parms.MultiSampleType = D3DMULTISAMPLE_NONE ; //swap effect parms.SwapEffect = D3DSWAPEFFECT_COPY ; //we want to copy from back buffer to screen //destination window parms.hDeviceWindow = g_hWnd ; parms.Windowed = FALSE ; //depth buffer information parms.EnableAutoDepthStencil = FALSE ; parms.AutoDepthStencilFormat = D3DFMT_UNKNOWN ; //flags parms.Flags = 0 ; //refresh rate and presentation interval parms.FullScreen_RefreshRateInHz = mode.RefreshRate ; //use mode's refresh rate parms.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT ; //attempt to create a HAL device HRESULT hr ; //store return values in this variable hr = g_pd3d->CreateDevice ( D3DADAPTER_DEFAULT , D3DDEVTYPE_HAL , g_hWnd , D3DCREATE_SOFTWARE_VERTEXPROCESSING , &parms , &g_pd3ddev ) ; //error check if ( FAILED ( hr ) ) { //could not create HAL device fprintf ( stdout , "Could not create HAL device!\n" ) ; //attempt to make REF device hr = g_pd3d->CreateDevice ( D3DADAPTER_DEFAULT , D3DDEVTYPE_REF , g_hWnd , D3DCREATE_SOFTWARE_VERTEXPROCESSING , &parms , &g_pd3ddev ) ; if ( FAILED ( hr ) ) { //could not create REF device fprintf ( stdout , "Could not create REF device!\n" ) ; //post a quit message PostQuitMessage ( 0 ) ; } else { //successfully made REF device, store this value in a global g_devtype = D3DDEVTYPE_REF ; //report fprintf ( stdout , "Successfully created REF device.\n" ) ; } } else { //successfully made a HAL device, store this value in a global g_devtype = D3DDEVTYPE_HAL ; //report fprintf ( stdout , "Successfully created HAL device.\n" ) ; } //set up viewports //main viewport g_vpmain.X = 0 ; g_vpmain.Y = 0 ; g_vpmain.Width = SCREENWIDTH ; g_vpmain.Height = SCREENHEIGHT ; g_vpmain.MinZ = 0.0f ; g_vpmain.MaxZ = 1.0f ; //set the viewport g_pd3ddev->SetViewport ( &g_vpmain ) ; //cell RECTs //loop through columns for ( int x = 0 ; x < CELLCOLUMNS ; x ++ ) { //loop through rows for ( int y = 0 ; y < CELLROWS ; y ++ ) { //set up viewport g_rccells [ x ] [ y ].x1 = CELLWIDTH * x + 1 ; g_rccells [ x ] [ y ].y1 = CELLHEIGHT * y + 1 ; g_rccells [ x ] [ y ].x2 =g_rccells [ x ] [ y ].x1 + CELLWIDTH - 2 ; g_rccells [ x ] [ y ].y2 = g_rccells [ x ] [ y ].y1 + CELLHEIGHT - 2 ; } } //set up the map ClearMap ( ) ;//clear out the map for ( int i = 0 ; i < 10 ; i ++ )//make 10 random moves { MakeMove ( rand ( ) % CELLCOLUMNS , rand ( ) % CELLROWS ) ; } //redraw the frame RedrawFrame ( ) ; } //clean up void Prog_Done ( ) { //safe release of device if ( g_pd3ddev ) { //release g_pd3ddev->Release ( ) ; //set to null g_pd3ddev = NULL ; //report fprintf ( stdout , "IDirect3DDevice8 object released.\n" ) ; } //safe release of IDirect3D8 object if ( g_pd3d ) { //release g_pd3d->Release ( ) ; //set to null g_pd3d = NULL ; //report action fprintf ( stdout , "IDirect3D8 object released.\n" ) ; } } //redraw frame void RedrawFrame ( ) { //clear the screen g_pd3ddev->Clear ( 0 , NULL , D3DCLEAR_TARGET , D3DCOLOR_XRGB ( 128 , 128 , 128 ) , 0.0f, 0 ) ; D3DCOLOR col ; //clear the cells for ( int x = 0 ; x < CELLCOLUMNS ; x ++ ) { for ( int y = 0 ; y < CELLCOLUMNS ; y ++ ) { //set the cell viewport g_pd3ddev->SetViewport ( &g_vpmain ) ; //unlit color col = D3DCOLOR_XRGB ( 0 , 0 , 255 ) ; //lit color if ( g_map [ x ] [ y ] ) col = D3DCOLOR_XRGB ( 255 , 255 , 0 ) ; //clear the viewport g_pd3ddev->Clear ( 1 , &g_rccells [ x ] [ y ] , D3DCLEAR_TARGET , col , 0.0f, 0 ) ; } } //present the scene g_pd3ddev->Present ( NULL , NULL , NULL , NULL ) ; } //clear the map void ClearMap ( ) { //clear out map cells to false for ( int x = 0 ; x < CELLCOLUMNS ; x ++ ) { for ( int y = 0 ; y < CELLROWS ; y ++ ) { g_map [ x ] [ y ] = false ; } } } //make a move void MakeMove ( int x , int y ) { //toggle center cell g_map [ x ] [ y ] = ! g_map [ x ] [ y ] ; //toggle cell to left if ( x > 0 ) g_map [ x - 1 ] [ y ] = ! g_map [ x - 1 ] [ y ] ; //toggle cell to right if ( x < CELLCOLUMNS - 1 ) g_map [ x + 1 ] [ y ] = ! g_map [ x + 1 ] [ y ] ; //toggle cell above if ( y > 0 ) g_map [ x ] [ y - 1 ] = ! g_map [ x ] [ y - 1 ] ; //toggle cell below if ( y < CELLROWS - 1 ) g_map [ x ] [ y + 1 ] = ! g_map [ x ] [ y + 1 ] ; }