void QtTestGui::resizeEvent(QResizeEvent *e){ HRESULT hr = S_OK; uint32_t width = static_cast<uint32_t>((std::max)(this->width(), 1)); uint32_t height = static_cast<uint32_t>((std::max)(this->height(), 1)); std::lock_guard<std::mutex> lk(this->d3dMtx); this->d3dRtView = nullptr; if (!this->d3dSwapChain){ Microsoft::WRL::ComPtr<IDXGIDevice2> dxgiDevice; Microsoft::WRL::ComPtr<IDXGIAdapter> dxgiAdapter; Microsoft::WRL::ComPtr<IDXGIFactory2> dxgiFactory; Microsoft::WRL::ComPtr<IDXGISwapChain1> swapChainTmp; hr = this->d3dDev.As(&dxgiDevice); hr = dxgiDevice->GetParent(IID_PPV_ARGS(dxgiAdapter.GetAddressOf())); hr = dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.GetAddressOf())); HWND hwnd = reinterpret_cast<HWND>(this->winId()); HWND hwnd2 = reinterpret_cast<HWND>(this->effectiveWinId()); DXGI_SWAP_CHAIN_DESC1 swapChainDesc; DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreenDesc; swapChainDesc.Width = width; swapChainDesc.Height = height; swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; swapChainDesc.Stereo = FALSE; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 2; swapChainDesc.Scaling = DXGI_SCALING::DXGI_SCALING_STRETCH; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT::DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;// DXGI_SWAP_EFFECT::DXGI_SWAP_EFFECT_SEQUENTIAL; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE::DXGI_ALPHA_MODE_IGNORE; swapChainDesc.Flags = 0; fullscreenDesc.RefreshRate.Numerator = 0; fullscreenDesc.RefreshRate.Denominator = 0; fullscreenDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER::DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; fullscreenDesc.Scaling = DXGI_MODE_SCALING::DXGI_MODE_SCALING_CENTERED; fullscreenDesc.Windowed = TRUE; hr = dxgiFactory->CreateSwapChainForHwnd(this->d3dDev.Get(), hwnd, &swapChainDesc, &fullscreenDesc, nullptr, swapChainTmp.GetAddressOf()); hr = swapChainTmp.As(&this->d3dSwapChain); } else{ hr = this->d3dSwapChain->ResizeBuffers(2, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, 0); } Microsoft::WRL::ComPtr<IDXGISurface> dxgiSurface; Microsoft::WRL::ComPtr<ID3D11Texture2D> d3dTex; hr = this->d3dSwapChain->GetBuffer(0, IID_PPV_ARGS(dxgiSurface.GetAddressOf())); hr = dxgiSurface.As(&d3dTex); D3D11_TEXTURE2D_DESC tex2dDec; D3D11_RENDER_TARGET_VIEW_DESC d3dRtDesc; d3dTex->GetDesc(&tex2dDec); d3dRtDesc.ViewDimension = D3D11_RTV_DIMENSION::D3D11_RTV_DIMENSION_TEXTURE2D; d3dRtDesc.Format = tex2dDec.Format; d3dRtDesc.Texture2D.MipSlice = 0; this->d3dDev->CreateRenderTargetView(d3dTex.Get(), &d3dRtDesc, this->d3dRtView.ReleaseAndGetAddressOf()); D3D11_VIEWPORT viewPort; viewPort.TopLeftX = viewPort.TopLeftY = 0.0f; viewPort.Width = static_cast<float>(width); viewPort.Height = static_cast<float>(height); viewPort.MinDepth = 0.0f; viewPort.MaxDepth = 1.0f; this->d3dCtx->RSSetViewports(1, &viewPort); this->UpdateProjection(); }
void DirectXPanelBase::CreateSizeDependentResources() { bool setSwapChain = false; // Ensure dependent objects have been released. ReleaseSizeDependentResources(); // If the swap chain already exists, then resize it. if (m_swapChain != nullptr) { // If the swap chain already exists, resize it. HRESULT hr = m_swapChain->ResizeBuffers( 2, // Double-buffered swap chain. static_cast<UINT>((float) max(m_width * m_compositionScaleX, 1)), static_cast<UINT>((float) max(m_height * m_compositionScaleY, 1)), DXGI_FORMAT_B8G8R8A8_UNORM, 0 ); if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { // If the device was removed for any reason, a new device and swap chain will need to be created. HandleDeviceLost(); // Everything is set up now. Do not continue execution of this method. return; } else { DX::ThrowIfFailed(hr); } } else // Otherwise, create a new one. { DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; swapChainDesc.Width = static_cast<UINT>((float) max(m_width * m_compositionScaleX, 1)); // Match the size of the panel. swapChainDesc.Height = static_cast<UINT>((float) max(m_height * m_compositionScaleY, 1)); swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format. swapChainDesc.Stereo = false; swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling. swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 2; // Use double buffering to enable flip. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect. swapChainDesc.Flags = 0; swapChainDesc.AlphaMode = m_alphaMode; // Get underlying DXGI Device from D3D Device. Microsoft::WRL::ComPtr<IDXGIDevice1> dxgiDevice; DX::ThrowIfFailed( m_d3dDevice.As(&dxgiDevice) ); // Get adapter. Microsoft::WRL::ComPtr<IDXGIAdapter> dxgiAdapter; DX::ThrowIfFailed( dxgiDevice->GetAdapter(&dxgiAdapter) ); // Get factory. Microsoft::WRL::ComPtr<IDXGIFactory2> dxgiFactory; DX::ThrowIfFailed( dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory)) ); Microsoft::WRL::ComPtr<IDXGISwapChain1> swapChain; // Create swap chain. DX::ThrowIfFailed( dxgiFactory->CreateSwapChainForComposition( m_d3dDevice.Get(), &swapChainDesc, nullptr, &swapChain ) ); swapChain.As(&m_swapChain); // Ensure that DXGI does not queue more than one frame at a time. This both reduces // latency and ensures that the application will only render after each VSync, minimizing // power consumption. DX::ThrowIfFailed( dxgiDevice->SetMaximumFrameLatency(1) ); setSwapChain = true; } // Ensure the physical pixel size of the swap chain takes into account both the XAML SwapChainPanel's logical layout size and // any cumulative composition scale applied due to zooming, render transforms, or the system's current scaling plateau. // For example, if a 100x100 SwapChainPanel has a cumulative 2x scale transform applied, we instead create a 200x200 swap chain // to avoid artifacts from scaling it up by 2x, then apply an inverse 1/2x transform to the swap chain to cancel out the 2x transform. DXGI_MATRIX_3X2_F inverseScale = { 0 }; inverseScale._11 = 1.0f / m_compositionScaleX; inverseScale._22 = 1.0f / m_compositionScaleY; m_swapChain->SetMatrixTransform(&inverseScale); D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1( D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), s_dipsPerInch * m_compositionScaleX, s_dipsPerInch * m_compositionScaleY ); // Direct2D needs the DXGI version of the backbuffer surface pointer. Microsoft::WRL::ComPtr<IDXGISurface> dxgiBackBuffer; DX::ThrowIfFailed( m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer)) ); // Get a D2D surface from the DXGI back buffer to use as the D2D render target. DX::ThrowIfFailed( m_d2dContext->CreateBitmapFromDxgiSurface( dxgiBackBuffer.Get(), &bitmapProperties, &m_d2dTargetBitmap ) ); m_d2dContext->SetDpi(s_dipsPerInch * m_compositionScaleX, s_dipsPerInch * m_compositionScaleY); m_d2dContext->SetTarget(m_d2dTargetBitmap.Get()); if (setSwapChain) { SetSwapChain(); } }