创建渲染过程
译者注:示例代码点击此处
帧缓冲区与渲染过程一起使用。 它们指定应该为渲染过程中定义的相应附件使用哪些图像资源。 它们还定义了可渲染区域的大小。 这就是为什么当我们想要记录绘图操作时,不仅需要创建渲染过程,还需要创建帧缓冲。
怎么做...
1.获取应与framebuffer兼容的渲染过程的句柄,并使用它来初始化名为render_pass的VkRenderPass类型的变量。
2.准备一个表示图像子资源的图像视图句柄列表,这些子资源应该用于渲染过程附件。 将所有准备好的图像视图存储在std::vector<VkImageView>类型的变量中。
3.创建一个名为framebuffer_create_info的VkFramebufferCreateInfo类型的变量。 使用以下值初始化其成员:
·sType为VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
·pNext为nullptr
·flags为0
·renderPass为render_pass
·attachmentCount为attachments向量中的元素数
·pAttachments为指向attachments向量第一个元素的指针(如果为空,则为nullptr值)
·width为可渲染区域的选定宽度
·height为可渲染区域的选定够大
·layers为帧缓冲区层的数目
4.获取逻辑设备的句柄,为其创建framebuffer,并将其存储在名为logical_device的vkdevice类型的变量中。
5.创建一个名为framebuffer的vkframebuffer类型变量,该变量将用创建的framebuffer的句柄初始化。
6.调用vkCreateFrameBuffer(logical_device, &frameBuffer_create_info, nullptr, &frameBuffer),为其提供logical_device、指向frameBuffer_create_info变量的指针、nullptr值和指向frameBuffer变量的指针。
7.通过检查调用是否返回vk_success值,确保已正确创建framebuffer。
这个怎么运作...
帧缓冲区始终与渲染过程一起创建。 它们定义了应该用于渲染过程中指定的附件的子资源,因此这两种对象类型应该相互对应。
当我们创建一个framebuffer时,我们提供了一个渲染过程对象,可以使用给定的framebuffer。但是,我们并不局限于仅在指定的渲染过程中使用它。我们也可以将framebuffer用于与提供的渲染过程兼容的所有渲染过程。
什么是兼容的渲染过程? 首先,它们必须具有相同数量的子过程。 每个子过程必须具有一组兼容的输入,颜色,分辨率和深度/模板附件。 这意味着格式和相应附件的样本数必须相同。 但是,附件可能具有不同的初始,子过程和最终布局以及不同的加载和存储操作。
除此之外,帧缓冲区还定义了可渲染区域的大小 - 所有渲染都将被限制的维度。 但是,我们需要记住的是,我们需要确保不修改指定范围之外的像素/片段。 为此,我们需要在管道创建期间或设置相应的动态状态时指定适当的参数(视口和剪刀测试)(请参阅第8章,图形和计算管道中的准备视口和剪刀测试状态内容以及设置 第9章命令记录和绘图中的动态视口和裁剪状态内容。
提示:我们必须确保渲染仅在帧缓冲区创建期间指定的维度中发生。
当我们在命令缓冲区中开始渲染传递并使用给定的帧缓冲区时,我们还需要确保在该帧缓冲区中指定的图像子资源不用于任何其他目的。 换句话说,如果我们使用图像的给定部分作为帧缓冲附件,我们就不能在渲染过程中以任何其他方式使用它。
提示:为渲染过程附件指定的图像子资源不能用于渲染过程的开始和结束之间的任何其他(非附件)目的。
这是一个负责创建帧缓冲区的代码示例:
VkFramebufferCreateInfo framebuffer_create_info = {
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
nullptr,
0,
render_pass,
static_cast<uint32_t>(attachments.size()),
attachments.data(),
width,
height,
layers
};
VkResult result = vkCreateFramebuffer( logical_device, &framebuffer_create_info, nullptr, &framebuffer );
if( VK_SUCCESS != result ) {
std::cout << "Could not create a framebuffer." << std::endl;
return false;
}
return true;