vulkanscenegraph显示倾斜模型(5.6)-vsg::RenderGraph的创建

前言

        上一章深入分析了vsg::CommandGraph的创建过程及其通过子场景遍历实现Vulkan命令录制的机制。本章将在该基础上,进一步探讨Vulkan命令录制中的核心封装——vsg::RenderGraph。作为渲染流程的关键组件,RenderGraph封装了vkCmdBeginRenderPass和vkCmdEndRenderPass的核心功能,RecordTraversal会在这两个关键调用之间遍历并处理其子节点。同时本章内容将涵盖vsg::FrameBuffer(封装VkFramebuffer)、vsg::RenderPass(封装VkRenderPass)和vsg::ImageView(封装VkImageView)等重要概念。


目录

  • 1 vsg::RenderPass
  • 2 vsg::FrameBuffer
  • 3 vsg::RenderGraph

1 vsg::RenderPass

       vsg::RenderPass 是 VulkanSceneGraph (VSG) 框架中的核心类,它封装了 Vulkan 的渲染通道(Render Pass),用于定义渲染过程中帧缓冲区附件的结构和组织方式。

1.1 VkRenderPass的创建

       颜色附件描述:

    VkAttachmentDescription colorAttachment{0, VK_FORMAT_B8G8R8A8_SRGB,VK_SAMPLE_COUNT_1_BIT,VK_ATTACHMENT_LOAD_OP_CLEAR,       // Load/StoreVK_ATTACHMENT_STORE_OP_STORE,VK_ATTACHMENT_LOAD_OP_DONT_CARE,   // stencilLoad/StoreVK_ATTACHMENT_STORE_OP_DONT_CARE,VK_IMAGE_LAYOUT_UNDEFINED,         // initialLayoutVK_IMAGE_LAYOUT_PRESENT_SRC_KHR    // finalLayout};VkAttachmentReference colorAttachmentRef{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};

       子通道描述:

    VkSubpassDescription subpass{0, VK_PIPELINE_BIND_POINT_GRAPHICS,0, nullptr,              // pInputAttachments1, &colorAttachmentRef,  // pColorAttachmentsnullptr,                 // pResolveAttachmentsnullptr,                 // pDepthStencilAttachment0, nullptr,              // pPreserveAttachments};

       渲染通道创建信息:

    VkRenderPassCreateInfo renderPassInfo{VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,nullptr, 0,1, &colorAttachment,  // pAttachments1, &subpass,          // pSubpasses0, nullptr            // pDependencies};

       创建渲染通道:

    VkRenderPass renderPass = nullptr;VkResult result = vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass);if (result != VK_SUCCESS){printf("Failed to create render-pass.\n");return 1;}

1.2 vsg::RenderPass的创建

       在5.1章(vulkanscenegraph显示倾斜模型(5.1)-窗口创建-CSDN博客)中深入探讨了窗口的创建过程,vsg中窗口相关的基类为vsg::Window,RenderPass的创建与窗口密切相关,如下为vsg::Window中初始化vsg::RenderPass相关代码:

void Window::_initRenderPass()
{if (!_device) _initDevice();bool requiresDepthRead = (_traits->depthImageUsage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0;if (_framebufferSamples == VK_SAMPLE_COUNT_1_BIT){_renderPass = vsg::createRenderPass(_device, _imageFormat.format, _depthFormat, requiresDepthRead);}else{_renderPass = vsg::createMultisampledRenderPass(_device, _imageFormat.format, _depthFormat, _framebufferSamples, requiresDepthRead);}
}

       在场景创建的过程中,vsg::RenderGraph 在初始化时会获取或创建 vsg::RenderPass 对象,vsg::RenderPass有三个来源,示例代码如下:

RenderPass* RenderGraph::getRenderPass()
{if (renderPass){return renderPass;}else if (framebuffer){return framebuffer->getRenderPass();}else if (window){return window->getOrCreateRenderPass();}return nullptr;
}

2 vsg::FrameBuffer

       vsg::FrameBuffer​封装了VkFramebuffer,用作与窗口关联的渲染目标或用于渲染到纹理。

2.1 VkFrameBuffer的创建

       VkFrameBuffer的创建分为VkImageView的创建与VkFrameBuffer的创建两个过程。

       获取所有图像:从VkSwapChain中获取VkImage分两步调用vkGetSwapchainImagesKHR函数:首先传入nullptr作为第四个参数以获取交换链中的图像数量,然后再次调用该函数来实际获取所有VkImage对象。

    uint32_t imageCount = 0;vkGetSwapchainImagesKHR(device, swapChain, &imageCount, nullptr);std::vector<VkImage> swapChainImages(imageCount);vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImages.data());

       创建图像视图:在vulkan中,图像视图提供了对图像的访问接口,图像视图的创建示例代码如下:

    VkImageViewCreateInfo createInfo{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,nullptr, 0,nullptr, VK_IMAGE_VIEW_TYPE_2D,VK_FORMAT_B8G8R8A8_SRGB,{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }};std::vector<VkImageView> swapchainImageViews(swapChainImages.size());for (size_t i = 0; i < swapchainImageViews.size(); ++i){createInfo.image = swapChainImages[i];VkResult result = vkCreateImageView(app.getDevice(), &createInfo, nullptr, &swapchainImageViews[i]);if (result != VK_SUCCESS){printf("Failed to create image view: %zd.\n", i);return 1;}}

       创建VkFramebuffer:下述代码表示为交换链(Swapchain)的每个图像视图(VkImageView)创建一个帧缓冲(VkFramebuffer),并建立它们与渲染流程(VkRenderPass)的关联,其中1024和768分别表示对应影像的宽高。VkRenderPass 定义了渲染流程的附件结构和子流程(Subpass),但不绑定具体图像,VkFramebuffer 将 VkRenderPass 的抽象附件绑定到具体的 VkImageView,使渲染操作可以实际写入图像。

    std::vector<VkFramebuffer> framebuffers(swapchainImageViews.size());for (size_t i = 0; i < framebuffers.size(); ++i){VkImageView attachments[] = { swapchainImageViews[i] };VkFramebufferCreateInfo framebufferInfo{VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,nullptr, 0,renderPass,1, attachments,1024, 768, 1};vkCreateFramebuffer(device, &framebufferInfo, nullptr, &framebuffers[i]);}

2.2 vsg::FrameBuffer的封装

       在5.2章(vulkanscenegraph显示倾斜模型(5.2)-交换链-CSDN博客)中深入探讨了交换链的创建过程,与交换链创建紧密相关的有VkImageView与VkFramebuffer的创建。 

      vsg中Window.cpp文件中372-339行代码如下,为Window::buildSwapchain()函数中,创建vsg::ImageView与vsg::Framebuffer的部分。

auto& imageViews = _swapchain->getImageViews();_availableSemaphore = vsg::Semaphore::create(_device, _traits->imageAvailableSemaphoreWaitFlag);size_t initial_indexValue = imageViews.size();
for (size_t i = 0; i < imageViews.size(); ++i)
{vsg::ImageViews attachments;if (_multisampleImageView){attachments.push_back(_multisampleImageView);}attachments.push_back(imageViews[i]);if (_multisampleDepthImageView){attachments.push_back(_multisampleDepthImageView);}attachments.push_back(_depthImageView);ref_ptr<Framebuffer> fb = Framebuffer::create(_renderPass, attachments, _extent2D.width, _extent2D.height, 1);ref_ptr<Semaphore> ias = vsg::Semaphore::create(_device, _traits->imageAvailableSemaphoreWaitFlag);//_frames.push_back({multisampling ? _multisampleImageView : imageViews[i], fb, ias});_frames.push_back({imageViews[i], fb, ias});_indices.push_back(initial_indexValue);
}

       如下代码为vsg中Framebuffer的构造函数,在构造函数中实现了VkFramebuffer的创建。

Framebuffer::Framebuffer(ref_ptr<RenderPass> renderPass, const ImageViews& attachments, uint32_t width, uint32_t height, uint32_t layers) :_device(renderPass->device),_renderPass(renderPass),_attachments(attachments),_width(width),_height(height),_layers(layers)
{auto deviceID = _device->deviceID;std::vector<VkImageView> vk_attachments;for (auto& attachment : attachments){vk_attachments.push_back(attachment->vk(deviceID));}VkFramebufferCreateInfo framebufferInfo = {};framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;framebufferInfo.flags = 0;framebufferInfo.renderPass = *_renderPass;framebufferInfo.attachmentCount = static_cast<uint32_t>(vk_attachments.size());framebufferInfo.pAttachments = vk_attachments.data();framebufferInfo.width = width;framebufferInfo.height = height;framebufferInfo.layers = layers;if (VkResult result = vkCreateFramebuffer(*_device, &framebufferInfo, nullptr, &_framebuffer); result != VK_SUCCESS){throw Exception{"Error: vsg::Framebuffer::create(...) Failed to create VkFramebuffer.", result};}
}

3 vsg::RenderGraph

      本章在上章(vulkanscenegraph显示倾斜模型(5.5)-CommandGraph的创建-CSDN博客)场景图构建基础上,继续深入vsg::RenderGraph的创建:

       vsg::RenderGraph中通过访问者模式(accept函数)实现场景的遍历,进而实现命令的录制,其核心过程如下(RenderGraph.cpp中146-151行代码):

    vkCmdBeginRenderPass(vk_commandBuffer, &renderPassInfo, contents);// traverse the subgraph to place commands into the command buffer.traverse(recordTraversal);vkCmdEndRenderPass(vk_commandBuffer);

文末:本章在上一篇文章的基础上,继续深入vsg场景图中另一关键的节点vsg::RenderGraph,RecordTraversal遍历场景图过程中,RenderGraph的子节点会在vkCmdBeginRenderPass和vkCmdEndRenderPass之间被遍历访问。同时本章介绍了vsg::FrameBuffer(封装VkFramebuffer)、vsg::RenderPass(封装VkRenderPass)和vsg::ImageView(封装VkImageView)三个关键概念,vsg::RenderPass定义渲染流程,vsg::ImageView提供图像资源访问接口,vsg::FrameBuffer将二者绑定为具体渲染目标。下章将介绍vulkan图形渲染过程中另一关键对象VkPipeline,以及vsg对其的封装vsg::GraphicsPipeline。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/74615.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第二十八章:Python可视化图表扩展-和弦图、旭日图、六边形箱图、桑基图和主题流图

一、引言 在数据可视化领域&#xff0c;除了常见的折线图、柱状图和散点图&#xff0c;还有一些高级图表类型可以帮助我们更直观地展示复杂数据关系。本文将介绍五种扩展图表&#xff1a;和弦图、旭日图、六边形箱图、桑基图和主题流图。这些图表在展示数据关系、层次结构和流量…

大模型-爬虫prompt

爬虫怎么写prompt 以下基于deepseek r1 总结&#xff1a; 以下是为大模型设计的结构化Prompt模板&#xff0c;用于生成专业级网络爬虫Python脚本。此Prompt包含技术约束、反检测策略和数据处理要求&#xff0c;可根据具体需求调整参数&#xff1a; 爬虫脚本生成Prompt模板1 …

Vue中将pdf文件转为图片

平时开发中,我们经常遇到的场景应该是调用后端接口返回给前端pdf格式的文件流,然后我们可以通过URL.createObjectURL的方式转为object url临时路径然后可以通过window.open的方式来打开一个新的浏览器页签来进行预览,效果如下图: 但有时候这样满足不了的需求,它不想这样预…

物联网安全技术:守护智能世界的防线

最近研学过程中发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击链接跳转到网站人工智能及编程语言学习教程。读者们可以通过里面的文章详细了解一下人工智能及其编程等教程和学习方法。下面开始对正文内容的…

kubernetes安装部署k8s

kubernetes https://github.com/kubernetes/kubernetes.git go mod tidy go mod vendor go build -o .\bin -v ./… //手动创建bin文件夹 使用 minikube&#xff1a;https://gitee.com/mirrors/minikube.git 使用minikube启动本地化的集群服务 minikube start 启动集群&…

JT/T 1078 协议基本介绍与解析

文章目录 一、JT/T 1078 协议基本介绍二、JT/T 1078 与 JT808 的关系三、JT1078 协议核心功能四、JT1078 数据结构概览4.1、消息结构&#xff1a;4.2、消息类型&#xff08;部分&#xff09;&#xff1a; 五、Java 中如何解析 JT1078 协议数据&#xff1f;5.1、JT1078 消息 ID …

手机为电脑提供移动互联网络的3种方式

写作目的 在当今数字化时代,电脑已成为人们日常工作和生活中不可或缺的工具,而网络连接更是其核心功能之一。无论是处理工作任务、进行在线学习、还是享受娱乐资源,稳定的网络环境都是保障这些活动顺利开展的关键。然而,在实际使用过程中,电脑网络驱动故障时有发生,这可…

Linux的 /etc/sysctl.conf 笔记250404

Linux的 /etc/sysctl.conf 笔记250404 /etc/sysctl.conf 是 Linux 系统中用于 永久修改内核运行时参数 的核心配置文件。它通过 sysctl 工具实现参数的持久化存储&#xff0c;确保系统重启后配置依然生效。以下是其详细说明&#xff1a; &#x1f4c2; 备份/etc/sysctl.conf t…

deepseek v3-0324 Markdown 编辑器 HTML

Markdown 编辑器 HTML 以下是一个美观的 Markdown 编辑器 HTML 页面&#xff0c;支持多种主题切换和实时预览功能&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&q…

Linux make 检查依赖文件更新的原理

1. 文件的时间戳 make 主要依靠文件的时间戳来判断依赖文件是否有更新。每个文件在文件系统中都有一个时间戳&#xff0c;记录了文件的三种重要时间&#xff1a; ​​访问时间&#xff08;Accesstime&#xff09;​​&#xff1a;文件最后一次被访问的时间。​​修改时间&…

HDEBits中组合逻辑类的部分题目练习

文章目录 1. More logic gates2. Truth tables3. 256-to-1 4-bit multiplexer4. 3-bit binary adder5. Signed addition overflow6. 4-digit BCD adder7. Minimum SOP and POS8. Karnaugh map9. K-map implemented with a multiplexer总结 1. More logic gates 题目&#xff1…

Apache httpclient okhttp(2)

学习链接 Apache httpclient & okhttp&#xff08;1&#xff09; Apache httpclient & okhttp&#xff08;2&#xff09; okhttp github okhttp官方使用文档 okhttp官方示例代码 OkHttp使用介绍 OkHttp使用进阶 译自OkHttp Github官方教程 SpringBoot 整合okHttp…

【git项目管理】长话短说

目录 主要分为三种使用情况 安装git后第一次使用创建新仓库并管理克隆仓库并管理 初次使用git 首先确定电脑的用户名是纯英文&#xff0c;没有中文和奇怪的符号&#xff0c;如果不满足这个条件&#xff0c;参考这个 链接 修改用户名 git config --global user.name "…

算法刷题记录——LeetCode篇(3.2) [第211~212题](持续更新)

更新时间&#xff1a;2025-04-04 算法题解目录汇总&#xff1a;算法刷题记录——题解目录汇总技术博客总目录&#xff1a;计算机技术系列博客——目录页 优先整理热门100及面试150&#xff0c;不定期持续更新&#xff0c;欢迎关注&#xff01; 215. 数组中的第K个最大元素 给…

【linux学习】linux系统调用编程

目录 一、任务、进程和线程 1.1任务 1.2进程 1.3线程 1.4线程和进程的关系 1.5 在linux系统下进程操作 二、Linux虚拟内存管理与stm32的真实物理内存区别 2.1 Linux虚拟内存管理 2.2 STM32的真实物理内存映射 2.3区别 三、 Linux系统调用函数 fork()、wait()、exec(…

react redux的学习,多个reducer

redux系列文章目录 第一章 简单学习redux,单个reducer 前言 前面我们学习到的是单reducer的使用&#xff1b;要知道redux是个很强大的状态存储库&#xff0c;可以支持多个reducer的使用。 combineReducers ‌combineReducers‌是Redux中的一个辅助函数&#xff0c;主要用于…

Oracle数据库数据编程SQL<3.5 PL/SQL 存储过程(Procedure)>

存储过程(Stored Procedure)是 Oracle 数据库中一组预编译的 PL/SQL 语句集合,存储在数据库中并可通过名称调用执行。它们是企业级数据库应用开发的核心组件。 目录 一、存储过程基础 1. 存储过程特点 2. 创建基本语法 3. 存储过程优点 4. 简单示例 二、没有参数的存储…

手撕AVL树

引入&#xff1a;为何要有AVL树&#xff0c;二次搜索树有什么不足&#xff1f; 二叉搜索树有其自身的缺陷&#xff0c;假如往树中插入的元素有序或者接近有序&#xff0c;二叉搜索树就会退化成单支树&#xff0c;时间复杂度会退化成O(N)&#xff0c;因此产生了AVL树&#xff0c…

《 C语言中的变长数组:灵活而强大的特性》

&#x1f680;个人主页&#xff1a;BabyZZの秘密日记 &#x1f4d6;收入专栏&#xff1a;C语言 &#x1f30d;文章目入 一、变长数组的定义二、变长数组的优势三、变长数组的使用示例示例1&#xff1a;动态输入数组大小示例2&#xff1a;变长数组在函数中的应用 四、变长数组的…

【微服务】基础概念

1.什么是微服务 微服务其实就是一种架构风格&#xff0c;他提倡我们在开发的时候&#xff0c;一个应用应该是一组小型服务而组成的&#xff0c;每一个服务都运行在自己的进程中&#xff0c;每一个小服务都通过HTTP的方式进行互通。他更加强调服务的彻底拆分。他并不是仅局限于…