<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [WinUI 3] 如何利用 D3D11 在 SwapChainPanel 控件上繪制 OpenGL(UWP通用)

      預覽

      技術實現

      看過我上篇在 WPF 中實現 OpenGLD3D 渲染的同學應該知道,我是依靠 WGLWGL_NV_DX_interop 擴展與 D3D Surface 關聯并在使用該 Surface 實現渲染。

      所以我們這次實現也是如此,但與 WPF 不同的是 WinUI 支持 D3D11 并在控件中提供 SwapChainPanel 作為載體。(WPF 中為 D3DImage
      代碼部分使用 Silk.NetOpenTK 實現。


      有一些關鍵部分,接下來我會單獨講下。

      WGL_NV_DX_interop

      WGL_NV_DX_interop是NVIDIA公司提出的一套擴展API(支持OpenGL 2.1及以上版本),該擴展允許 OpenGL 可以直接訪問 DirectX 緩沖區與 Surface,并作為 OpenGL 共享紋理或渲染緩沖區對象使用。

      擴展支持版本

      WGL_NV_DX_interop - Direct3D 9
      WGL_NV_DX_interop2 - Direct3D 10、11

      D3D11與SwapChainPanel

      SwapChainPanel 是用于支持高性能圖形和游戲的 Windows 運行時類型,你可以在其中直接管理交換鏈。
      在此情況下,你可以創建自己的 DirectX 交換鏈并管理所呈現內容的顯示。

      需要注意的是,為了確保良好的性能 SwapChainPanel 存在一些限制。

      • 一個程序中 SwapChainPanel 實例不能超過四個。
      • 關聯的 DirectX 交換鏈應要明確設置寬高。
      • DirectX 交換鏈的縮放模式必須設置為 DXGI_SCALING_STRETCH。
      • 只能通過 DXGI 中 CreateSwapChainForComposition 函數進行交換鏈創建。

      代碼實現 (只存在關鍵代碼,完整代碼在文章最下方 GitHub 鏈接)

      D3D

      • 創建 DXGI 工廠,用于后續創建 SwapChain(交換鏈)
      IDXGIFactory2* factory;
      
      // 獲取該類型 Guid,這跟Com組件有關,本文不多闡述。
      // GetTypeInfo 為擴展函數,存在 WinRT 命名空間。
      Guid guid = typeof(IDXGIFactory2).GetTypeInfo().GUID;
      DXGI.GetApi().CreateDXGIFactory2(0, &guid, (void**)&factory);
      
      • 創建設備
      ID3D11Device* device;
      ID3D11DeviceContext* devCtx;
      
      // 創建設備
      D3D11.GetApi().CreateDevice(null, D3DDriverType.Hardware, 0, 0, null, 0, D3D11.SdkVersion, &device, null, &devCtx);
      
      • 創建 SwapChain (使用 IDXGIFactory2 創建)
      IDXGISwapChain1* swapChain;
      
      // SwapChain 配置信息。
      SwapChainDesc1 swapChainDesc = new()
      {
        Width = 寬度,
        Height = 高度,
        Format = Format.FormatB8G8R8A8Unorm,
        Stereo = 0,
        SampleDesc = new SampleDesc()
        {
          Count = 1,
          Quality = 0
        },
        BufferUsage = DXGI.UsageRenderTargetOutput,
        BufferCount = 2,
        Scaling = Scaling.Stretch,
        SwapEffect = SwapEffect.FlipSequential,
        Flags = 0,
      };
      factory->CreateSwapChainForComposition((IUnknown*)device, &swapChainDesc, null, &swapChain);
      
      • 獲取 SwapChain 緩沖區(我們需要用它來創建 OpenGL 的渲染緩沖區)
      ID3D11Texture2D* colorbuffer;
      Guid guid = typeof(ID3D11Texture2D).GetTypeInfo().GUID;
      swapChain->GetBuffer(0, &guid, (void**)&colorbuffer);
      

      OpenGL

      • 創建 GL 設備與幀緩沖區
      nint glDeviceHandle = Wgl.DXOpenDeviceNV((IntPtr)device);
      
      // 創建一個幀緩沖區,后續渲染前需要先進行綁定。
      int gLFramebufferHandle = GL.GenFramebuffer();
      
      • 關聯 SwapChain 緩沖區
      // 創建一個渲染緩沖區。
      int gLColorRenderbufferHandle = GL.GenRenderbuffer();
      
      // 關聯 SwapChain 緩沖區到指定 Renderbuffer 上。
      nint dxInteropColorHandle = Wgl.DXRegisterObjectNV(device, (nint)colorbuffer, (uint)gLColorRenderbufferHandle, (uint)RenderbufferTarget.Renderbuffer, WGL_NV_DX_interop.AccessReadWrite);
      
      • 渲染
      // 鎖定緩沖區進行操作
      Wgl.DXLockObjectsNV(glDeviceHandle, 1, new[] { dxInteropColorHandle });
      
      // 綁定幀緩沖區
      GL.BindFramebuffer(FramebufferTarget.Framebuffer, gLFramebufferHandle);
      
      // 重置視口
      GL.Viewport(0, 0, 寬度, 高度);
      
      // GL 繪制代碼
      
      // 結束繪制
      GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
      Wgl.DXUnlockObjectsNV(glDeviceHandle, 1, new[] { dxInteropColorHandle });
      
      // 注意:一定要取消注冊并刪除緩沖區,不然 swapChain 讀取不到數據。
      Wgl.DXUnregisterObjectNV(glDeviceHandle, dxInteropColorHandle);
      GL.DeleteRenderbuffer(gLColorRenderbufferHandle);
      
      swapChain->Present(1, 0);
      

      關聯 WinUI

      • 創建 ISwapChainPanelNative 接口類
      [ComImport]
      [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      [Guid("63aad0b8-7c24-40ff-85a8-640d944cc325")]
      public interface ISwapChainPanelNative
      {
          [PreserveSig] HResult SetSwapChain([In] IntPtr swapChain);
          [PreserveSig] ulong Release();
      }
      
      • 與 SwapChain 關聯
      SwapChainPanel swapChainPanel = new SwapChainPanel();
      swapChainPanel.As<ISwapChainPanelNative>().SetSwapChain((IntPtr)swapChain)
      

      基本上,一次的渲染流程到這里就結束了。
      但有很多問題需要解決,比如修改控件寬高重新注冊緩沖區等等。。。

      完整代碼我會放到 GitHub 上,需要的同學可以下載看看,里面包含 WPF、WinUI 的 3D Demo,并解決了剛才說的一些問題。


      WPF、WinUI 使用 Silk.Net 繪制示例(OpenGL、DirectX)

      posted @ 2023-03-15 15:41  o王先生o  閱讀(2183)  評論(3)    收藏  舉報
      主站蜘蛛池模板: 亚洲AV国产福利精品在现观看| 亚洲一区中文字幕第十页| 新安县| 少妇人妻偷人精品一区二| 亚洲欧美日韩综合久久久| 日本精品一区二区不卡| 成人aⅴ综合视频国产| 国产日韩一区二区天美麻豆 | 德格县| 亚洲av日韩在线资源| 国产精品无码成人午夜电影| 日韩人妻精品中文字幕| 久久香蕉国产线看观看猫咪av| 天堂网av最新版在线看| 荡乳尤物h| 日本韩国一区二区精品| 无码激情亚洲一区| 亚洲成亚洲成网中文字幕| 老司机午夜免费精品视频| 亚洲天堂亚洲天堂亚洲色图| 日本中文字幕久久网站| 欧美人与zoxxxx另类| 国产一区二区三区自拍视频| 亚洲欧美综合一区二区三区| 夜夜躁狠狠躁日日躁| 制服 丝袜 亚洲 中文 综合| 97精品人妻系列无码人妻| 国厂精品114福利电影免费| 日韩av日韩av在线| 国产精品性色一区二区三区| 2018av天堂在线视频精品观看 | 黑人av无码一区| 人妻出轨av中文字幕| 国产va免费精品观看| 蜜臀午夜一区二区在线播放| 四虎国产精品永久在线下载| 亚洲成AV人片在线观高清| 吃奶还摸下面动态图gif| 日本一卡2卡3卡四卡精品网站| 亚洲精品一区二区18禁| 凹凸国产熟女精品视频|