www.pudn.com > bookcode.rar > main.cpp


//Example4_10 
//main.cpp 
//Ernest Pazera 
//13OCT2001 
//TGO-04-F 
//Libs: d3d8.lib 
 
#include 	//include windows stuff 
#include 		//standard input/output 
#include  
#include "D3D8.h"	//include direct3d8 stuff 
#include "d3dfmtutils.h"	//include format utility functions 
 
//custom vertex 
#define CUSTOM_VERTEX_FVF D3DFVF_XYZRHW | D3DFVF_DIFFUSE  
struct CustomVertex 
{ 
	float x , y , z , rhw ; 
	D3DCOLOR diffuse ; 
} ; 
 
//constants 
	//window class name 
	const char* WINDOWCLASS = "3D42DGP" ; 
	//window title 
	const char* WINDOWTITLE = "Example 4.10 (TGO-04-G): Drawing Triangle Fans with a Vertex Buffer and Index Buffer" ; 
	//screen width and height 
	const int SCREENWIDTH = 640 ; 
	const int SCREENHEIGHT = 480 ; 
	//vertex and primitive counts 
	const int VERTEXCOUNT = 11 ; 
	const int PRIMITIVECOUNT = 10 ; 
	const int INDEXCOUNT = 12 ; 
	//pi 
	const float PI = 3.14159f ; 
	//radius 
	const float RADIUS = 200.0f ; 
 
//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 ; 
	//vertices 
	CustomVertex g_vertices [ VERTEXCOUNT ] ; 
	//indices 
	WORD g_indices [ INDEXCOUNT ] ; 
	//angle of rotation 
	float g_angle = 0.0f; 
	//vertex buffer 
	IDirect3DVertexBuffer8* g_pvb = NULL ; 
	//index buffer 
	IDirect3DIndexBuffer8* g_pib = NULL ; 
 
//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 ( ) ; 
 
//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_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 ) ; 
		} 
		else 
		{ 
			//no message, update frame 
			RedrawFrame ( ) ; 
		} 
	} 
 
	//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 ) ; 
 
	//create vertex buffer 
	hr = g_pd3ddev->CreateVertexBuffer ( VERTEXCOUNT * sizeof ( CustomVertex ) , 0 , CUSTOM_VERTEX_FVF , D3DPOOL_DEFAULT , &g_pvb ) ; 
	//error check 
	if ( FAILED ( hr ) ) 
	{ 
		//report the error 
		fprintf ( stdout , "Failed to create vertex buffer!\n" ) ; 
 
		//quit application 
		PostQuitMessage ( 0 ) ; 
 
		//exit function 
		return ; 
	}  
	else 
	{ 
		//report success 
		fprintf ( stdout , "Created vertex buffer.\n" ) ; 
	} 
 
	//set vertex buffer as stream source 
	g_pd3ddev->SetStreamSource ( 0 , g_pvb , sizeof ( CustomVertex ) ) ; 
 
	//create index buffer 
	hr = g_pd3ddev->CreateIndexBuffer ( INDEXCOUNT * sizeof ( WORD ) , 0 , D3DFMT_INDEX16 , D3DPOOL_DEFAULT , &g_pib ) ; 
	//error check 
	if ( FAILED ( hr ) ) 
	{ 
		//report the error 
		fprintf ( stdout , "Failed to create index buffer!\n" ) ; 
 
		//quit application 
		PostQuitMessage ( 0 ) ; 
 
		//exit function 
		return ; 
	}  
	else 
	{ 
		//report success 
		fprintf ( stdout , "Created index buffer.\n" ) ; 
	} 
 
	//set indices 
	g_pd3ddev->SetIndices ( g_pib , 0 ) ; 
	 
	//set vertex shader 
	g_pd3ddev->SetVertexShader ( CUSTOM_VERTEX_FVF ) ; 
 
	//turn off lighting 
	g_pd3ddev->SetRenderState ( D3DRS_LIGHTING , FALSE ) ; 
 
	//set up vertex rhw 
	g_vertices [ 0 ].rhw = 1.0f ; 
	g_vertices [ 1 ].rhw = 1.0f ; 
	g_vertices [ 2 ].rhw = 1.0f ; 
	g_vertices [ 3 ].rhw = 1.0f ; 
	g_vertices [ 4 ].rhw = 1.0f ; 
	g_vertices [ 5 ].rhw = 1.0f ; 
	g_vertices [ 6 ].rhw = 1.0f ; 
	g_vertices [ 7 ].rhw = 1.0f ; 
	g_vertices [ 8 ].rhw = 1.0f ; 
	g_vertices [ 9 ].rhw = 1.0f ; 
	g_vertices [ 10 ].rhw = 1.0f ; 
 
	//set up vertex z 
	g_vertices [ 0 ].z = 0.0f; 
	g_vertices [ 1 ].z = 0.0f; 
	g_vertices [ 2 ].z = 0.0f; 
	g_vertices [ 3 ].z = 0.0f; 
	g_vertices [ 4 ].z = 0.0f; 
	g_vertices [ 5 ].z = 0.0f; 
	g_vertices [ 6 ].z = 0.0f; 
	g_vertices [ 7 ].z = 0.0f; 
	g_vertices [ 8 ].z = 0.0f; 
	g_vertices [ 9 ].z = 0.0f; 
	g_vertices [ 10 ].z = 0.0f; 
 
	//set up vertex colors 
	g_vertices [ 0 ].diffuse = D3DCOLOR_XRGB ( 255 , 0 , 0 ) ; 
	g_vertices [ 1 ].diffuse = D3DCOLOR_XRGB ( 0 , 255 , 0 ) ; 
	g_vertices [ 2 ].diffuse = D3DCOLOR_XRGB ( 0 , 0 , 255 ) ; 
	g_vertices [ 3 ].diffuse = D3DCOLOR_XRGB ( 0 , 255 , 0 ) ; 
	g_vertices [ 4 ].diffuse = D3DCOLOR_XRGB ( 0 , 0 , 255 ) ; 
	g_vertices [ 5 ].diffuse = D3DCOLOR_XRGB ( 0 , 255 , 0 ) ; 
	g_vertices [ 6 ].diffuse = D3DCOLOR_XRGB ( 0 , 0 , 255 ) ; 
	g_vertices [ 7 ].diffuse = D3DCOLOR_XRGB ( 0 , 255 , 0 ) ; 
	g_vertices [ 8 ].diffuse = D3DCOLOR_XRGB ( 0 , 0 , 255 ) ; 
 	g_vertices [ 9 ].diffuse = D3DCOLOR_XRGB ( 0 , 255 , 0 ) ; 
	g_vertices [ 10 ].diffuse = D3DCOLOR_XRGB ( 0 , 0 , 255 ) ; 
 
	//set up indices 
	g_indices [ 0 ] = 0 ; 
	g_indices [ 1 ] = 1 ; 
	g_indices [ 2 ] = 2 ; 
	g_indices [ 3 ] = 3 ; 
	g_indices [ 4 ] = 4 ; 
	g_indices [ 5 ] = 5 ; 
	g_indices [ 6 ] = 6 ; 
	g_indices [ 7 ] = 7 ; 
	g_indices [ 8 ] = 8 ; 
	g_indices [ 9 ] = 9 ; 
	g_indices [ 10 ] = 10 ; 
	g_indices [ 11 ] = 1 ; 
 
	//lock index buffer 
	BYTE* buffer ; 
	g_pib->Lock ( 0 , INDEXCOUNT * sizeof ( WORD ) , &buffer , 0 ) ; 
 
	//copy index data to buffer 
	memcpy ( buffer , g_indices , INDEXCOUNT * sizeof ( WORD ) ) ; 
 
	//unlock index buffer 
	g_pib->Unlock ( ) ; 
 
	//redraw the frame 
	RedrawFrame ( ) ; 
} 
 
//clean up 
void Prog_Done ( )  
{ 
	//safe release of index buffer 
	if ( g_pib ) 
	{ 
		//set device indices to NULL 
		g_pd3ddev->SetIndices ( NULL , 0 ) ; 
 
		//release 
		g_pib->Release ( ) ; 
 
		//set to null 
		g_pib = NULL ; 
 
		//report 
		fprintf ( stdout , "Released index buffer.\n" ) ; 
	} 
 
	//safe release of vertex buffer 
	if ( g_pvb ) 
	{ 
		//set device stream 0 to null 
		g_pd3ddev->SetStreamSource ( 0 , NULL , 0 ) ; 
 
		//release 
		g_pvb->Release ( ) ; 
 
		//set to null 
		g_pvb = NULL ; 
 
		//report 
		fprintf ( stdout , "Released Vertex Buffer.\n" ) ; 
 
	} 
 
	//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 ( 0 , 0 , 0 ) , 0.0f, 0 ) ; 
 
	//set up vertices 
	//vertex 0 
	g_vertices [ 0 ].x = SCREENWIDTH / 2 ; 
	g_vertices [ 0 ].y = SCREENHEIGHT / 2 ; 
	//vertex 1 
	g_vertices [ 1 ].x = SCREENWIDTH / 2 + cos ( g_angle ) * RADIUS ; 
	g_vertices [ 1 ].y = SCREENHEIGHT / 2 + sin ( g_angle ) * RADIUS ; 
	//vertex 2 
	g_vertices [ 2 ].x = SCREENWIDTH / 2 + cos ( g_angle + 2.0 * PI / 10.0 ) * RADIUS / 2.0 ; 
	g_vertices [ 2 ].y = SCREENHEIGHT / 2 + sin ( g_angle + 2.0 * PI / 10.0 ) * RADIUS / 2.0 ; 
	//vertex 3 
	g_vertices [ 3 ].x = SCREENWIDTH / 2 + cos ( g_angle + 2.0 * 2.0 * PI / 10.0 ) * RADIUS ; 
	g_vertices [ 3 ].y = SCREENHEIGHT / 2 + sin ( g_angle + 2.0 * 2.0 * PI / 10.0 ) * RADIUS ; 
	//vertex 4 
	g_vertices [ 4 ].x = SCREENWIDTH / 2 + cos ( g_angle + 3.0 * 2.0 * PI / 10.0 ) * RADIUS / 2.0 ; 
	g_vertices [ 4 ].y = SCREENHEIGHT / 2 + sin ( g_angle + 3.0 * 2.0 * PI / 10.0 ) * RADIUS / 2.0 ; 
	//vertex 5 
	g_vertices [ 5 ].x = SCREENWIDTH / 2 + cos ( g_angle + 4.0 * 2.0 * PI / 10.0 ) * RADIUS ; 
	g_vertices [ 5 ].y = SCREENHEIGHT / 2 + sin ( g_angle + 4.0 * 2.0 * PI / 10.0 ) * RADIUS ; 
	//vertex 6 
	g_vertices [ 6 ].x = SCREENWIDTH / 2 + cos ( g_angle + 5.0 * 2.0 * PI / 10.0 ) * RADIUS / 2.0 ; 
	g_vertices [ 6 ].y = SCREENHEIGHT / 2 + sin ( g_angle + 5.0 * 2.0 * PI / 10.0 ) * RADIUS / 2.0 ; 
	//vertex 7 
	g_vertices [ 7 ].x = SCREENWIDTH / 2 + cos ( g_angle + 6.0 * 2.0 * PI / 10.0 ) * RADIUS ; 
	g_vertices [ 7 ].y = SCREENHEIGHT / 2 + sin ( g_angle + 6.0 * 2.0 * PI / 10.0 ) * RADIUS ; 
	//vertex 8 
	g_vertices [ 8 ].x = SCREENWIDTH / 2 + cos ( g_angle + 7.0 * 2.0 * PI / 10.0 ) * RADIUS / 2.0 ; 
	g_vertices [ 8 ].y = SCREENHEIGHT / 2 + sin ( g_angle + 7.0 * 2.0 * PI / 10.0 ) * RADIUS / 2.0 ; 
	//vertex 9 
	g_vertices [ 9 ].x = SCREENWIDTH / 2 + cos ( g_angle + 8.0 * 2.0 * PI / 10.0 ) * RADIUS ; 
	g_vertices [ 9 ].y = SCREENHEIGHT / 2 + sin ( g_angle + 8.0 * 2.0 * PI / 10.0 ) * RADIUS ; 
	//vertex 10 
	g_vertices [ 10 ].x = SCREENWIDTH / 2 + cos ( g_angle + 9.0 * 2.0 * PI / 10.0 ) * RADIUS / 2.0 ; 
	g_vertices [ 10 ].y = SCREENHEIGHT / 2 + sin ( g_angle + 9.0 * 2.0 * PI / 10.0 ) * RADIUS / 2.0 ; 
 
	//lock vertex buffer 
	BYTE* buffer ; 
	g_pvb->Lock ( 0 , 0 , &buffer , 0 ) ; 
 
	//copy information to vertex buffer 
	memcpy ( buffer , g_vertices , VERTEXCOUNT * sizeof ( CustomVertex ) ) ; 
 
	//unlock vertex buffer 
	g_pvb->Unlock ( ) ; 
 
	//increase angle for next time 
	g_angle += ( 2.0 * PI / 360.0 ) ; 
 
	//begin the scene 
	g_pd3ddev->BeginScene ( ) ; 
 
	g_pd3ddev->DrawIndexedPrimitive ( D3DPT_TRIANGLEFAN , 0 , VERTEXCOUNT, 0 , PRIMITIVECOUNT ) ; 
 
	//end the scene 
	g_pd3ddev->EndScene ( ) ; 
 
	//present the scene 
	g_pd3ddev->Present ( NULL , NULL , NULL , NULL ) ; 
}