In the last two chapters, we implemented the Render Pass instance and displayed swapchain images with specified background colors. In the previous chapter, we put various pipeline states together along with Render Pass in the graphics pipeline. In this chapter, we will put all previous implementations together to build the first Hello World! program in Vulkan and display our first rendering object on the display output.
This chapter thoroughly covers the process of drawing objects in Vulkan; it comprises recording and executing the drawing object's command buffers. The recording associates the Render Pass, framebuffer, and the pipeline together with the viewport and geometry data. Command buffer execution involves submitting the command buffer in the device queue and presenting the drawn swapchain image onto the presentation engine. Toward the end of this chapter, we will discuss various synchronization primitives available in the Vulkan API.
In this chapter, we will cover the following topics:
Implementing a drawing object in Vulkan is simple; it consists of two phases: preparation, or building the drawing object, and rendering it. The former phase produces the command buffer and records the drawing commands. In the latter phase, the command buffer executes these drawing commands to render the object. Let's take a look at these phases in detail:
The preparation and rendering of the drawable object are implemented through the prepare()
and render()
functions of the VulkanDrawable
class.
In this section, we will take a look at the header file declaration for VulkanDrawable
. Please follow through the inline comments to understand the functionality and purpose of each function and variable. As we proceed through the chapter, we will implement these functions and discuss them in detail. The following are the new member variables and functions added:
class VulkanDrawable { public: // Prepares the drawing object before rendering, // allocate, create, record command buffer void prepare(); // Renders the drawing object void render(); // Initialize the viewport parameters here void initViewports(VkCommandBuffer* cmd); // Initialize the scissor parameters here void initScissors(VkCommandBuffer* cmd); // Destroy the drawing command buffer object void destroyCommandBuffer(); private: // Command buffer for drawing std::vector<VkCommandBuffer> vecCmdDraw; // Prepares render pass instance void recordCommandBuffer(int currentImage, VkCommandBuffer* cmdDraw); // Viewport and Scissor variables VkViewport viewport; VkRect2D scissor; VkSemaphore presentCompleteSemaphore; VkSemaphore drawingCompleteSemaphore; };
The prepare()
function creates the command buffer objects, which are used in the render()
function to draw the object. The prepare()
function allocates the memory for the command buffer (vecCmdDraw
) from the command pool (VulkanRenderer::cmdPool
) and creates the command buffer object. The command buffer commands are recorded inside the recordCommandBuffer()
function; this creates the Render Pass instance and other important jobs, such as associating the graphics pipeline with the drawing object and specifying the viewport and scissoring management through initViewport()
and initScissor()
.
The render()
function uses the prepared recorded command buffer and renders the drawing on the available swapchain color image. Once the drawing is finished on the swapchain's color image, then it is given to the presentation engine for display purposes.
18.226.165.70