News
DirectX
Links
Contact Me

In Association with Amazon.com
In Association with Amazon.ca

$5 via PayPal


Direct3D Tutorials

Direct3D Tutorials

My primary goal in doing these tutorials is to learn. By developing these tutorials I hope to learn my way around Direct3D much quicker than I would otherwise. Also I hope to be able to provide a valuable resource for others who want to learn.

While I'm not new to programming, Direct3D & 3D programming in general is new to me. These examples may not illustrate the best way to do things. I'm open to (constructive) criticism, if you have a better way of doing something, let me know.

I've tried to use a clear and easy to read style with a fair number of comments. If you have any problems understanding my code or comments, please let me know and I'll see what I can do to make them clearer.

These tutorials cover Direct3D8. The DirectX SDK is required to compile them. The tutorials are written in C++ but some have been converted to Visual Basic as well.

I've created 2 email lists. The Tutorial Announce list can only be posted to by me. Whenever I add a tutorial or update a tutorial, I'll send out an email to the list. No spamming.

The d3d-beginners list is for discussion. It's a good place to post general questions about D3D when you're stuck. The members have been quite helpful to each other, it's building into a nice community.

Subscribe to the Tutorial Announce List: Click here
Subscribe to the Direct3D Discussion List: Click here


NeHe-Style Tutorials

This set of tutorials is modelled after the OpenGL tutorials developed & hosted by Jeff Molofee (NeHe). Check out his site here, there is some amazing material there. Even if you have no interest in OpenGL or game/graphics programming, it's worth the visit to check out some of the sample programs.

Tutorial Last Updated
Lesson 1:Your First WindowMarch 20, 2003
Lesson 2a:Your First Polygons (Screen Space)March 20, 2003
Lesson 2b:Your First Polygons (Model Space)March 20, 2003
Lesson 3:Coloured PolygonsMarch 20, 2003
Lesson 4:RotationMarch 20, 2003
Lesson 5:Solid ObjectsMarch 20, 2003
Lesson 6:Texture MappingMarch 5, 2001
Lesson 7:Texture Filters, Lighting & Keyboard ControlMarch 5, 2001
Lesson 8:Alpha Blending (Vertex Alpha)September 30, 2002
Lesson 9:Moving Bitmaps in 3D SpaceApril 9, 2002
Lesson 10:Moving in a 3D WorldOctober 13, 2002
There are no Lessons 11 & 12n/a
Lesson 13:D3DXFontApril 9, 2002

Drunken Hyena-Style Tutorials

This set of tutorials was created to either try out something I was interested in, or created in response to a request I receieved. I frequent the forums on GameDev.net and a lot of the tutorials are made to answer questions asked there.

Tutorial Last Updated
X Rotations without D3DXMarch 5, 2001
Y Rotations without D3DXMarch 5, 2001
Z Rotations without D3DXMarch 5, 2001
Translations without D3DXMarch 5, 2001
Scaling without D3DXMarch 8, 2001
Dancing SquareMarch 8, 2001
Colour Key TransparencyMarch 23, 2001
Alpha Channel TransparencyApril 3, 2001
Computed Alpha ChannelApril 15, 2001
Loading a Texture From a ResourceMay 21, 2001
Additive BlendingMay 21, 2001
3D FontsApril 9, 2002
Using CD3DFontApril 9, 2002


Lesson 1: Your First Window

In this tutorial we will create a window and initialize Direct3D. This is the bare minimum you can do and still claim to have written a Direct3D program. It can be run in full-screen or windowed mode..

This code base will be used for the more advanced tutorials, so it's definitely worth a look.

DirectX 8 Online Tutorial (Commented C++ Source) Download C++ Source & Exe Download VB Source & Exe
Donate $5


Lesson 2a: Your First Polgons (Screen Space)

Now that you know how to open a window, let's draw something. Being able to draw a triangle may not seem like much, but it's the foundation of all the more complex drawing. A Quake model is nothing more than a bunch of textured triangles.

In this tutorial we're going to draw a triangle and a square (which is just 2 triangles together). Each vertex in the triangle (and square of course) has a set of coordinates (x,y,z). These coordinates can be given in Screen Space (called Transformed Vertices), or Model Space (Untransformed Vertices). Coordinates can also be given in World Space (also Untransformed Vertices)

In Screen Space, the top, left corner is at 0,0 (x,y) and the units of measurements are actual pixels used by the screen resolution you're using. Adding 10 to the x-coordinates of a triangle will move that triangle 10 pixels to the right. Since Screen Space is flat, the z-coordinate does very little. Changing the z-coordinate will not visibly make the object move deeper into the screen. If you're using a Z Buffer, changing the z-coordinate will determine which objects are in front of each other. Transformed Vertices are often used to draw 2D-style objects, such as a console, or interface.

In World Space your units of measurement are arbitrary. Adding 1 to a coordinate could move something 1 centimeter, 1 meter, or whatever distance you choose. If the coordinates of your model are given in World Space, they still have to be Transformed, but since they don't change, it's a trivial Transformation. Operating on the object (rotation for example) can be tricky though.

In Model Space the coordinates are relative to the model itself. Often the center of the model is at (0,0,0) which makes rotation easy to calculate. Matrices are used to transform the objects coordinates into World Space and then Screen Space. The Transformation into World Space allows object 'interaction' (lighting, object blocking each other from view) and the Transformation into Screen Space then allows the 3D objects to be presented on a 2D screen.

In this tutorial we will use Transformed Vertices, because they're really easy. The Online Tutorial below shows the changes necessary to the code given in Lesson 1. Revisiting all of the code each time seems a bit excessive. Of course the complete source is given in the Source & Exe zip file.

DirectX 8 Online Tutorial (Commented C++ Source) Download C++ Source & Exe Download VB Source & Exe
Donate $5


Lesson 2b: Your First Polygons (Model Space)

In this version we specify our coordinates in Model Space and then Transform them into World Space.

We also use a single Vertex Buffer to store the vertices for both the triangle and the square and just use an offset into the Vertex Buffer when drawing them.

DirectX 8 Online Tutorial (Commented C++ Source) Download C++ Source & Exe Download VB Source & Exe
Donate $5


Lesson 3: Coloured Polygons

Plain white polygons are boring. This time we'll show how you can blend colours together by setting vertices to different colours on our triangle. We'll colour our square a flat blue to show how the 2 methods contrast.

DirectX 8 Online Tutorial (Commented C++ Source) Download C++ Source & Exe Download VB Source & Exe
Donate $5


Lesson 4: Rotation

Now it's time to make them dance. Well, rotate anyway. We'll make the triangle rotate on the x-axis, and the square rotate on the y-axis.

The Online Tutorial shows the changes from code in Lesson 3.

DirectX 8 Online Tutorial (Commented C++ Source) Download C++ Source & Exe Download VB Source & Exe
Donate $5


Lesson 5: Solid Objects

Now it's time to really enter the world of 3D. We've drawn, coloured, and rotated flat, 2D objects, now we're going to do the same to real (simple) 3D objects. A pyramid and a cube are our next victims.

The pyramid will rotate on the Y-axis (which means we don't have to draw a bottom on it, you'd never see it). Since we're not drawing a bottom, all of the triangles that make up the pyramid share a common point, the top. This means we can draw them as a Triangle Fan. In a Triangle Fan, each triangle after the first is made up of the first vertex drawn, the previously drawn vertex and then the new vertex provided. Obviously fans can't be used in many places. Fan shapes (obviously), circles, spikes, pyramids, etc can be done with Triangle Fans.

The cube will rotate on the X-axis. For simplicity, we'll use standard Triangle Lists to draw our cube. This means every single vertex has to be given for each triangle drawn, no sharing. It can't be done with a single Triangle Fan (correct me if I'm wrong), and Triangle Strips wouldn't be pretty (degenerate triangles would be required). Since our goal is simplicity, Triangle Lists win.

In this tutorial we create a Z-Buffer. Normally if we drew the cube, we would have to make sure that we drew the triangles starting with the ones in the back, otherwise the triangles would clobber each other randomly. The Z-Buffer (also known as a depth buffer) tracks the depth at each point and only draws an object if it would be in front of what's already drawn.

The Online Tutorial shows the changes from code in Lesson 4.

DirectX 8 Online Tutorial (Commented C++ Source) Download C++ Source & Exe Download VB Source & Exe
Donate $5


Lesson 6: Texture Mapping

Coloured solids are nice, but they can't compare to the results you can get with textures. In this tutorial we'll take the cube from Lesson 5 and slap a texture on all 6 faces. It's not the prettiest texture in the world, but that's why I'm a programmer and not an artist.

The Online Tutorial shows the changes from code in Lesson 5.

Online Tutorial (Commented C++ Source) Download C++ Source & Exe
Download VB Source & Exe Donate $5


Lesson 7:Texture Filters, Lighting & Keyboard Control

We're going to cover a lot of ground in this one. The keyboard control is a simple modification of the message handler for our window, no DirectInput(yet). The arrow keys control the speed that the cube spins on the X-axis and Y-axis. Page Up and Page Down move the cube along the Z-axis. 'L' turns lighting on and off while 'F' changes the type of texture filtering being used.

The texture filters show the difference between No Filtering, Point Filtering, and Linear Filtering.

Last, but definitely not least, we bring in lighting. Lighting can get complex, so we'll keep it as simple as we can while we introduce it.

The Online Tutorial shows the changes from code in Lesson 6.

Online Tutorial (Commented C++ Source) Download C++ Source & Exe
Download VB Source & Exe Donate $5


Lesson 8:Alpha Blending (Vertex Alpha)

Now the lessons are starting to look good. There just aren't a lot of people who are impressed by a triangle & square, no matter how quickly they are rotating (the triangle and square, not the people).

To the best of my knowledge, this lesson is done the 'proper' way. No quick hacks. The transparent triangles are drawn back-to-front, normals are set up so lighting works without any trickery.

The Online Tutorial shows the changes from code in Lesson 7.

NOTE : The dhSimpleMesh class is required to re-compile this lesson. It can be downloaded from this page.

Online Tutorial (Commented C++) Download C++ Source & Exe


Lesson 9:Moving Bitmaps in 3D Space

This tutorial shows how to build a simple particle system. It loads a 2D image of a star and moves 50 of them around in 3D space. Since the particle is a 2D image, we have to make sure it always faces the camera. This is known as billboarding.

Features:
- Simple particle system
- Billboards
- Variable step timing
- Uses the dhEngine

Controls:
Zoom - Up/Down arrow
Tilt - Page Up/Page Down
'T' - Toggle Twinkle
Escape - Exit

NOTE : The dhEngine class is required to re-compile this lesson. It can be downloaded from this page.

Online Tutorial (Commented C++) Download C++ Source & Exe


Lesson 10:Moving in a 3D World

A first-person camera tutorial has been requested many times. This is a simple tutorial and as such we don't cover more advanced issues like collision detection.

NOTE : The dhEngine class is required to re-compile this lesson. It can be downloaded from this page.

Online Tutorial Download C++ Source & Exe


Lesson 13:D3DXFont

The associated NeHe tutorial builds Font bitmaps using wglUseFontBitmaps. A close analog to that in Direct3D8 is the D3DXFont class. It's extremely easy to set up, and the results look really nice. D3DXFont supports anti-aliasing and kerning. The cost is that it's not incredibly fast. See my dhFastFont class for a faster (though less featured) alternative.

If you've worked your way up through the tutorials, this one will be really easy for you.

NOTE : The dhEngine class is required to re-compile this lesson. It can be downloaded from this page. dhFPSTimer is also required.

Online Tutorial (Commented C++ Source) Download C++ Source & Exe



X Rotations without D3DX

The D3DX library provides a number of helpful routines, the ones that build rotation matrices are particularly handy. Some people cannot use D3DX (using a compiler other than VC++) and others choose not to. This mini-tutorial is for both groups.

Writing the function to do the rotations was trivial because the DX8 SDK includes the source for this function, so I just cut 'n' pasted. If they gave out the source for all of the D3DX functions things would be a lot easier for users of other compilers.

DirectX uses 4x4 matrices for transformations (scaling/rotation/translation/etc). Creating a matrix for X-axis rotation is as simple as calculating the sine and cosine of the given angle (in radians) and plugging those values into the right places in a matrix. And that's what our new function dhMatrixRotationX() does.

We rotate 2 triangles on their x-axis. The left one uses the D3DX function, the right one uses mine. As you can see they're in perfect sync which gives me a fair bit of confidence in the quality of the function.

NOTE: You still need D3DX to recompile this tutorial because I use D3DX's RotateX to compare to mine, and I also use the Translation & Multiply functions. In future tutorials, I'll provide non-D3DX versions of these as well.

Online Tutorial (Commented C++ Source) Download Source & Exe (28K)


Y Rotations without D3DX

In this tutorial I provide a function to calculate matrices for Y-axis rotation. Otherwise it's identical to the X Rotation tutorial.

NOTE: You still need D3DX to recompile this tutorial because I use D3DX's RotateY to compare to mine, and I also use the Translation & Multiply functions. In future tutorials, I'll provide non-D3DX versions of these as well.

Online Tutorial (Commented C++ Source) Download Source & Exe (28K)


Z Rotations without D3DX

In this tutorial I provide a function to calculate matrices for Z-axis rotation. Otherwise it's identical to the Y Rotation tutorial.

NOTE: You still need D3DX to recompile this tutorial because I use D3DX's RotateZ to compare to mine, and I also use the Translation & Multiply functions. In future tutorials, I'll provide non-D3DX versions of these as well.

Online Tutorial (Commented C++ Source) Download Source & Exe (28K)


Translations without D3DX

In this tutorial I provide a function to calculate matrices for Translation (movement on the X, Y, or Z axis). Otherwise it's identical to the Rotation tutorials.

NOTE: You still need D3DX to recompile this tutorial because I use D3DX's Translation to compare to mine.

Online Tutorial (Commented C++ Source) Download Source & Exe (28K)


Scaling without D3DX

In this tutorial I provide a function to calculate matrices for Scaling (size changing on the X, Y, or Z axis). Otherwise it's identical to the Rotation tutorials.

NOTE: You still need D3DX to recompile this tutorial because I haven't replaced all of the D3DX Matrix functions yet.

Online Tutorial (Commented C++ Source) Download Source & Exe (28K)


Dancing Square

The basic purpose of this tutorial is to animate a simple shape, but I managed to sneak in a few extras. In this tutorial we cover:
- Animating a simple shape by modifying vertices
- Variable step timing to make the animation run the same speed on different computers
- Rotation of the camera to show the scene from different angles

Online Tutorial (Commented C++ Source) Download Source & Exe (29K)


Colour Key Transparency

DirectDraw supported blitting with a Colour Key. A Colour Key is a colour value which is to be treated as if it were completely transparent. Black was commonly used for the background on sprites and by specifying that black was the colour key, you could draw (blit) your sprite and the black areas wouldn't be drawn allowing the background to show.

In Direct3D transparency is achieved with AlphaBlending. Each pixel (if using the alpha in a texture) and/or vertex has an Alpha or Transparency value. Since 255 is fully opaque and 0 is fully transparent, it's best thought of as the level of Opaqueness. With 256 levels of transparency some very cool effects can be achieved. Once you get used to AlphaBlending you'll never wish for Colour Keys again.

There are times when it would be nice to simulate a Colour Key. Quite often it's good enough to specify a single colour as completely transparent and everything else as fully opaque. Another advantage is that you can use image formats like BMP which do not support alpha channels.

To simulate Colour Keys with D3D8 we use D3DXCreateTextureFromFileEx, an unwieldy yet descriptively named function. It allows a Colour Key arguement. It loads your texture and then processes it setting the alpha value of each pixel to 0 wherever it finds your specified Colour Key.

One big disadvantage of using Colour Keys is coloured jaggies. If you use any anti-aliasing on the edges of your sprite, it will blend with the background. So if your texture is white text drawn on a black background will have grey jaggies on it which will look wrong if you draw it over a green background.

NOTE:When specifying your Colour Key you provide it as an ARGB quad (DWORD, 0xAARGGBB). The Alpha component is significant, if your background is opaque black (from a BMP all colours will be opaque since there is no alpha channel) then you have to give it as 0xFF000000 NOT 0x00000000. This is because D3D only looks for an exact match. This is probably the number 1 mistake people make when using D3DXCreateTextureFromFileEx.

This lesson uses Lesson 2a as a base. The Online Tutorial describes the changes that were made to that code base.I removed a lot of comments from the source. By the time you reach this tutorial, the explanation of why I'm including windows.h shouldn't be necessary and only bloats the file. I haven't removed all of the comments, just some of the (by now) painfully obvious ones.

The 'A' or 'B' key can be used to toggle blending off and on. They both do exactly the same thing, I use both because it's more intuitive.

Online Tutorial (Commented C++ Source) Download Source & Exe (108K)


Alpha Channel Transparency

Since we've discussed the limitations of Colour Keys, it's time to show you a better way. A small number of image formats (notably Targa & PNG) support per-pixel transparency by means of an alpha channel.

When dealing with 32-bit colours, they are represented like this 0xAARRGGBB, where RR is the red channel, BB is the blue channel, GG is the green channel and AA is the alpha channel. Since they are each 1 byte in length they can have values from 0-255. For the red channel, 0 has no red, 255 has the full amount of red. Similarly, in the alpha channel 0 is full transparent while 255 is fully opaque.

This extra byte per pixel can add to the images size, but that's about the only downside. Alpha channels allow incredible flexibility.

This lesson uses the Colour Key lesson as a base. The Online Tutorial describes the changes that were made to that code base. The changes required were VERY minor. You can literally make the required changes in about 30 seconds. This means it's very important that you understand the Colour Key lesson before you tackle this one.

The image being loaded is actually just a big red square. The alpha channel creates variable levels of transparency on this square so it looks like a solid dot that fades off on the edges. Toggling the transparency will show the dramatic difference. You cannot achieve this effect with a Colour Key.

The 'A' or 'B' key can be used to toggle blending off and on. They both do exactly the same thing, I use both because it's more intuitive.

Online Tutorial (Commented C++ Source) Download Source & Exe (111K)


Computed Alpha Channel

In this lesson we load a simple grayscale image that does not have an Alpha Channel and we compute the alpha component based on the intensity of each pixel. A white spot will be opaque, a black spot will be transparent and gray will be semi-transparent. We do this by setting the alpha component equal to the red component, since it's a grayscale image we could have used blue or green and achieved the same result.

Since it's a grayscale image with no alpha, the file sizes are quite small. This 64x64 texture is only 5K on disk. This technique could be used to load font textures that are anti-aliased against a black background. By adding a diffuse colour component to our vertices we could change the colours of our images while maintaining a small image on disk.

This example builds off of the previous Alpha Channel Transparency lesson so please study it before reviewing this one.

The 'A' or 'B' key can be used to toggle blending off and on. They both do exactly the same thing, I use both because it's more intuitive.

Online Tutorial (Commented C++ Source) Download Source & Exe (111K)


Loading a Texture from a Resource

This tutorial is based off of Lesson 6 (the first texture mapping tutorial). A lot of people have asked how to load a texture from a VC++ Resource, so I put this together.

The online tutorial gives instructions on how to make a resource from your bitmap and then shows the code required to load it. Once you've seen it, it's pretty simple.

Online Tutorial (Commented C++ Source) Download Source & Exe (266K)


Additive Blending

This tutorial shows off the power of the D3DBLEND_ONE render state. By setting the source and destination blend states to D3DBLEND_ONE we're enabling Additive Blending.

What this means is that each object we draw will add to what has already been drawn. Blue drawn over green will yield aqua, red over green will yield yellow. Black will magically be ignored, so we don't have to worry about the backgrounds on our sprites. No alpha channels are used, not in the texture, not in the vertices.

Online Tutorial (Commented C++ Source) Download Source & Exe (119K)


3D Font

This tutorial shows how to create a 3D mesh from a string/font combination. Here we create the string "Drunken Hyena" from the Arial font.

After creating the string, we spin it in the middle of the display and have a light shine on it just for kicks.

Note:This tutorial requires the dhEngine class. It's available here.

Online Tutorial (Commented C++ Source) Download Source & Exe (72K)


Using CD3DFont

This tutorial shows how to use the CD3DFont class provided with the DirectX 8 SDK. If you look in your SDK folder in Sample/Multimedia/Common there's a source and include directory. There is a d3dfont source file and include, you'll need those for this tutorial.

Note:This tutorial requires the dhEngine class. It's available here.dhFPSTimer is also required.

Download (49K) Online Tutorial (Not Available) Donate $5