Friday, March 13, 2009

Final

In our final we are suppose to make a game engine work. I was responsible for making the sound work. I re wrote the code for the sound two times. Asad a classmate of mine figured out why I couldn't make it run. With the code fixed we managed to get sound into the game.

Obj model


This is where we learned how to import models into the project. The code to do this is below.
Loader for the object:

/*
Demo Name: OBJ Model Loading Demo
Author: Allen Sherrod
Chapter: Ch 12
*/

#ifndef _OBJ_LOADER_H_
#define _OBJ_LOADER_H_
#include
#include
#include
#include"Token.h"
// Pretty straight forward don't you think?
struct stObjModel
{
float *vertices;
float *normals;
float *texCoords;
int numFaces;
};
stObjModel *LoadOBJModel(char *fileName);
void FreeModel(stObjModel *model);
#endif
Code that does the loading unto the screen:

/*
Demo Name: OBJ Model Loading Demo
Author: Allen Sherrod
Chapter: Ch 10
*/

#include"objLoader.h"

stObjModel *LoadOBJModel(char *fileName)
{
FILE *file;
char *data = NULL;
CToken lexer, tempLex;
char tempLine[512];
char token[512];
// Open file for input.
file = fopen(fileName, "r");
if(!file) return NULL;
// Get the length of the file.
fseek(file, 0, SEEK_END);
int length = ftell(file);
fseek(file, 0, SEEK_SET);
// Read in all data from the file.
data = new char[(length + 1) * sizeof(char)];
if(!data) return NULL;
fread(data, length, 1, file);
data[length] = '\0';
// Close the file when we are done.
fclose(file);
// Set our file to our lexer.
lexer.SetTokenStream(data);
// No longer need.
delete[] data; data = NULL;
bool validFile = false;
// Look for the word Wavefront somewhere in the file to
// determine if this .obj is compatiable since so modelers export
// to slightly different formats.
while(lexer.GetNextToken(token))
{
if(strcmp(token, "Wavefront") == 0)
{
validFile = true;
break;
}
}
if(!validFile) return NULL;
// Reset for next pass.
lexer.Reset();
// Used to get the total number of each declared in a file.
// Since faces uses indices these number could be different.
int totalVertices = 0, totalNormals = 0,
totalTexC = 0, totalFaces = 0;
// Get the first (or next) line.
while(lexer.MoveToNextLine(tempLine))
{
// Set line to the temp lexer.
tempLex.SetTokenStream(tempLine);
// Read the new line character.
lexer.GetNextToken(NULL);
// If something was set to the temp lex then we keep going.
if(!tempLex.GetNextToken(token)) continue;
// If the first token of the line is a v, vn, vt, or f
// increment the respective counter.
if(strcmp(token, "v") == 0) totalVertices++;
else if(strcmp(token, "vn") == 0) totalNormals++;
else if(strcmp(token, "vt") == 0) totalTexC++;
else if(strcmp(token, "f") == 0) totalFaces++;
token[0] = '\0';
}
// Allocate temp space to hold the data. Face are by 9 since there are
// 3 vertices each with 3 values (v index/vt index/vn index).
float *verts = new float[totalVertices * 3];
float *norms = new float[totalNormals * 3];
float *texC = new float[totalTexC * 2];
int *faces = new int[totalFaces * 9];
int vIndex = 0, nIndex = 0, tIndex = 0, fIndex = 0, index = 0;
// Move to the beginning of the file.
lexer.Reset();
// Do it all again but this time we get the data.
while(lexer.MoveToNextLine(tempLine))
{
// Set to temp lex, read past newline, get token.
tempLex.SetTokenStream(tempLine);
lexer.GetNextToken(NULL);
if(!tempLex.GetNextToken(token)) continue;
// If v then we get the vertex x, y, z.
if(strcmp(token, "v") == 0)
{
// Get the x and save it.
tempLex.GetNextToken(token);
verts[vIndex] = (float)atof(token);
vIndex++;
// Get the y and save it.
tempLex.GetNextToken(token);
verts[vIndex] = (float)atof(token);
vIndex++;
// Get the z and save it.
tempLex.GetNextToken(token);
verts[vIndex] = (float)atof(token);
vIndex++;
}
// Else If vn then we get the normal x, y, z.
else if(strcmp(token, "vn") == 0)
{
// Get the x and save it.
tempLex.GetNextToken(token);
norms[nIndex] = (float)atof(token);
nIndex++;
// Get the y and save it.
tempLex.GetNextToken(token);
norms[nIndex] = (float)atof(token);
nIndex++;
// Get the z and save it.
tempLex.GetNextToken(token);
norms[nIndex] = (float)atof(token);
nIndex++;
}
// Else If vt then we get the tex coord u, v.
else if(strcmp(token, "vt") == 0)
{
// Get the u and save it.
tempLex.GetNextToken(token);
texC[tIndex] = (float)atof(token);
tIndex++;
// Get the v and save it.
tempLex.GetNextToken(token);
texC[tIndex] = (float)atof(token);
tIndex++;
}
// Else If f then get each vertex 3 indices set.
else if(strcmp(token, "f") == 0)
{
// Load for each vertex (3 in a triangle).
for(int i = 0; i < 3; i++)
{
// Get first set. Get the length of it.
tempLex.GetNextToken(token);
int len = strlen(token);
// Since there are no spaces between a set (1/1/1)
// we can't simply read tokens so we must loop
// through and take out each value before the / sign.
for(int s = 0; s < len + 1; s++)
{
char buff[64];
// If this is not a / or if not at the end.
if(token[s] != '/' && s < len)
{
buff[index] = token[s];
index++;
}
else
{
// Else end the string, convert it, save it.
buff[index] = '\0';
faces[fIndex] = (int)atoi(buff);
fIndex++;
index = 0;
}
}
}
}
token[0] = '\0';
}
// No longer need.
lexer.Shutdown();
// Create the model object by allocating.
stObjModel *model = new stObjModel;
if(!model) return NULL;
memset(model, 0, sizeof(stObjModel));
// Save face count.
model->numFaces = totalFaces;
// Reset temp counters.
vIndex = 0, nIndex = 0, tIndex = 0, fIndex = 0, index = 0;
// Allocate data for each part of the model.
model->vertices = new float[totalFaces * 3 * 3];
if(totalNormals) model->normals = new float[totalFaces * 3 * 3];
if(totalTexC) model->texCoords = new float[totalFaces * 3 * 2];
// Loop through and fill in our model.
for(int f = 0; f < totalFaces * 9; f+=3)
{
// Get vertex. We subtract by 1 since we need our indices to be
// in the range of 0 to max - 1 not 1 to max. We multiply by 3
// since there are 3 componets (x, y, z) in a vertex.
model->vertices[vIndex + 0] = verts[(faces[f + 0] - 1) * 3 + 0];
model->vertices[vIndex + 1] = verts[(faces[f + 0] - 1) * 3 + 1];
model->vertices[vIndex + 2] = verts[(faces[f + 0] - 1) * 3 + 2];
vIndex += 3;
// We do the same with the texture coordinate data. Since tex coord
// data in the second thing we app 1 to f (v/vt/vn).
if(model->texCoords)
{
model->texCoords[tIndex + 0] = texC[(faces[f + 1] - 1) * 2 + 0];
model->texCoords[tIndex + 1] = texC[(faces[f + 1] - 1) * 2 + 1];
tIndex += 2;
}
// We do the same with the normal coordinate data.
if(model->normals)
{
model->normals[nIndex + 0] = norms[(faces[f + 2] - 1) * 3 + 0];
model->normals[nIndex + 1] = norms[(faces[f + 2] - 1) * 3 + 1];
model->normals[nIndex + 2] = norms[(faces[f + 2] - 1) * 3 + 2];
nIndex += 3;
}
}
// Delete temp data.
delete[] verts;
delete[] norms;
delete[] texC;
delete[] faces;
return model;
}

void FreeModel(stObjModel *model)
{
if(!model) return;
// Release all resources.
if(model->vertices) delete[] model->vertices;
model->vertices = NULL;
if(model->normals) delete[] model->normals;
model->normals = NULL;
if(model->texCoords) delete[] model->texCoords;
model->texCoords = NULL;
delete model;
model = NULL;
}

Collision




This was also fun to work on. It would change from truth to false if that line hit the white area. We used to change the picture of it to look like something else. The code for this is below.

/*
Demo Name: Plane/Line Collisions
Author: Allen Sherrod
Chapter: Ch 9
*/

#include
#include
#include
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#define WINDOW_CLASS "UGPDX"
#define WINDOW_NAME "Plane/Line Collision Detection"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
// Function Prototypes...
bool InitializeD3D(HWND hWnd, bool fullscreen);
bool InitializeObjects();
void RenderScene();
void Shutdown();

// Direct3D object and device.
LPDIRECT3D9 g_D3D = NULL;
LPDIRECT3DDEVICE9 g_D3DDevice = NULL;
// Matrices.
D3DXMATRIX g_projection;
D3DXMATRIX g_worldMatrix;
D3DXMATRIX g_ViewMatrix;

// DirectX font object.
LPD3DXFONT g_Font = NULL;

// Vertex buffers to hold the geometry.
LPDIRECT3DVERTEXBUFFER9 g_squareBuffer = NULL;
LPDIRECT3DVERTEXBUFFER9 g_lineBuffer = NULL;
// A structure for our custom vertex type
struct stD3DVertex
{
float x, y, z;
unsigned long color;
};
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_VERTEX (D3DFVF_XYZ D3DFVF_DIFFUSE)

#define UGP_FRONT 0
#define UGP_BACK 1
#define UGP_ON_PLANE 2
class CPlane
{
public:
CPlane() { a = b = c = d = 0; }
void NormalizeVec(stD3DVertex &v)
{
// Normalize normal.
float lenght = (float)sqrt((v.x * v.x +
v.y * v.y +
v.z * v.z));
if(lenght == 0.0f) lenght = 1.0f;
v.x /= lenght;
v.y /= lenght;
v.z /= lenght;
}
void CreatePlaneFromTri(stD3DVertex &v1, stD3DVertex &v2,
stD3DVertex &v3)
{
// Get triangle normal.
stD3DVertex normal, e1, e2;
// Get edge 1.
e1.x = v3.x - v1.x;
e1.y = v3.y - v1.y;
e1.z = v3.z - v1.z;
NormalizeVec(e1);
// Get edge 2.
e2.x = v2.x - v1.x;
e2.y = v2.y - v1.y;
e2.z = v2.z - v1.z;
NormalizeVec(e2);
// Get cross product of the edges.
normal.x = ((e1.y * e2.z) - (e1.z * e2.y));
normal.y = ((e1.z * e2.x) - (e1.x * e2.z));
normal.z = ((e1.x * e2.y) - (e1.y * e2.x));
NormalizeVec(normal);
// Save normal and calculate d.
a = normal.x;
b = normal.y;
c = normal.z;
d = - (a * v1.x + b * v1.y + c * v1.z);
}
int ClassifyPoint(float x, float y, float z)
{
float distance = a * x + b * y + c * z + d;
if(distance > 0.001) return UGP_FRONT;
if(distance < -0.001) return UGP_BACK;
return UGP_ON_PLANE;
}
float a, b, c, d;
};
CPlane g_plane;

// Start and end Z positions and amounts to move each point.
float g_lineStartZPos = -1;
float g_lineEndZPos = 1;
float g_lineZMoveAmt = 0;
float g_lineZDir = -0.02f;
// True if collision occurred, false if not.
bool g_collision = false;

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_KEYUP:
if(wParam == VK_ESCAPE) PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst, LPSTR cmdLine, int show)
{
// Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
WINDOW_CLASS, NULL };
RegisterClassEx(&wc);
// Create the application's window
HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW,
100, 100, WINDOW_WIDTH, WINDOW_HEIGHT,
GetDesktopWindow(), NULL, wc.hInstance, NULL);
// Initialize Direct3D
if(InitializeD3D(hWnd, false))
{
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
// Enter the message loop
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
RenderScene();
}
}
// Release any and all resources.
Shutdown();
// Unregister our window.
UnregisterClass(WINDOW_CLASS, wc.hInstance);
return 0;
}

bool InitializeD3D(HWND hWnd, bool fullscreen)
{
D3DDISPLAYMODE displayMode;
// Create the D3D object.
g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
if(g_D3D == NULL) return false;
// Get the desktop display mode.
if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
return false;
// Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
if(fullscreen)
{
d3dpp.Windowed = FALSE;
d3dpp.BackBufferWidth = WINDOW_WIDTH;
d3dpp.BackBufferHeight = WINDOW_HEIGHT;
}
else
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = displayMode.Format;
d3dpp.BackBufferCount = 1;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

// Create the D3DDevice
if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING D3DCREATE_PUREDEVICE,
&d3dpp, &g_D3DDevice))) return false;
// Initialize any objects we will be displaying.
if(!InitializeObjects()) return false;
return true;
}

bool InitializeObjects()
{
// Create the font.
if(FAILED(D3DXCreateFont(g_D3DDevice, 18, 0, 0, 1, 0,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH FF_DONTCARE, "Arial",
&g_Font))) return false;

// Create our objects.
stD3DVertex squareData[] =
{
{-0.3f, -0.4f, 0, D3DCOLOR_XRGB(255,255,255)},
{0.3f, -0.4f, 0, D3DCOLOR_XRGB(255,255,255)},
{0.3f, 0.4f, 0, D3DCOLOR_XRGB(255,255,255)},
{0.3f, 0.4f, 0, D3DCOLOR_XRGB(255,255,255)},
{-0.3f, 0.4f, 0, D3DCOLOR_XRGB(255,255,255)},
{-0.3f, -0.4f, 0, D3DCOLOR_XRGB(255,255,255)}
};
stD3DVertex lineData[] =
{
{0, 0, g_lineStartZPos, D3DCOLOR_XRGB(0,255,0)},
{0, 0, g_lineEndZPos, D3DCOLOR_XRGB(0,255,0)},
};

// Get plane from the object. Only need one triangle since
// it is a even square (plane will be the same for both tris).
g_plane.CreatePlaneFromTri(squareData[0], squareData[1], squareData[2]);

// Create square vertex buffer.
if(FAILED(g_D3DDevice->CreateVertexBuffer(sizeof(squareData), 0,
D3DFVF_VERTEX, D3DPOOL_DEFAULT,
&g_squareBuffer, NULL))) return false;
void *ptr;
// Fill the vertex buffer.
if(FAILED(g_squareBuffer->Lock(0, sizeof(squareData),
(void**)&ptr, 0))) return false;
memcpy(ptr, squareData, sizeof(squareData));
g_squareBuffer->Unlock();

// Create line vertex buffer.
if(FAILED(g_D3DDevice->CreateVertexBuffer(sizeof(lineData), 0,
D3DFVF_VERTEX, D3DPOOL_DEFAULT,
&g_lineBuffer, NULL))) return false;
// Fill the vertex buffer.
if(FAILED(g_lineBuffer->Lock(0, sizeof(lineData),
(void**)&ptr, 0))) return false;
memcpy(ptr, lineData, sizeof(lineData));
g_lineBuffer->Unlock();

// Set default rendering states.
g_D3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_D3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_D3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);

// Set the projection matrix.
D3DXMatrixPerspectiveFovLH(&g_projection, D3DX_PI / 4,
WINDOW_WIDTH/WINDOW_HEIGHT, 0.1f, 1000.0f);
g_D3DDevice->SetTransform(D3DTS_PROJECTION, &g_projection);

// Define camera information.
D3DXVECTOR3 cameraPos(5.0f, 0.0f, -5.0f);
D3DXVECTOR3 lookAtPos(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 upDir(0.0f, 1.0f, 0.0f);
// Build view matrix.
D3DXMatrixLookAtLH(&g_ViewMatrix, &cameraPos,
&lookAtPos, &upDir);
return true;
}

void RenderScene()
{
// RECT used to position the font and a string.
RECT fontPos = {0, 125, WINDOW_WIDTH, WINDOW_HEIGHT};
char str[64] = {0};

// Move line. If position limit is hit, switch directions.
g_lineZMoveAmt += g_lineZDir;
if(g_lineZMoveAmt > 2) g_lineZDir *= -1;
if(g_lineZMoveAmt < -2) g_lineZDir *= -1;

// Test which side of the plane both points are.
int result1 = g_plane.ClassifyPoint(0, 0, g_lineStartZPos + g_lineZMoveAmt);
int result2 = g_plane.ClassifyPoint(0, 0, g_lineEndZPos + g_lineZMoveAmt);
// Test for collision. True if points are on different ends.
g_collision = (result1 != result2);
// Create string.
if(g_collision) sprintf(str, "Collision: TRUE");
else sprintf(str, "Collision: FALSE");

// Clear the backbuffer.
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
// Begin the scene. Start rendering.
g_D3DDevice->BeginScene();
// Display if collision occurred.
g_Font->DrawText(NULL, str, -1, &fontPos, DT_CENTER,
D3DCOLOR_XRGB(255,255,255));

// Apply the view (camera).
g_D3DDevice->SetTransform(D3DTS_VIEW, &g_ViewMatrix);

// Draw line.
g_D3DDevice->SetStreamSource(0, g_lineBuffer,
0, sizeof(stD3DVertex));
D3DXMatrixTranslation(&g_worldMatrix, 0, 0, g_lineZMoveAmt);
g_D3DDevice->SetTransform(D3DTS_WORLD, &g_worldMatrix);
g_D3DDevice->SetFVF(D3DFVF_VERTEX);
g_D3DDevice->DrawPrimitive(D3DPT_LINELIST, 0, 1);

// Draw square.
g_D3DDevice->SetStreamSource(0, g_squareBuffer,
0, sizeof(stD3DVertex));
D3DXMatrixIdentity(&g_worldMatrix);
g_D3DDevice->SetTransform(D3DTS_WORLD, &g_worldMatrix);
g_D3DDevice->SetFVF(D3DFVF_VERTEX);
g_D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

// End the scene. Stop rendering.
g_D3DDevice->EndScene();
// Display the scene.
g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}

void Shutdown()
{
if(g_D3DDevice != NULL) g_D3DDevice->Release();
g_D3DDevice = NULL;
if(g_D3D != NULL) g_D3D->Release();
g_D3D = NULL;
if(g_squareBuffer != NULL) g_squareBuffer->Release();
g_squareBuffer = NULL;
if(g_lineBuffer != NULL) g_lineBuffer->Release();
g_lineBuffer = NULL;
if(g_Font != NULL) g_Font->Release();
g_Font = NULL;
}

Fog


This code alowed us to use fog within a window. We learned alot from this chapter as it was very interactive. The code for it is below.

/*
Demo Name: Fog
Author: Allen Sherrod
Chapter: Ch 6
*/

#include
#include
#define WINDOW_CLASS "UGPDX"
#define WINDOW_NAME "Fog"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
// Function Prototypes...
bool InitializeD3D(HWND hWnd, bool fullscreen);
bool InitializeObjects();
void RenderScene();
void Shutdown();

// Direct3D object and device.
LPDIRECT3D9 g_D3D = NULL;
LPDIRECT3DDEVICE9 g_D3DDevice = NULL;
// Matrices.
D3DXMATRIX g_projection;
D3DXMATRIX g_ViewMatrix;
// Vertex buffer to hold the geometry.
LPDIRECT3DVERTEXBUFFER9 g_VertexBuffer = NULL;
// Holds a texture image.
LPDIRECT3DTEXTURE9 g_Texture = NULL;
// A structure for our custom vertex type
struct stD3DVertex
{
float x, y, z;
unsigned long color;
float tu, tv;
};
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_VERTEX (D3DFVF_XYZ D3DFVF_DIFFUSE D3DFVF_TEX1)

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_KEYUP:
if(wParam == VK_ESCAPE) PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst, LPSTR cmdLine, int show)
{
// Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
WINDOW_CLASS, NULL };
RegisterClassEx(&wc);
// Create the application's window
HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW,
100, 100, WINDOW_WIDTH, WINDOW_HEIGHT,
GetDesktopWindow(), NULL, wc.hInstance, NULL);
// Initialize Direct3D
if(InitializeD3D(hWnd, false))
{
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
// Enter the message loop
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
RenderScene();
}
}
// Release any and all resources.
Shutdown();
// Unregister our window.
UnregisterClass(WINDOW_CLASS, wc.hInstance);
return 0;
}

bool InitializeD3D(HWND hWnd, bool fullscreen)
{
D3DDISPLAYMODE displayMode;
// Create the D3D object.
g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
if(g_D3D == NULL) return false;
// Get the desktop display mode.
if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
return false;
// Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
if(fullscreen)
{
d3dpp.Windowed = FALSE;
d3dpp.BackBufferWidth = WINDOW_WIDTH;
d3dpp.BackBufferHeight = WINDOW_HEIGHT;
}
else
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = displayMode.Format;
// Create the D3DDevice
if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_D3DDevice)))
{
return false;
}
// Initialize any objects we will be displaying.
if(!InitializeObjects()) return false;
return true;
}

bool InitializeObjects()
{
D3DCAPS9 caps;
g_D3DDevice->GetDeviceCaps(&caps);
// Start and end distance of the fog.
float start = 2, end = 8;
// Set fog properties.
g_D3DDevice->SetRenderState(D3DRS_FOGENABLE, true);
g_D3DDevice->SetRenderState(D3DRS_FOGCOLOR,
D3DCOLOR_XRGB(128, 128, 128));
g_D3DDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
g_D3DDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD*)(&start));
g_D3DDevice->SetRenderState(D3DRS_FOGEND, *(DWORD*)(&end));
// Pixel Fog
//g_D3DDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
// Can only use if hardware supports it.
if(caps.RasterCaps & D3DPRASTERCAPS_FOGRANGE)
g_D3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, true);

// Object
stD3DVertex objData[] =
{
{-2.5f, -0.5f, -6.0f, D3DCOLOR_XRGB(255,255,255), 0.0f, 1.0f},
{2.5f, -0.5f, -6.0f, D3DCOLOR_XRGB(255,255,255), 1.0f, 1.0f},
{2.5f, -0.5f, 6.0f, D3DCOLOR_XRGB(255,255,255), 1.0f, 0.0f},
{2.5f, -0.5f, 6.0f, D3DCOLOR_XRGB(255,255,255), 1.0f, 0.0f},
{-2.5f, -0.5f, 6.0f, D3DCOLOR_XRGB(255,255,255), 0.0f, 0.0f},
{-2.5f, -0.5f, -6.0f, D3DCOLOR_XRGB(255,255,255), 0.0f, 1.0f}
};
// Create the vertex buffer.
if(FAILED(g_D3DDevice->CreateVertexBuffer(sizeof(objData), 0,
D3DFVF_VERTEX, D3DPOOL_DEFAULT,
&g_VertexBuffer, NULL))) return false;
// Fill the vertex buffer.
void *ptr;
if(FAILED(g_VertexBuffer->Lock(0, sizeof(objData),
(void**)&ptr, 0))) return false;
memcpy(ptr, objData, sizeof(objData));
g_VertexBuffer->Unlock();

// Load the texture image from file.
if(D3DXCreateTextureFromFile(g_D3DDevice, "ground.bmp",
&g_Texture) != D3D_OK) return false;

// Set default rendering states.
g_D3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_D3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

// Set the projection matrix.
D3DXMatrixPerspectiveFovLH(&g_projection, 45.0f,
WINDOW_WIDTH/WINDOW_HEIGHT, 0.1f, 1000.0f);
g_D3DDevice->SetTransform(D3DTS_PROJECTION, &g_projection);

// Define camera information.
D3DXVECTOR3 cameraPos(0.0f, 0.0f, -3.0f);
D3DXVECTOR3 lookAtPos(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 upDir(0.0f, 1.0f, 0.0f);
// Build view matrix.
D3DXMatrixLookAtLH(&g_ViewMatrix, &cameraPos,
&lookAtPos, &upDir);
return true;
}

void RenderScene()
{
// Clear the backbuffer.
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(128,128,128), 1.0f, 0);
// Begin the scene. Start rendering.
g_D3DDevice->BeginScene();
// Apply the view (camera).
g_D3DDevice->SetTransform(D3DTS_VIEW, &g_ViewMatrix);
// Draw square.
g_D3DDevice->SetTexture(0, g_Texture);
g_D3DDevice->SetStreamSource(0, g_VertexBuffer,
0, sizeof(stD3DVertex));
g_D3DDevice->SetFVF(D3DFVF_VERTEX);
g_D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
// End the scene. Stop rendering.
g_D3DDevice->EndScene();
// Display the scene.
g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}

void Shutdown()
{
if(g_D3DDevice != NULL) g_D3DDevice->Release();
g_D3DDevice = NULL;
if(g_D3D != NULL) g_D3D->Release();
g_D3D = NULL;
if(g_VertexBuffer != NULL) g_VertexBuffer->Release();
g_VertexBuffer = NULL;
if(g_Texture != NULL) g_Texture->Release();
g_Texture = NULL;
}

Thursday, March 12, 2009

Chapter 5 GUI


Here we learned how to Make text appear on screen. It was a fun program as we replaced the text with something else. The code we used to make this screen on the left is below.

/*
Demo Name: Direct3D Text
Author: Allen Sherrod
Chapter: Ch 5
*/

#include
#include
#define WINDOW_CLASS "UGPDX"
#define WINDOW_NAME "D3D Text Demo"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
// Function Prototypes...
bool InitializeD3D(HWND hWnd, bool fullscreen);
bool InitializeObjects();
void RenderScene();
void Shutdown();

// Direct3D object and device.
LPDIRECT3D9 g_D3D = NULL;
LPDIRECT3DDEVICE9 g_D3DDevice = NULL;
// DirectX font object.
LPD3DXFONT g_Font = NULL;
// RECT used to position the font.
RECT g_FontPosition = {0, 0, 0, 0};

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_KEYUP:
if(wp == VK_ESCAPE) PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msg, wp, lp);
}

int WINAPI WinMain(HINSTANCE h, HINSTANCE ph, LPSTR cmd, int show)
{
// Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc,
0L, 0L, GetModuleHandle(NULL), NULL, NULL,
NULL, NULL, WINDOW_CLASS, NULL };
RegisterClassEx(&wc);
// Create the application's window
HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME,
WS_OVERLAPPEDWINDOW, 100, 100, WINDOW_WIDTH,
WINDOW_HEIGHT, GetDesktopWindow(), NULL,
wc.hInstance, NULL);
// Initialize Direct3D
if(InitializeD3D(hWnd, false))
{
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
// Enter the message loop
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
RenderScene();
}
}
// Release any and all resources.
Shutdown();
// Unregister our window.
UnregisterClass(WINDOW_CLASS, wc.hInstance);
return 0;
}

bool InitializeD3D(HWND hWnd, bool fullscreen)
{
D3DDISPLAYMODE displayMode;
// Create the D3D object.
g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
if(g_D3D == NULL) return false;
// Get the desktop display mode.
if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,
&displayMode))) return false;
// Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
if(fullscreen)
{
d3dpp.Windowed = FALSE;
d3dpp.BackBufferWidth = WINDOW_WIDTH;
d3dpp.BackBufferHeight = WINDOW_HEIGHT;
}
else
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = displayMode.Format;
// Create the D3DDevice
if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING
D3DCREATE_PUREDEVICE, &d3dpp, &g_D3DDevice)))
{
return false;
}
// Initialize any objects we will be displaying.
if(!InitializeObjects()) return false;
return true;
}

bool InitializeObjects()
{
// Create the font.
if(FAILED(D3DXCreateFont(g_D3DDevice, 18, 0, 0, 1, 0,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH FF_DONTCARE, "Arial",
&g_Font))) return false;
// Here we are setting the position of the font.
g_FontPosition.top = 0;
g_FontPosition.left = 0;
g_FontPosition.right = WINDOW_WIDTH;
g_FontPosition.bottom = WINDOW_HEIGHT;
return true;
}

void RenderScene()
{
// Clear the backbuffer.
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
// Begin the scene. Start rendering.
g_D3DDevice->BeginScene();
// Set next position and draw text.
g_FontPosition.top = 150;
g_Font->DrawText(NULL, "Ultimate Game Programming!",
-1, &g_FontPosition, DT_CENTER,
D3DCOLOR_XRGB(255,255,255));
// Set next position and draw text.
g_FontPosition.top = 180;
g_Font->DrawText(NULL, "Demo on displaying text.",
-1, &g_FontPosition, DT_CENTER,
D3DCOLOR_XRGB(255,255,255));
// Set next position and draw text.
g_FontPosition.top = 210;
g_Font->DrawText(NULL, "Chapter 5 - TEXT.",
-1, &g_FontPosition, DT_CENTER,
D3DCOLOR_XRGB(255,255,255));
// Set next position and draw text.
g_FontPosition.top = 240;
g_Font->DrawText(NULL, "Next up - GUIs.",
-1, &g_FontPosition, DT_CENTER,
D3DCOLOR_XRGB(255,255,255));
// Set next position and draw text.
g_FontPosition.top = 270;
g_Font->DrawText(NULL, "Bye!",
-1, &g_FontPosition, DT_CENTER,
D3DCOLOR_XRGB(255,255,255));
// End the scene. Stop rendering.
g_D3DDevice->EndScene();
// Display the scene.
g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}

void Shutdown()
{
if(g_D3DDevice != NULL) g_D3DDevice->Release();
if(g_D3D != NULL) g_D3D->Release();
if(g_Font) g_Font->Release();
g_D3DDevice = NULL;
g_D3D = NULL;
g_Font = NULL;
}

Chapter 4 Textures


In this chapter we learned how direct x manages textures. We also learned how the code can make images into textures like you can see on the right side. This is the first time I have heard of Direct x being able to do that. The code for the process is below with comments.

/*
Demo Name: Texture Mapping
Author: Allen Sherrod
Chapter: Ch 4
*/

#include
#include
#define WINDOW_CLASS "UGPDX"
#define WINDOW_NAME "D3D Texture Mapping"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
// Function Prototypes...
bool InitializeD3D(HWND hWnd, bool fullscreen);
bool InitializeObjects();
void RenderScene();
void Shutdown();

// Direct3D object and device.
LPDIRECT3D9 g_D3D = NULL;
LPDIRECT3DDEVICE9 g_D3DDevice = NULL;
// Matrices.
D3DXMATRIX g_projection;
D3DXMATRIX g_ViewMatrix;
// Vertex buffer to hold the geometry.
LPDIRECT3DVERTEXBUFFER9 g_VertexBuffer = NULL;
// Holds a texture image.
LPDIRECT3DTEXTURE9 g_Texture = NULL;
// A structure for our custom vertex type
struct stD3DVertex
{
float x, y, z;
unsigned long color;
float tu, tv;
};
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_VERTEX (D3DFVF_XYZ D3DFVF_DIFFUSE D3DFVF_TEX1)

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_KEYUP:
if(wParam == VK_ESCAPE) PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst, LPSTR cmdLine, int show)
{
// Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
WINDOW_CLASS, NULL };
RegisterClassEx(&wc);
// Create the application's window
HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW,
100, 100, WINDOW_WIDTH, WINDOW_HEIGHT,
GetDesktopWindow(), NULL, wc.hInstance, NULL);
// Initialize Direct3D
if(InitializeD3D(hWnd, false))
{
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
// Enter the message loop
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
RenderScene();
}
}
// Release any and all resources.
Shutdown();
// Unregister our window.
UnregisterClass(WINDOW_CLASS, wc.hInstance);
return 0;
}

bool InitializeD3D(HWND hWnd, bool fullscreen)
{
D3DDISPLAYMODE displayMode;
// Create the D3D object.
g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
if(g_D3D == NULL) return false;
// Get the desktop display mode.
if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
return false;
// Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
if(fullscreen)
{
d3dpp.Windowed = FALSE;
d3dpp.BackBufferWidth = WINDOW_WIDTH;
d3dpp.BackBufferHeight = WINDOW_HEIGHT;
}
else
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = displayMode.Format;
// Create the D3DDevice
if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_D3DDevice)))
{
return false;
}
// Initialize any objects we will be displaying.
if(!InitializeObjects()) return false;
return true;
}

bool InitializeObjects()
{
// Fill in our structure to draw an object.
// x, y, z, color, texture coords.
stD3DVertex objData[] =
{
{-0.3f, -0.4f, 0, D3DCOLOR_XRGB(255,255,255), 0, 1},
{0.3f, -0.4f, 0, D3DCOLOR_XRGB(255,255,255), 1, 1},
{0.3f, 0.4f, 0, D3DCOLOR_XRGB(255,255,255), 1, 0},
{0.3f, 0.4f, 0, D3DCOLOR_XRGB(255,255,255), 1, 0},
{-0.3f, 0.4f, 0, D3DCOLOR_XRGB(255,255,255), 0, 0},
{-0.3f, -0.4f, 0, D3DCOLOR_XRGB(255,255,255), 0, 1}
};
// Create the vertex buffer.
if(FAILED(g_D3DDevice->CreateVertexBuffer(sizeof(objData), 0,
D3DFVF_VERTEX, D3DPOOL_DEFAULT,
&g_VertexBuffer, NULL))) return false;
// Fill the vertex buffer.
void *ptr;
if(FAILED(g_VertexBuffer->Lock(0, sizeof(objData),
(void**)&ptr, 0))) return false;
memcpy(ptr, objData, sizeof(objData));
g_VertexBuffer->Unlock();

// Load the texture image from file.
if(D3DXCreateTextureFromFile(g_D3DDevice, "ugp.tga",
&g_Texture) != D3D_OK) return false;
// Set the image states to get a good quality image.
g_D3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER,
D3DTEXF_LINEAR);
g_D3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER,
D3DTEXF_LINEAR);

// Set default rendering states.
g_D3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_D3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

// Set the projection matrix.
D3DXMatrixPerspectiveFovLH(&g_projection, 45.0f,
WINDOW_WIDTH/WINDOW_HEIGHT, 0.1f, 1000.0f);
g_D3DDevice->SetTransform(D3DTS_PROJECTION, &g_projection);
// Define camera information.
D3DXVECTOR3 cameraPos(0.0f, 0.0f, -1.0f);
D3DXVECTOR3 lookAtPos(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 upDir(0.0f, 1.0f, 0.0f);
// Build view matrix.
D3DXMatrixLookAtLH(&g_ViewMatrix, &cameraPos,
&lookAtPos, &upDir);
return true;
}

void RenderScene()
{
// Clear the backbuffer.
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
// Begin the scene. Start rendering.
g_D3DDevice->BeginScene();
// Apply the view (camera).
g_D3DDevice->SetTransform(D3DTS_VIEW, &g_ViewMatrix);
// Draw square.
g_D3DDevice->SetTexture(0, g_Texture);
g_D3DDevice->SetStreamSource(0, g_VertexBuffer,
0, sizeof(stD3DVertex));
g_D3DDevice->SetFVF(D3DFVF_VERTEX);
g_D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
// End the scene. Stop rendering.
g_D3DDevice->EndScene();
// Display the scene.
g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}

void Shutdown()
{
if(g_D3DDevice != NULL) g_D3DDevice->Release();
g_D3DDevice = NULL;
if(g_D3D != NULL) g_D3D->Release();
g_D3D = NULL;
if(g_VertexBuffer != NULL) g_VertexBuffer->Release();
g_VertexBuffer = NULL;
if(g_Texture != NULL) g_Texture->Release();
g_Texture = NULL;
}

Sorry for the delay

Sorry for the delay in updates. I have been busy as of late with projects out side of school. Anywho In the following post's Ill talk about certain things we have worked on in class and how our final project went along.