Clearing the background color

In this section, we use the created Render Pass and framebuffer object and implement the Render Pass instance. This Render Pass instance is very simple and will only clear the background image with a specified color. For each swapchain image, different colors can be specified using the pClearValues field of the VkRenderPassBeginInfo structure; this structure is then passed to the Render Pass instance.

The Render Pass instance is implemented during the preparation stage in which the command buffers are created. For each swapchain image, a corresponding command buffer object is created. This means, for n swapchain images, we need to create n command buffer objects.

The preparation is done using the VulkanDrawable::prepare() function, and the rendering of the swapchain images will be performed using the VulkanDrawable::render() function.

The following diagram shows the call stack of the prepare() and render() function:

Clearing the background color

The following class declaration shows the new member variables and functions added to the VulkanDrawable class. The prepare() function produces the command buffers in the vecCmdDraw vector and records the drawing commands; these are used in the render() function where the command buffer executes and renders the swapchain images. The recordCommandBuffer() function records the commands in the Render Pass instance.

Note

For a detailed understanding of the preparation and rendering of a drawing object, refer to the Preparing the drawing object and Rendering the drawing object sections in Chapter 9, Drawing Objects.

class VulkanDrawable 
{ 
public: 
   // Prepares the drawing object before rendering

   // Allocate, create, record command buffer 
   void prepare(); 
 
   // Renders the drawing object 
   void render(); 
 
private: 
   // Command buffer for drawing 
   std::vector<VkCommandBuffer> vecCmdDraw; 
   // Prepares render pass instance  
   void recordCommandBuffer(int currentImage,  
            VkCommandBuffer* cmdDraw); 
}; 

Setting the background color in the Render Pass instance

In this section, we will implement the prepare() function of VulkanDrawable. Inside this, the command buffer wrapper class (CommandBufferMgr) is used to manage (allocate, record, and submit) the command buffers (vecCmdDraw). The following code implements the prepare() function:

void VulkanDrawable::prepare() 
{ 
   VulkanDevice* deviceObj = rendererObj->getDevice(); 
   vecCmdDraw.resize(rendererObj->getSwapChain()->scPublicVars 
                                     .colorBuffer.size()); 
 
   // For each swapbuffer color image buffer
 
  // allocate the corresponding command buffer 
   for (int i = 0; i < rendererObj->getSwapChain()->scPublicVars. 
                                      colorBuffer.size(); i++){ 
        // Allocate, create and start command buffer recording 
         CommandBufferMgr::allocCommandBuffer(&deviceObj->device,  
               *rendererObj->getCommandPool(), &vecCmdDraw[i]); 
         CommandBufferMgr::beginCommandBuffer(vecCmdDraw[i]); 
 
        // Create the render pass instance  
         recordCommandBuffer(i, &vecCmdDraw[i]); 
 
        // Finish the command buffer recording 
         CommandBufferMgr::endCommandBuffer(vecCmdDraw[i]); 
   } 
} 

The implementation first checks the number of color images supported by the swapchain and creates the same number of command buffer objects, associating each one of them logically with the corresponding swapchain image. The clearing of the swapchain image is always performed on the back image (back buffer), while the front image (front buffer) is used to display the rendered contents. Once the back image is cleared and rendered (if any), it is swapped with the front buffer.

Use the created command buffer (vecCmdDraw) and record the commands inside the recordCommandBuffer() function. This function specifies the clear color value for each swapchain image using the pClearValues field of the VkRenderPassBeginInfo data structure that is passed into the vkCmdBeginRenderPass() API. The vkCmdBeginRenderPass() and vkCmdEndRenderPass() APIs define a scope under which the Render Pass instance commands are recorded.

Note

For more information on Render Pass commands and its associated APIs, refer to the Recording the Render Pass commands section in Chapter 9, Drawing Objects.

There are two objects of the clear values (VkClearValue). The first one specifies the clear color value of the associated swapchain image indicated by the currentImage index. The second object specifies the clear color value to be used for the depth image:

void VulkanDrawable::recordCommandBuffer(int currentImage, VkCommandBuffer* cmdDraw) 
{ 
    // Specify the clear color value 
    VkClearValue clearValues[2]; 
    switch (currentImage) 
    { 
       case 0: clearValues[0].color = { 1.0f,0.0f,0.0f,1.0f };break; 
       case 1: clearValues[0].color = { 0.0f,1.0f,0.0f,1.0f };break; 
       case 2: clearValues[0].color = { 0.0f,0.0f,1.0f,1.0f };break; 
       default:clearValues[0].color = { 0.0f,0.0f,0.0f,1.0f };break; 
    } 
 
    // Specify the depth/stencil clear value 
    clearValues[1].depthStencil.depth  = 1.0f; 
    clearValues[1].depthStencil.stencil      = 0; 
 
    // Define the VkRenderPassBeginInfo control structure 
    VkRenderPassBeginInfo renderPassBegin = {}; 
    renderPassBegin.sType=VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 
    renderPassBegin.renderPass   = rendererObj->renderPass; 
    renderPassBegin.framebuffer = rendererObj-> 
    framebuffers[currentImage]; 
    renderPassBegin.renderArea.extent.width = rendererObj->width; 
    renderPassBegin.renderArea.extent.height= rendererObj->height; 
    renderPassBegin.clearValueCount          = 2; 
    renderPassBegin.pClearValues       = clearValues; 
    
    // Start recording the render pass instance 
    vkCmdBeginRenderPass(*cmdDraw, &renderPassBegin,  
                                 VK_SUBPASS_CONTENTS_INLINE); 
 
    // End of render pass instance recording 
    vkCmdEndRenderPass(*cmdDraw); 
} 

Rendering the colored background

The cleared swapchain images are rendered one by one inside the render() function, as implemented in the following code snippet. The WSI windowing system extension vkAcquireNextImageKHR() is used to query the next available swapchain image index. This index indicates which swapchain image will be available for drawing. Using this index, the corresponding command buffer is selected and submitted to the queue. Once processed on the GPU, the swapchain image is ready for displaying purposes using the presentation engine. The presentation is performed using the WSI extension fpQueuePresentKHR. This API intakes the VkPresentInfoKHR structure; this contains the swapchain object and the index of the swapchain image that needs to be displayed on the window.

Note

Rendering the drawing object is a separate topic altogether and is out of the scope of this chapter. For more information on this topic and the associated WSI extensions with their related data structures, refer to the Rendering the drawing object section in Chapter 9, Drawing Objects.

The following code implements the clearing where the background color is cleared every second with red, blue and green background color:

void VulkanDrawable::render() 
{ 
    VulkanDevice* deviceObj            = rendererObj->getDevice(); 
    VulkanSwapChain* swapChainObj      = rendererObj->getSwapChain(); 
 
    uint32_t& currentColorImage        = swapChainObj->scPublicVars. 
                                         currentColorBuffer; 
    VkSwapchainKHR& swapChain          = swapChainObj->scPublicVars. 
                                         swapChain; 
    // Render each background color for 1 second. 
    Sleep(1000); 
    
    // Get the index of the next available swapchain image: 
    VkResult result = swapChainObj->fpAcquireNextImageKHR 
    (deviceObj->device, swapChain, UINT64_MAX, VK_NULL_HANDLE,  
    VK_NULL_HANDLE, &currentColorImage); 
 
    // Queue the command buffer for execution 
    CommandBufferMgr::submitCommandBuffer(deviceObj->queue, 
    &vecCmdDraw[currentColorImage], NULL); 
 
    // Present the image in the window 
    VkPresentInfoKHR present     = {}; 
    present.sType                = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; 
    present.swapchainCount       = 1; 
    present.pSwapchains          = &swapChain; 
    present.pImageIndices        = &currentColorImage; 
 
    // Queue the image for presentation, 
    result = swapChainObj->fpQueuePresentKHR 
    (deviceObj->queue, &present); 
    assert(result == VK_SUCCESS); 
} 

The following is the output of the implemented exercise. The output will display various background colors, and each image will be displayed for one second.

Rendering the colored background

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

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