Example #1
0
        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            // 根据 [Surface sharing between Windows graphics APIs - Win32 apps](https://docs.microsoft.com/en-us/windows/win32/direct3darticles/surface-sharing-between-windows-graphics-apis?WT.mc_id=WD-MVP-5003260 ) 文档

            var width  = ImageWidth;
            var height = ImageHeight;

            // 2021.12.23 不能在 x86 下运行,会炸掉。参阅 https://github.com/dotnet/Silk.NET/issues/731

            var texture2DDesc = new D3D11.Texture2DDesc()
            {
                BindFlags  = (uint)(D3D11.BindFlag.BindRenderTarget | D3D11.BindFlag.BindShaderResource),
                Format     = DXGI.Format.FormatB8G8R8A8Unorm, // 最好使用此格式,否则还需要后续转换
                Width      = (uint)width,
                Height     = (uint)height,
                MipLevels  = 1,
                SampleDesc = new DXGI.SampleDesc(1, 0),
                Usage      = D3D11.Usage.UsageDefault,
                MiscFlags  = (uint)D3D11.ResourceMiscFlag.ResourceMiscShared,
                // The D3D11_RESOURCE_MISC_FLAG cannot be used when creating resources with D3D11_CPU_ACCESS flags.
                CPUAccessFlags = 0, //(uint) D3D11.CpuAccessFlag.None,
                ArraySize      = 1
            };

            D3D11.ID3D11Device *       pD3D11Device;
            D3D11.ID3D11DeviceContext *pD3D11DeviceContext;
            D3DFeatureLevel            pD3DFeatureLevel = default;

            D3D11.D3D11 d3D11 = D3D11.D3D11.GetApi();

            var hr = d3D11.CreateDevice((DXGI.IDXGIAdapter *)IntPtr.Zero, D3DDriverType.D3DDriverTypeHardware,
                                        Software: 0,
                                        Flags: (uint)D3D11.CreateDeviceFlag.CreateDeviceBgraSupport,
                                        (D3DFeatureLevel *)IntPtr.Zero,
                                        FeatureLevels: 0,                        // D3DFeatureLevel 的长度
                                        SDKVersion: 7,
                                        (D3D11.ID3D11Device * *) & pD3D11Device, // 参阅 [C# 从零开始写 SharpDx 应用 聊聊功能等级](https://blog.lindexi.com/post/C-%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E5%86%99-SharpDx-%E5%BA%94%E7%94%A8-%E8%81%8A%E8%81%8A%E5%8A%9F%E8%83%BD%E7%AD%89%E7%BA%A7.html )
                                        ref pD3DFeatureLevel,
                                        (D3D11.ID3D11DeviceContext * *) & pD3D11DeviceContext
                                        );

            SilkMarshal.ThrowHResult(hr);

            Debugger.Launch();
            Debugger.Break();

            _pD3D11Device        = pD3D11Device;
            _pD3D11DeviceContext = pD3D11DeviceContext;

            D3D11.ID3D11Texture2D *pD3D11Texture2D;
            hr = pD3D11Device->CreateTexture2D(ref texture2DDesc, (D3D11.SubresourceData *)IntPtr.Zero, &pD3D11Texture2D);
            SilkMarshal.ThrowHResult(hr);

            var renderTarget = pD3D11Texture2D;

            _pD3D11Texture2D = pD3D11Texture2D;

            DXGI.IDXGISurface *pDXGISurface;
            var dxgiSurfaceGuid = DXGI.IDXGISurface.Guid;

            renderTarget->QueryInterface(ref dxgiSurfaceGuid, (void **)&pDXGISurface);
            _pDXGISurface = pDXGISurface;

            var d2DFactory = new D2D.Factory();

            var renderTargetProperties =
                new D2D.RenderTargetProperties(new D2D.PixelFormat(SharpDXDXGI.Format.Unknown, D2D.AlphaMode.Premultiplied));
            var surface = new SharpDXDXGI.Surface(new IntPtr((void *)pDXGISurface));

            _d2DRenderTarget = new D2D.RenderTarget(d2DFactory, surface, renderTargetProperties);

            SetRenderTarget(renderTarget);

            var viewport = new D3D11.Viewport(0, 0, width, height, 0, 1);

            pD3D11DeviceContext->RSSetViewports(NumViewports: 1, ref viewport);

            CompositionTarget.Rendering += CompositionTarget_Rendering;
        }
Example #2
0
        private void SetRenderTarget(D3D11.ID3D11Texture2D *target)
        {
            DXGI.IDXGIResource *pDXGIResource;
            var dxgiResourceGuid = DXGI.IDXGIResource.Guid;

            target->QueryInterface(ref dxgiResourceGuid, (void **)&pDXGIResource);

            D3D11.Texture2DDesc texture2DDescription = default;
            target->GetDesc(ref texture2DDescription);

            void *sharedHandle;
            var   hr = pDXGIResource->GetSharedHandle(&sharedHandle);

            SilkMarshal.ThrowHResult(hr);

            var d3d9 = D3D9.D3D9.GetApi();

            D3D9.IDirect3D9Ex *pDirect3D9Ex;
            hr = d3d9.Direct3DCreate9Ex(SDKVersion: 32, &pDirect3D9Ex);
            SilkMarshal.ThrowHResult(hr);
            var d3DContext = pDirect3D9Ex;

            _pDirect3D9Ex = pDirect3D9Ex;

            var presentParameters = new D3D9.PresentParameters()
            {
                Windowed             = 1,// true
                SwapEffect           = D3D9.Swapeffect.SwapeffectDiscard,
                HDeviceWindow        = GetDesktopWindow(),
                PresentationInterval = D3D9.D3D9.PresentIntervalDefault,
            };

            // 设置使用多线程方式,这样的性能才足够
            uint createFlags = D3D9.D3D9.CreateHardwareVertexprocessing | D3D9.D3D9.CreateMultithreaded | D3D9.D3D9.CreateFpuPreserve;

            D3D9.IDirect3DDevice9Ex *pDirect3DDevice9Ex;
            hr = d3DContext->CreateDeviceEx(Adapter: 0,
                                            DeviceType: D3D9.Devtype.DevtypeHal,// 使用硬件渲染
                                            hFocusWindow: IntPtr.Zero,
                                            createFlags,
                                            ref presentParameters,
                                            pFullscreenDisplayMode: (D3D9.Displaymodeex *)IntPtr.Zero,
                                            &pDirect3DDevice9Ex);
            SilkMarshal.ThrowHResult(hr);

            var d3DDevice = pDirect3DDevice9Ex;

            D3D9.IDirect3DTexture9 *pDirect3DTexture9;
            hr = d3DDevice->CreateTexture(texture2DDescription.Width, texture2DDescription.Height, Levels: 1,
                                          D3D9.D3D9.UsageRendertarget,
                                          D3D9.Format.FmtA8R8G8B8, // 这是必须要求的颜色,不能使用其他颜色
                                          D3D9.Pool.PoolDefault,
                                          &pDirect3DTexture9,
                                          &sharedHandle);
            SilkMarshal.ThrowHResult(hr);
            _renderTarget = pDirect3DTexture9;

            D3D9.IDirect3DSurface9 *pDirect3DSurface9;
            _renderTarget->GetSurfaceLevel(0, &pDirect3DSurface9);
            _pDirect3DSurface9 = pDirect3DSurface9;

            D3DImage.Lock();
            D3DImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, new IntPtr(pDirect3DSurface9));
            D3DImage.Unlock();
        }