首页 > 其他分享 >Vulkan 开发(十三):Vulkan 帧缓冲区(FrameBuffer)

Vulkan 开发(十三):Vulkan 帧缓冲区(FrameBuffer)

时间:2025-01-07 16:30:45浏览次数:3  
标签:渲染 附件 framebufferInfo 图像 缓冲区 FrameBuffer Vulkan

Vulkan 系列文章:

1. 开篇,Vulkan 概述

2. Vulkan 实例

3. Vulkan 物理设备

4. Vulkan 设备队列

5. Vulkan 逻辑设备

6. Vulkan 内存管理

7. Vulkan 缓存

8. Vulkan 图像

9. Vulkan 图像视图

10. Vulkan 窗口表面(Surface)

11. Vulkan 交换链

12. Vulkan 渲染通道


Vulkan 帧缓冲区

Vulkan 帧缓冲区(Framebuffer)是一个容器对象(资源管理类型的对象),包含了一组图像视图(Image Views),用于在渲染通道(Render Pass)中作为附件(Attachments)进行渲染。

每个帧缓冲区的附件与渲染通道的附件描述(Attachment Description)相对应,它们共同定义了渲染的目标,重点强调一下,附件必须与渲染通道的附件描述匹配

帧缓冲区在 Vulkan 中的概念类似于 OpenGL 的帧缓冲对象(FBO),每个帧缓冲区包含一组图像视图,这些图像视图表示实际的图像资源,可以是颜色附件、深度附件或模板附件,帧缓冲区用于将渲染输出写入这些图像中(存储渲染通道(Render Pass)输出的图像)。

在 Vulkan 中,每个帧缓冲区至少需要一个颜色附件,而这个颜色附件可以是与 SwapChain 关联的 ImageView。

创建 Vulkan 帧缓冲区

帧缓冲区的创建过程通常涉及以下步骤:

  1. 确定帧缓冲区需要兼容的 RenderPass(前文中已经讲过),因为 RenderPass 定义了渲染操作的结构和执行顺序,以及所需的附件的数量、类型和格式。

  2. 为每个 SwapChain 图像创建对应的 ImageView (前文中已经讲过),因为最终渲染的图像需要显示在屏幕上,SwapChain 的 ImageView 就是用来呈现到屏幕上的。

  3. 使用 VkFramebufferCreateInfo 结构体来创建 Framebuffer,指定渲染通道、附件个数、附件信息、宽度、高度和层数等参数。

用于创建帧缓冲区(Framebuffer)的结构体 VkFramebufferCreateInfo :

 1typedef struct VkFramebufferCreateInfo {
 2    VkStructureType          sType;         // 必须是 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
 3    const void*              pNext;         // 指向扩展结构的指针,通常为 nullptr
 4    VkFramebufferCreateFlags flags;         // 帧缓冲区创建标志,目前保留,必须为 0
 5    VkRenderPass             renderPass;    // 与帧缓冲区相关联的渲染通道(Render Pass)
 6    uint32_t                 attachmentCount; // 帧缓冲区的附件数量
 7    const VkImageView*       pAttachments;  // 指向 VkImageView 的指针数组,每个指针指向一个附件
 8    uint32_t                 width;         // 帧缓冲区的宽度
 9    uint32_t                 height;        // 帧缓冲区的高度
10    uint32_t                 layers;        // 帧缓冲区的层数(通常为 1)
11} VkFramebufferCreateInfo;

创建包含颜色、深度模版附件的帧缓冲区:

 1// 创建交换链图像视图(作为颜色附件)
 2std::vector<VkImageView> swapChainImageViews(swapChainImages.size());
 3for (size_t i = 0; i < swapChainImages.size(); i++) {
 4    VkImageViewCreateInfo createInfo = {};
 5    createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
 6    createInfo.image = swapChainImages[i]; // 交换链图像
 7    createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; // 2D 图像视图
 8    createInfo.format = swapChainImageFormat; // 图像格式
 9    createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; // 红色分量
10    createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; // 绿色分量
11    createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; // 蓝色分量
12    createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; // 透明度分量
13    createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; // 颜色附件
14    createInfo.subresourceRange.baseMipLevel = 0; // 基础 mip 级别
15    createInfo.subresourceRange.levelCount = 1; // mip 级别数量
16    createInfo.subresourceRange.baseArrayLayer = 0; // 基础数组层
17    createInfo.subresourceRange.layerCount = 1; // 数组层数量
18
19    if (vkCreateImageView(device, &createInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) {
20        throw std::runtime_error("failed to create image views!");
21    }
22}
23
24//创建深度模版图像视图
25VkImage depthStencilImage;//假设已经创建好
26VkImageView depthStencilImageView;
27VkImageViewCreateInfo viewInfo = {};
28viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
29viewInfo.image = depthStencilImage;
30viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
31viewInfo.format = depthFormat;
32viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
33viewInfo.subresourceRange.baseMipLevel = 0;
34viewInfo.subresourceRange.levelCount = 1;
35viewInfo.subresourceRange.baseArrayLayer = 0;
36viewInfo.subresourceRange.layerCount = 1;
37
38if (vkCreateImageView(device, &viewInfo, nullptr, &depthStencilImageView) != VK_SUCCESS) {
39    throw std::runtime_error("failed to create depth image view!");
40}
41
42
43// 创建帧缓冲区
44std::vector<VkFramebuffer> swapChainFramebuffers(swapChainImageViews.size());
45for (size_t i = 0; i < swapChainImageViews.size(); i++) {
46    std::array<VkImageView, 2> attachments = {
47        swapChainImageViews[i],   // 颜色附件
48        depthStencilImageView     // 深度模板附件
49    };
50
51    VkFramebufferCreateInfo framebufferInfo = {};
52    framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
53    framebufferInfo.renderPass = renderPass; // 前文创建好的渲染通道
54    framebufferInfo.attachmentCount = static_cast<uint32_t>(attachments.size()); // 附件数量
55    framebufferInfo.pAttachments = attachments.data(); // 附件数组数据
56    framebufferInfo.width = swapChainExtent.width; // 帧缓冲区宽度
57    framebufferInfo.height = swapChainExtent.height; // 帧缓冲区高度
58    framebufferInfo.layers = 1; // 层数量
59
60    if (vkCreateFramebuffer(device, &framebufferInfo, nullptr, &swapChainFramebuffers[i]) != VK_SUCCESS) {
61        throw std::runtime_error("failed to create framebuffer!");
62    }
63}
64
65// Vulkan 编程。。。
66
67// 销毁帧缓冲区
68for (size_t i = 0; i < swapChainFramebuffers.size(); i++) {
69    vkDestroyFramebuffer(device, swapChainFramebuffers[i], nullptr);
70}
71
72// 销毁交换链图像视图
73for (size_t i = 0; i < swapChainImageViews.size(); i++) {
74    vkDestroyImageView(device, swapChainImageViews[i], nullptr);
75}
76
77// 销毁深度模板图像视图
78vkDestroyImageView(device, depthStencilImageView, nullptr);

标签:渲染,附件,framebufferInfo,图像,缓冲区,FrameBuffer,Vulkan
From: https://blog.csdn.net/Kennethdroid/article/details/144988302

相关文章

  • Emacs 中的缓冲区(Buffer)介绍
    Emacs中的缓冲区(Buffer)在Emacs中,缓冲区(buffer)是一个核心概念,表示Emacs内部用于处理和显示文本的“工作区域”。每个打开的文件、运行的命令、显示的消息、终端会话等都被分配到一个独立的缓冲区。缓冲区的特点不局限于文件:缓冲区不一定与文件相关联。它可以是用......
  • Vulkan VertexInput 相关概念了解
    VkVertexInputBindingDescription一个buffer下面可以有多个binding,每一个binding里面可以有多个locationstructVertex{glm::vec2pos;glm::vec3color;};VkVertexInputBindingDescriptionbindingDescription{};bindingDescription.binding=0;bindingDescrip......
  • 网站服务器响应缓冲区超出限制,如何解决?
    当您遇到“超过响应缓冲限制”的错误提示时,通常意味着您的ASP页面在执行过程中生成的输出数据量超过了服务器配置中设定的缓冲区大小。这种问题可能会导致页面无法正常加载或显示不完整的内容。要解决这个问题,您可以采取以下几种方法:调整IIS/服务器配置:如果您使用的是IIS(Inte......
  • 缓冲区管理
    缓冲区管理‍​​‍一、缓冲区的概念(一)实现方式缓冲区是一个存储区域,可以有两种实现方式:用专门的硬件寄存器组成缓冲区:成本较高,容量较小,一般仅用在对速度要求非常高的场合利用内存的一部分作为缓冲区:一般情况下的选择。I/O软件层次结构的“设备独立性软件”的缓......
  • Linux---对缓冲区的简单理解--第一个系统程序
    前序:首先先理解一下什么是回车与换行;回车和换行是两个概念,它们不是一个东西;回车:光标回到开始;换行:换到下一行;如下图:行缓冲区如何理解缓冲区问题?可以认为,缓冲区就是一块内存块,有的输出的内容会先这个缓冲区中,在缓冲区刷新时一起输出到输出端;如下图如果想让他立马刷新......
  • 数据结构小白一小时手搓环形缓冲区
    什么是环形缓冲区环形缓冲区是一种非常高效且常用的数据结构,特别适用于需要处理数据流的场景。它通过循环利用固定大小的内存空间来实现数据的缓存和传输,避免了频繁的内存分配和释放,提高了系统性能和实时性。理解其工作原理和优缺点,可以帮助开发者更好地选择和使用这种数据......
  • SEEDLab —— 缓冲区溢出实验
    【软件安全】实验2缓冲区溢出漏洞目录【软件安全】实验2缓冲区溢出漏洞环境设置关闭反制措施地址空间布局随机化配置/bin/shTask1:熟悉shellcodeC语言版本的shellcode32bitshellcode64bitshellcode调用shellcodeTask2:理解漏洞程序源码解释编译Task3:对32-bit程序实施攻击(Le......
  • 【Vulkan入门】04-开启Debug输出
    目录先叨叨git信息关键代码和主要APIVulkanEnv::SetDebugUtilMessenger()VulkanEnv::CreateVkInstance()题外话先叨叨到上篇为止我们已经作了很多事情了。建立了Instance、挑选了物理设备、建立的Device和Queue。之前做的都是相对简单和线性的工作,只要认真对照说明......
  • 【Vulkan入门】05-开启Vulkan的validation
    目录先叨叨关键函数和APIVulkanEnv::GetAllSupportedLayers()VulkanEnv::CreateVkInstance()运行代码先叨叨Vulkan为了尽量提高执行效率,因此所有API对传入的参数没有作任何校验。即使传错了参数也会继续执行,对错误参数会造成的后果不做任何定义。不过Vulkan也提供......
  • 大师开讲-图形学领域顶级专家王锐开讲Vulkan、VSG开源引擎
    王锐,毕业于清华大学,图形学领域顶级专家,开源技术社区的贡献者与推广者。三维引擎OpenSceneGraph的核心基石开发者与维护者,倾斜摄影数据格式osgb的发明人。著有《OpenSceneGraph3Cookbook》,《OpenSceneGraph3Beginer'sGuide》两本英文专著,并作为美国海军研究生院指定教材。......