微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在WPF上使用SharpDX的DirectX实时图形

如何解决在WPF上使用SharpDX的DirectX实时图形

我在SharpDX上使用DirectX在WPF应用程序中具有实时图形。我使用Direct2D1,直接合成,SwapCain。它可以完美地与窗口上的1个对象一起工作,但是如果我添加多个(9),则存在问题:在1-2分钟后进行调试,或者如果我在监视器之间积极移动窗口,则会在Windows中捕获访问冲突异常或设备已删除。发布部署后,我捕获了一次。我尝试在删除设备后重新创建设备,但是它不起作用。

public class DirectX
    {
        public BitmapProperties1 BitmapProperties1 { get; private set; }
        public SharpDX.Direct2D1.Factory1 Factory1 { get; private set; }
        private SharpDX.dxgi.Device _genericDevice;
        private SharpDX.DirectComposition.Visual _visual;
        private Target _target;
        private SharpDX.DirectComposition.Device _compDevice;
        private SharpDX.Direct3D11.Device d11Device;
        private IntPtr _hwnd;
        public Result? DeviceRemovedReason => d11Device?.DeviceRemovedReason;
        public DirectX(Window window)
        {
            _hwnd = new WindowInteropHelper(window).Handle;
            InitilizeDevices();
        }
        private bool _isRefreshed = false;
        public void InitilizeDevices()
        {
            var creationFlags = SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport;
            var factory1Flags = DebugLevel.None;
#if DEBUG
            creationFlags |= SharpDX.Direct3D11.DeviceCreationFlags.Debug;
            factory1Flags = DebugLevel.information;
#endif
            SharpDX.Direct3D.FeatureLevel[] featureLevels =
            {
                SharpDX.Direct3D.FeatureLevel.Level_11_1,SharpDX.Direct3D.FeatureLevel.Level_11_0,SharpDX.Direct3D.FeatureLevel.Level_10_1,SharpDX.Direct3D.FeatureLevel.Level_10_0,SharpDX.Direct3D.FeatureLevel.Level_9_3,SharpDX.Direct3D.FeatureLevel.Level_9_2,SharpDX.Direct3D.FeatureLevel.Level_9_1,};
            if (d11Device != null)
                Utilities.dispose(ref d11Device);
            d11Device = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware,creationFlags,featureLevels);
            Factory1 = new SharpDX.Direct2D1.Factory2(FactoryType.MultiThreaded,factory1Flags);
            if (_genericDevice != null)
                Utilities.dispose(ref _genericDevice);
            _genericDevice = d11Device.QueryInterface<SharpDX.dxgi.Device>();
            if (_compDevice != null)
                Utilities.dispose(ref _compDevice);
            _compDevice = new SharpDX.DirectComposition.Device(_genericDevice);
            BitmapProperties1 = new BitmapProperties1(new SharpDX.Direct2D1.PixelFormat(Format.R8G8B8A8_Unorm,SharpDX.Direct2D1.AlphaMode.Ignore),Factory1.DesktopDpi.Width,Factory1.DesktopDpi.Height,BitmapOptions.CannotDraw | BitmapOptions.Target);
            if (_visual == null)
                _visual = new SharpDX.DirectComposition.Visual(_compDevice);
            if (_target == null)
                _target = Target.FromHwnd(_compDevice,_hwnd,true);
            _target.Root = _visual;
            _compDevice.Commit();
        }
        public void CreateSwapChainAndDeviceContext(int width,int height,float offsetX,float offsetY,out SwapChain1 swapChain,out DeviceContext deviceContext)
        {
            var desc = new SwapChainDescription1()
            {
                BufferCount = 2,Width = width,Height = height,Format = Format.R8G8B8A8_Unorm,SampleDescription = new SampleDescription(1,0),SwapEffect = SwapEffect.FlipSequential,Usage = Usage.rendertargetOutput
            };

            swapChain = new SwapChain1(new SharpDX.dxgi.Factory2(),_genericDevice,ref desc);

            var visual = new SharpDX.DirectComposition.Visual(_compDevice)
            {
                Content = swapChain,};
            visual.SetoffsetX(offsetX);
            visual.SetoffsetY(offsetY);
            _visual.AddVisual(visual,true,null);
            _compDevice.Commit();
            using (var d2Device = new SharpDX.Direct2D1.Device(Factory1,_genericDevice))
                deviceContext = new DeviceContext(d2Device,DeviceContextOptions.None) { AntialiasMode = AntialiasMode.Aliased };
        }
    }

控制之下:

public void Init(float offsetX,DirectX directX)
        {
            _directX = directX;
            _offsetX = offsetX;
            _offsetY = offsetY;
            Stopwatch = new Stopwatch();
            _directX.CreateSwapChainAndDeviceContext((int)ActualWidth,(int)ActualHeight,_offsetX,_offsetY,out swapchain,out deviceContext);
            brush = new SharpDX.Direct2D1.solidColorBrush(deviceContext,new Color4(1f,0f,1f));
            stop = false;
            var thread = new Thread(new ThreadStart(Render));
            thread.Start();
        }
        public Action RefreshAction { get; set; } // call InitializeDevices in DirectX
        Random rand = new Random();
        public bool stop;
        SharpDX.dxgi.SwapChain1 swapchain;
        SharpDX.Direct2D1.solidColorBrush brush;
        DeviceContext deviceContext;
        SharpDX.dxgi.Surface2 backBuffer;
        Stopwatch Stopwatch;
        object _lock = new object();
        DirectX _directX;
        private void Render()
        {
            while (!stop)
            {
                Stopwatch.Start();
                try
                {
                    backBuffer = swapchain.GetBackBuffer<SharpDX.dxgi.Surface2>(0);
                    var bitmap1 = new SharpDX.Direct2D1.Bitmap1(deviceContext,backBuffer,_directX.BitmapProperties1);
                    deviceContext.Target = bitmap1;
                    deviceContext.BeginDraw();
                    deviceContext.Clear(SharpDX.Color.Green);
                    using (var geometry = new SharpDX.Direct2D1.PathGeometry(_directX.Factory1))
                    {
                        using (var path = geometry.open())
                        {
                            double angle = 10 * Math.PI * (rand.NextDouble() - 0.5);
                            sin.Add(100 + 10 * Math.Sin(angle));
                            sin.RemoveAt(0);
                            path.Beginfigure(new Vector2(0,(float)sin[0]),figureBegin.Hollow);
                            for (int k = 1; k < 100; k++)
                            {
                                path.AddLine(new Vector2(k * 5,(float)sin[k]));
                            }
                            path.Endfigure(figureEnd.Open);

                            path.Close();
                        }
                        deviceContext.DrawGeometry(geometry,brush,1);
                    }
                    deviceContext.DrawEllipse(new SharpDX.Direct2D1.Ellipse(new Vector2(100,100),20,20),brush);
                    deviceContext.EndDraw();
                    swapchain.Present(1,PresentFlags.None);
                    bitmap1.dispose();
                    backBuffer.dispose();
                }
                catch (SharpDXException ex) when ((uint)ex.HResult == 0x8899000C || (uint)ex.HResult == 0x887A0020 || (uint)ex.HResult == 0x887A0005)
                {
                    Console.WriteLine(_directX?.DeviceRemovedReason);
                    Console.WriteLine(ex);
                    if (!stop)
                        RefreshAction();
                     return;
                }
                catch (AccessViolationException ex)
                {
                    Console.WriteLine(ex);
                }
                Stopwatch.Stop();
                Stopwatch.Reset();
                if (Stopwatch.ElapsedMilliseconds < 20)
                    Thread.Sleep(20 - (int)Stopwatch.ElapsedMilliseconds);
            }
        }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。