Asteroids::~Asteroids() { ReleaseSwapChain(); SafeRelease(&mDepthStencilState); SafeRelease(&mInputLayout); SafeRelease(&mIndexBuffer); SafeRelease(&mVertexBuffer); SafeRelease(&mVertexShader); SafeRelease(&mPixelShader); SafeRelease(&mDrawConstantBuffer); SafeRelease(&mSamplerState); SafeRelease(&mBlendState); SafeRelease(&mSpriteBlendState); for (auto i : mSpriteTextures) { i.second->Release(); } SafeRelease(&mSpriteInputLayout); SafeRelease(&mSpriteVertexShader); SafeRelease(&mSpritePixelShader); SafeRelease(&mSpriteVertexBuffer); SafeRelease(&mFontPixelShader); SafeRelease(&mFontTextureSRV); SafeRelease(&mSkyboxVertexShader); SafeRelease(&mSkyboxPixelShader); SafeRelease(&mSkyboxConstantBuffer); SafeRelease(&mSkyboxVertexBuffer); SafeRelease(&mSkyboxInputLayout); SafeRelease(&mSkyboxSRV); for (auto& texture : mTextures) SafeRelease(&texture); for (auto& srv : mTextureSRVs) SafeRelease(&srv); if (mSwapChain != nullptr) { mSwapChain->Release(); mSwapChain = nullptr; } SafeRelease(&mDeviceCtxt); SafeRelease(&mDevice); }
// incoming resize event to be handled and translated //----------------------------------------------------------------------------- void CPUT_DX11::ResizeWindow(UINT width, UINT height) { HRESULT hr; CPUTResult result; CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibraryDX11::GetAssetLibrary(); // TODO: Making the back and depth buffers into CPUTRenderTargets should simplify this (CPUTRenderTarget* manages RTV, SRV, UAV, etc.) if( mpBackBuffer ) ((CPUTBufferDX11*)mpBackBuffer)->ReleaseBuffer(); if( mpDepthBuffer ) ((CPUTBufferDX11*)mpDepthBuffer)->ReleaseBuffer(); if( mpBackBufferTexture ) ((CPUTTextureDX11*)mpBackBufferTexture)->ReleaseTexture(); if( mpDepthBufferTexture ) ((CPUTTextureDX11*)mpDepthBufferTexture)->ReleaseTexture(); // Make sure we don't have any buffers bound. mpContext->ClearState(); Present(); mpContext->Flush(); SAFE_RELEASE(mpBackBufferRTV); SAFE_RELEASE(mpBackBufferSRV); SAFE_RELEASE(mpBackBufferUAV); SAFE_RELEASE(mpDepthStencilSRV); CPUT::ResizeWindow( width, height ); // Call the sample's clean up code if present. ReleaseSwapChain(); // handle the internals of a resize int windowWidth, windowHeight; CPUTOSServices *pServices = CPUTOSServices::GetOSServices(); pServices->GetClientDimensions( &windowWidth, &windowHeight); // resize the swap chain hr = mpSwapChain->ResizeBuffers(mSwapChainBufferCount, windowWidth, windowHeight, mSwapChainFormat, 0); ASSERT( SUCCEEDED(hr), _L("Error resizing swap chain") ); // re-create the render-target view ID3D11Texture2D *pSwapChainBuffer = NULL; hr = mpSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), (LPVOID*) (&pSwapChainBuffer)); ASSERT(SUCCEEDED(hr), _L("")); hr = mpD3dDevice->CreateRenderTargetView( pSwapChainBuffer, NULL, &mpBackBufferRTV); ASSERT(SUCCEEDED(hr), _L("")); hr = mpD3dDevice->CreateShaderResourceView( pSwapChainBuffer, NULL, &mpBackBufferSRV); ASSERT(SUCCEEDED(hr), _L("")); #ifdef CREATE_SWAP_CHAIN_UAV // Not every DXGI format supports UAV. So, create UAV only if sample chooses to do so. hr = mpD3dDevice->CreateUnorderedAccessView( pSwapChainBuffer, NULL, &mpBackBufferUAV); ASSERT(SUCCEEDED(hr), _L("")); #endif // Add the back buffer to the asset library. Create CPUTBuffer and a CPUTTexture forms and add them. if( mpBackBuffer ) { ((CPUTBufferDX11*)mpBackBuffer)->SetBufferAndViews( NULL, mpBackBufferSRV, mpBackBufferUAV ); } else { cString backBufferName = _L("$BackBuffer"); mpBackBuffer = new CPUTBufferDX11( backBufferName, NULL, mpBackBufferUAV ); pAssetLibrary->AddBuffer( backBufferName, mpBackBuffer ); } if( mpBackBufferTexture ) { ((CPUTTextureDX11*)mpBackBufferTexture)->SetTextureAndShaderResourceView( NULL, mpBackBufferSRV ); } else { cString backBufferName = _L("$BackBuffer"); mpBackBufferTexture = new CPUTTextureDX11( backBufferName, NULL, mpBackBufferSRV ); pAssetLibrary->AddTexture( backBufferName, mpBackBufferTexture ); } // release the old depth buffer objects // release the temporary swap chain buffer SAFE_RELEASE(pSwapChainBuffer); SAFE_RELEASE(mpDepthStencilBuffer); SAFE_RELEASE(mpDepthStencilState); SAFE_RELEASE(mpDepthStencilView); result = CreateAndBindDepthBuffer(windowWidth, windowHeight); if(CPUTFAILED(result)) { // depth buffer creation error ASSERT(0,_L("")); } if( mpDepthBuffer ) { ((CPUTBufferDX11*)mpDepthBuffer)->SetBufferAndViews( NULL, mpDepthStencilSRV, NULL ); } else { cString depthBufferName = _L("$DepthBuffer"); mpDepthBuffer = new CPUTBufferDX11( depthBufferName, NULL, mpDepthStencilSRV ); pAssetLibrary->AddBuffer( depthBufferName, mpDepthBuffer ); } if( mpDepthBufferTexture ) { ((CPUTTextureDX11*)mpDepthBufferTexture)->SetTextureAndShaderResourceView( NULL, mpDepthStencilSRV ); } else { cString DepthBufferName = _L("$DepthBuffer"); mpDepthBufferTexture = new CPUTTextureDX11( DepthBufferName, NULL, mpDepthStencilSRV ); pAssetLibrary->AddTexture( DepthBufferName, mpDepthBufferTexture ); } // Release our extra reference to each view. // if(mpBackBufferSRV) mpBackBufferSRV->Release(); // if(mpBackBufferUAV) mpBackBufferUAV->Release(); // if(mpDepthStencilSRV) mpDepthStencilSRV->Release();; // set the viewport D3D11_VIEWPORT vp; vp.Width = (FLOAT) windowWidth; vp.Height = (FLOAT)windowHeight; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; mpContext->RSSetViewports( 1, &vp ); // trigger the GUI manager to resize CPUTGuiControllerDX11::GetController()->Resize(); }
void Asteroids::ResizeSwapChain(IDXGIFactory2* dxgiFactory, HWND outputWindow, unsigned int width, unsigned int height) { ReleaseSwapChain(); // Create swap chain { DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; swapChainDesc.Width = width; swapChainDesc.Height = height; swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // Can create an SRGB render target view on the swap chain buffer swapChainDesc.Stereo = FALSE; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = NUM_SWAP_CHAIN_BUFFERS; swapChainDesc.Scaling = DXGI_SCALING_STRETCH; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Not used swapChainDesc.Flags = 0; ThrowIfFailed(dxgiFactory->CreateSwapChainForHwnd( mDevice, outputWindow, &swapChainDesc, nullptr, nullptr, &mSwapChain)); // MakeWindowAssociation must be called after CreateSwapChain DisableDXGIWindowChanges(mDevice, outputWindow); } // create render target view { ThrowIfFailed(mSwapChain->GetBuffer(0, IID_PPV_ARGS(&mRenderTarget))); D3D11_RENDER_TARGET_VIEW_DESC desc = {}; desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; desc.Texture2D.MipSlice = 0; ThrowIfFailed(mDevice->CreateRenderTargetView(mRenderTarget, &desc, &mRenderTargetView)); } // create depth stencil view { CD3D11_TEXTURE2D_DESC desc = CD3D11_TEXTURE2D_DESC( DXGI_FORMAT_D32_FLOAT, width, height, 1, 1, D3D11_BIND_DEPTH_STENCIL); ID3D11Texture2D* depthStencil = nullptr; ThrowIfFailed(mDevice->CreateTexture2D(&desc, nullptr, &depthStencil)); ThrowIfFailed(mDevice->CreateDepthStencilView(depthStencil, nullptr, &mDepthStencilView)); depthStencil->Release(); } // update the viewport and scissor ZeroMemory(&mViewPort, sizeof(D3D11_VIEWPORT)); mViewPort.TopLeftX = 0; mViewPort.TopLeftY = 0; mViewPort.Width = (float)width; mViewPort.Height = (float)height; mViewPort.MinDepth = 0.0f; mViewPort.MaxDepth = 1.0f; mScissorRect.left = 0; mScissorRect.top = 0; mScissorRect.right = width; mScissorRect.bottom = height; }