How-to Render managed (.NET) form using native DirectX

Microsoft DirectX is a collection of application programming interfaces (APIs) for handling tasks related to multimedia, especially game programming and video, on Microsoft platforms. Although a managed DirectX exist some of the time you need the power of C++ when using it.
In the past I used DirectX with C++ for image processing and video both needs a lot of byte operations and pointer arithmetic that I could not do in C# (due to performance considerations) But I wanted to create the application GUI using C# forms.
The solution for this problem is quite easy create two projects: C++ DLL that would handle all of the heavy duty performance and graphic rendering and a C# windows forms project to handle interaction with the user.

Prerequisites

To start development you need two things:
  1. Although not a must Visual Studio can help development so you can either use a paid version or download C# Express Edition. Both C++ and C# are required in order to run the sample project.
  2. DirectX SDK – you can get the latest SDK from MSDN DirectX Downloads page.
After installing DirectX you can go over the included Sample Browser and learn how to program using this great resource.
image

Remark – I used pInvoke as a connector between the managed and unmanaged bits but there are other ways such as COM and C++.NET that have better performance and might be more suited for actual real world projects.

1. The C++ DirectX Project

For the purpose of this post I took DX9 sample called vertices (DX10 only works on Vista some of us not there yet).
Take the code in the sample and removing the Windows API functions and adding the following in the SampleDX.h file:
#pragma once

extern "C"
{    
    __declspec(dllexport) void InitD3D( HWND hWnd );
    __declspec(dllexport) void Render();
    __declspec(dllexport) void Cleanup();    
    __declspec(dllexport) void InitVB();
};

Notice that the windows handle is passed as parameter to the InitD3D function.

You can find the source for the SimpleDX project here.

2. The C# WinForm project

Create a new C# windows form project and the following code:

[DllImport("SimpleDX.dll", SetLastError = true)]
static extern void InitD3D(Int32 hWnd);

[DllImport("SimpleDX.dll", SetLastError = true)]
static extern void InitVB();

[DllImport("SimpleDX.dll", SetLastError = true)]
static extern void Render();

[DllImport("SimpleDX.dll", SetLastError = true)]
static extern void Cleanup();

In here Int32 variable is used to pass the window handle – I think that in 64bit machine an Int64 argument type should be used. InitD3D shall be called using this.Handle.ToInt32() function in the class constructor and Render shall be called as part of the form’s OnPaint function:


public Form1()
{
    InitializeComponent();

    InitD3D(this.Handle.ToInt32());
    InitVB();
}

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);

    Render();
}

The entire source of the SimpleDXForm project can be downloaded here.

Press F5 and presto –> we get the colored triangle from the sample inside our winform.

image

Conclusion (What exactly is my point)

  1. Although Microsoft has created a managed wrapper for directX it lacks the power and functioanlity you need in some cases.
  2. This tutorial I showed that the power of C++ can be used along with the rapid development power of C#.
  3. That’s it – go out and explore!

Labels: , , ,