Click here to Skip to main content
15,890,527 members
Articles / Multimedia / DirectX
Article

Managed DirectX Tutorials: Part 2 - Initialising Direct3D

Rate me:
Please Sign up or sign in to vote.
4.04/5 (14 votes)
3 Feb 20064 min read 72.8K   892   42   6
This is the second in a series of tutorials designed to show you how to create a basic terrain engine.

Introduction

This is the second in a series of tutorials which will allow you to create your own game engine (from initialization, to a fully rotatable, height-mapped 3D world!).

In this second tutorial, we will actually write code to create a link to the computer's graphics card. To do this, we will initialize Direct3D, and create a Device object to represent the user's graphics card.

Background

The code from these tutorials is taken from my own game engine: MAGEngine.NET at different stages in development.

Using the code

You may use all of the code I provide as how you see fit, except to create another tutorial. You can use it as a sturdy(ish ;)) framework for your own applications, or print loads of copies off so that when I'm rich and famous you can sell them for $100 each ;)

Prerequisites

To do this series of tutorials, you will need:

  • C# Compiler (preferably Visual C# 2005 Express)
  • Managed DirectX 9.0 October SDK

Tutorial 1: Setting Up DirectX

Direct3D is the main component of DirectX graphics. With it, you can render and initialize 3D objects. We will not get to render anything in this tutorial, but we will set D3D up so that we can do this easily in the next tutorial.

Initialization

The point of initialising Direct3D is to get a Device object. This represents the user’s graphics card and has a set of functions to send and return data from it. To get this object, you need to set some variables.

The initialization function is as follows:

C#
public Device( 
    <A href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemint32classtopic.asp" target=_blank>int</A> adapter, 
    <A href="http://msdn.microsoft.com/archive/en-us/directx9_m_dec_2004/directx/ref/ns/microsoft.directx.direct3d/e/devicetype/devicetype.asp" target=_blank>DeviceType</A> deviceType, 
    <A href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemwindowsformscontrolclasstopic.asp" target=_blank>Control</A> renderWindow, 
    <A href="http://msdn.microsoft.com/archive/en-us/directx9_m_dec_2004/directx/ref/ns/microsoft.directx.direct3d/e/createflags/createflags.asp" target=_blank>CreateFlags</A> behaviorFlags, 
    <A href="http://msdn.microsoft.com/archive/en-us/directx9_m_dec_2004/directx/ref/ns/microsoft.directx.direct3d/c/presentparameters/presentparameters.asp" target=_blank>PresentParameters</A>[] presentationParameters );

OK, this may look complicated at first, but we can break it down.

  • adapter simply indicates which device to use – so for our purposes, this will always be 0.
  • deviceType is an enumeration of devices. For example, software or hardware.
  • renderWindow is simply a reference to the window it will be created in.
  • behaviourFlags are a set of flags defining how the device will be used.
  • presentationParameters is simply a structure you fill in with more detailed options regarding how the device will be used.

So, our initialization process will consist of two parts:

  • Initialize presentationParameters
  • Initialize device

To start with, add the following variables to the top of your window class:

C#
public Device device; 
public PresentParameters presentParams;

Now, before we get started on making a class and functions to initialize Direct3D, we should explore the PresentParameters structure more.

For this application, we only need to assign two members from the PresetnParameters structure - bool Windowed and SwapEffect swapEffect.

SwapEffect is an enumeration of ways to “flip” the screen. This means, to update or refresh the current frame in the game, we can do:

C#
public PresentParameters SetPParams() { 
  PresentParameters pp = new PresentParameters(); 
  return pp;
}

This will be set as the framework for the function that will create the presentation parameters for us in our engine. Now, as stated before, we need to input two variables and edit these accordingly, so simply add a bool and SwapEffect to the parameters of the function, and then in the body, in between the PresentParameters() initialization and the return code, put the lines to assign your present parameters. Your finished function (and class) should look like this (put this in a separate code file called Engine.cs):

C#
public partial class cEngine
// the partial keyword specifies that this
// class is declared in multiple files
{
  public PresentParameters SetPParams (bool wind, SwapEffect swap)
  { 
    PresentParameters pp = new PresentParameters();
    pp.Windowed = wind; // Is our device going to be running
    // in a windowed or full screen application?

    pp.SwapEffect = swap;
    // How should we handle the refreshing of our application? 
    return pp; 
  }
}

So, that covers PresentationParameters - but now we need to create a class to initialize the device.

As mentioned before, the device represents the GPU, or graphics card. Towards the top of this tutorial, you saw a layout of the Device constructor. There are some overloads of this, but the one chosen above is the best for our needs. It shouldn't be too hard to make a function within our cEngine class to handle the device - but if you were wondering:

C#
public partial class cEngine
// the partial keyword specifies that
// this class is declared in multiple files
{
  public Device SetDevice( Control wnd, PresentParameters pp)
  {
    Device device = new Device(0, DeviceType.Hardware, 
           wnd, CreateFlags.HardwareVertexProcessing, pp);
    return device;
  }
}

This function simplifies the creation of a device by limiting the number of parameters, as ones which are almost always the same are omitted.

With these two methods, all you need to do to get your D3D application running is add the required variables to the Form class and then call the two methods like so:

C#
//Form1
public cEngine Engine = new cEngine(); 

//Main
using (Form1 GameWindow = new Form1())
{
  GameWindow.presentParams = 
     GameWindow.Engine.SetPParams(true, 
     SwapEffect.Discard);
  GameWindow.device = 
     GameWindow.Engine.SetDevice(GameWindow, 
     GameWindow.presentParams);
  Application.Run(GameWindow);
}

If you get errors, make sure you have using statements in your Form class for the namespace containing your engine declaration.

Now, when you run this application, there is no proof of all that work you did - which I personally find annoying. So, add a paint event handler to the form.

X-CHALLENGE

  • Create an overload for the above function which sets the number of back buffers as well as the back buffer width and height.
  • Create a function which merges the Device and PresentParameter initialization functions.

Well done - you should now have a working Direct3D application, along with a basic framework!

Get ready to move on to tutorial 3 - where we will actually render something on screen!

Contact

Please send all emails to xpyder@magclan.cwhnetworks.com. I do have MSN Messenger, my email address for this is jamespraveen@aol.com.

History

  • 19/01/06: Submitted tutorials 1-3 to CodeProject.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
CEO Synap
United Kingdom United Kingdom
Founder & CEO of Synap, an online education platform that uses machine learning to help people learn more in less time.

Software developer, main languages currently are Objective-C, MySQL and Javascript, though I got started on C++, C# and PHP.

Comments and Discussions

 
GeneralSlight clarification needed... [modified] Pin
Vorlin26-Dec-06 20:07
Vorlin26-Dec-06 20:07 
James,

********* Edit: It's 2 AM and the dog has it coming out of "both ends" as I try to do this tute.... somehow in an over tired haze, I couldn't find the source download link... so I wrote the below post. I'll leave it here so you can see where the explaination was unclear but by the time you read this I'll have looked at the source, figured it out and moved on. That is, after I get some more paper towels and burn a few candles because the dog is at it again. She's tiny and it's way too cold to lock her outside... and how can you be mad at a dog for being sick? Ugh, what a night....*********

Way to go with all this! I'm 41 and it's a little odd to be taking lessons from you considering your age but not as odd as one might think... after all, the technology is only a few years old so you've had as much time to lean it as anyone else.

The one thing that has me wondering is where you say to declare a new cEngine inside the form when you used //Form, which is fine, but then you say:

//Main
using (Form1 GameWindow = new Form1())
{
bla bla bla
}

Ummm, James? What do you mean by "//Main"???

This gets tricky because you had us create a new Windows project in Tute 1 and then delete the Designer.cs file rather than do what most others are doing with D3D, which is start with a completely empty project. In their code, I'd say that your Main = their Main() but, since you had us use a windows project, the Main() is elsewhere.

I tried placing it inside:
public partial class Form1 : Form { }

... but it's erroring out, saying that the using() is illegal within a class/struct/member declaration.

I understand the using() part just fine and why it's needed... but this tute is a little unclear when it comes to where I need to place this particular piece of code. I'll try fudging around a bit to see where it works and what I can get to happen.

I've tried a few other tutes on DX D3D and I have to say that you're a better tute writer than most... you explain it all very well and stay with terms, and a pace, that don't lose your reader. In the other tutes, they all start with an empty project so a lot of this is going into a manually written Main()... which is leaving me just a little unsure about where I'll be able to make this fit into a windows project but I'll see what I can figure out.

Any clarification is appreciated... and, again, nice job on these tutes in general! You've got a real future in documentation writing if you decide to go that route!

Vorlin / Scott


-- modified at 2:15 Wednesday 27th December, 2006
GeneralException when creating the device Pin
iGb2-Nov-06 1:31
iGb2-Nov-06 1:31 
GeneralRe: Exception when creating the device Pin
iGb2-Nov-06 3:27
iGb2-Nov-06 3:27 
GeneralLooking For A Link Pin
xcorporation8-Oct-06 22:45
xcorporation8-Oct-06 22:45 
GeneralThis is me.... 15 years ago :-) Pin
Sascha Sertel3-Feb-06 9:31
Sascha Sertel3-Feb-06 9:31 
GeneralRe: This is me.... 15 years ago :-) Pin
bootkey11-Jan-07 3:31
bootkey11-Jan-07 3:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.