Greg Dolley’s Weblog

A Blog about Graphics Programming, Game Programming, Tips and Tricks

Archive for February 26th, 2008

Managed DirectX C# Graphics Tutorial 1: Getting Started

Posted by gregd1024 on February 26, 2008

I’m going to demonstrate the same principles as my last post (DirectX 9 C++ Graphics Tutorial 1), how to fill a form with a solid color – except this time it’ll be in .NET using C# and Managed DirectX (MDX 1.1). MDX 1.1 is meant to expose most of the functionality as native DirectX 9.

Requirements

Everything in this tutorial is based on Visual Studio 2008 Express.

You’ll also need the DirectX SDK. You can download it from Microsoft’s site with this link. Note that this is the June 2007 release. I purposely didn’t link to the latest (November 2007 at the time of this writing) because Microsoft has removed the Managed DirectX samples and documentation from that release. If you read my last post, then you know that Microsoft has moved MDX’s functionality into the XNA framework, but threw out all features which were not simultaneously supported by both Xbox and Windows.

Tutorial Source and Project Files

To get the finished result of what this tutorial teaches – project files, binaries, and source – use this link:

Download C# Sources and Binaries [~10k]

Step 1: Create and Setup Your Project

We’re going to start from absolute scratch – that means no wizards and no auto-generated code. So start out by creating an empty C# project. You can name it whatever you like and place it in any directory.

Now add the following references:

  • Microsoft.DirectX
  • Microsoft.DirectX.Direct3D
  • System
  • System.Drawing
  • System.Windows.Forms

Go into your project settings and change the output type from “Console Application” to “Windows Application.”

managed_directx_tutorial_1_project_settings

Add one source file called “main.cs” (actually, you can use a different name but I’m going to refer to this file as “main.cs” throughout the tutorial).

Step 2: Create the Form

Inside “main.cs” you’re going to add the following “using” statements:

using System;

using System.Windows.Forms;

using Microsoft.DirectX;

using Microsoft.DirectX.Direct3D;

To make the form, copy the following code snippet and paste it directly underneath the “using” statements:

namespace MDX_Tutorial1
{
   class MainClass:Form
   {
      MainClass()
      {
         this.Text = “Managed DirectX Tutorial 1”;
      }

 

      static void Main()
      {
         MainClass MainForm = new MainClass();
         Application.Run(MainForm);
      }
   }
}

Step 3: Create the Device Object

Just like the previous post’s C++ example, you’ll have to create a device object. Since we’ll be accessing this object in multiple functions, it must be a class member variable. Add the following declaration inside “MainClass”:

private Device m_device = null;

Also add a method called “InitGraphics()” – this is where we’ll create and initialize the device object. The initialization code is only a few lines:

void InitGraphics()
{
   PresentParameters present_params = new PresentParameters();
  

   present_params.Windowed = true;
   present_params.SwapEffect = SwapEffect.Discard;
  

   m_device = new Device(0, DeviceType.Hardware, this,

                         CreateFlags.SoftwareVertexProcessing, present_params);
}

First, we create the “PresentParameters” object. This object describes how DirectX should behave in our application. We want the application to be a window and we’ll let the device handle the back buffer (“Windowed” and “SwapEffect”). Next, we actually create the device. There are several overloads for the constructor of “Device” but the one we’re interested in takes five arguments as described below:

  • Parameter 1: “int adapter”
  • Parameter 2: “DeviceType deviceType”
  • Parameter 3: “Control renderWindow”
  • Parameter 4: “CreateFlags behaviorFlags”
  • Parameter 5: “params PresentParameters[] presentationParameters”

For the adapter we used “0” since this designates the default. We chose hardware rendering as opposed to software emulation. Our main application class is also our render target form (hence the “this” keyword). We wanted software vertex processing instead of hardware calculated transforms. Lastly, we passed in our “present_params” object as the fifth parameter.

Now we must call “InitGraphics()” from somewhere. Add the following line in “Main()”:

static void Main()
{
   MainClass MainForm = new MainClass();
   MainForm.InitGraphics(); // <— ADD THIS LINE
   Application.Run(MainForm);
}

Step 4: Draw on the Form

In order to draw on the form we must override the “OnPaint()” function. In this function we use the “m_device” member to call “Clear()” and “Present()” like this:

protected override void OnPaint(PaintEventArgs e)
{
   m_device.Clear(ClearFlags.Target,
                  System.Drawing.Color.FromArgb(0, 0, 255).ToArgb(), 1.0f, 0);
   m_device.Present();
}

The “Clear()” function fills one or more buffers with a single value. The first parameter specifies which buffer, or series of buffers, to fill. It can be the rendering target buffer (Target), depth buffer (ZBuffer), or stencil buffer (Stencil). You can specify more than one by combining their values via a bitwise “OR” operation. The second parameter specifies what color to use in clearing the render target surface. In our case we chose blue. The third parameter specifies what value to use for clearing the depth buffer. Lastly, the fourth parameter specifies what value to use for clearing the stencil buffer.

The “Present()” function displays everything to the screen. It is equivalent to calling the C++ version with four NULL parameters.

Run the Program!

Our first managed DirectX program is done! Now compile and run the program. You should see output similar to this:

managed_directx_tutorial_1_output

Conclusion

While this program is rather boring, in the next tutorial we’ll cover how to draw a 2D triangle with different colored vertices.

-Greg Dolley

*Get new posts automatically! Grab the RSS feed here. Want email updates instead? Click here.

Posted in .NET Graphics, C# Programming, DirectX | 35 Comments »