Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
97 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

  Contents

 DirectX Graphics
 Basic Application
 Drawing Triangles
 Indexed Triangles
 Adding Texture
 Full Screen
 Graphics


 Get the source
 Printable version

 


Adding Texture (d3d4.cpp)

Texturing is just one of those things that adds so much visual bang for the buck, that is would be ludicrous not to add it. Luckily for us, doing this in DX8 is painless.

First you add texture coordinates, tu and tv, into your MYVERTEX structure. Then add the appropriate values to your vertices array.

Next, in your CreateVertexBuffer and SetVertexShader methods, you have a parameter that looks like D3DFVF_XYZRHW|D3DFVF_DIFFUSE. You add D3DFVF_TEX1 to these flags to tell DirectX that you have one set of texture coordinates.

Add the code to copy tu and tv into the vertex array (between your Lock and Unlock methods).

DirectX will now draw the texture, but you have to tell it what texture to draw. In your InitDirect3D function, you add:

D3DXCreateTextureFromFile(pID3DDevice, "dx5_logo.bmp", &pTexture); pID3DDevice->SetTexture(0, pTexture);

Change "dx5_logo.bmp" to whatever bitmap you want to display. Here you are using the D3DX library to build an IDirect3DTexture8 interface. Next you put this texture into stage zero. You can have up to eight stages of textures, but for now, you will just use the one. You could also use the SetTextureStageState to add different features like MIP mapping and bump mapping, but you will just use the default values for now.

Now you have a texture-mapped triangle.

Using Matrices and Extra Texture Coordinates (d3d5.cpp)

It is time to build our cube. Now that you are entering the 3rd dimension (the previous examples were on a single plane), you have to enable your z-buffer. You also have to set up some matrices for model, world, and projection transformations.

Enabling the z-buffer is fairly easy. In your call to CreateDevice, you must add some extra fields to your D3DPRESENT_PARAMETERS structure:

present.EnableAutoDepthStencil = TRUE; present.AutoDepthStencilFormat = D3DFMT_D16;

This tells DirectX to use a 16 bit z-buffer. Next you call

pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);

and your z-buffer is set up. Lastly, in your DrawScene function, you must modify the Clear method to clear the z-buffer in addition to the back buffer:

pID3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0,63,0,0), 1.0, 0);

You add the flag D3DCLEAR_ZBUFFER to enable z-buffer clearing, and you pass 1.0 as the fill value for the z-buffer. Now all of your polygons will be drawn correctly.

Since you will be doing some transformations to your vertices, you can go ahead and remove the extra rhw parameter from your MYVERTEX structure. Remove the values from your vertices array, and the reference between your Lock and Unlock calls. Lastly, change your D3DFVF_XYZRHW references to D3DFVF_XYZ.

Direct3D has several types of matrices available, but we will use only three: World, View, and Projection. The World transformation will move the cube into world coordinates. The View transformations will move the world into view space. The Projection matrix will scale the world to make it look as if it has depth.

Now add a call to a new function, BuildMatrices, to your DrawScene function. BuildMatrices will build and activate your three matrices as described above. After you build each matrix, you call SetTransform, passing the matrix itself and the type of matrix it is.

As an example, we will build a no-op matrix:

D3DXMATRIX matrix; D3DXMatrixIdentity(&matrix); pID3DDevice->SetTransform(D3DTS_WORLD, &matrix);

As you can see, this fills the matrix structure with an identity matrix, and then tells DirectX to use this as the World transformation. The D3DX library does all the menial work for us.

In the example program, your model coordinates are already transformed to world coordinates, so you could just leave this code as is. However, this needs a bit of flavor. In your code, start your BuildMatrices function with:

D3DXMATRIX matrix; D3DXMatrixRotationY(&matrix, timeGetTime() / 1000.0f); pID3DDevice->SetTransform(D3DTS_WORLD, &matrix);

This setup will rotate the cube about the Y-axis. The parameter timeGetTime() / 1000.0f is the angle in radians. Doing this will give a smooth constant rotation.

Now you build the other two matrices:

D3DXMatrixLookAtLH(&matrix, &D3DXVECTOR3(0.0f, 3.0f, -5.0f), &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); pID3DDevice->SetTransform(D3DTS_VIEW, &matrix); D3DXMatrixPerspectiveFovLH(&matrix, D3DX_PI / 4, 4.0f / 3.0f, 1.0f, 100.0f); pID3DDevice->SetTransform(D3DTS_PROJECTION, &matrix);

D3DXMatrixLookAtLH builds a left-handed view matrix (some textbooks call this the camera). You pass three vectors: the position of the camera, the point you are looking at, and a vector that points up. Then you tell DirectX to use this as the view matrix.

D3DXMatrixPerspectiveFovLH builds a left-handed projection matrix that uses a variable field of view. D3DX_PI / 4 is the field of view in radians, which is 45 degrees. Then you pass the aspect ratio (most monitors are 4:3), and values representing our near and far clip plane. Lastly, you tell DirectX to use this as your projection matrix.

After adding the rest of the vertices to your vertex array, you are ready to go. The result should be a spinning textured cube.

Note, you are not reusing the vertices as described in example three. This is because you need up to three texture coordinates per vertex and you only have specified the one.




Next : Full Screen Graphics