5

I'm toying with a little 2D game engine in C# and decided to use Direct2D and DirectWrite for rendering. I know there's the Windows API Code Pack and SlimDX, but I'd really like to dig in and write an interface from scratch. I'm trying to do it without Managed C++, but Direct2D and DirectWrite don't appear to use traditional COM objects. They define interfaces that derive from IUnknown, but there appears to be no way to actually use them from C# with COM interop. There are IIDs in d2d1.h, but no CLSID.

Of course, I'm really new to COM interop, so perhaps I'm just missing something. Can someone shed some light on this situation?

David Brown
  • 35,411
  • 11
  • 83
  • 132
  • Check this post: http://www.itcommunity.ru/blogs/nesteruk/archive/2009/09/14/76753.aspx It still involves some C++. And you're not looking for COM, but to load dlls and wrap the signatures using DllImport – Mikael Svenson May 14 '10 at 22:17
  • Because DirectX was geared around C/C++ from way back. – Paul Nathan May 14 '10 at 23:34

3 Answers3

8

Got it. You can't create the objects directly, but d2d1.dll contains an export called D2D1CreateFactory that returns an ID2DFactory interface. Using this, you can implement a Direct2D wrapper without Managed C++.

public static class Direct2D1Util {
    public const string IID_ID2D1Factory =
        "06152247-6f50-465a-9245-118bfd3b6007";

    [DllImport("d2d1.dll", PreserveSig = false)]
    [return: MarshalAs(UnmanagedType.Interface)]
    private static extern object D2D1CreateFactory(D2D1_FACTORY_TYPE factoryType,
        [MarshalAs(UnmanagedType.LPStruct)] Guid riid,
        D2D1_FACTORY_OPTIONS pFactoryOptions);

    public static ID2D1Factory CreateFactory() {
        D2D1_FACTORY_OPTIONS opts = new D2D1_FACTORY_OPTIONS();
        object factory = D2D1CreateFactory(
            D2D1_FACTORY_TYPE.D2D1_FACTORY_TYPE_SINGLE_THREADED,
            new Guid(IID_ID2D1Factory), opts);
        return (ID2D1Factory)factory;
    }
}

I won't include all of the types, because they're all defined in d2d1.h, but here's how to use the code to get a factory:

ID2DFactory factory = Direct2D1Util.CreateFactory();

Make sure your ID2DFactory interface has the appropriate Guid and InterfaceType(ComInterfaceType.InterfaceIsIUnknown) attributes.

David Brown
  • 35,411
  • 11
  • 83
  • 132
  • The signature of D2D1CreateFactory is HRESULT WINAPI D2D1CreateFactory( _In_ D2D1_FACTORY_TYPE factoryType, _In_ REFIID riid, _In_opt_ CONST D2D1_FACTORY_OPTIONS *pFactoryOptions, _Out_ void **ppIFactory ); How can this be declared as a method in C# that returns a object? Because the ppIFactory is the last argument of the function? But why? – zwcloud Sep 13 '15 at 03:23
6

The "Windows® API Code Pack for Microsoft® .NET Framework" has managed libraries that allow access to Direct2D and DirectWrite.

http://code.msdn.microsoft.com/WindowsAPICodePack

Update

Whilst the DirectX wrappers are written in managed C++, they produce managed libraries. By the looks of things these can be used from C#. There look to be plenty of examples included in the download that do exactly this i.e. use the managed C++ Direct wrapper libraries from C#.

Using Windows 7 features in my own C# application would be very nice, so I am currently installing the Window7 SDK (so that I can build the managed C++ DirectX solution) and will give the whole thing a bash.

I am following the instructions at:

http://blogs.msdn.com/msaleh/archive/2009/08/25/introducing-directx-features-of-windows-api-code-pack.aspx

Update 2

Following the instructions in the above link I got the managed C++ libraries compiled and you can indeed use them from C# very easily.

Now I'm not sure if I understand correctly, but are you just looking at some way of using Direct2D and DirectWrite from C#, or does it have to be COM or P\Invoke.

I would very much doubt there would be a COM wrapper, as it's a mismatched technology. COM is not really well designed for the sort of high-frequency method call patterns that you get in Graphics programming - it is way too slow.

If you really want to do P\Invoke you could always look at the DirectX header files (in the Windows 7 SDK) and use a tool to create all your P\Invoke call stubs, e.g.

http://www.pinvoker.com/

That would probably be a major PITA though to develop a wrapper this way.

Tim Lloyd
  • 37,954
  • 10
  • 100
  • 130
  • 1
    Please read my question. I stated that I have checked the Windows API Code Pack and SlimDX, but they are written in Managed C++, whereas I would like to do this with pure C# and COM Interop/PInvoke. – David Brown May 14 '10 at 23:02
  • 1
    My apologies, didn't scan the question correctly. I really should get some sleep... – Tim Lloyd May 14 '10 at 23:19
2

There's a project on codeplex that provides managed wrappers for Direct2D. I have no idea if it's any good, but most likely the source code will help you get started.

http://direct2dsharp.codeplex.com/

Tor Haugen
  • 19,509
  • 9
  • 45
  • 63
  • Thanks. Unfortunately, it's written in Managed C++. I'd really like to do this using COM interop direct from C#. – David Brown May 14 '10 at 22:35
  • COM interop is used to use COM objects from managed code. Are you wanting to find COM wrappers that essentially P/Invoke for you so that you can generate interops for them? If so, I can't imagine what kind of performance you are expecting.... – Rick Mogstad May 15 '10 at 03:24