Vulkan 画三角形第十二章:创建帧缓冲区
在之前的文章中已经讨论了很多帧缓冲区相关的东西,并且我们已经配置了渲染路径,渲染路径基于一个单独的与交换链图像具有相同格式的帧缓冲区,但我们实际上还没有创建它
在渲染路径创建时指定的附着通过封装为 VkFramebuffer
对象进行绑定。一个帧缓冲区对象引用了代表这些附着的所有 VkImageView
对象。当然我们这里只有一个,也就是颜色附着。然而,我们需要用于附着的图像取决于我们在展示时交换链提供的图像。这意味这我们必须对交换链中所有的图像都创建一个帧缓冲区,并且在渲染的时候使用与交换链提供的图像相对应的那个帧缓冲区
首先添加一个成员变量用来持有这些帧缓冲区
std::vector<VkFramebuffer> swapchainFramebuffers;
接下来添加一个成员函数来为这个数组创建对象,并在 initVulkan
中调用它
void initVulkan() {
createInstance();
createSurface();
pickPhysicalDevice();
createLogicalDevice();
createSwapchain();
createImageViews();
createRenderPass();
createGraphicsPipeline();
createFrambuffers();
}
void createFramebuffers() {
}
然后直接填充这个函数
void createFramebuffers() {
swapchainFramebuffers.resize(swapchainImageViews.size());
for (size_t i = 0; i < swapchainImageViews.size(); i++) {
VkImageView attachments[] = {swapchainImageViews[i]};
VkFramebufferCreateInfo framebufferInfo = {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = renderPass;
framebufferInfo.attachmentCount = 1;
framebufferInfo.pAttachments = attachments;
framebufferInfo.width = swapchainExtent.width;
framebufferInfo.height = swapchainExtent.height;
framebufferInfo.layers = 1;
if (vkCreateFramebuffer(device, &framebufferInfo, nullptr, &swapchainFramebuffers[i]) != VK_SUCCESS)
throw std::runtime_error("failed to create framebuffer!");
}
}
首先第一步是调整数组的长度来持有所有的缓冲区
之后的创建过程十分显然。先通过创建信息的 renderPass
成员指定与帧缓冲区兼容的渲染路径。我们只能选择兼容的渲染路径,这大致上意味着它们都要使用相同数量和相同类型的附着
attachmentCount
和 pAttachments
参数指定了帧缓冲区对应的图像视图对象,它需要与渲染路径创建信息中的 pAttachment
数组中的附着描述相匹配
width
和 height
参数非常显然,layers
指的是图像的层数,我们使用的交换链图像都是单层的,因此层数为一
最后需要在 cleanup
中销毁所有的帧缓冲区
void cleanup() {
for (auto framebuffer : swapchainFramebuffers)
vkDestroyFramebuffer(device, framebuffer, nullptr);
vkDestroyPipeline(device, graphicsPipeline, nullptr);
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyRenderPass(device, renderPass, nullptr);
for (auto imageView : swapchainImageViews)
vkDestroyImageView(device, imageView, nullptr);
vkDestroySwapchainKHR(device, swapchain, nullptr);
vkDestroyDevice(device, nullptr);
vkDestroySurfaceKHR(instance, surface, nullptr);
vkDestroyInstance(instance, nullptr);
glfwDestroyWindow(window);
glfwTerminate();
}
Thanks for reading! Read other posts?