在 C# WPF 或 Windows Forms 应用程序中使用 DirectX c++ DLL

Using a DirectX c++ DLL in a C# WPF or Windows Forms Application

我用c++写了一个DX11渲染器。我现在正在寻找一种方法来为它实现 Editor/GUI。

因为我已经习惯了 Windows 表单和 WPF C# 应用程序,我正在考虑将我的渲染器放在 dll 中,从 c# 应用程序加载 dll 并使用它绘制到表单的定义部分。这甚至可以与托管 C# 应用程序传递的 window 句柄一起使用吗?如果可以,性能如何?

根据我的理解,由于与 DX11 API 的实际通信仍将直接在 c++ 中进行,而 c# 部分只会告诉 dll 做什么,因此性能损失应该几乎没有。或者这通常是个坏主意,使用库或 D2D 在 C++ 中直接实现 GUI 是更好的方法。

在 WPF 中,您可以使用 D3DImage,这就像 xaml 中的简单图像一样。总的原则如下:

  • 分配一个 Direct3D 9 纹理,这将是您的渲染目标。
  • 交给D3DImage.SetBackBuffer。
  • 将渲染代码放入 CompositionTarget.Rendering 事件处理程序中。

        RenderStuffToTexture();
        d3dImage.Lock();
        d3dImage.AddDirtyRect(new Int32Rect()
        {
            X = 0,
            Y = 0,
            Height = d3dImage.PixelHeight,
            Width = d3dImage.PixelWidth
        });
        d3dImage.Unlock();
    

由于使用的是Direct3D 11,所以必须使用DXGI surface sharing to share the D3D9 textute with D3D11. There are 2 examples I know of that illustrate how to do just that. Microsoft D3D11Image和D3DImageEx(个人喜好,网上多处可以找到)

关于性能,一旦你使用了 WPF,你就不再需要自己做演示了。您实际上是在基于 WPF D3D9 的渲染器中编写一个小的渲染到纹理逻辑。因此,并非一切都可以控制,包括演示时间。根据我的个人经验,您绝对可以以不错的帧率渲染简单的场景。对于真正的图形密集型应用程序和严格的 FPS 要求,我会使用更轻量级(且侵入性更小)UI 解决方案。

请注意,您还可以使用 WinformHost 控件获取 HWND 并呈现给它。如果您想在渲染帧上覆盖 UI 控件,这有一个严重的缺点 - 据我所知,您根本做不到。