views:

380

answers:

4

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?

+2  A: 

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
Thanks. Unfortunately, it's written in Managed C++. I'd really like to do this using COM interop direct from C#.
David Brown
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
+2  A: 

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.

chibacity
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
My apologies, didn't scan the question correctly. I really should get some sleep...
chibacity
Maybe this thing will just work from C# - answer updated...
chibacity
+1  A: 

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
A: 

Hello, if this still actual and some of you want to get C# version of DirectX interfaces. I can suggest to WRITE IT together. I have started project MDXGI and have interesting results. I also have D3D10, D3D11, D2D1, DWrite interop code. But it still some buggy. I need help. We can write it. But i just one man and dont have enought time for all components. And some stupid interop problems with i cant solve... For example IDXGIFactory1 don't create IDXGISwapChain at any way :(

WSairus
Are you still working on this? I'm highly interested in what you are doing and would be interested in discussing collaboration.
chrensli