Beginning Game Development: Part II - Introduction to DirectX

Published 03 November 06 12:56 AM | Coding4Fun 
  This is Part 2 of an introductory series on game programming using the Microsoft .NET Framework and managed DirectX 9.0. This article covers the basics of DirectX.
3Leaf Development

Difficulty: Intermediate
Time Required: 1-3 hours
Cost: Free
Software: Visual Basic or Visual C# Express Editions, DirectX SDK
Hardware: None
Download: Download
 
Beginning Game Development Series
  1. Beginning Game Development Part 1 - Introduction
  2. Beginning Game Development Part II - Introduction to DirectX
  3. Beginning Game Development: Part III - DirectX II
  4. Beginning Game Development: Part IV - DirectInput
  5. Beginning Game Development: Part V - Adding Units
  6. Beginning Game Development: Part VI - Lights, Materials and Terrain
  7. Beginning Game Development: Part VII –Terrain and Collision Detection
  8. Beginning Game Development: Part VIII - DirectSound
  9. Beginning Game Development: Part VIII - DirectSound II
  10. Beginning Game Development: Part VIII - DirectSound III

Introduction

Welcome to the second article on beginning game development. In this article we are going to cover the basics of DirectX.

DirectX is a multimedia API that provides a standard interface to interact with graphics and sound cards, input devices and more. Without this standard set of APIs you would have to write different code for each combination of graphics and sound cards and for each type of keyboard, mouse and joystick. DirectX abstracts us from the specific hardware and translates a common set of instructions into the hardware specific commands.

Like all new tools, DirectX has a number of new terms and definitions that you need to understand. In addition to these new terms you also are going to have to brush up on your math skills. DirectX and game development in general is pretty math intensive, and it helps if you understand the basics. There is no need to get out the old calculator however, the idea is to understand the goal and the way to get to that goal, the rest we do in code with a number of pre-prepared math libraries.

DirectX Overview

DirectX first appeared in 1995 and was then called the “GameSDK”. In its original form it was targeted at developers using C and C++. Only with the release of the first managed version (9.0) of the API in December 2002 has it been possible to use C# or VB.NET with DirectX (actually you can use any CLR compliant language if you want to).

While much has been said and written about the performance of managed DirectX when compared to the unmanaged version, the fact that commercial games have already been created using managed DirectX should settle that argument once and for all. While certain games with extreme performance needs might need to use unmanaged code, most games can be created with managed code or using a mix of managed and unmanaged code. Writing in managed code makes the developers more productive and thus write more code and produces safer code.

After installing the DirectX SDK you should have a directory at C:\WINDOWS\Microsoft.NET\Managed DirectX with a subdirectory for each version of the SDK that has been installed on your machine. I am on my fourth version on the machine I am using and consequently I have four subdirectories. In each of these subdirectories you should have nine DLL and nine XML files. Since the managed world of .NET allows us to have multiple versions of the same DLL file on the same computer without causing the problems previously referred to as DLL-hell we can have multiple versions of the managed DirectX libraries available to us. This allows you to easily roll back to a previous version after installing a new version.

If you have previous experience with DLL files in Windows you might be worried that having multiple versions of the same file installed on the same computer will cause problems. These versioning issues are no longer an issue since the introduction of side-by-side versioning in .NET.  This means you can use the multiple versions to check for compatibility issues when a new version of the SDK is released without having to commit yourself to an upgrade.

The nine DLL files roughly correspond to the ten namespaces in DirectX. As we create our game we’ll use a number of these namespaces to provide support for input devices, sound, network play and of course 3D graphics.

Namespace Description
Microsoft.DirectX Common Classes and math Structures
Microsoft.DirectX.Direct3D 3D graphics and helper libraries
Microsoft.DirectX.DirectDraw Direct Draw graphics API. This is a legacy namespace and you should not need to use it.
Microsoft.DirectX.DirectPlay Networking API for multiplayer games
Microsoft.DirectX.DirectSound Sound support
Microsoft.DirectX.DirectInput Input device support (i.e mouse and joystick)
Microsoft.DirectX.AudioVideoPlayback Play Video and Audio (i.e playback a DVD on your PC)
Microsoft.DirectX.Diagnostics Troubleshooting
Microsoft.DirectX.Security Access security
Microsoft.DirectX.Security.Permissions Access security permissions

Figure 1. List of DirectX 9.0 namespaces.

Before we go any further we need to complete some unfinished business from the last article. After adding the FrameworkTimer class we were no longer able to build the project because we were missing the references to DirectX. Let’s fix that now and add them.

  • Right-click References in the Solution Explorer and select Add Reference.
  • On the .NET tab scroll down until you find the component named Microsoft.DirectX
  • While pressing the CTRL key select the following components: Microsoft.DirectX, Microsoft.DirectX.Direct3D and click OK.
  • The last step we need to complete before we can finally build the solution is to comment out the portions of the dxmutmisc.cs file we do not need.
  • Open the dxmutmisc.cs file and comment out all of the code other than that in the Native Methods and Timer regions.
  • Now build the solution (press F6). If you did everything right the solution will now build.

 My GPU is Bigger than Yours

Before we dig into the DirectX API let’s take a step back and think about what we are trying to do. To create a fast game we need to use some type of processor that allows us to compute the actual picture that will be shown on the monitor. Since none of us have 3D monitors that image will be 2D. So we need to do some math to compute each and every frame by converting 3D models into 2D images. If we used the CPU of the computer for all of these calculations our game would run slower, since we also have to use the same CPU to compute the AI, check for input, and oh by the way, we still need to run the operating system and all the background processes. If we can pass the computation of the graphics portions to a separate processor we can speed things up.

Modern graphics cards have their own processor called a Graphics Processing Unit or GPU. These GPUs are specialized processors optimized to do the type of calculations we need. In addition each graphics card also has its own memory, in effect making it a separate computer inside our computer. This means that regardless how big and fast your basic computer is, graphics speed is dependent more on the GPU and video memory than anything else.

Adapters and Devices

Most graphics cards allow only one monitor to be connected at a time, but some provide support for multiple monitors. You could also have more than one graphics card in your computer at a time. Regardless of your setup, each graphics card has an Adapter. You can think of this as the physical video card in your computer.  The adapters have “names” in the computer sense, with the first, or default adapter, being “named” 0, the second adapter 1 and so on. In DirectX you do not directly interact with the adapter. Instead you connect to an adapter using a Device.

A device represents a connection to a specific adapter; each adapter can have multiple devices associated with it. DirectX supports three types of devices: Hardware, References and Software. We will use the Hardware type for our game as it provides the speed we need to run our game.

Now its time to create the device we are going to use for our game. Add the following code to the constructor of the GameEngine form after the existing code. We are using the constructor because we can guarantee that any code in it will be run before anything else. This ensures that we always have a valid device object to reference later on.

  • Add the following code to the GameEngine constructor immediately following the this.SetStyle statement

Visual C#

// Get the ordinal for  the default adapter    
int adapterOrdinal = Manager.Adapters.Default.Adapter;
// Get our device capabilities so we can check them to set up the
// CreateFlags
Caps caps = Manager.GetDeviceCaps(adapterOrdinal, DeviceType.Hardware);
CreateFlags createFlags;
// Check the capabilities of the graphcis card is capable of
// performing the vertex-processing operations
// The HardwareVertexProcessing choice is the best
if (caps.DeviceCaps.SupportsHardwareTransformAndLight)
{
createFlags = CreateFlags.HardwareVertexProcessing;
}
else
{
createFlags = CreateFlags.SoftwareVertexProcessing;
}
// If the graphics card supports vertex processing check if the device
// can do rasterization, matrix transformations, and lighting and
//shading operations
// This combination provides the fastest game experience
if (caps.DeviceCaps.SupportsPureDevice && createFlags ==
CreateFlags.HardwareVertexProcessing)
{
createFlags |= CreateFlags.PureDevice;
}

// Set up the PresentParameters which determine how the device behaves
PresentParameters presentParams = new PresentParameters();
presentParams.SwapEffect = SwapEffect.Discard;

// Make sure we are in windowed mode when we are debugging
#if DEBUG
presentParams.Windowed = true;
#endif
// Now create the device
device = new Device(adapterOrdinal,DeviceType.Hardware,this,
createFlags,presentParams);

Visual Basic

' Get the ordinal for the  default adapter
Dim adapterOrdinal As Integer = Manager.Adapters.Default.Adapter
' Get our device capabilities so we can check them to set up the
' CreateFlags
Dim caps As Caps = Manager.GetDeviceCaps(adapterOrdinal,
DeviceType.Hardware)
Dim createFlags As CreateFlags

' Check the capabilities of the graphcis card is capable of
' performing the vertex-processing operations
' The HardwareVertexProcessing choice is the best
If caps.DeviceCaps.SupportsHardwareTransformAndLight Then
createFlags = createFlags.HardwareVertexProcessing
Else
createFlags = createFlags.SoftwareVertexProcessing
End If
' If the graphics card supports vertex processing check if the device
' can
' do rasterization, matrix transformations, and lighting and shading
' operations
' This combination provides the fastest game experience
If caps.DeviceCaps.SupportsPureDevice AndAlso createFlags = _
createFlags.HardwareVertexProcessing Then
createFlags = createFlags Or createFlags.PureDevice
End If
' Set up the PresentParameters which determine how the device behaves
Dim presentParams As New PresentParameters()
presentParams.SwapEffect = SwapEffect.Discard

' Make sure we are in windowed mode when we are debugging
#If DEBUG Then
presentParams.Windowed = True
#End If
' Now create the device
device = New Device(adapterOrdinal, DeviceType.Hardware, Me, _
createFlags, presentParams)
  • At the end of the form, right after the declaration of the deltaTime variable, add the following code:

Visual C#

private Device device;

Visual Basic

Private device As Device

This is a lot of code just to get a Device configured, but this approach to setting up the device is the safest way of ensuring that we maximize the performance of our game based on the graphics card’s hardware. The easiest way to understand this block of code is to break it into four distinct pieces.

  1. The first line of code simply gets the name of the default adapter which is usually 0. Instead of betting that it is zero it is safer to use the Manager class to get the name of the default adapter. This way things don’t go south if for some reason the default adapter name is really 2.
  2. The next section of code is used to determine the settings of the CreateFlags enumeration that we pass to the Device constructor and which governs the behavior of the device after creation. Again we use the Manager to get a listing of the capabilities (called Caps for short) for the default adapter. We then use this listing of capabilities to determine whether to perform vertex processing in hardware (which is faster) or in software (which is slower but guaranteed to always work). This is actually a misnomer, as the SoftwareVertexProcessing really means that we use the CPU while the HardwareVertexProcessing uses the GPU. We then perform another check to see if our adapter can support a pure device, meaning the graphics card can do rasterization, matrix transformations and lighting and shading calculations. If the device can and the previous check determined that we can use hardware vertex processing we add the PureDevice setting to the CreateFlags enumeration. The combination of HardwareVertexProcessing and PureDevice provides us with the best possible performance, so we want to use it if we can.
  3. The final parameter required to create the Device is the PresentParameters object. This object determines how the device presents its data to the screen, hence the name. First we set the SwapEffect enumeration, which determines how the buffer and the device relate to each other. By selecting the Discard option we are choosing to simply discard the back buffer and write directly to the front buffer. Inside the If statement we determine if the application is running in Debug mode. If we are in debug mode we do not want to run in full screen mode, which is the default, because it makes debugging very difficult. Using this method to determine the configuration is better than hard coding it and then forgetting to switch it when releasing the game.
  4. The final step is to actually create the device. We pass in the ordinal of the default adapter, the window we want to bind the device to, the device type, and then pass in the CreateFlags and PresentParameters objects we created previously.

The net effect of all of this code is that we have a valid device we can use to draw to the screen with. To actually use the device we need to add two lines of code inside the render loop.

  • Add the following code in the OnPaint method immediately following the FrameworkTimer.Start() statement.

Visual C#

device.Clear(ClearFlags.Target, Color.DarkBlue, 1.0f, 0);
device.Present();

Visual Basic

device.Clear(ClearFlags.Target, Color.DarkBlue, 1.0F, 0)
device.Present()

The first line clears the window with the color indicated in the second parameter (you can use any of the predefined windows colors in the Color enumeration). The last two parameters of the Clear method describe the z-depth and stencil values and are not important at this time.

The Present method of the device causes the device to display the contents of the back buffer to the screen. The screen is also called the front buffer and how these buffers interact is the determined by the SwapEffect enumeration you set earlier.

Now we run the solution and viola – we have a blue screen. While this is not very impressive and it seems like a lot of code to get a simple blue screen we have now successfully integrated DirectX into our GameEngine.

3D Graphics Terminology

Before we continue and render the terrain and units we need to step back for a minute and cover some of the principles and definitions used in three-dimensional graphics programming. We are not doing this so we can sound smart among our friends, but because these principles and terms provide the foundation for programming with three-dimensional graphics.

The game I am currently playing is called Brothers in Arms: Road to Hill 30 (www.brothersinarmsgame.com). It is a first person shooter game set in Normandy France in 1942. All of the terrain, buildings, roads, rivers, etc. in this game are exact replicas of the original terrain in Normandy in 1942. The game creators used aerial photographs and maps to recreate the terrain and traveled to France to survey the terrain themselves. They used this information to recreate the original terrain for the game. When we need to describe where in the world something is located, such as the Space Needle in Seattle, we commonly use a coordinate system called the geographic coordinate system (http://en.wikipedia.org/wiki/Geographic_coordinate_system). In this system we express each point as a unique Latitude/Longitude pair (the Space Needle is located at: Lat: 47.62117, Long: -122.34923).

When the creators of the game transferred the terrain to the computer they could not just provide the Latitude/Longitude coordinates to DirectX because the computer has no idea how to represent geographic coordinates. To be able to place objects into a three-dimensional world we have to come up with a coordinate system the computer does understand and transform the coordinates from one system to another. The coordinate system used in DirectX is the left-handed Cartesian coordinate system.

Cartesian Coordinate system

To properly place objects into a three-dimensional world we need to know where to place them and how to define each point unambiguously. We accomplish this using the Cartesian coordinate system. This Cartesian coordinate system is comprised of three axes at right angles to each other with the point of intersection being called the origin (the one you are probably more familiar with is the two-dimensional version with only the x and y axes used in High School geometry). Two additional properties are needed to fully define this three-dimensional coordinate system: handedness and orientation.

Handedness

To make life just a little bit more challenging, there are actually two ways to represent a three-dimensional Cartesian coordinate system: Left-handed and right-handed. If you follow this link (http://en.wikipedia.org/wiki/Cartesian_coordinate_system) you can find out more behind the reason for this, but the main thing to remember is that DirectX uses the left-handed coordinate system. The net effect of using the left-handed coordinate system is that the greater the Z value the greater the distance, while in the right-handed system the values get smaller as the distance increases. You need to know the handedness of the coordinate space to compare two objects using their Z values and to know which one is further away from you.

Orientation

The only other thing of note about the three-dimensional Cartesian coordinate system is that it can have different orientations depending on how the z-axis is drawn. If it is drawn vertically as pictured below on the left then it is called the world coordinates orientation if it is drawn as on the right it is called the local or body coordinates orientation.

Regardless of the orientation you use to reference your points to, the coordinates must be transformed to screen coordinates (two-dimensional screen space) in order to be drawn on the screen.

Figure 2: 3D Cartesian Coordinate systems

Vector

Each point in the three-dimensional coordinate system is defined by three values, the X, Y and Z values. To make life a little easier DirectX provides us with a structure called a Vector3 that lets us store these coordinates. This is purely for our convenience though, as a vector is defined as an object that denotes both direction and velocity and not a location. The methods of the vector class are used towards that end, but for now it’s a convenient structure to store the three values in. Depending on your need can also use the Vector2 or Vector4 structures.

Vertex

In the code we added to connect to our device you may have noticed that we needed to determine if we should do vertex processing in software or hardware. So what is vertex processing and what is a vertex? A vertex is a point that is part of a three-dimensional object. A vertex consists of a vector and additional information concerning texture mapping.

Texture

A texture is simply a 2D bitmap that is applied to a 3D object to provide it with some type of look (texture) such as grass, concrete etc.

Mesh

We are not going to cover using meshes in this article; the definition of a mesh is tied to that of a vertex, so let’s get it out of the way now. A mesh is the data that describes a three-dimensional shape. This data includes the list of vertexes for the shape as well as information describing how the vertexes are connected and information concerning the textures that cover them.

As you can see, a Mesh is made up of vertices, which in turn contain a vector. Each level simply adds some information concerning how the separate pieces are related to each other. From now on when you hear vector think point, when you hear vertex think point and data, and when you hear mesh think many points and more data.

Triangles

Now that you know that a vertex is really just a point in 3D space, we need to cover how the points are combined to form the objects. Every object in DirectX is composed of one or more triangles. While this may seem awkward at first, it is actually possible to represent any 2D or 3D shape using triangles. The reason for this is simple: triangles are the simplest polygon that is coplanar (all the points of the triangle are on the same plane). This simplifies the math needed to perform all calculations.

While all of this seems to be a lot of new terms to learn, it is important to understand these basic ideas before moving on to matrices. We are going to cover them and the principle behind a camera (in the DirectX sense of the word) and transformations in the next article. We are also going to explain what meshes are and how the texture mapping information of a vertex is used.

A Frame Rate Counter

As I mentioned in the first article, we are going to add a frame rate counter to our game. Knowing the frame rate of your game is important because it determines the speed of your game. Additionally, knowing what the frame rate is now before we add any code to the render loop will show us how each addition affects the speed of the game.

  • Add a new class to the project and name it FrameRate.
  • Add the following code inside the class declaration.

Visual C#

public static int CalculateFrameRate()
{
if (System.Environment.TickCount - lastTick >= 1000)
{
lastFrameRate = frameRate;
frameRate = 0;
lastTick = System.Environment.TickCount;
}
frameRate++;
return lastFrameRate;
}

private static int lastTick;
private static int lastFrameRate;
private static int frameRate;

Visual Basic

Public Shared Function CalculateFrameRate() As Integer
If System.Environment.TickCount - lastTick >= 1000 Then
lastFrameRate = frameRate
frameRate = 0
lastTick = System.Environment.TickCount
End If frameRate += 1
Return lastFrameRate
End Function 'CalculateFrameRate

Private Shared lastTick As Integer
Private Shared lastFrameRate As Integer
Private Shared frameRate As Integer
  • In the GameEngine OnPaint method add the following line of code immediately after the assignment of deltaTime.

Visual C#

this.Text = string.Format("The framerate is {0}", 
FrameRate.CalculateFrameRate());

Visual Basic

Me.Text = String.Format("The framerate is {0}", _
FrameRate.CalculateFrameRate())

This frame rate counter uses the TickCount property of the System class which is a wrapper to the GetTickCount method of the WIN32 API and has a precision of approximately 15 milliseconds. While the FrameworkTimer class is more accurate, this precision is good enough to compute the frame rate.

Code Housekeeping

Before we finish up there are two code changes I made to the original code. First I removed the Application.EnablRTLMirroring() statement from the Program class. This method has been deprecated in the Beta2 version of the .NET Framework. The other change I made is to wrap the creation of the GameEngine class into a using statement. This ensures that regardless of what happens in the GameEngine class it will always be properly disposed when we close the application.

Summary

At this point you might be wondering if we are ever going to start working on our game. One of the challenges with learning game development is that you have to create a good foundation at the beginning so the more advanced ideas make sense later on. Once you understand the 3D graphics terms and principles you are free to concentrate on the game creation.

In this article we introduced DirectX which is the API we are going to use for 3D graphics, input device control and sound in BattleTank 2005. Then we discussed what a GPU is and why it is so important for today’s games. We also covered what an Adapter and Device are and how to configure them in DirectX. Then we entered the world of terms and definitions that we need to understand moving forward. Finally we added a frame rate counter to the game to track game performance.

In the next article we’ll cover matrices and transforms, how to place a camera into the 3D world and what clipping and culling are. In that article we are also going to add the landscape for our game.

I hope that the first foray into the world of DirectX has not discouraged you too much. Because some definitions and principles are a little hard to understand just by reading them I suggest you write some code and play with the various settings to see what happens. The DirectX SDK also includes a great number of samples and tutorials that cover this same subject matter and let you experiment with the settings.

]]>

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Adam Duncan said on February 10, 2007 7:20 PM:

Just thought I'd suggest linking to the previous/next sections of this tutorial. I've also have troubles finding each section of this article via your web page. After I did section 1 I couldn't find section 2 without typing 'Beginning Game Development: Part II' into google. Perhaps I'm blind and just missed a very visible link to the articles but right now I'm not seeing it. Thanks,

Adam

# Sean said on April 7, 2007 2:40 AM:

After Putting in Private Device device .......... It said It couldn't find a Namespace Device

# Trubkins said on April 21, 2007 5:42 AM:

Sean, you must right-click it and choose "using Microsoft.DirectX" to link it to that class ;)

# Bob said on April 23, 2007 4:42 AM:

make sure you put in -

using Microsoft.DirectX.Direct3D;

- on around line 13 in the GameEngine.cs

# Lubo said on April 24, 2007 4:58 AM:

"After Putting in Private Device device .......... It said It couldn't find a Namespace Device"

u just need to put

using Microsoft.DirectX;

using Microsoft.DirectX.Direct3D;

in GameEngine class

# Anton said on April 25, 2007 4:35 AM:

I have had the same issue as Sean (April 7, 2007)

I added the code: using Microsoft.DirectX.Direct3D;

and the error dissapeared. I hope that this would be sufficient to use for the rest of the game.

Anton

# Alxandr said on April 25, 2007 10:45 AM:

I still get the error about namespace samples is not part of class microsoft... I've done everything as you said... Pleas help...

# Daniel Gouveia said on April 26, 2007 9:37 PM:

Hi!

Sean, you must put the following line:

using Microsoft.DirectX.Direct3D;

See ya!

# Neil said on April 26, 2007 9:42 PM:

re: Namespace Device error, make sure to add the "using Microsoft.DirectX;" and "using Microsoft.DirectX.Direct3D;" directives to the top of your GameEngine.cs file

# Nebs said on April 27, 2007 11:15 AM:

I get the same error as Sean...

Error 1 The type or namespace name 'Device' could not be found (are you missing a using directive or an assembly reference?)

# Nebs said on April 27, 2007 11:21 AM:

Never mind, fixed the problem.

You must add this at the top:

using Microsoft.DirectX.Direct3D;

# Billy said on April 27, 2007 9:33 PM:

I plugged in the Private Device device, and is said that it coudn't find a namespace device.

# Matt said on April 28, 2007 10:39 AM:

Same problem,Can't find the Namespace Device

# yianna said on April 29, 2007 7:10 AM:

if it couldn't find a Namespace...add to code

using Microsoft.DirectX.Direct3D;

# daniel eaton said on April 30, 2007 5:56 AM:

yea it says to be exact.. The type or namespace name 'Device' could not be found(are you missing a using directive or an assembly reference.

those words pop up in my compiler. it is saying to me as i think i may be wrong but your trying to create a type of something we havent got down.. #include<somefile> anyone?

# daniel eaton said on April 30, 2007 5:58 AM:

also any chance you can post the actual code. this will enable us to compare it. copy paste the gameengine class would be appreciated

# Lee Gould said on May 3, 2007 2:54 PM:

I am interested in learning how to use models in this content, I am a new person to this your help would be apreciated.

# Noah said on May 4, 2007 11:56 AM:

Visual C# didn't like the int's in declarations in the FrameRate class

# Pratith said on May 5, 2007 4:22 AM:

yeah!....i'm having the same problem....it said it couldn't  find a namespace Device....

# Mike said on May 6, 2007 5:49 PM:

Device is located under Microsoft.DirectX.Direct3D

# Croc said on May 10, 2007 7:20 AM:

Sean: you must add

"using Microsoft.DirectX.Direct3D;"

to the GameEngine-class.

# Silicon Brain said on May 11, 2007 10:18 AM:

># Sean said on April 7, 2007 2:40 AM:

>After Putting in Private Device device .......... It said It couldn't find a Namespace Device

You should add 'using Microsoft.DirectX.Direct3D;' to the others, than it'll work.

Silicon Brain

# Sunny said on May 13, 2007 1:54 AM:

private Device device; gave an error, adding Microsoft.DirectX and Microsoft.DirectX.Direct3D to the references did not work for me (c# express).  I had to add them in the using section:

using Microsoft.DirectX;

using Microsoft.DirectX.Direct3D;

# Heien said on May 15, 2007 5:02 AM:

The type of namespace name 'Device' could not be found.

It occured after putting in the: private Device device;

I'm a total noob in this and am stuck here, can anybody help me?

# Aaron said on May 15, 2007 5:00 PM:

Use

using Microsoft.DirectX.Direct3D;

in the using region

if you get the namespace error for

private Device device;

# Carl said on May 21, 2007 5:58 PM:

To Sean

Just float your mouse on the device word in your code page.Click on the arrow that appears you'll get a small box next to the word device.Click on Direct 3D Device.

# Tim said on May 22, 2007 3:58 AM:

To Sean

You just need to include directX libraries

# Shane said on May 22, 2007 10:25 PM:

i had the same problem as sean

# Nevin Morrison said on May 24, 2007 1:53 AM:

Sean,

Add the following using directive to the top of your GameEngine form:

using Microsoft.DirectX.Direct3D;

Nevin

# Medárd said on May 24, 2007 9:06 AM:

Type this line:

using Microsoft.DirectX.Direct3D;

and the problem is solved

# Peter said on May 24, 2007 3:05 PM:

I've just made the program upto the paragraph "3d Graphics Terminology" and my program just crashes. After commenting some code out is seems that the line with "new Device(etc.)" causes the problem, any suggestions?

# Mark said on May 25, 2007 1:52 AM:

you need to make sure you have using Microsoft.DirectX.Direct3D; at the top when u have ur input of "private device device" to work and not bring up the namespace not found message

# Dast said on May 27, 2007 12:01 AM:

For whatever reason, I get an exception thrown from the constructor of Device if I don't set presentParams.Windowed = true.  I don't know why, but when this is not set on my system, the constructor throws an unhelpful (Message = "Error in Application") exception...

Any ideas?

# Mike said on May 30, 2007 5:00 AM:

Dast, in order to you Windowed mode you must setup BackBuffers in the PresentParameters.

# Ondrej said on May 30, 2007 12:03 PM:

When I try code for VB from part I or part II, I get the same error message: 'Samples' is not a member of 'Microsoft'. Do I have to install C# for support of DirectXSampleFramework?

# Craig said on June 6, 2007 5:00 PM:

When i get to the point of commenting out the stuff in dxmutmisc.cs and try to build i get the following errors:

This one is from the GameEngine.cs file, with reference to the OnPaint method parameters:

Error 1 The type or namespace name 'PaintEventArgs' could not be found (are you missing a using directive or an assembly reference?)

And i get a few of these every time i have something to do with the Drawing object.

Error 7 The type or namespace name 'Drawing' does not exist in the namespace 'System' (are you missing an assembly reference?)

I have followed everything as explained and i am using the DirectX SDK (April 2007)

# Jon said on June 14, 2007 1:43 PM:

I get an error when trying to compile and the debugger stops at the line of code: Application.Run(new GameEngine() );

The error is:

BadImageFormatException was unhandled

"is not a valid Win32 application. (Exception from HRESULT: 0x800700C1)"

Anyone else get this or know how to resolve it?  I assume it may have something to do with the 64-bit OS.

# Dennis said on June 23, 2007 10:17 AM:

Caps caps = Manager.GetDeviceCaps(adapterOrdinal, DeviceType.Hardware); throws an exception

An unhandled exception of type 'Microsoft.DirectX.Direct3D.NotAvailableException' occurred in Microsoft.DirectX.Direct3D.dll

Any Ideas

# Dan said on June 23, 2007 6:42 PM:

I made the program up to "3d Graphics Terminology", and I'm using Microsoft.DirectX.Direct3D but the program will only run in Debug mode.  Otherwise it crashes.

# Luke said on June 26, 2007 8:42 AM:

I get this exception when I try and debug or run the program, this is with downloaded battletank files so no mistyping from me.  Can anyone help me (email:luke321321{at]gmail DoT com, exception:

System.BadImageFormatException was unhandled

 Message=" is not a valid Win32 application. (Exception from HRESULT: 0x800700C1)"

 Source="BattleTank2005"

 StackTrace:

      at BattleTank2005.GameEngine..ctor()

      at BattleTank2005.Program.Main() in C:\Users\Luke\Documents\Visual Studio 2005\Projects\BattleTank2005\BattleTank2005\Program.cs:line 19

      at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)

      at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()

      at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

      at System.Threading.ThreadHelper.ThreadStart()

# Angel said on July 1, 2007 8:16 PM:

I cant build at the step right before "My GPU is Bigger than Yours". I get this error:

Error 1 'BattleTank2005.GameEngine.Dispose(bool)': no suitable method found to override C:\Users\Angel\AppData\Local\Temporary Projects\BattleTank2005\Form1.Designer.cs 14 33 BattleTank2005

and it points to the line:

protected override void Dispose(bool disposing)

# Angel said on July 1, 2007 8:46 PM:

Ok, I fixed the problem (I didnt add .cs when I renamed form1 to GameEngine). But now, after adding "Microsoft.Samples.DirectX.UtilityToolkit;" at the top of the code, I get an error that says:

Error 1 A namespace does not directly contain members such as fields or methods C:\Users\Angel\AppData\Local\Temporary Projects\BattleTank2005\GameEngine.cs 1 1 BattleTank2005

P.S. Is it the placement? I put it at the very top

# Zach said on July 3, 2007 4:15 PM:

      When I put in the code:

this.Text = string.Format("The framerate is {0}",

       FrameRate.CalculateFrameRate());

C# comes up with a bunch of errors.

I put the code right after the code that says:

private double deltaTime;

Am I putting it in the wrong place or what. Please help

# Lance said on July 10, 2007 8:40 AM:

Anyone solved Dast's problem?  I am having the same issue.

# Hagit said on July 12, 2007 10:12 AM:

Hello,

I get an error after I press f6: "Error 1 The type or namespace name 'Samples' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) "

I tried to add: using Microsoft.DirectX.Direct3D;

The problem remains.

my email:hagitha25@walla.co.il

Do you know what to do in this case?

thank u...

# gopal said on July 12, 2007 3:24 PM:

I am getting Microsoft.DirectX.Direct3D.NotAvailableException at Caps caps = Manager.GetDeviceCaps(adapterOrdinal, DeviceType.Hardware);

Any suggessions?

Thanks

# belay said on August 2, 2007 7:55 AM:

I've got exception on the Device Constructor as Dast said it. Any useful ideas from those of who has worked it out after removing(commenting out) the

#if DEBUG

presentParams.Windowed=true;

#endif

section.

# Chris said on August 2, 2007 8:16 AM:

hey there,

at first i wan't to thank you for this very good article(s). I'm a programmer since two years now but i've never tried to to desing a came yet. YOU got me realy into that now ;)

Now my question:

is there any specific reason why you create global variables such as "deltaTime" or "device" at the very END of a class or is it just some sort of style?

I learned to create global variables always at the BEGINNING of a class.

It doesn't matter anyhow where i create them, does it?

Seems like i just learned a diffrent style... please correct me if i'm wrong.

chris from germany

# Zack said on August 8, 2007 11:01 AM:

When I run it in debug mode I get the blue window... but if I just run it (full-screen) it crashes.

I suspect Vista and DX10 are my problems... and fixes?

# rashmi said on August 9, 2007 1:25 AM:

I am getting a similar exception at

Caps caps = Manager.GetDeviceCaps(adapterOrdinal, DeviceType.Hardware)

The error string :"D3DERR_NOTAVAILABLE" and errror code -2005530518.

# jmasloff said on August 16, 2007 1:10 PM:

I am up to the part where it says to complile the program and you get a blue screen. I have done all the suggestions made including DirectX libraries and remcoing a few "unsafe" words from the dxmutmisc.cs file but I still get an error message about not finding the namespace "Framework" in that very file. I am using Visual C# Express Edition.

Any ideas?

# russ said on August 27, 2007 1:31 AM:

Hey just FYI, if you are running on 64 bit, you have to change the build tab on the project properties to build for x86, otherwise you get an error every time you try to run.

# Jason said on September 1, 2007 10:00 AM:

I get an error that says cannot process code for

if  (caps.DeviceCaps.SupportsHardwareTransformAndLight)    {

  createFlags = CreateFlags.HardwareVertexProcessing;

}    

else

{  

createFlags = CreateFlags.SoftwareVertexProcessing;

}

it says you shouldn't modify the code in the Initialize Component method.

# Ben said on September 5, 2007 10:41 AM:

I get the same exception if I don't set presentParams.Windowed = true

# Sean75071 said on September 6, 2007 9:26 PM:

I got the same error Sean did... I added using Microsoft.DirectX.Direct3D; but then it threw a warning:

Warning 1 Field 'BattleTank2005.GameEngine.device' is never assigned to, and will always have its default value null C:\Users\Sean\Documents\Visual Studio 2005\Projects\BattleTank2005\BattleTank2005\GameEngine.cs 32 24 BattleTank2005

Any one else get this warning also??

# David Powell said on September 10, 2007 6:19 PM:

I really like your writing style and I feel like I am learning a lot. At time it seems like you are trying to cram a lot of information into a little space but I understand where you are coming from. This is a tutorial and not a book. With that said I would like to suggest that you write a book and try to get one of those big publishers to pick you up. I'm sure it's easier said then done but after reading two parts of your tutorial I am hooked and would purchase your book and recommend it to others in a heart beat. I have wanted to write games for a long time now and this is the first time any tutorials have made since to me.

You stated you removed Application.EnablRTLMirroring() from the Program.cs class. My program.cs class did not have this method call in it. I assume this is because I am running a newer update of VS2005

My only question is: Can you elaborate more on why you added a using block in the program.cs class. Or better yet can you explain why or how it works. I understand the purpose but not why it does that.

# Martin said on September 11, 2007 9:51 PM:

Just so i understand, what do you mean by "wraping the creation of the GameEngine class into a using statement"? That was mentionned in the Code Housekeeping section.

Thank-you!

# Otto said on September 23, 2007 5:42 PM:

Same problem as Dast - without adding

presentParams.Windowed = true;

to the GameEngine() class, the program crashes.

OS I'm using is Windows Vista.

# Jerimie said on September 29, 2007 10:40 AM:

Problem that I am having is in the dxmutmisc.cs file provided with the 2007 SDK. FramWork is not identiefied:

Error 1 The type or namespace name 'Framework' could not be found (are you missing a using directive or an assembly reference?) C:\Projects C#\BattleTank2005\BattleTank2005\DirectXSupport\dxmutmisc.cs 2189 61 BattleTank2005

# Wayne said on October 6, 2007 9:31 PM:

Anyone figure out why it Crashes?  

I've added all the includes and what not... runs but crashes..

# Ryan said on October 15, 2007 5:46 AM:

Would anyone please tell me why the window stays grey when I start it? I told the computer to change the color to dark blue in the color part of the device's setup near the framework timer start function but it just won't do it! Any suggestions?

# Qua said on October 20, 2007 9:50 PM:

This articel is great. You understand how to take this subject and make me wanna learn everything about it. Your humor mixed in along is great!

Thumbs up for you.

# Anthony said on November 6, 2007 3:40 PM:

In the code housekeeping section you said you wrapped up creation of the GameEngine class into a using statement.

How and where did you do that?

Thanks!

# Alexander said on November 6, 2007 11:52 PM:

Your articles are great. Thanks!

# Coding4Fun said on November 15, 2007 11:53 AM:

@ Martin, Anthony:  using statements cause the dispose method to be called when a block is exited.  Very useful for closing connections and resource clean up.

http://ryanfarley.com/blog/archive/2004/03/18/447.aspx

http://dotnet.org.za/ernst/articles/510.aspx

# ayyash said on November 19, 2007 7:28 PM:

the crash pleeeeeeease ... what are we doing wrong ?????????

# SaWi81 said on November 29, 2007 4:48 AM:

After comparing files I found that

device.VertexFormat = CustomVertex.PositionColored.Format;

hast to before

device.DrawUserPrimitives(PrimitiveType.LineStrip, 6, CreateCrossHairVertexArrayTop());

Thats all with my crashes now it works fine

# Finn said on January 5, 2008 12:23 AM:

It looks like a lot of people are having the same problem that I am, namely that the Device constructor is throwing an InvalidCallException when running in non-Windowed mode.  As far as I can tell from documentation the back buffer format needs to be set to something other than unknown if you want to run non-windowed.  I've looked through the available formats and tried a few, but I still get the exception.  Anyone know if this is why the exception is occurring?  It's difficult to debug as you can't step into the Device constructor code.

# Jesse said on January 15, 2008 12:38 AM:

I'm using Visual Studio C# '05 Express Edition and have commenced developing an Xbox 360 game. I'm wondering if coding is any different because I have 12 errors and have done exactly as this tutorial has shown. PLEASE HELP

# Coding4Fun said on January 16, 2008 12:46 PM:

@Jesse, use XNA Game Studio instead if you want to develop in managed code for the 360.

# janaka said on January 17, 2008 2:17 PM:

Hi I am getting the following errors and cannot seem to able to get rid of them on the follow ing lines of code

// Tell DirectX we are about to draw something

           device.BeginScene();

device.DrawUserPrimitives(PrimitiveType.LineStrip, 6 , CreateCrossHairVertexArrayTop());

           device.DrawUserPrimitives(PrimitiveType.LineStrip, 6, CreateCrossHairVertexArrayBottom());

errors i get:

The name 'CreateCrossHairVertexArrayTop' does not exist in the current context

The name 'CreateCrossHairVertexArrayBottom' does not exist in the current context

Help

# Software Information » Coding4Fun : Beginning Game Development: Part II - Introduction to DirectX said on January 24, 2008 7:00 PM:

PingBack from http://softwareinformation.247blogging.info/coding4fun-beginning-game-development-part-ii-introduction-to-directx/

# Beginning Game Development with MS .NET | Newbie Game Programmers said on February 15, 2008 8:33 AM:

PingBack from http://www.savware.net/beginning-game-development-with-ms-net/

# Beginning Game Development with MS .NET | Newbie Game Programmers said on February 15, 2008 8:33 AM:

PingBack from http://www.savware.net/beginning-game-development-with-ms-net/

# daniel said on April 23, 2008 3:58 AM:

It is not looking for namespace Device it is looking for device.  (notice the case)

The name given to the variable Device is device.  It needs to be visible in other methods, so it needs to be declared at the beginning of the class.

Put in this line of code

Device = device.

# Coding4Fun : Beginning Game Development: Part II - Introduction to DirectX said on September 11, 2008 4:31 PM:

PingBack from http://blogs.msdn.com/coding4fun/archive/2006/11/03/940223.aspx

# Coding4Fun : Beginning Game Development: Part V - Adding Units said on September 11, 2008 4:37 PM:

PingBack from http://blogs.msdn.com/coding4fun/archive/2006/11/03/941679.aspx

# Coding4Fun : Beginning Game Development: Part I ??? Introduction said on September 11, 2008 4:40 PM:

PingBack from http://blogs.msdn.com/coding4fun/archive/2006/11/02/938703.aspx

# Coding4Fun : Beginning Game Development Part X ???Direct Sound Part III said on September 11, 2008 4:44 PM:

PingBack from http://blogs.msdn.com/coding4fun/archive/2008/01/07/7020067.aspx

# Coding4Fun : Beginning Game Development: Part VIII - DirectSound said on September 11, 2008 4:55 PM:

PingBack from http://blogs.msdn.com/coding4fun/archive/2006/11/06/999786.aspx

# Jenya said on October 2, 2008 1:35 AM:

I was wondering how do you properly wrap the 'GameEngine' class to dispose things in a correct manner. I set up the framework for the dispose following the links you provided.

But how do we exactly 'dispose' and what.

# Tim Martin said on December 7, 2008 11:56 AM:

In the #if state with the debug, DEBUG has to be in all caps in order for it to work.

# Nate said on April 29, 2009 12:24 PM:

For people having problems with 64 bit OS

  1. G in to the menu option Tools>Options and the in the dialog box tick the box in the bottom right corner to "Show all settings"

  2. Once the settings expand go to "Projects and Settings" expand it and click on "General"

  3. Check the option which is called "Show advanced build configurations", then close the dialog box

  4. Now if you right click on the solution explorer, chose properties

  5. Goto "Configuration Properties", now you should be able to see the platform drop down. This will probably have only "Any CPU" selected; if so click on "Configuration Manager"

  6. Chose the option "New" under the "Active Solution Platform" drop down box

  7. Chose the new platform of x86 and copy your settings from "Any CPU"

  8. Then just make sure that your projects in your solution refer to x86 as the platform rather that "Any CPU"

from http://opensebj.blogspot.com/2007/12/64-bit-windows-with-c-express-net-and.html

Leave a Comment

(required) 
(optional)
(required) 
Page view tracker