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


//Example4_1 
//main.cpp 
//Ernest Pazera 
//12OCT2001 
//TGO-04-D 
//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.1 (TGO-04-D): Drawing Points without a Vertex Buffer" ; 
	//screen width and height 
	const int SCREENWIDTH = 640 ; 
	const int SCREENHEIGHT = 480 ; 
	//vertex and primitive counts 
	const int VERTEXCOUNT = 3 ; 
	const int PRIMITIVECOUNT = 3 ; 
	//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 ] ; 
	//angle of rotation 
	float g_angle = 0.0f; 
 
//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 ) ; 
 
	//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 ; 
 
	//set up vertex z 
	g_vertices [ 0 ].z = 0.0f; 
	g_vertices [ 1 ].z = 0.0f; 
	g_vertices [ 2 ].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 ) ; 
  
	//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 ( 0 , 0 , 0 ) , 0.0f, 0 ) ; 
 
	//set up vertices 
	//vertex 0 
	g_vertices [ 0 ].x = SCREENWIDTH / 2 + cos ( g_angle ) * RADIUS ; 
	g_vertices [ 0 ].y = SCREENHEIGHT / 2 + sin ( g_angle ) * RADIUS ; 
	//vertex 1 
	g_vertices [ 1 ].x = SCREENWIDTH / 2 + cos ( g_angle + 2.0 * PI / 3.0 ) * RADIUS ; 
	g_vertices [ 1 ].y = SCREENHEIGHT / 2 + sin ( g_angle + 2.0 * PI / 3.0 ) * RADIUS ; 
	//vertex 2 
	g_vertices [ 2 ].x = SCREENWIDTH / 2 + cos ( g_angle - 2.0 * PI / 3.0 ) * RADIUS ; 
	g_vertices [ 2 ].y = SCREENHEIGHT / 2 + sin ( g_angle - 2.0 * PI / 3.0 ) * RADIUS ; 
 
	//increase angle for next time 
	g_angle += ( 2.0 * PI / 360.0 ) ; 
 
	//begin the scene 
	g_pd3ddev->BeginScene ( ) ; 
 
	g_pd3ddev->DrawPrimitiveUP ( D3DPT_POINTLIST , PRIMITIVECOUNT ,g_vertices , sizeof ( CustomVertex ) ) ; 
 
	//end the scene 
	g_pd3ddev->EndScene ( ) ; 
 
	//present the scene 
	g_pd3ddev->Present ( NULL , NULL , NULL , NULL ) ; 
}