zoukankan      html  css  js  c++  java
  • SlimDX和WPF的合作应用

    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硬件加速不可用!
    
    " + _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
    " + 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.定义准备显卡硬件,和释放显卡硬件方法

    定义一些变量

           /// <summary>
            /// 离屏表面
            /// </summary>
            private Surface _offscrn;
            /// <summary>
            /// 交换链
            /// </summary>
            private SwapChain _swapChain;
            private D3DImage _d3dImage = null;    
     1      /// <summary>
     2         /// 准备DirectX显卡硬件
     3         /// </summary>
     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)0x32315659;
    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         /// <summary>
    36         /// 释放DirectX显卡硬件
    37         /// </summary>
    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);
  • 相关阅读:
    HihoCoder 1245:王胖浩与三角形 三角形边长与面积
    C++ 读写注册表
    Codestorm:Counting Triangles 查各种三角形的个数
    2015年10月之 叽里咕噜
    HDU 5523:Game
    Codestorm:Game with a Boomerang
    关于GPU-driver for linux的资料
    ACER NV47H75C 安装CUDA 驱动以及调整屏幕
    服务器GTX590安装CUDA
    观后感,读了几篇博文
  • 原文地址:https://www.cnblogs.com/smartsensor/p/4815381.html
Copyright © 2011-2022 走看看