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