之前的几章中,我们已经讨论了很多帧缓冲相关的内容,我们也创建了一个渲染通道来生成一个和交换链图像格式相同的帧缓冲,但我们还并没有实际创建帧缓冲。
在渲染通道创建时指定的附件需要包装为VkFramebuffer
对象。帧缓冲引用了所有代表福建的VkImageView
对象。我们的程序中只有一个颜色附件。我们用于附件的图像都来自于交换链,所以我们需要为每个交换链中的图像创建一个帧缓冲,在绘制的时候使用其中一个。
创建一个std::vector
成员变量保存帧缓冲:
std::vector<VkFramebuffer> swapChainFramebuffers;
我们写一个函数createFramebuffers
来创建帧缓冲,并在initVulkan
函数中调用:
void initVulkan() {
createInstance();
setupDebugMessenger();
createSurface();
pickPhysicalDevice();
createLogicalDevice();
createSwapChain();
createImageViews();
createRenderPass();
createGraphicsPipeline();
createFramebuffers();
}
...
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
参数指定附件,应该和渲染通道的pAttachments
一样的。
width
和height
是宽高,layers
指的是图像的层数。我们这边只有一张图,一层。
我们在渲染之后,图像视图和渲染通道之前销毁帧缓冲。
void cleanup() {
for (auto framebuffer : swapChainFramebuffers) {
vkDestroyFramebuffer(device, framebuffer, nullptr);
}
...
}
我们已经到达了一个里程碑——所有渲染所需的对象都有了。下一章,我们将编写第一个实际的绘制命令。
目录
上一节 - 绘制一个三角形/图形管线基础/汇总(Conclusion)
下一节 - 绘制一个三角形/绘制/命令缓冲(Command buffers)