//Apply the transformations and render our objects
m_pD3DDevice->SetTransform(D3DTS_WORLD, &matRotationX);
m_pCube1->Render();
m_pD3DDevice->SetTransform(D3DTS_WORLD, &matTransformation2);
m_pCube2->Render();
m_pD3DDevice->SetTransform(D3DTS_WORLD, &matTransformation3);
m_pCube3->Render();
m_pD3DDevice->SetTransform(D3DTS_WORLD, &matTransformation4);
m_pCube4->Render();
m_pD3DDevice->SetTransform(D3DTS_WORLD, &matTransformation5);
m_pCube5->Render();
//End the scene
m_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).
m_pD3DDevice->Present(NULL, NULL, NULL, NULL);
//Count Frames
m_dwFrames++;
}
Once you have made these changes, you should finish up with five rotating cubes (shown below).
In this tutorial we learnt what a matrix is, how matrices work and how to multiply them together. We also saw how to use transformation matrices in our DirectX applications. In the next tutorial we'll take a look a textures.
DirectX Tutorial 6: Textures
In this tutorial we will learn about textures, what they are and how to use them. Textures can be used to add realism to your scenes. From our example from the last tutorial, we will add a different texture to each rotating cube, numbering them from 1 to 5 in different colours. You can download the full source code by clicking the "Download Source" link above.
A texture in 3D graphics is a 2D bitmap that can be applied to a polygon (or a number of polygons) to increase realism. For example, lets say that you want to have a brick wall in your scene. You could create a square object in front of the camera and colour it red. Hmm… that looks more like a red square than a brick wall, what you really want to see are the bricks and maybe a window. You can do this using textures. All you need is an object (your square) and a wall texture. You can create your texture in any art package that will save .bmp files, I use Adobe Photoshop but you can use any software you like, even Microsoft Paint that comes with Windows.
You can create a texture in any size you like. But to improve efficiency you should (where possible) keep your textures small and square and to a power of 2: 16×16, 32×32, 64×64, 128×128, 256×256 etc. 256×256 is the most efficient size, but only use this size of texture if you need to. Remember: the smaller the texture, the better.
What are texture coordinates? Well, texture coordinates are used to specify a point on a texture. Because a texture is 2D we only need two values to specify any point: U and V. U is the number of units across (columns) and V is the number of units down (rows). The values of U and V should be between 0 and 1 (you can specify other values to create special effects, more on this later). The top left corner of the texture is (0, 0) and the bottom right corner is (1, 1) in the form (U, V). Fig 6.1 below shows the texture coordinates of nine points of a texture.
Fig 6.1
Now that we know about texture coordinates, we can apply our texture to an object in our scene, this is called Texture Mapping. The process of texture mapping is to map texture coordinates to vertices in a scene, therefore each vertex will have two extra values, U and V. Fig 6.2 below, shows an example of mapping a texture on to a cube. The example uses one texture placed on each side of a cube. The cubes vertices have been numbered in the same way as our cube structure in http://www.andypike.com/tutorials/directx8/003.htm and our code for this tutorial.
Therefore, the texture coordinates for each vertex are as follows (where vertex number = (U, V)):
0 = (0, 1) 9 = (0, 0)
1 = (0, 0) 10 = (1, 1)
2 = (1, 1) 11 = (1, 0)
3 = (1, 0) 12 = (0, 1)
4 = (0, 1) 13 = (0, 0)
5 = (0, 0) 14 = (0, 1)
6 = (1, 1) 15 = (0, 0)
7 = (1, 0) 16 = (1, 1)
8 = (0, 1) 17 = (1, 0)
Fig 6.2
Step 1: Modify FVF and Custom Vertex
This first thing that we need to do is change our custom vertex structure to hold the texture coordinates U and V, these are the two new FLOAT values tu and tv. We also need to modify our FVF to match by adding the D3DFVF_TEX1 flag.
//Define a FVF for our cuboids
#define CUBIOD_D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
//Define a custom vertex for our cuboids
struct CUBIOD_CUSTOMVERTEX {
FLOAT x, y, z;
DWORD colour;
FLOAT tu, tv;
};
Step 2: Load Texture
We need to add a new member variable to our CCuboid class to hold a pointer to the texture once it is loaded. The new member is called m_pTexture and is of type LPDIRECT3DTEXTURE8. We then need a new method to set the texture by passing in a filename, remember that the file needs to be a .bmp.
LPDIRECT3DTEXTURE8 m_pTexture;
bool CCuboid::SetTexture(const char *szTextureFilePath) {
if (FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, szTextureFilePath, &m_pTexture))) {
return false;
}
return true;
}
Step 3: Set Texture Coordinates
In our UpdateVertices method of CCudoid, we need to set the texture coordinates for each vertex. Notice that after the colour value for each vertex we have added two new values, these are the U and V values of our texture coordinates. These texture coordinates match the values from Fig 6.2.
bool CCuboid::UpdateVertices() {
VOID* pVertices;
//Store each point of the cube together with it's colour and texture coordinates
//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).
CUBIOD_CUSTOMVERTEX cvVertices[] = {
//Top Face
{m_rX – (m_rWidth/2), m_rY + (m_rHeight/2), m_rZ – (m_rDepth/2), D3DCOLOR_XRGB(0, 0, 255), 0.0f, 1.0f,}, //Vertex 0 – Blue
{m_rX – (m_rWidth/2), m_rY + (m_rHeight/2), m_rZ + (m_rDepth/2), D3DCOLOR_XRGB(255, 0, 0), 0.0f, 0.0f,}, //Vertex 1 – Red
{m_rX + (m_rWidth/2), m_rY + (m_rHeight/2), m_rZ – (m_rDepth/2), D3DCOLOR_XRGB(255, 0, 0), 1.0f, 1.0f,}, //Vertex 2 – Red
{m_rX + (m_rWidth/2), m_rY + (m_rHeight/2), m_rZ + (m_rDepth/2), D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0.0f,}, //Vertex 3 – Green
//Face 1
{m_rX – (m_rWidth/2), m_rY – (m_rHeight/2), m_rZ – (m_rDepth/2), D3DCOLOR_XRGB(255, 0, 0), 0.0f, 1.0f,}, //Vertex 4 – Red