vulkanscenegraph显示倾斜模型(5.2)-交换链
前言
在 VulkanSceneGraph(VSG)中,vsg::Window 类对窗口进行了高层次的封装,为开发者提供了便捷的窗口管理接口。在上一篇文章中,我们探讨了 VkInstance、VkSurfaceKHR、VkPhysicalDevice 和 VkDevice 的创建过程,以及它们在 VSG 中的封装方式及其相互关系。本章将继续深入探讨与窗口创建密切相关的另一个核心对象——交换链 VkSwapchainKHR,并分析其与上述四个 Vulkan 对象之间的关系,同时探讨 VSG 如何对 VkSwapchainKHR 进行封装。
目录
- 1 VkSwapchainKHR的创建
- 2 vsg中对VkSwapchainKHR的封装
1 VkSwapchainKHR的创建
在Vulkan中,Swapchain是用于管理图像的核心机制,它允许应用程序将渲染结果展示到屏幕上。Swapchain本质上是一个图像队列,包含多个图像缓冲区(也可称为"交换图像"),应用程序将内容渲染到这些图像中,然后将其提交给显示设备进行呈现。VkSwapchainKHR与VkSurfaceKHR、VkPhysicalDevice联系紧密,VkSwapchainKHR的创建依赖于VkSurfaceKHR,在创建VkSwapchainKHR前必须确保VkSurfaceKHR已经创建,并且物理设备VkPhysicalDevice支持此VkSurfaceKHR。
VkSwapchainKHR包含查询表面支持、选择表面格式和呈现模式、Swapchain的创建与销毁三个步骤。
1.1 查询表面支持
VkSurfaceCapabilitiesKHR caps;VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(app.getPhysicalDevice(), app.getSurface(), &caps);if (result != VK_SUCCESS){printf("Failed to get surface capabilities.\n");return 1;}
通过vkGetPhysicalDeviceSurfaceCapabilitiesKHR查询物理设备对表面的支持能力,从中可获取最小最大图象数、图像最大分辨率,代码如下:
caps.maxImageExtent.width;//最大分辨率//宽度
caps.maxImageExtent.height;//最大分辨率//高度
caps.minImageCount;//最小影像数
caps.maxImageCount;//最打影像数
1.2 选择表面格式和呈现模式
uint32_t formatCount = 0, presentModeCount = 0;result = vkGetPhysicalDeviceSurfaceFormatsKHR(app.getPhysicalDevice(), app.getSurface(), &formatCount, nullptr);if (result != VK_SUCCESS || formatCount == 0){return 1;}result = vkGetPhysicalDeviceSurfacePresentModesKHR(app.getPhysicalDevice(), app.getSurface(), &presentModeCount, nullptr);if (result != VK_SUCCESS || presentModeCount == 0){return 1;}uint32_t formatIndex = 0, presentModeIndex = 0;std::vector<VkSurfaceFormatKHR> formats(formatCount);std::vector<VkPresentModeKHR> presentModes(presentModeCount);vkGetPhysicalDeviceSurfaceFormatsKHR(app.getPhysicalDevice(), app.getSurface(), &formatCount, formats.data());for (uint32_t i = 0; i < formatCount; ++i){if (formats[i].format == VK_FORMAT_B8G8R8A8_SRGB &&formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) formatIndex = i;}vkGetPhysicalDeviceSurfacePresentModesKHR(app.getPhysicalDevice(), app.getSurface(), &presentModeCount, presentModes.data());for (uint32_t i = 0; i < presentModeCount; ++i){if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) presentModeIndex = i;}
通过vkGetPhysicalDeviceSurfaceFormatsKHR获取表面格式,以上代码中vkGetPhysicalDeviceSurfaceFormatsKHR共调用两次,第一次第四个参数传入nullptr,可获取表面格式的个数,第二次调用可获取所有表面模式。同时通过vkGetPhysicalDeviceSurfacePresentModesKHR获取呈现模式,函数共调用两次,第一次第四个参数传入nullptr,可获取呈现模式的个数,第二次调用可获取所有呈现模式。
1.3 Swapchain的创建与销毁
VkSwapchainCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,nullptr, 0,app.getSurface(),std::max(caps.minImageCount + caps.maxImageCount),VK_FORMAT_B8G8R8A8_SRGB,VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,caps.maxImageExtent,1, // imageArrayLayersVK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,VK_SHARING_MODE_EXCLUSIVE, 0, nullptr,caps.currentTransform,VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,VK_PRESENT_MODE_MAILBOX_KHR,VK_TRUE,nullptr};VkSwapchainKHR swapChain = nullptr;result = vkCreateSwapchainKHR(app.getDevice(), &createInfo, nullptr, &swapChain);if (result != VK_SUCCESS){printf("Failed to create swap chain.\n");return 1;}uint32_t imageCount = 0;vkGetSwapchainImagesKHR(app.getDevice(), swapChain, &imageCount, nullptr);std::vector<VkImage> swapChainImages(imageCount);vkGetSwapchainImagesKHR(app.getDevice(), swapChain, &imageCount, swapChainImages.data());if (swapChain != nullptr) {vkDestroySwapchainKHR(app.getDevice(), swapChain, nullptr);}
在 Vulkan 中,交换链(VkSwapchainKHR)通过 vkCreateSwapchainKHR 函数创建,可配置表面格式为 VK_FORMAT_B8G8R8A8_SRGB、颜色空间为 VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,并选择呈现模式为 VK_PRESENT_MODE_MAILBOX_KHR。创建后,使用 vkGetSwapchainImagesKHR 查询交换链的图像缓冲区,并通过 vkDestroySwapchainKHR 销毁交换链以释放资源。
2 vsg中对VkSwapchainKHR的封装
在 VulkanSceneGraph (VSG) 中,VkSwapchainKHR 的功能被封装在 vsg::Swapchain 类中,该类提供了对 Vulkan 交换链的高层次抽象,简化了交换链的创建、管理和使用。本章主要深入探讨vsg中交换链的创建过程,并与上篇文章提及的vsg::WindowTraits关联,暂时不深入其它如图像缓冲区管理、动态重建支持等功能,这些留待后续剖析。
auto windowTraits = vsg::WindowTraits::create();
windowTraits->width = 800;
windowTraits->height = 600;
windowTraits->swapchainPreferences.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;auto window = vsg::Window::create(windowTraits);
if (!window) {std::cerr << "Failed to create window and swapchain." << std::endl;return -1;
}
通过vsg::WindowTraits创建窗口的属性,窗口的宽和长分别设置为800和600。传入创建vsg::Window对象,在windows系统下创建vsg::Win32_Window,在vsg::Win32_Window对象
if (_swapchain){// make sure all operations on the device have stopped before we go on deleting associated resourcesvkDeviceWaitIdle(*_device);// clean up previous swap chain before we begin creating a new one._frames.clear();_indices.clear();_depthImageView.reset();_depthImage.reset();_multisampleImage.reset();_multisampleImageView.reset();}// is width and height even required here as the surface appears to control it?_swapchain = Swapchain::create(_physicalDevice, _device, _surface, _extent2D.width, _extent2D.height, _traits->swapchainPreferences, _swapchain);// pass back the extents used by the swap chain._extent2D = _swapchain->getExtent();
vsg::Swapchain的创建传入宽高参数_extent2D.width和_extent2D.height,而变量_extent2D的初始化在vsg::Win32_Window对象的构造函数中由传入的vsg::WindowTraits对象经过一系列的转换得到。
文末:本章在上一篇文章的基础上,继续深入探讨与窗口创建密切相关的另一个核心对象——交换链 VkSwapchainKHR,并分析其与 Vulkan 核心对象之间的关系。具体而言,VkSwapchainKHR 的创建依赖于 VkSurfaceKHR,并且在创建交换链之前,必须确保 VkSurfaceKHR 已经成功创建,同时物理设备 VkPhysicalDevice 支持该表面。本章内容分为两部分:交换链的创建与销毁 和 VSG 对 VkSwapchainKHR 的封装。至此,关于 vsg::Window 创建的介绍告一段落,下一章将接着探讨 vsg::Camera 的创建与赋值过程。
相关文章:
vulkanscenegraph显示倾斜模型(5.2)-交换链
前言 在 VulkanSceneGraph(VSG)中,vsg::Window 类对窗口进行了高层次的封装,为开发者提供了便捷的窗口管理接口。在上一篇文章中,我们探讨了 VkInstance、VkSurfaceKHR、VkPhysicalDevice 和 VkDevice 的创建过程&…...
【极光 Orbit•STC8A-8H】03. 小刀初试:点亮你的LED灯
【极光 Orbit•STC8H】03. 小刀初试:点亮你的 LED 灯 七律 点灯初探 单片方寸藏乾坤,LED明灭见真章。 端口配置定方向,寄存器值细推敲。 高低电平随心控,循环闪烁展锋芒。 嵌入式门初开启,从此代码手中扬。 摘要 …...
实现一键不同环境迁移ES模板
实现概述: 1、查询环境A模板信息 2、获取模板信息值转换 3、同步保存至环境B package com.jayce.boot.route.common.util;import com.fasterxml.jackson.databind.JsonNode; import com.google.common.collect.Lists; import com.jayce.boot.route.common.util.…...
Nacos学习笔记-占位符读取其他命名空间内容
Nacos当前命名空间下的配置文件需要跨命名空间读取其他配置文件的内容。可以先通过Nacos提供的API接口获取配置文件内容,然后解析数据将其放入环境的PropertySource中。 相关依赖包 <!-- Nacos依赖包 --> <dependency><groupId>com.alibaba.clo…...
OSPF报文分析
OSPF报文分析 组播地址 224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用; 224.0.1.0~238.255.255.255为用户可用的组播地址(…...
MySql性能(9)- mysql的order by的工作原理
全字段排序rowid排序全字段排序和rowid排序 3.1 联合索引优化 3.2 覆盖索引优化优先队列算法优化建议 5.1 修改系统参数 5.2 优化sql 1. 全字段排序 CREATE TABLE t ( id int(11) NOT NULL,city varchar(16) NOT NULL, name varchar(16) NOT NULL, age int(11) NOT NULL,addr v…...
死锁问题分析工具
使用 gdb 调试 gdb ./your_program (gdb) run (gdb) thread apply all bt还可以分析pthread_mutex内部,查看owen字段分析哪个线程占用的锁,一个可能的 pthread_mutex 内部结构可以大致表示为: typedef struct pthread_mutex_t {int state; …...
爬虫案例七Python协程爬取视频
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Python协程爬取视频 前言 提示:这里可以添加本文要记录的大概内容: 爬虫案例七协程爬取视频 提示:以下是本篇文章正文…...
智慧城市智慧社区项目建设方案
一、项目背景 在全球化进程加速的今天,城市化问题日益凸显,传统的城市管理模式已难以满足现代社会对高效、智能化管理的需求。智慧城市和智慧社区的概念应运而生,其核心目标是通过信息技术手段,提升城市资源的利用效率࿰…...
STM32常见外设的驱动示例和代码解析
以下是针对STM32常见外设的驱动示例和代码解析,基于HAL库实现,适用于大多数STM32系列(如F1/F4/H7等),可根据具体型号调整引脚和时钟配置。 1. GPIO驱动 应用场景:控制LED、按键检测、继电器开关等。 示例代码: // 初始化LED(推挽输出) void LED_Init(void) {GPIO_In…...
RabbitMQ高级特性--消息确认机制
目录 一、消息确认 1.消息确认机制 2.手动确认方法 二、代码示例 1. AcknowledgeMode.NONE 1.1 配置文件 1.2 生产者 1.3 消费者 1.4 运行程序 2.AcknowledgeMode.AUTO 3.AcknowledgeMode.MANUAL 一、消息确认 1.消息确认机制 生产者发送消息之后,到达消…...
Java EE 进阶:Spring IoCDI
IOC的简单介绍 什么是Spring?Spring是一个开源的框架,让我们的开发更加的简单,我们可以用一句更加具体的话来概括Spring,就是Spring是一个包含众多工具方法的IOC容器。 简单介绍一下IOC,我们之前说过通过ReqestContr…...
deepseek为什么要开源
一、生态位的抢占与锁定:以 JDK 版本为例 在软件开发的世界里,生态位的抢占和先入为主的效应十分显著。就拿 Java 开发中的 JDK 版本来说,目前大多数开发者仍在广泛使用 JDK8。尽管 JDK17 和 JDK21 已经推出,且具备更多先进特性…...
Java数据结构第二十期:解构排序算法的艺术与科学(二)
专栏:Java数据结构秘籍 个人主页:手握风云 目录 一、常见排序算法的实现 1.1. 直接选择排序 1.2. 堆排序 1.3. 冒泡排序 1.4. 快速排序 一、常见排序算法的实现 1.1. 直接选择排序 每⼀次从待排序的数据元素中选出最小的⼀个元素,存放在…...
【算法day5】最长回文子串——马拉车算法
最长回文子串 给你一个字符串 s,找到 s 中最长的 回文 子串。 https://leetcode.cn/problems/longest-palindromic-substring/description/ 算法思路: class Solution { public:string longestPalindrome(string s) {int s_len s.size();string tmp …...
《如何排查Linux系统平均负载过高》
【系统平均负载导读】何为系统平均负载?假设一台云服务主机,突然之间响应用户请求的时间变长了,那么这个时候应该如何去排查?带着这个问题,我们对“平均负载”展开深入的探讨和研究。 何为Linux系统的平均负载…...
基于DeepSeek实现PDF嵌入SVG图片无损放大
1. PDF中效果图 2. 询问Deepseek进行代码书写,不断优化后结果 /*** SVG工具类,用于生成价格趋势的SVG图表*/ public class SvgUtils {// SVG画布尺寸private static final int WIDTH 800;private static final int HEIGHT 500;private static final i…...
整型的不同类型和溢出
一、整数的不同类型 不同编程语言中的整数类型主要通过以下两个维度区分: 1. 存储大小 字节数:决定整数能表示的范围(如 1字节8位)。 常见类型: byte(1字节)、short(2字节&#x…...
使用express创建服务器保存数据到mysql
创建数据库和表结构 CREATE DATABASE collect;USE collect;CREATE TABLE info (id int(11) NOT NULL AUTO_INCREMENT,create_date bigint(20) DEFAULT NULL COMMENT 时间,type varchar(20) DEFAULT NULL COMMENT 数据分类,text_value text COMMENT 内容,PRIMARY KEY (id) ) EN…...
小程序 wxml 语法 —— 41列表渲染 - 进阶用法
这一节讲解列表渲染的两个进阶用法: 如果需要对默认的变量名和下标进行修改,可以使用 wx:for-item 和 wx:for-item: 使用 wx:for-item 可以指定数组当前元素的变量名使用 wx:for-index 可以指定数组当前下标的变量名 将 wx:for 用在 标签上&…...
python语言总结(持续更新)
本文主要是总结各函数,简单的函数不会给予示例,如果在平日遇到一些新类型将会添加 基础知识 输入与输出 print([要输出的内容])输出函数 input([提示内容]如果输入提示内容会在交互界面显示,用以提示用户)输入函数 注释 # 单行注释符&…...
正则表达式简述
普通字符 普通字符代表它们自身,用于精确匹配字符串中的字符。例如,a 匹配字符 a,1 匹配数字 1。元字符 元字符是具有特殊含义的字符,用于匹配特定类型的字符或字符串模式。 常用元字符 . :匹配除换行符以外的任意单个…...
FPGA学习篇——Verilog学习5(reg,wire区分及模块例化)
1 何时用reg,何时用wire? 这个我找了一些网上的各种资料,大概说一下自己的理解,可能还不太到位... wire相当于一根线,是实时传输的那种,而reg是一个寄存器,是可以存储数据的,需要立…...
Redis 数据持久化之AOF
AOF(Append Only File) 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换…...
【芯片验证】verificationguide上的74道SystemVerilog面试题
诧异啊,像我这种没事在网上各处捡东西吃的人为什么之前一直没有用过verificationguide这个网站呢?总不能是大家都已经看过就留下我不知道吧。前几天在论坛上和朋友谈论验证面试题时才搜到这个网站的,感觉挺有意思: .: Verification Guide :.verificationguide.com/https…...
C++进阶知识10 封装unordered_map和unordered_set
封装unordered_map和unordered_set 1. 模拟实现unordered_map和unordered_set1.1 实现出复⽤哈希表的框架,并⽀持insert 1. 模拟实现unordered_map和unordered_set 1.1 实现出复⽤哈希表的框架,并⽀持insert • 参考源码框架,unordered_map…...
大白话JavaScript数据类型判断方法的原理与实践
大白话JavaScript数据类型判断方法的原理与实践 答题思路 明确 JavaScript 数据类型:JavaScript 数据类型分为基本数据类型(如 Number、String、Boolean、Null、Undefined、Symbol)和引用数据类型(如 Object、Array、Function 等…...
Java后端高频面经——计算机网络
TCP/IP四层模型?输入一个网址后发生了什么,以百度为例?(美团) (1)四层模型 应用层:支持 HTTP、SMTP 等最终用户进程传输层:处理主机到主机的通信(TCP、UDP&am…...
面试题(二)--Object中的常见方法
Object Java的Object是所有Java类的父类,所有的Java类直接或者间接的继承了Object类,Object类位于java.lang包中(编译时自动导入),主要提供了11种方法。 /*** native 方法,用于返回当前运行时对象的 Class…...
运行OpenManus项目(使用Conda)
部署本项目需要具备一定的基础:Linux基础、需要安装好Anaconda/Miniforge(Python可以不装好,直接新建虚拟环境的时候装好即可),如果不装Anaconda或者Miniforge,只装过Python,需要确保Python是3.…...
