使用RDP上的WPF的Direct2d

时间:2019-07-02 09:19:02

标签: c# wpf rdp direct2d

我正在开发一个使用SharpDx渲染Direct2d地图的C#应用​​程序。该地图与D3DImage一起显示在WPF主机上。在本地计算机上,一切正常,但是当我尝试通过远程桌面连接时,D3DImage丢失了Backbuffer,并且渲染的图像无法用WPF显示。

我在绑定Backbuffer时尝试启用软件后备。结果是应用程序设法渲染一幅图像,然后又丢失了后缓冲。 我还尝试过使用gpedit在远程桌面连接上启用硬件加速,但未做任何更改。

    public void SetBackBuffer(D3D11.Texture2D texture)
    {
      using (var device = CreateDevice(NativeMethods.GetDesktopWindow()))
      {
        using (var texture9 = GetSharedSurface(device, texture))
        {
          this.surface = texture9.GetSurfaceLevel(0);
        }
      }

      this.Lock();
      this.SetBackBuffer(D3DResourceType.IDirect3DSurface9, this.surface.NativePointer, true);
      this.Unlock();
    }

    private static D3D9.Texture GetSharedSurface(D3D9.Device device, D3D11.Texture2D texture)
    {
      using (var surface = texture.QueryInterface<DXGI.Resource>())
      {
        IntPtr handle = surface.SharedHandle;

        return new D3D9.Texture(
          device,
          texture.Description.Width,
          texture.Description.Height,
          1,
          D3D9.Usage.RenderTarget,
          D3D9.Format.A8R8G8B8, // D3DFMT_A8R8G8B8
          D3D9.Pool.Default,  // D3DPOOL_DEFAULT
          ref handle);
      }
    }

    private static D3D9.DeviceEx CreateDevice(IntPtr handle)
    {
      using (var d3D9Ex = new D3D9.Direct3DEx())
      {
        var present = new D3D9.PresentParameters
        {
          Windowed = true,
          SwapEffect = D3D9.SwapEffect.Discard,
          DeviceWindowHandle = handle,
          PresentationInterval = D3D9.PresentInterval.Immediate,
        };

        const D3D9.CreateFlags CreateFlags = D3D9.CreateFlags.HardwareVertexProcessing | D3D9.CreateFlags.Multithreaded | D3D9.CreateFlags.FpuPreserve;

        return new D3D9.DeviceEx(
          d3D9Ex,
          0, // D3DADAPTER_DEFAULT
          D3D9.DeviceType.Hardware, // D3DDEVTYPE_HAL
          handle,
          CreateFlags,
          present);
      }
    }

修改 当我使用HKEY_CURRENT_USER / SOFTWARE / Microsoft / Avolon.Graphics / DisableHWAcceleration禁用硬件加速时,在没有RDP的本地计算机上也会遇到相同的问题。

Edit2 我尝试使用Direct11创建参考或扭曲设备。但是经过一番研究,结果发现这两种软件设备都不支持我用来创建WPF图像的SharedSurfaces。

1 个答案:

答案 0 :(得分:1)

所以我找到了解决问题的方法:

首先,当您将BackBuffer绑定到D3DImage时,您必须启用软件后备。我的问题是在一帧之后,我收到IsFrontBufferAvailableChanged事件,IsFrontBufferAvailable变为false,并且我停止了渲染。但是在软件渲染时,您可以忽略这些事情。

这是一个github问题,可帮助我修复它: https://github.com/Sascha-L/WPF-MediaKit/issues/3