Example #1
0
        void InitSwapChain()
        {
            var    panelUnknown            = Marshal.GetIUnknownForObject(SwapChain);
            IntPtr swapChainPanelNativePtr = IntPtr.Zero;

            try
            {
                var guid = Guid.Parse("63aad0b8-7c24-40ff-85a8-640d944cc325");
                Marshal.ThrowExceptionForHR(Marshal.QueryInterface(panelUnknown, ref guid, out swapChainPanelNativePtr));
            }
            finally
            {
                Marshal.Release(panelUnknown);
            }

            if (swapChainPanelNativePtr != IntPtr.Zero)
            {
                m_swapChainNative = (ISwapChainPanelNative *)swapChainPanelNativePtr;

                try
                {
                    #region Init SwapChain
                    DXGI_SWAP_CHAIN_DESC1 swapChainDesc = new DXGI_SWAP_CHAIN_DESC1
                    {
                        Width       = (uint)SwapChain.ActualWidth,
                        Height      = (uint)SwapChain.ActualHeight,
                        Format      = colorFormat,   // This is the most common swapchain format.
                        Stereo      = 0,
                        BufferUsage = (uint)(1L << (1 + 4)),
                        BufferCount = 2,
                        Scaling     = DXGI_SCALING.DXGI_SCALING_STRETCH,
                        SwapEffect  = DXGI_SWAP_EFFECT.DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,
                        Flags       = 0
                    };
                    swapChainDesc.SampleDesc.Count   = 1;                        // Don't use multi-sampling.
                    swapChainDesc.SampleDesc.Quality = 0;

                    // Get D3DDevice
                    // This flag adds support for surfaces with a different color channel
                    // ordering than the API default. It is required for compatibility with Direct2D.
                    D3D11_CREATE_DEVICE_FLAG creationFlags = D3D11_CREATE_DEVICE_FLAG.D3D11_CREATE_DEVICE_BGRA_SUPPORT;

                    #if DEBUG
                    // If the project is in a debug build, enable debugging via SDK Layers.
                    creationFlags |= D3D11_CREATE_DEVICE_FLAG.D3D11_CREATE_DEVICE_DEBUG;
                    #endif

                    // This example only uses feature level 9.1.
                    D3D_FEATURE_LEVEL[] featureLevels =
                    {
                        D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_9_1
                    };
                    var pFeatureLevel = D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_1;

                    // Create the Direct3D 11 API device object and a corresponding context.
                    D3D11CreateDevice(
                        (IDXGIAdapter *)IntPtr.Zero.ToPointer(), // Specify nullptr to use the default adapter.
                        D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_HARDWARE,
                        IntPtr.Zero,
                        (uint)creationFlags,
                        InteropUtilities.AsPointer(featureLevels.AsSpan()),
                        (uint)featureLevels.Length,
                        D3D11_SDK_VERSION,          // UWP apps must set this to D3D11_SDK_VERSION.
                        m_d3dDevice.GetAddressOf(), // Returns the Direct3D device created.
                        InteropUtilities.AsPointer(ref pFeatureLevel),
                        m_d3dContext.GetAddressOf() // Returns the device immediate context.
                        );

                    // QI for DXGI device
                    m_d3dDevice.As(ref m_dxgiDevice);

                    // Get the DXGI adapter.
                    IDXGIAdapter *dxgiAdapter;
                    m_dxgiDevice.Get()->GetAdapter(&dxgiAdapter);

                    // Get the DXGI factory.
                    IDXGIFactory2 *dxgiFactory;
                    var            dxgiFactoryGuid = typeof(IDXGIFactory2).GUID;
                    dxgiAdapter->GetParent(InteropUtilities.AsPointer(ref dxgiFactoryGuid), (void **)&dxgiFactory);

                    // Create a swap chain by calling CreateSwapChainForComposition.
                    dxgiFactory->CreateSwapChainForComposition(
                        (IUnknown *)(ID3D11Device *)m_d3dDevice,
                        &swapChainDesc,
                        null,        // Allow on any display.
                        m_swapChain.GetAddressOf()
                        );

                    m_swapChainNative.Get()->SetSwapChain((IDXGISwapChain *)m_swapChain.Get());
                    #endregion

                    InitPipeline();
                    InitGraphics();

                    int hr = m_swapChain.Get()->Present(1, 0);
                    Marshal.ThrowExceptionForHR(hr);

                    SwapChain.SizeChanged += SwapChain_SizeChanged;
                }
                finally
                {
                    m_swapChainNative.Get()->Release();
                }
            }
        }
Example #2
0
        private void SwapChain_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            uint width, height;

            if (sender is Tuple <double, double> size)
            {
                width  = (uint)size.Item1;
                height = (uint)size.Item2;
            }
            else
            {
                width  = (uint)e.NewSize.Width;
                height = (uint)e.NewSize.Height;
            }
            if (width <= 0 || height <= 0)
            {
                return;
            }

            InitPipeline();

            m_d3dContext.Get()->ClearState();
            m_renderTargetView.Dispose();
            m_depthStencilView.Dispose();
            m_renderTargetView = new ComPtr <ID3D11RenderTargetView>();
            m_depthStencilView = new ComPtr <ID3D11DepthStencilView>();

            // resize the swap chain
            int hr = m_swapChain.Get()->ResizeBuffers(
                0,  // Don't change buffer count
                width,
                height,
                DXGI_FORMAT.DXGI_FORMAT_UNKNOWN, // Don't change format
                0                                // No flags
                );

            Marshal.ThrowExceptionForHR(hr);

            // (re)-create the render target view
            ComPtr <ID3D11Texture2D> backBuffer = new ComPtr <ID3D11Texture2D>();
            var d3d11Text2D = typeof(ID3D11Texture2D).GUID;
            D3D11_RENDER_TARGET_VIEW_DESC desc = new D3D11_RENDER_TARGET_VIEW_DESC
            {
                ViewDimension = D3D11_RTV_DIMENSION.D3D11_RTV_DIMENSION_BUFFER
            };

            m_renderTargetView = new ComPtr <ID3D11RenderTargetView>();

            if (FAILED(m_swapChain.Get()->GetBuffer(0, InteropUtilities.AsPointer(ref d3d11Text2D), (void **)backBuffer.GetAddressOf())))
            {
                throw new Exception("Direct3D was unable to acquire the back buffer!");
            }
            if (FAILED(m_d3dDevice.Get()->CreateRenderTargetView(
                           (ID3D11Resource *)backBuffer.Get(),
                           null,
                           m_renderTargetView.GetAddressOf())))
            {
                throw new Exception("Direct3D was unable to create the render target view!");
            }

            // create the depth and stencil buffer
            D3D11_TEXTURE2D_DESC     dsd;
            ComPtr <ID3D11Texture2D> dsBuffer = new ComPtr <ID3D11Texture2D>();

            backBuffer.Get()->GetDesc(&dsd);
            dsd.Format    = DXGI_FORMAT.DXGI_FORMAT_D24_UNORM_S8_UINT;
            dsd.Usage     = D3D11_USAGE.D3D11_USAGE_DEFAULT;
            dsd.BindFlags = (uint)D3D11_BIND_FLAG.D3D11_BIND_DEPTH_STENCIL;
            if (FAILED(m_d3dDevice.Get()->CreateTexture2D(&dsd, null, dsBuffer.GetAddressOf())))
            {
                throw new Exception("Direct3D was unable to create a 2D-texture!");
            }
            if (FAILED(m_d3dDevice.Get()->CreateDepthStencilView((ID3D11Resource *)dsBuffer.Get(), null, m_depthStencilView.GetAddressOf())))
            {
                throw new Exception("Direct3D was unable to create the depth and stencil buffer!");
            }

            // activate the depth and stencil buffer
            m_d3dContext.Get()->OMSetRenderTargets(1, m_renderTargetView.GetAddressOf(), m_depthStencilView.Get());

            // set the viewport to the entire backbuffer
            D3D11_VIEWPORT vp;

            vp.TopLeftX = 0;
            vp.TopLeftY = 0;
            vp.Width    = dsd.Width;
            vp.Height   = dsd.Height;
            vp.MinDepth = 0.0f;
            vp.MaxDepth = 1.0f;
            m_d3dContext.Get()->RSSetViewports(1, &vp);

            Present();
            //m_renderTargetView.Get()->Release();
            backBuffer.Get()->Release();
        }