www.pudn.com > Direct3D_ZBuffer.zip > Direct3D.cpp


// 
// 
// 
 
#include  
#include  
#include  
 
LPDIRECT3D9 g_pD3D = NULL; 
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL; 
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL;	// Buffer to hold vertices 
 
struct CUSTOMVERTEX 
{ 
	float x, y, z;		// The transformed position for the vertex 
	DWORD color;		// The vertex colour 
}; 
 
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE) 
#define SafeRelease(pObject) if(pObject != NULL){pObject->Release(); pObject = NULL;} 
 
const TCHAR g_szClassName[] = _T("Direct3D"); 
const TCHAR g_szWindowName[] = _T("Direct3D"); 
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 
HRESULT InitD3D(HWND hWnd); 
HRESULT InitVertexBuffer(void); 
void Render(void); 
void Cleanup(void); 
void GameLoop(void); 
void SetupRotation(void); 
void SetupCamera(void); 
void SetupPerspective(void); 
 
//Application entry point 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) 
{ 
	WNDCLASSEX wc; 
	wc.cbClsExtra	= 0; 
	wc.cbSize		= sizeof(WNDCLASSEX); 
	wc.cbWndExtra	= 0; 
	wc.hbrBackground= NULL; 
	wc.hCursor		= NULL; 
	wc.hIcon		= NULL; 
	wc.hIconSm		= NULL; 
	wc.hInstance	= hInstance; 
	wc.lpfnWndProc	= WndProc; 
	wc.lpszClassName= g_szClassName; 
	wc.lpszMenuName	= NULL; 
	wc.style		= CS_CLASSDC; 
 
	// Register the window class 
	if(!RegisterClassEx(&wc)) 
	{ 
		MessageBox(NULL, _T("RegisterClass failed !"), _T("Warning"), MB_OK); 
	} 
 
	// Create the application's window 
	HWND hWnd = CreateWindow(g_szClassName, g_szWindowName, WS_OVERLAPPEDWINDOW, 50, 50, 500, 500, GetDesktopWindow(), NULL, hInstance, NULL); 
 
	//Initialize Direct3D 
	if(SUCCEEDED(InitD3D(hWnd))) 
	{ 
		// Show our window 
		ShowWindow(hWnd, nShowCmd); 
		UpdateWindow(hWnd); 
 
        // Initialize Vertex Buffer 
        if(SUCCEEDED(InitVertexBuffer())) 
        { 
            // Start game running: Enter the game loop 
            GameLoop(); 
        } 
	} 
 
	Cleanup(); 
 
	UnregisterClass(g_szClassName, hInstance); 
 
	return 0; 
} 
 
//The windows message handler 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	switch(message) 
	{ 
	case WM_DESTROY: 
		{ 
			PostQuitMessage(0); 
			return 0; 
		} 
		break; 
 
	case WM_KEYDOWN: 
		{ 
			switch(wParam) 
			{ 
			case VK_ESCAPE: 
				{ 
					//User has pressed the escape key, so quit 
					DestroyWindow(hWnd); 
					return 0; 
				} 
				break; 
			} 
		} 
		break; 
	} 
 
	return DefWindowProc(hWnd, message, wParam, lParam); 
} 
 
HRESULT InitD3D(HWND hWnd) 
{ 
    // First of all, create the main D3D object. If it is created successfully we 
    // should get a pointer to an IDirect3D8 interface. 
	g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); 
	if(g_pD3D == NULL) 
	{ 
		return E_FAIL; 
	} 
 
	// Get the current display mode 
	D3DDISPLAYMODE d3ddm; 
	if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) 
	{ 
		return E_FAIL; 
	} 
 
    // Create a structure to hold the settings for our device 
	D3DPRESENT_PARAMETERS d3dpp; 
	memset(&d3dpp, 0, sizeof(D3DPRESENT_PARAMETERS)); 
 
    // Fill the structure.  
    // We want our program to be windowed, and set the back buffer to a format 
    // that matches our current display mode 
	d3dpp.Windowed = TRUE; 
	d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; 
	d3dpp.BackBufferFormat = d3ddm.Format; 
 
	// Create a Direct3D device 
	if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice))) 
	{ 
		return E_FAIL; 
	} 
 
    // Turn on back face culling. 
    // This is because we want to hide the back of our polygons 
	g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); 
 
	// Turn off lighting because we are specifying that our vertices have colour 
	g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); 
	 
 
	return S_OK; 
} 
 
HRESULT InitVertexBuffer() 
{ 
	// Store each point of the triangle together with it's colour 
	CUSTOMVERTEX cvVertices[] = { 
									// Top face 
									{-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0,0,255)},	// Blue 
									{-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255,0,0)},	// Red 
									{5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(255,0,0)},	// Red 
									{5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(0,0,255)},		// Green 
 
									// Face 1 
									{-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255,0,0)},	// Red 
									{-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0,0,255)},	// Blue 
									{5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(0,255,0)},	// Green 
									{5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(255,0,0)},	// Red 
 
									// Face 2 
									{5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0,0,255)},	// Blue 
									{5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(0,0,255)},		// Green 
 
									// Face 3 
									{-5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0,0,255)},	// Green 
									{-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255,0,0)},	// Red 
 
									// Face 4 
									{-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255,0,0)},	// Red 
									{-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0,0,255)},	// Blue 
 
									// Bottom face 
									{5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(0,255,0)},	// Green 
									{5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0,0,255)},	// Blue 
									{-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255,0,0)},	// Red 
									{-5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0,0,255)},	// Green 
								}; 
 
	// Create the vertex buffer from our device 
	if(FAILED(g_pD3DDevice->CreateVertexBuffer(18 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL))) 
	{ 
		return E_FAIL; 
	} 
 
	// Get a pointer to the vertex buffer vertices and lock the vertex buffer 
	void *pVertices; 
	if(FAILED(g_pVertexBuffer->Lock(0, sizeof(cvVertices), (void **)&pVertices, 0))) 
	{ 
		return E_FAIL; 
	} 
 
	// Copy our stored vertices values into the vertex buffer 
	memcpy(pVertices, cvVertices, sizeof(cvVertices)); 
 
	// Unlock the vertex buffer 
	g_pVertexBuffer->Unlock(); 
 
	return S_OK; 
} 
 
void SetupRotation() 
{ 
	// Here we will rotate our world around the x, y and z axis. 
	D3DXMATRIX matWorld, matWorldX, matWorldY, matWorldZ; 
 
	// Create the transformation matrices 
	D3DXMatrixRotationX(&matWorldX, timeGetTime()/400.0f); 
	D3DXMatrixRotationY(&matWorldY, timeGetTime()/400.0f); 
	D3DXMatrixRotationZ(&matWorldZ, timeGetTime()/400.0f); 
 
	// Combine the transformations by multiplying them together 
	D3DXMatrixMultiply(&matWorld, &matWorldX, &matWorldY); 
	D3DXMatrixMultiply(&matWorld, &matWorld, &matWorldZ); 
 
	// Apply the tansformation 
	g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld); 
} 
 
void SetupCamera() 
{ 
	// Here we will setup the camera. 
    // The camera has three settings: "Camera Position", "Look at Position" and "Up Direction" 
    // We have set the following: 
    // Camera Position: (0, 0, -30) 
    // Look at Position: (0, 0, 0) 
    // Up direction: Y-Axis. 
	D3DXMATRIX matView; 
	D3DXVECTOR3 eye(0.0f, 0.0f, -30.0f); 
	D3DXVECTOR3 lookat(0.0f, 0.0f, 0.0f); 
	D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); 
 
	D3DXMatrixLookAtLH(&matView, &eye, &lookat, &up); 
	g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView); 
} 
 
void SetupPerspective() 
{ 
    // Here we specify the field of view, aspect ration and near and 
    // far clipping planes. 
	D3DXMATRIX matProj; 
	D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 500.0f); 
	g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj); 
} 
 
void Render() 
{ 
	if(g_pD3DDevice == NULL) 
	{ 
		return; 
	} 
 
	// Clear the back buffer to a specified color 
	g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); 
 
	// Begin the scene 
	g_pD3DDevice->BeginScene(); 
 
	// Setup the rotation, camera, and perspective matrices 
	SetupRotation(); 
	SetupCamera(); 
	SetupPerspective(); 
 
	// Rendering our object 
	g_pD3DDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(CUSTOMVERTEX)); 
	//g_pD3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX); 
	g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX); 
	g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); 
	g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 8); 
	g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 14, 2); 
 
	// End the scene 
	g_pD3DDevice->EndScene(); 
 
    // Filp the back and front buffers so that whatever has been rendered on the 
    // back buffer will now be visible on screen (front buffer) 
	g_pD3DDevice->Present(NULL, NULL, NULL, NULL); 
} 
 
void Cleanup() 
{ 
	if(g_pVertexBuffer != NULL) 
	{ 
		g_pVertexBuffer->Release(); 
		g_pVertexBuffer = NULL; 
	} 
 
	if(g_pD3DDevice != NULL) 
	{ 
		g_pD3DDevice->Release(); 
		g_pD3DDevice = NULL; 
	} 
 
	if(g_pD3D != NULL) 
	{ 
		g_pD3D->Release(); 
		g_pD3D = NULL; 
	} 
} 
 
void GameLoop() 
{ 
	// Enter the game loop 
	MSG msg; 
	BOOL fMessage; 
 
	PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); 
 
	while(msg.message != WM_QUIT) 
	{ 
		fMessage = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); 
		if(fMessage) 
		{ 
			// Process message 
			TranslateMessage(&msg); 
			DispatchMessage(&msg); 
		} 
		else 
		{ 
			// No message to process, so render the current scene 
			Render(); 
		} 
	} 
}