通过 RDP 使用 WPF 的 Direct2d [英] Direct2d with WPF over RDP

查看:83
本文介绍了通过 RDP 使用 WPF 的 Direct2d的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 C# 应用程序,它使用 SharpDx 通过 Direct2d 呈现地图.该地图与 WPF 主机上的 D3DImage 一起显示.在本地机器上一切正常,但是当我尝试通过远程桌面连接时,D3DImage 丢失了其后台缓冲区,并且无法使用 WPF 显示渲染图像.

I'm developing a C# application which uses SharpDx to render a map with Direct2d. This map get displayed with the D3DImage on a WPF host. On a local machine everything works fine but when I try to connect via Remote Desktop, the D3DImage loses its Backbuffer and the rendered image can't be displayed with WPF.

我在绑定 Backbuffer 时尝试启用软件回退.结果是应用程序设法渲染一张图像,然后再次丢失后台缓冲区.我还尝试使用 gpedit 在远程桌面连接上启用硬件加速,但没有任何改变.

I tried to enable the software fallback when I bind the Backbuffer. The result is that the application manages to render one image and then loses the backbuffer again. I also tried to enable hardware acceleration on remote desktop connections with gpedit but nothing changed.

    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 的本地机器上遇到了同样的问题.

Edit When I disable hardware acceleration with HKEY_CURRENT_USER/SOFTWARE/Microsoft/Avolon.Graphics/DisableHWAcceleration, I get the same issue on a local machine without RDP.

编辑 2我尝试使用 Direct11 创建参考或扭曲设备.但是经过一些研究,结果证明这两种软件设备都不支持我用来创建 WPF 图像的 SharedSurfaces.

Edit2 I tried to create a Reference or a Warp Device with Direct11. But after a bit of research it turns out that both software devices do not support SharedSurfaces which I am using to create the WPF image.

推荐答案

于是我找到了解决我的问题的方法:

So I found a solution for my problem:

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

First of all you have to enable the software fallback when you bind the BackBuffer to your D3DImage. My problem was that after one frame I received the IsFrontBufferAvailableChanged event, IsFrontBufferAvailable turned to false and I stopped rendering. But on software rendering you can ignore those things.

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

Here is a github issue which helped me fix it: https://github.com/Sascha-L/WPF-MediaKit/issues/3

这篇关于通过 RDP 使用 WPF 的 Direct2d的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆