Resizing the display window

When a display window resizes, the Vulkan application is given the new window dimensions to re-paint the drawing images. On the Windows platform, the WM_SIZE message of the associated window's procedure can be used to indicate the change in the dimension size as shown in the following highlighted code. The new changes added to the WndProc() function are highlighted with bold; the new dimension size is updated to the VulkanSwapChain class using the setSwapChainExtent() function, which will be later used to recreate the new swapchain images with the indicated dimensions:

LRESULT CALLBACK VulkanRenderer::WndProc(HWND hWnd, UINT uMsg,  
WPARAM wParam, LPARAM lParam) 
{ 
  VulkanApplication* appObj = VulkanApplication::GetInstance(); 
  switch (uMsg) 
 { 
   case WM_CLOSE: 
   PostQuitMessage(0); 
   break; 
   case WM_PAINT: 
   // Many lines skipped please, refer to the source code
   case WM_SIZE:

   if (wParam != SIZE_MINIMIZED) {

   appObj->rendererObj->width = lParam & 0xffff;

   appObj->rendererObj->height = (lParam &

   0xffff0000) >> 16;

   appObj->rendererObj->getSwapChain()->

   setSwapChainExtent(appObj->rendererObj->

   width, appObj->rendererObj->height);

   appObj->resize()

 }

  break; 
 
  default: 
  break; 
} 
return (DefWindowProc(hWnd, uMsg, wParam, lParam)); 
} 

The VulkanApplication class is added with a new function called resize(); this function handles resize activities. The Vulkan application's resize function is called by the VulkanRenderer::WndProc()when a resize event happens.

The resize() function destroys created resources and recreates them again. The resource preparation status can be checked using the isPrepared flag in VulkanApplication; if this flag is false, it means resources are not prepared yet and resizing cannot be performed.

When the resources are recreated,the old swapchain images are destroyed and created again to match the new window size.

Note

A swapchain image must only be recreated when it is not being used by any pending command or presentation operation. This can be ensured by calling the vkDeviceWaitIdle() API; this API guarantees that there is no pending operation on this device. This API keeps the host waiting until the device become idle.

When the waiting in resize function finishes, it can go ahead and recreate the swapchain images; but before doing so we will also need to destroy and recreate the framebuffer, command pool, graphics pipeline, Render Pass, depth buffer image, image view, vertex buffer, and so on. The following is the implementation of the resize function showing this:

void VulkanApplication::resize() 
{ 
   // If prepared then only proceed for 
   if (!isPrepared) { 
      return; 
   } 
 
  isResizing = true; 
 
  vkDeviceWaitIdle(deviceObj->device); 
  rendererObj->destroyFramebuffers(); 
  rendererObj->destroyCommandPool(); 
  rendererObj->destroyPipeline(); 
  rendererObj->getPipelineObject()->destroyPipelineCache(); 
  rendererObj->destroyRenderpass(); 
  rendererObj->getSwapChain()->destroySwapChain(); 
  rendererObj->destroyDrawableVertexBuffer(); 
  rendererObj->destroyDepthBuffer(); 
  rendererObj->initialize(); 
  prepare(); 
 
  isResizing = false; 
} 

The application must prevent any render operation when resizing is going on; for this purpose, the isResizing flag can be used to indicate the resizing status. The reinitialization is performed by calling the VulkanRender'sinitialize() function. The drawing commands are recorded in the Vulkan application's prepare function:

void VulkanRenderer::initialize() 
{ 
   // We need command buffers, so create a command buffer pool 
   createCommandPool(); 
 
   // Let's create the swap chain color images and depth image 
   buildSwapChainAndDepthImage(); 
 
   // Build the vertex buffer  
   createVertexBuffer(); 
 
   const bool includeDepth = true; 
   // Create the render pass now.. 
   createRenderPass(includeDepth); 
 
   // Use render pass and create frame buffer 
   createFrameBuffer(includeDepth); 
 
   // Create the vertex and fragment shader 
   createShaders(); 
 
   // Manage the pipeline state objects 
   createPipelineStateManagement(); 
} 
void VulkanApplication::prepare() 
{ 
   isPrepared = false; 
   rendererObj->prepare(); 
   isPrepared = true; 
} 

The following screenshot shows the output of the resize window implementation:

Resizing the display window

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.187.108