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

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;

 D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, 0.0f,-30.0f), //Camera Position

  &D3DXVECTOR3(0.0f, 0.0f, 0.0f), //Look At Position

  &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); //Up Direction

  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 backbuffer to black

 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 objects

 g_pD3DDevice->SetStreamSource(0, g_pVertexBuffer, sizeof(CUSTOMVERTEX));

 g_pD3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX);

 g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); //Top

 g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 8); //Sides

 g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 14, 2); //Bottom

 //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() {

 SafeRelease(g_pVertexBuffer);

 SafeRelease(g_pD3DDevice);

 SafeRelease(g_pD3D);

}

void GameLoop() {

 //Enter the game loop

 MSG msg;

 BOOL fMessage;

 PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);

 while (msg.message != WM_QUIT) {

  fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);

  if (fMessage) {

   //Process message

   TranslateMessage(&msg);

   DispatchMessage(&msg);

  } else {

   //No message to process, so render the current scene

   Render();

  }

 }

}

//The windows message handler

LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {

 switch(msg) {

 case WM_DESTROY:

  PostQuitMessage(0);

  return 0;

  break;

 case WM_KEYUP:

  switch (wParam) {

  case VK_ESCAPE:

   //User has pressed the escape key, so quit

   DestroyWindow(hWnd);

   return 0;

   break;

  }

  break;

 }

 return DefWindowProc(hWnd, msg, wParam, lParam);

}

//Application entry point

INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT) {

 //Register the window class

 WNDCLASSEX wc = {

  sizeof(WNDCLASSEX), CS_CLASSDC, WinProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, "DX Project 3", NULL

 };

 RegisterClassEx(&wc);

 //Create the application's window

 HWND hWnd = CreateWindow("DX Project 3", "www.andypike.com: Tutorial 3", WS_OVERLAPPEDWINDOW, 50, 50, 500, 500, GetDesktopWindow(), NULL, wc.hInstance, NULL);

 //Initialize Direct3D

 if (SUCCEEDED(InitialiseD3D(hWnd))) {

  //Show our window

  ShowWindow(hWnd, SW_SHOWDEFAULT);

  UpdateWindow(hWnd);

  //Initialize Vertex Buffer

  if (SUCCEEDED(InitialiseVertexBuffer())) {

   //Start game running: Enter the game loop

   GameLoop();

  }

 }

 CleanUp();

 UnregisterClass("DX Project 3", wc.hInstance);

 return 0;

}

You should finish up with a window with a black background and a multi-coloured cube in the middle rotating (shown below).

So, what have we added/changed:

Include and lib files

We have a new header file, which replaces the old one. The new header file is: <d3dx8.h>

We also have two new lib files to specify in our project settings (as in tutorial 1). They are: "d3dx8.lib" and "winmm.lib".

CUSTOMVERTEX

We have changed our custom vertex to only include x, y, z and colour values. These will allow us to specify a point in 3D space and a colour.

D3DFVF_CUSTOMVERTEX

To match our custom vertex structure, we have modified our FVF. We now use the flags D3DFVF_XYZ and D3DFVF_DIFFUSE.

InitaliseD3D

We have enabled Backface Culling (explained above). We use the SetRenderState function to do this, notice that we use the D3DCULL_CCW flag to specify that we want DirectX to cull the anti-clockwise faces.

We have also used the SetRenderState function to specify that we want to disable lighting, this is because we have given a colour (light) value to each of our vertices.

InitaliseVertexBuffer

Here we have set the values for our 18 vertices. Each vertex has a comment next to it with it's number, these numbers match the diagrams above (Fig 3.3 and 3.4). The cube is centred about the origin (0, 0, 0) and is 10 units wide/high/deep.

SetupRotation