vulkanscenegraph显示倾斜模型(5.2)-交换链

news2025/3/10 9:26:40

 前言

       在 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,  // imageArrayLayers
        VK_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 resources
        vkDeviceWaitIdle(*_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 的创建与赋值过程。

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

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

相关文章

【极光 Orbit•STC8A-8H】03. 小刀初试:点亮你的LED灯

【极光 Orbit•STC8H】03. 小刀初试&#xff1a;点亮你的 LED 灯 七律 点灯初探 单片方寸藏乾坤&#xff0c;LED明灭见真章。 端口配置定方向&#xff0c;寄存器值细推敲。 高低电平随心控&#xff0c;循环闪烁展锋芒。 嵌入式门初开启&#xff0c;从此代码手中扬。 摘要 …

OSPF报文分析

OSPF报文分析 组播地址 224.0.0.0&#xff5e;224.0.0.255为预留的组播地址&#xff08;永久组地址&#xff09;&#xff0c;地址224.0.0.0保留不做分配&#xff0c;其它地址供路由协议使用&#xff1b; 224.0.1.0&#xff5e;238.255.255.255为用户可用的组播地址&#xff08;…

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…

爬虫案例七Python协程爬取视频

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Python协程爬取视频 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 爬虫案例七协程爬取视频 提示&#xff1a;以下是本篇文章正文…

智慧城市智慧社区项目建设方案

一、项目背景 在全球化进程加速的今天&#xff0c;城市化问题日益凸显&#xff0c;传统的城市管理模式已难以满足现代社会对高效、智能化管理的需求。智慧城市和智慧社区的概念应运而生&#xff0c;其核心目标是通过信息技术手段&#xff0c;提升城市资源的利用效率&#xff0…

RabbitMQ高级特性--消息确认机制

目录 一、消息确认 1.消息确认机制 2.手动确认方法 二、代码示例 1. AcknowledgeMode.NONE 1.1 配置文件 1.2 生产者 1.3 消费者 1.4 运行程序 2.AcknowledgeMode.AUTO 3.AcknowledgeMode.MANUAL 一、消息确认 1.消息确认机制 生产者发送消息之后&#xff0c;到达消…

Java EE 进阶:Spring IoCDI

IOC的简单介绍 什么是Spring&#xff1f;Spring是一个开源的框架&#xff0c;让我们的开发更加的简单&#xff0c;我们可以用一句更加具体的话来概括Spring&#xff0c;就是Spring是一个包含众多工具方法的IOC容器。 简单介绍一下IOC&#xff0c;我们之前说过通过ReqestContr…

Java数据结构第二十期:解构排序算法的艺术与科学(二)

专栏&#xff1a;Java数据结构秘籍 个人主页&#xff1a;手握风云 目录 一、常见排序算法的实现 1.1. 直接选择排序 1.2. 堆排序 1.3. 冒泡排序 1.4. 快速排序 一、常见排序算法的实现 1.1. 直接选择排序 每⼀次从待排序的数据元素中选出最小的⼀个元素&#xff0c;存放在…

【算法day5】最长回文子串——马拉车算法

最长回文子串 给你一个字符串 s&#xff0c;找到 s 中最长的 回文 子串。 https://leetcode.cn/problems/longest-palindromic-substring/description/ 算法思路&#xff1a; class Solution { public:string longestPalindrome(string s) {int s_len s.size();string tmp …

《如何排查Linux系统平均负载过高》

【系统平均负载导读】何为系统平均负载&#xff1f;假设一台云服务主机&#xff0c;突然之间响应用户请求的时间变长了&#xff0c;那么这个时候应该如何去排查&#xff1f;带着这个问题&#xff0c;我们对“平均负载”展开深入的探讨和研究。 何为Linux系统的平均负载&#xf…

基于DeepSeek实现PDF嵌入SVG图片无损放大

1. PDF中效果图 2. 询问Deepseek进行代码书写&#xff0c;不断优化后结果 /*** SVG工具类&#xff0c;用于生成价格趋势的SVG图表*/ public class SvgUtils {// SVG画布尺寸private static final int WIDTH 800;private static final int HEIGHT 500;private static final i…

整型的不同类型和溢出

一、整数的不同类型 不同编程语言中的整数类型主要通过以下两个维度区分&#xff1a; 1. 存储大小 字节数&#xff1a;决定整数能表示的范围&#xff08;如 1字节8位&#xff09;。 常见类型&#xff1a; byte&#xff08;1字节&#xff09;、short&#xff08;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列表渲染 - 进阶用法

这一节讲解列表渲染的两个进阶用法&#xff1a; 如果需要对默认的变量名和下标进行修改&#xff0c;可以使用 wx:for-item 和 wx:for-item&#xff1a; 使用 wx:for-item 可以指定数组当前元素的变量名使用 wx:for-index 可以指定数组当前下标的变量名 将 wx:for 用在 标签上&…

python语言总结(持续更新)

本文主要是总结各函数&#xff0c;简单的函数不会给予示例&#xff0c;如果在平日遇到一些新类型将会添加 基础知识 输入与输出 print([要输出的内容])输出函数 input([提示内容]如果输入提示内容会在交互界面显示&#xff0c;用以提示用户)输入函数 注释 # 单行注释符&…

FPGA学习篇——Verilog学习5(reg,wire区分及模块例化)

1 何时用reg&#xff0c;何时用wire&#xff1f; 这个我找了一些网上的各种资料&#xff0c;大概说一下自己的理解&#xff0c;可能还不太到位... wire相当于一根线&#xff0c;是实时传输的那种&#xff0c;而reg是一个寄存器&#xff0c;是可以存储数据的&#xff0c;需要立…

Redis 数据持久化之AOF

AOF&#xff08;Append Only File&#xff09; 以日志的形式来记录每个写操作&#xff0c;将Redis执行过的所有写指令记录下来&#xff08;读操作不记录&#xff09;&#xff0c;只许追加文件但不可以改写文件&#xff0c;redis启动之初会读取该文件重新构建数据&#xff0c;换…

【芯片验证】verificationguide上的74道SystemVerilog面试题

诧异啊,像我这种没事在网上各处捡东西吃的人为什么之前一直没有用过verificationguide这个网站呢?总不能是大家都已经看过就留下我不知道吧。前几天在论坛上和朋友谈论验证面试题时才搜到这个网站的,感觉挺有意思: .: Verification Guide :.​verificationguide.com/https…

Java后端高频面经——计算机网络

TCP/IP四层模型&#xff1f;输入一个网址后发生了什么&#xff0c;以百度为例&#xff1f;&#xff08;美团&#xff09; &#xff08;1&#xff09;四层模型 应用层&#xff1a;支持 HTTP、SMTP 等最终用户进程传输层&#xff1a;处理主机到主机的通信&#xff08;TCP、UDP&am…

面试题(二)--Object中的常见方法

Object Java的Object是所有Java类的父类&#xff0c;所有的Java类直接或者间接的继承了Object类&#xff0c;Object类位于java.lang包中&#xff08;编译时自动导入&#xff09;&#xff0c;主要提供了11种方法。 /*** native 方法&#xff0c;用于返回当前运行时对象的 Class…