www.pudn.com > Fog_D3D.zip > d3d_obj.cpp


#include  
#include "d3d_obj.h" 
 
// Constructor -- Zero out our data 
CD3DObj::CD3DObj() 
{ 
	d3d_interface = NULL; 
	d3d_device = NULL; 
 
	// Set data to zero 
	fov = aspect_ratio = near_clip = far_clip = 0.0f; 
	result = 0; 
} 
 
// Initializes our D3D object -- Returns true on success, false otherwise 
bool CD3DObj::init(HWND hwnd) 
{ 
	// Create the D3D object, which is needed to create the D3DDevice. 
	d3d_interface = Direct3DCreate9(D3D_SDK_VERSION); 
 
		// Error Check 
		if(d3d_interface == NULL) 
			return false; 
 
	// This is the structure that defines how our 3D device (the thing that allows us 
	// to render) is going to be created. 
	D3DPRESENT_PARAMETERS params = {0}; // Start by zeroing out the parameters 
     
	// There's a bunch of parameters we could set up, however for this tutorial we 
	// only care about a few. 
	params.Windowed = TRUE; // This parameter says if the application runs in a window (TRUE) 
						   // or is full screen (FALSE) 
	params.SwapEffect = D3DSWAPEFFECT_DISCARD; // We're not enabling any double buffering, thus 
											  // we discard any swap effect					   
    params.BackBufferFormat = D3DFMT_UNKNOWN; // We specify unknown for our back buffer so that 
											 // it will choose whatever is the current display mode 
											// as the format for the back buffer  
	params.EnableAutoDepthStencil = true; // Allow a Z-buffer and stencil buffer 
	params.AutoDepthStencilFormat = D3DFMT_D16; // The format for the Z-buffer is 16-bit 
 
	 
	// Create the Direct3D device that lets us talk to the graphics card 
	result = d3d_interface->CreateDevice(D3DADAPTER_DEFAULT, 
										 D3DDEVTYPE_HAL, 
										 hwnd, 
										 D3DCREATE_HARDWARE_VERTEXPROCESSING, 
										 ¶ms, 
										 &d3d_device); 
 
	// It's possible we'll get an error because not all vid-cards can handle vertex processing 
	// So in the event we do get an error we'll try to make the device again.  We will 
	// only change D3DCREATE_HARDWARE_VERTEXPROCESSING to D3DCREATE_SOFTWARE_VERTEXPROCESSING 
	// which says, "Do the vertex processing in software"  
	if(result != D3D_OK) 
	{ 
		result = d3d_interface->CreateDevice(D3DADAPTER_DEFAULT, 
											 D3DDEVTYPE_HAL, 
											 hwnd, 
											 D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
											 ¶ms, 
											 &d3d_device); 
		if(result != D3D_OK) 
			return false; // Couldn't create a D3D 9.0 device 
	} 
		 
	// Turn off lighting 
	d3d_device->SetRenderState(D3DRS_LIGHTING, FALSE); 
	 
	// Turn on the zbuffer 
    d3d_device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); 
		 
	RECT rect; 
	GetClientRect(hwnd, &rect); // Get the client rect 
 
	// Set the Aspect Ratio 
	aspect_ratio = (float)rect.right / (float)rect.bottom; 
 
	// Initialize all other parameters to a default value 
	initToDefaultParams(); 
		return true; // We got loaded! 
} 
 
// Init all applicable parameters to a default value 
void CD3DObj::initToDefaultParams() 
{ 
	fov = kFOV; // Field of View 
	near_clip = kNearClip; // Near Clip Plane 
	far_clip = kFarClip; // Far Clip Plane 
} 
 
// Begins the scene 
void CD3DObj::begin() 
{ 
	// This begins our scene. 
	result = d3d_device->BeginScene(); 
	assert(result == D3D_OK); 
} 
 
// End the scene and draw it 
void CD3DObj::end() 
{ 
	// This ends the scene 
	result = d3d_device->EndScene(); 
	assert(result == D3D_OK); 
 
	// This draws the scene to the screen 
	result = d3d_device->Present(NULL, NULL, NULL, NULL); 
	assert(result == D3D_OK); 
} 
 
// Sets up the view of the scene based on the CCamera passed in 
void CD3DObj::setViewMatrix(const CCamera *camera) 
{ 
	D3DXMATRIXA16 matrix; 
 
	// Create "D3D Vector" versions of our camera's eye, look at position, and up vector 
	D3DXVECTOR3 eye(camera->getEye().x, camera->getEye().y, camera->getEye().z); 
	D3DXVECTOR3 lookAt(camera->getTarget().x, camera->getTarget().y, camera->getTarget().z); 
	D3DXVECTOR3 up(0, 1, 0); // The world's up vector 
	 
	// Using our camera's stuff (you know the eye, look at, and up vector) we  
	// create a matrix that represents our camera's view of the world.  Notice 
	// the "LH" on the end of the function.  That says, "Hey create this matrix for 
	// a left handed coordinate system". 
	D3DXMatrixLookAtLH(&matrix, &eye, &lookAt, &up); 
    d3d_device->SetTransform(D3DTS_VIEW, &matrix); // Set our view of the world 
} 
 
void CD3DObj::setProjMatrix() 
{ 
	D3DXMATRIXA16 matrix; 
 
	// Here we're creating our projection matrix.  This is sometimes  
	// referred to as a "perspective transform" because what it does 
	// is take our 3D geometry from our world and project it to 2D space, 
	// our screen.  A quick run down of the parameters: 
	// fov -- Field of View.  Essentially your peripheral vision 
	// aspect_ratio -- Width of viewing area / Height of viewing area 
	// near_clip -- Represents the plane that nothing can be rendered before 
	// far_clip -- Represents the plane that nothing can be rendered after 
    D3DXMatrixPerspectiveFovLH(&matrix, fov, aspect_ratio, near_clip, far_clip); 
    d3d_device->SetTransform(D3DTS_PROJECTION, &matrix); 
} 
 
// Sets "which" world matrix 
void CD3DObj::setWorldMatrix(int which, D3DXMATRIX *matrix) 
{ 
	assert(which >= 0 && which <= 255); 
	assert(matrix != NULL); 
	 
	d3d_device->SetTransform(D3DTS_WORLDMATRIX(which), matrix); 
} 
 
// Turns on or off fog 
bool CD3DObj::setFogStatus(bool onOrOff) 
{ 
	result = d3d_device->SetRenderState(D3DRS_FOGENABLE, (DWORD)onOrOff); 
		return (result == D3D_OK); 
} 
 
// Sets the fog color 
bool CD3DObj::setFogColor(int color) 
{ 
	result = d3d_device->SetRenderState(D3DRS_FOGCOLOR, (DWORD)color); 
		return (result == D3D_OK); 
} 
 
// Sets the mode, either D3DFOG_NONE, D3DFOG_EXP, D3DFOG_EXP2, or D3DFOG_LINEAR, 
// for pixel based fog 
bool CD3DObj::setPixelFogMode(D3DFOGMODE mode) 
{ 
	result = d3d_device->SetRenderState(D3DRS_FOGTABLEMODE, mode); 
		return (result == D3D_OK); 
} 
 
// Sets the mode, either D3DFOG_NONE, D3DFOG_EXP, D3DFOG_EXP2, or D3DFOG_LINEAR, 
// for vertex based fog 
bool CD3DObj::setVertexFogMode(D3DFOGMODE mode) 
{ 
	result = d3d_device->SetRenderState(D3DRS_FOGVERTEXMODE, mode); 
		return (result == D3D_OK); 
} 
 
// Sets the starting distance of the fog (applies only to D3DFOG_LINEAR fog)  
bool CD3DObj::setFogStart(float start) 
{ 
	result = d3d_device->SetRenderState(D3DRS_FOGSTART, (*(DWORD*)(&start))); 
		return (result == D3D_OK); 
} 
 
// Sets the ending distance of the fog (applies only to D3DFOG_LINEAR fog)  
bool CD3DObj::setFogEnd(float end) 
{ 
	result = d3d_device->SetRenderState(D3DRS_FOGEND, (*(DWORD*)(&end))); 
		return (result == D3D_OK); 
} 
 
// Sets the thickness of the fog (applies to D3DFOG_EXP and D3DFOG_EXP2 fog) 
bool CD3DObj::setFogDensity(float density) 
{ 
	result = d3d_device->SetRenderState(D3DRS_FOGDENSITY, *((DWORD*)(&density))); 
		return (result == D3D_OK); 
} 
 
// Renders the passed in vertex list using the passed in index list 
bool CD3DObj::render(SVertex *vList, int vertCount, WORD *iList, int indexCount) 
{ 
	IDirect3DVertexBuffer9 *vertexBuf = NULL; // Our interface for manipulating vertex buffers 
	IDirect3DIndexBuffer9 *indexBuf = NULL; // Our interface for manipulating index buffers 
	 
	// Get the size of our vertex list 
	int vertListSize = sizeof(SVertex) * vertCount; 
	assert(vertListSize > 0); 
 
	// Create the vertex buffer 
	result = d3d_device->CreateVertexBuffer(vertListSize, 0, SVertexType,  
											D3DPOOL_MANAGED, &vertexBuf, NULL); 
											 
	if(result != D3D_OK) 
		return false; 
 
	VOID *verts = NULL; // We'll use this as our pointer to the vertices 
 
	// Now we fill the vertex buffer. To do this, we need to Lock() the vertex buffer to 
	// gain access to the vertices 
	result = vertexBuf->Lock(0, 0, (void**)&verts, 0); 
	 
		// Error Check 
		if(result != D3D_OK) 
		{ 
			vertexBuf->Release(); 
				return false; 
		} 
	 
	// We have a pointer to our vertices, so we copy over our vertex list 
	// that was passed into the function 
	memcpy(verts, vList, vertListSize); 
	vertexBuf->Unlock(); // We're done with the vertex buffer so we unlock it 
	 
	// Calculate the size of the index list 
	int indexListSize = sizeof(WORD) * indexCount; 
	assert(indexListSize > 0); 
 
	// Create the index buffer 
	result = d3d_device->CreateIndexBuffer(indexListSize, 0, D3DFMT_INDEX16,  
										   D3DPOOL_MANAGED, &indexBuf, NULL); 
	 
	if(result != D3D_OK) 
	{ 
		vertexBuf->Release(); // Free memory to this point 
			return false; 
	} 
 
	VOID* indices = NULL; // We'll use this as the pointer to our indices  
	 
	// Before we can fill the index buffer we need to Lock() the index buffer to 
	// gain access to the indices 
	result = indexBuf->Lock(0, 0, (void**)&indices, 0); 
 
    if(result != D3D_OK) 
    { 
		// Free memory to this point 
		vertexBuf->Release(); 
		indexBuf->Release(); 
			return false; 
	} 
 
	// Copy over the index buffer list 
	memcpy(indices, iList, indexListSize); 
	indexBuf->Unlock(); // We've copied the data, unlock the buffer 
 
	// Tell our 3D device where the vertex data is coming from 
	result = d3d_device->SetStreamSource(0, vertexBuf, 0, sizeof(SVertex)); 
	assert(result == D3D_OK); 
 
	// Tell our 3D device where the index data is coming from 
	result = d3d_device->SetIndices(indexBuf); 
	assert(result == D3D_OK); 
 
	// Specify the vertex type 
	d3d_device->SetFVF(SVertexType); 
	 
	// Draw the geometry 
	result = d3d_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,vertCount,0,indexCount / 3); 
	assert(result == D3D_OK); 
 
	// Free up our buffers 
	vertexBuf->Release(); 
	indexBuf->Release(); 
		return true; 
} 
 
// Clears the viewport to a specified ARGB color and the Z-buffer to the far clip plane 
bool CD3DObj::clear(int color, float zDepth) 
{ 
	// This clears our viewport and z-depth 
	result = d3d_device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,  
							   color, zDepth, 0); 
	return (result == D3D_OK); 
} 
 
// Deconstructor -- Free up all the memory 
CD3DObj::~CD3DObj() 
{ 
	if(d3d_device != NULL) 
		d3d_device->Release(); 
 
    if(d3d_interface != NULL) 
		d3d_interface->Release(); 
 
	// Zero out our D3D interface and device  
	d3d_device = NULL; 
	d3d_interface = NULL; 
} 
 
CD3DObj theD3DObj; // Create our 3D Object 
CD3DObj *g3D = &theD3DObj; // Set the global pointer to our 3D Object