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(); } } }
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(); }