Выбрать главу

Projection Matrix

The projection matrix can be thought of as the camera lens. It specifies the field of view angle, aspect ratio and near/far clipping planes. For the time being at least, we will keep these settings the same throughout our examples.

Here is the code for this tutorial. It's just the same as the code from the last tutorial, except for a few modifications:

#include <d3dx8.h>

LPDIRECT3D8 g_pD3D = NULL;

LPDIRECT3DDEVICE8 g_pD3DDevice = NULL;

LPDIRECT3DVERTEXBUFFER8 g_pVertexBuffer = NULL; // Buffer to hold vertices

struct CUSTOMVERTEX {

 FLOAT x, y, z;

 DWORD colour;

};

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

#define SafeRelease(pObject) if (pObject != NULL) {pObject->Release(); pObject=NULL;}

HRESULT InitialiseD3D(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 = Direct3DCreate8(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;

 ZeroMemory(&d3dpp, sizeof(d3dpp));

 //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_VSYNC;

 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 becuase we want to hide the back of our polygons

 g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

 //Turn off lighting becuase we are specifying that our vertices have colour

 g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

 return S_OK;

}

HRESULT InitialiseVertexBuffer() {

 VOID* pVertices;

 //Store each point of the cube together with it's colour

 //Make sure that the points of a polygon are specified in a clockwise direction,

 //this is because anti-clockwise faces will be culled

 //We will use a three triangle strips to render these polygons (Top, Sides, Bottom).

 CUSTOMVERTEX cvVertices[] = {

  //Top Face

  {-5.0f, 5.0f, –5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 0 – Blue

  {-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 1 – Red

  {5.0f, 5.0f, –5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 2 – Red

  {5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 3 – Green

  //Face 1

  {-5.0f, –5.0f, –5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 4 – Red

  {-5.0f, 5.0f, –5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 5 – Blue

  {5.0f, –5.0f, –5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 6 – Green

  {5.0f, 5.0f, –5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 7 – Red

  //Face 2

  {5.0f, –5.0f, 5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 8 – Blue

  {5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 9 – Green

  //Face 3

  {-5.0f, –5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 10 – Green

  {-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 11 – Red

  //Face 4

  {-5.0f, –5.0f, –5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 12 – Red

  {-5.0f, 5.0f, –5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 13 – Blue

  //Bottom Face

  {5.0f, –5.0f, –5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 14 – Green

  {5.0f, –5.0f, 5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 15 – Blue

  {-5.0f, –5.0f, –5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 16 – Red

  {-5.0f, –5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 17 – Green

 };

 //Create the vertex buffer from our device.

 if (FAILED(g_pD3DDevice->CreateVertexBuffer(18 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVertexBuffer))) {

  return E_FAIL;

 }

 //Get a pointer to the vertex buffer vertices and lock the vertex buffer

 if (FAILED(g_pVertexBuffer->Lock(0, sizeof(cvVertices), (BYTE**)&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 transformation

 g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);

}