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

  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 2", NULL

 };

 RegisterClassEx(&wc);

 //Create the application's window

 HWND hWnd = CreateWindow("DX Project 2", "www.andypike.com: Tutorial 2", 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 2", wc.hInstance);

 return 0;

}

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

Summary

So, there you have it. The second tutorial complete. We've learnt a lot in this tutoriaclass="underline" Vertices, Coordinated Systems, 3D Primitives, FVF, Vertex Buffers and specifying colours. To take this tutorial a bit further, try adding another triangle. In the next tutorial we will create our first real 3D object.

DirectX Tutorial 3: Rotating 3D Cube

Introduction

In our last tutorial we drew a 2D triangle. That was good, but this time we are going to create our very first 3D object… a cube. And to show that it really is 3D, we are going to rotate it about the x, y and z axis. Remember that all 3D objects are made up from polygons, normally triangles. So for our cube, we will use 12 triangles (2 for each face).

3D World Space

In the last tutorial we saw how the Left-Handed 3D Coordinate System worked. This is the coordinate system that we will use from now on. We will specify in our code (below) that the y axis points up.

What is the difference between left and right-handed coordinate systems? In left-handed coordinates, the positive z axis points away from you. In right-handed coordinates, the positive z axis points towards you. In both cases the positive y axis points up and the positive x axis points to the right. You can remember this by holding up your left hand so that the palm is facing up (y axis) and your fingers point to the right (x axis). Your thumb represents the positive z axis (points away). If you did the same with your right hand, your thumb would point towards you, hence left and right-handed coordinate systems. We will always use the left-handed system, this is what DirectX uses.

Backface Culling

What is Backface Culling? Backface Culling is a pretty simple concept. Basically, it is a process where all of the polygons that are "facing" away from the user are not rendered. For example, I have created a square with one side red and the other blue. Let's say that I defined the polygons so that the red side was "facing" the user and then started rotating the square. With Backface Culling enabled, the user would only see the red face and would never see the blue face. Why is this useful? Well, if we are creating a closed 3D object (like a cube), we do not need to render the inside faces because they are never seen anyway. This makes the rendering of a cube more efficient.

How do I specify which face is "facing" the user and which face to cull (not render)? It's all in the order that you specify your vertices. Below are two diagrams showing the order in which to define a "Clockwise" polygon. If you created a polygon in this way, the polygon would be rendered as shown, but if you were to flip the polygon (rotate), it would not be rendered. You can define which faces are culled, clockwise or anti-clockwise. By default, DirectX will cull anti-clockwise polygons.

Fig 3.1   

Fig 3.2

How to make a cube

Below are two diagrams showing how our cube is going to be made up. Here we have used three triangle strips, one for the top of the cube, one for the sides and one for the bottom. The diagram below shows the vertices and polygons for each triangle strip (Fig 3.3). The vertices are numbered from 0 to 17, this is the order that we must specify our vertices in the vertex buffer. Under that is a diagram that shows our cube (Fig 3.4). Notice where each of the vertices are in relation to each other. Also, look at how the vertices are always in a clockwise direction (except the bottom). This is because we have enabled Backface Culling (see above).

Fig 3.3

Fig 3.4

Matrices

What is a Matrix? Matrices are a pretty advanced mathematics topic, so I will only give you a brief summary. A matrix can be thought of as a grid of numbers that can be applied to the coordinates of a vertex to change their values. You can use matrices in DirectX to translate, rotate and scale objects (vertices). In DirectX, a matrix is a 4x4 grid of numbers. There are three types of matrix: World, View and Projection.

World Matrix

You can use the world matrix to rotate, scale and translate objects in 3D space (World Space) by modifying their vertices. All of these transformations will be performed about the origin (0, 0, 0). You can combine transformations by multiplying them together, but be aware that it is important which order you perform the multiplication. Matrix1 x Matrix2 is not the same as Matrix2 x Matrix1. When you perform a world matrix transformation, all subsequent vertices will be transformed by this matrix. To rotate two objects, one about the x axis and one about the y axis, you must perform the x axis transformation first, then render object 1. Next, perform the y axis transformation, then render object 2.

View Matrix

The view matrix is the camera (or eye). The camera has a position in world space and also has a "look at" position. For example, you can place the camera above an object (camera position) and point it at the centre of the object (look at position). You can also specify which way is up, in our example below we will specify that the positive y axis is up.