[.net] Render unmanaged C++/Direct3D in .NET forms

Started by
3 comments, last by Splo 15 years, 10 months ago
Hi! I made searches for that but couldn't find any help ... I'm sure I don't use the right keywords ... Ok, suppose I have a game written in C++ that works quite well on Windows. Cool. The game is composed of 2 parts: - A dll library that contains most classes of the game: the engine. It uses Direct3D. - An executable that just loads this library, renders the game on a very basic Win32 window, listens to the Win32 input (or DirectInput), etc, and allows to start and play the game. Now suppose I want to develop an editor for the game using .NET (C#) Window Forms. I don't want to recode the engine in C#. I don't want to use SlimDX, Managed DirectX or XNA. I want my editor to use the unmanaged C++ dll. There will be several different components and one (or more) of them will display the game (in a "paused" state). I know how to make a managed C++/CLI wrapper around an unmanaged C++ dll. No problem, that works fine. My questions are: how can I draw a Direct3D window in a C# Windows Form component? What exactly should I export in the dll? A Direct3D device? A Windows GDI handle/something/stuff/whatever? What does a component accept for "painting"? What's the right approach? The truth is I still don't have really started this game. I only have a basic understanding of Direct3D. I know a bit more of OpenGL but I really want to learn Direct3D. At first, my "game" will be a simple spinning cube. I want to put myself in the place of a company that have legacy Win32 apps and want to quickly build tools in .NET without having to re-invent its wheels. The goal is to become a good Tools Programmer.
Advertisement
This is easy to do. All you have to pass into your unmanaged c++ code, is the HANDLE of the form/control you are rendering to. You can get this via:

HWND handle = static_cast<HWND> (Form1->Handle.ToPointer());

For my editor, I compile my base engine as an unmanaged c++ static library, and reference it directly in my managed c++ editor.

I've also done this to legacy Win32 Direct3D apps without any issue.
So my engine should just accept a method that takes a HWND handle and render using that. Indeed that sounds easy.

An unmanaged c++ static library? I never tried that, only dll. I'll check that ASAP. I suspect this will invoke a portal to the Linker Hell and hours of frustration in front of the build errors window. :)

Thanks for your quick and efficient reply!
Quote:Original post by Splo
So my engine should just accept a method that takes a HWND handle and render using that. Indeed that sounds easy.


Yep, thats all you need to do to get your engine rendering to a .NET Form or Control.

You'll also need to build some type of render loop for your application. One of the more common ways of doing this is outlined here:

Render Loop.

The code presented in the post is in C#, but you should be able to easily port the presented code to C++/CLI if decide against going the C# route. There are several other ways to accomplish a rendering loop, however, this has always been my favorate method. FYI: With the C++/CLI route, you wont need to declare the Message struct or import the PeekMessage function. Instead you can just use the MSG struct and PeekMessage function defined in the Win32 API.

So at a bare minimum, you need some way of passing a form/control handle to your unmanaged code. Additionally, you need some way to invoke your engine to update and draw itself. Once you have this ironed out, its just a matter of designing your communication layer. :-)

[Edited by - Billr17 on May 28, 2008 10:14:39 PM]
I wrote the code and it works! Thanks again!

I had to tag my Windows Forms Application project with "unsafe" because of the call of Handle.ToPointer().
Quote:Original post by Billr17
Quote:Original post by Splo
So my engine should just accept a method that takes a HWND handle and render using that. Indeed that sounds easy.


Yep, thats all you need to do to get your engine rendering to a .NET Form or Control.

You'll also need to build some type of render loop for your application. One of the more common ways of doing this is outlined here:

Render Loop.

The code presented in the post is in C#, but you should be able to easily port the presented code to C++/CLI if decide against going the C# route. There are several other ways to accomplish a rendering loop, however, this has always been my favorate method. FYI: With the C++/CLI route, you wont need to declare the Message struct or import the PeekMessage function. Instead you can just use the MSG struct and PeekMessage function defined in the Win32 API.

So at a bare minimum, you need some way of passing a form/control handle to your unmanaged code. Additionally, you need some way to invoke your engine to update and draw itself. Once you have this ironed out, its just a matter of designing your communication layer. :-)

That was very helpful, thanks! I already read this page some months ago but I forgot it. I used it in my code.
++UserRating;

This topic is closed to new replies.

Advertisement