SlimDX和WPF的合作应用

SlimDX和WPF的合作应用1 首先定义一个 DX 操作类 1usingSystem 2usingSlimDX 3usingSlimDX Direct3D9 4usingSystem Windows Interop 5usingSystem Windows Media 67publicclas

1.首先定义一个DX操作类

 1 using System;  2 using SlimDX;  3 using SlimDX.Direct3D9;  4 using System.Windows.Interop;  5 using System.Windows.Media;  6  7 public class DX  8  {  9 private enum DirectXStatus  10  {  11  Available,  12  Unavailable_RemoteSession,  13  Unavailable_LowTier,  14  Unavailable_MissingDirectX,  15  Unavailable_Unknown  16  };  17  18 public static Device Device { get; private set; }  19 public static bool Available { get { return DX.Device != null; } }// = false;  20  21 private static DX _dx;  22 private static DirectXStatus _status = DirectXStatus.Unavailable_Unknown;  23 private static string _statusMessage = "";  24  25 [System.Runtime.InteropServices.DllImport("user32")]  26 private static extern int GetSystemMetrics(int smIndex);  27 private const int SM_REMOTESESSION = 0x1000;  28  29 // device settings  30 private const Format _adapterFormat = Format.X8R8G8B8;  31 private const Format _backbufferFormat = Format.A8R8G8B8;  32 private const Format _depthStencilFormat = Format.D16;  33 private static CreateFlags _createFlags = CreateFlags.Multithreaded | CreateFlags.FpuPreserve;  34  35 private Direct3D _d3d;  36  37  38 private DX()  39  {  40  initD3D();  41 if (_d3d != null)  42  initDevice();  43 //if (!DX.Available)  44 // MessageBox.Show("DirectX硬件加速不可用!\n\n" + _statusMessage, "", MessageBoxButton.OK, MessageBoxImage.Warning);  45  }  46  47 ~DX()  48  {  49 if (DX.Device != null)  50 if (!DX.Device.Disposed)  51  DX.Device.Dispose();  52 if (_d3d != null)  53 if (!_d3d.Disposed)  54  _d3d.Dispose();  55  }  56  57 public static void Init()  58  {  59 if (_dx == null)  60 _dx = new DX();  61  }  62  63 private void initD3D()  64  {  65 if (_d3d != null)  66 return;  67  68 _status = DirectXStatus.Unavailable_Unknown;  69  70 //// assume that we can't run at all under terminal services  71 if (GetSystemMetrics(SM_REMOTESESSION) != 0)  72  {  73 _status = DirectXStatus.Unavailable_RemoteSession;  74 return;  75  }  76  77 int renderingTier = (RenderCapability.Tier >> 16);  78 if (renderingTier < 2)  79  {  80 _status = DirectXStatus.Unavailable_LowTier;  81 _statusMessage = "low tier";  82 return;//注意:发现某些集成显卡,在这里出去!!  83  }  84  85 try  86  {  87 _d3d = new Direct3DEx();  88  }  89 catch  90  {  91 try  92  {  93 _d3d = new Direct3D();  94  }  95 catch (Direct3DX9NotFoundException dfe)  96  {  97 _status = DirectXStatus.Unavailable_MissingDirectX;  98 _statusMessage = "Direct3DX9 Not Found\n" + dfe.Message;  99 return; 100  } 101 catch (Exception e) 102  { 103 _status = DirectXStatus.Unavailable_Unknown; 104 _statusMessage = e.Message; 105 return; 106  } 107  } 108 109 bool ok; 110  Result result; 111 112 ok = _d3d.CheckDeviceType(0, DeviceType.Hardware, _adapterFormat, _backbufferFormat, true, out result); 113 if (!ok) 114  { 115 //Debug.WriteLine("* failed to CheckDeviceType"); 116 //MessageBox.Show("Failed to CheckDeviceType"); 117 return; 118  } 119 120 ok = _d3d.CheckDepthStencilMatch(0, DeviceType.Hardware, _adapterFormat, _backbufferFormat, _depthStencilFormat, out result); 121 if (!ok) 122  { 123 //Debug.WriteLine("* failed to CheckDepthStencilMatch"); 124 _statusMessage = "Failed to CheckDepthStencilMatch"; 125 return; 126  } 127 128 Capabilities deviceCaps = _d3d.GetDeviceCaps(0, DeviceType.Hardware); 129 if ((deviceCaps.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0) 130 _createFlags |= CreateFlags.HardwareVertexProcessing; 131 else 132 _createFlags |= CreateFlags.SoftwareVertexProcessing; 133 134 _status = DirectXStatus.Available; 135  } 136 137 private void initDevice() 138  { 139 if (_status != DirectXStatus.Available) 140 return; 141 142 HwndSource hwnd = new HwndSource(0, 0, 0, 0, 0, 0, 0, "SlimDX_Wnd", IntPtr.Zero); 143 PresentParameters pp = new PresentParameters(); 144 //pp.SwapEffect = SwapEffect.Copy; 145 //pp.DeviceWindowHandle = hwnd.Handle; 146 pp.Windowed = true; 147 pp.PresentFlags = PresentFlags.Video; 148 pp.SwapEffect = SwapEffect.Discard; 149 //pp.BackBufferCount = 1; 150 //pp.BackBufferWidth = 320; 151 //pp.BackBufferHeight = 240; 152 //pp.BackBufferFormat = _backbufferFormat; 153 //pp.AutoDepthStencilFormat = _depthStencilFormat; 154 try 155  { 156 DeviceType deviceType = DeviceType.Hardware; 157 if (_d3d is Direct3DEx) 158 DX.Device = new DeviceEx((Direct3DEx)_d3d, 0, deviceType, hwnd.Handle, _createFlags, pp); 159 else 160 DX.Device = new Device(_d3d, 0, deviceType, hwnd.Handle, _createFlags, pp); 161  } 162 catch (Exception ex) 163  { 164 //Debug.WriteLine("Exception in Direct3DReset " + ex.StackTrace); 165 //Debug.WriteLine("Exception in Direct3DReset " + ex.Message); 166  } 167  } 168 }

2.定义准备显卡硬件,和释放显卡硬件方法

定义一些变量

    ///  /// 离屏表面 ///  private Surface _offscrn; ///  /// 交换链 ///  private SwapChain _swapChain; private D3DImage _d3dImage = null; 

 

 1      ///   2 /// 准备DirectX显卡硬件  3 ///   4 private bool prepareHardware(VideoFormat videoFormat, int videoWidth, int videoHeight)//, VideoFormat videoFormat)  5  {  6 if (!DX.Available)  7 return true;  8  9 try 10  { 11 SlimDX.Direct3D9.Format format = SlimDX.Direct3D9.Format.A8R8G8B8; 12 if (videoFormat == VideoFormat.Yuv420) 13 format = (SlimDX.Direct3D9.Format)0x; 14 if (_offscrn != null) 15 if (videoWidth == _offscrn.Description.Width && videoHeight == _offscrn.Description.Height && _offscrn.Description.Format == format) 16 return true; 17 18  releaseHardware(); 19 _offscrn = Surface.CreateOffscreenPlain(DX.Device, videoWidth, videoHeight, format, Pool.Default); 20 PresentParameters pp = new PresentParameters(); 21 pp.Windowed = true; 22 pp.PresentFlags = PresentFlags.Video; 23 pp.SwapEffect = SwapEffect.Discard; 24 pp.BackBufferCount = 1; 25 pp.BackBufferWidth = videoWidth; 26 pp.BackBufferHeight = videoHeight; 27 _swapChain = new SwapChain(DX.Device, pp); 28 return true; 29  } 30 catch 31  { 32 return false; 33  } 34  } 35 ///  36 /// 释放DirectX显卡硬件 37 ///  38 private void releaseHardware() 39  { 40 if (!DX.Available) 41 return; 42 if (_offscrn != null) 43 if (!_offscrn.Disposed) 44  _offscrn.Dispose(); 45 _offscrn = null; 46 if (_swapChain != null) 47 if (!_swapChain.Disposed) 48  _swapChain.Dispose(); 49 _swapChain = null; 50 }

3.

 private void drawFrame(VideoFormat videoFormat, int width, int height, IntPtr Y, IntPtr U, IntPtr V) { if (!prepareHardware(videoFormat, width, height)) return; if (_swapChain == null) return; DataRectangle dr = _offscrn.LockRectangle(LockFlags.None);//在离屏表面上锁定一个矩形 drawYuv420(width, height, Y, U, V, dr.Data.DataPointer, dr.Pitch);//DataPointer 内部指针指向当前流的存储备份; Pitch 两个连续的行之间的数据的字节数 _offscrn.UnlockRectangle();//解锁矩形 using (Surface bb = _swapChain.GetBackBuffer(0))//从交换链中检索一个后台缓冲区  { System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bb.Description.Width, bb.Description.Height); _swapChain.Device.StretchRectangle(_offscrn, rect, bb, rect, TextureFilter.None);//将后台缓冲区的内容交换到前台缓冲区 _swapChain.Device.Present();//呈现后台缓冲区序列中下一个后台缓冲区的内容  _d3dImage.Lock(); _d3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, bb.ComPointer); _d3dImage.AddDirtyRect(new Int32Rect(0, 0, _d3dImage.PixelWidth, _d3dImage.PixelHeight)); _d3dImage.Unlock(); } } private void drawYuv420(int width, int height, IntPtr Y, IntPtr U, IntPtr V, IntPtr dest, int pitch) { IntPtr py = dest; IntPtr pv = py + (pitch * height); IntPtr pu = pv + ((pitch * height) / 4); int w2 = width / 2, pitch2 = pitch / 2; for (int y = 0; y < height; y++) { CopyMemory(py, Y + y * width, (uint)width); py += pitch; if ((y & 1) != 0) continue; int offset = y / 2 * w2; CopyMemory(pu, U + offset, (uint)w2); CopyMemory(pv, V + offset, (uint)w2); pu += pitch2; pv += pitch2; } } [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")] private static extern void CopyMemory(IntPtr Destination, IntPtr Source, uint Length);

 

转载于:https://www.cnblogs.com/smartsensor/p/4815381.html

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/227831.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午8:25
下一篇 2026年3月16日 下午8:26


相关推荐

  • 基于Hmily实现TCC分布式事务解决方案[通俗易懂]

    基于Hmily实现TCC分布式事务解决方案[通俗易懂]前言在上一篇中,我们大致讲述了TCC事务的来源以及执行原理,并使用seata提供的解决方案完成了一个简单案例的整合与代码演示,本篇我们将采用Hmily的方式实现TCC事务的解决方案与演示业务描述有一个银行转账的场景,用户A需要向用户B转1块钱,如果大家使用的是同一个数据库,就不存在分布式事务的问题,现实中大家都各自使用自己的库,就产生了分布式事务可以理解为,两个账户分别在不同的银行(用户…

    2022年5月21日
    40
  • FVWM_fw一流是什么意思

    FVWM_fw一流是什么意思国庆期间,把自己的FVWM好好整理了一下,现在我的桌面看上去是这个样子滴(点击可放大):我的.fvwm2rc可以下载。我的部分FVWM笔记:***   如何使用托盘      $sudoapt-getinstalltrayer      $trayer–widthtypepixel–width128–height32–edgebottom&***  

    2022年10月4日
    4
  • mysql-jdbc 6.0 serverTimezone参数详解

    mysql-jdbc 6.0 serverTimezone参数详解2 1 遇到的问题虽然上面加上时区程序不出错了 但是我们在用 java 代码插入到数据库时间的时候却出现了问题 比如在 java 代码里面插入的时间为 2017 08 2117 29 56 但是在数据库里面显示的时间却为 2017 08 2109 29 563 根本原因因为时区设置的问题 UTC 代表的是全球标准时间 但是我们使用的时间是北京时

    2026年3月26日
    2
  • android 混淆规则作用,Android代码混淆详解

    android 混淆规则作用,Android代码混淆详解一、混淆的意义混淆代码并不是让代码无法被反编译,而是将代码中的类、方法、变量等信息进行重命名,把它们改成一些毫无意义的名字,同时也可以移除未被使用的类、方法、变量等。所以直观的看,通过混淆可以提高程序的安全性,增加逆向工程的难度,同时也有效缩减了apk的体积。总结如下:1、将项目中的类、方法、变量等信息进行重命名,变成一些无意义的简短名字。2、移除未被使用的类、方法、变量等。二、混淆的规则和配置…

    2022年5月30日
    39
  • 量子光学中的分束器[通俗易懂]

    量子光学中的分束器[通俗易懂]量子光学中的分束器

    2022年4月22日
    138
  • object.hashcode的作用_java的hashcode方法

    object.hashcode的作用_java的hashcode方法Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。其主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值,实际上在HashMap的具…

    2025年10月4日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号