(六)窗口表面

这节主要三部分
一,窗口表面的创建和销毁
二,呈现队列
三,与以前实现的图形能力队列的兼容

一,窗口表面
1,创建
VkSurfaceKHR surface;

//创建窗口表面
glfwCreateWindowSurface(instance,	//vkInstance对象window,		//GLFW窗口指针nullptr,	//自定义内存分配器&surface);	//存储返回的表面的内存地址

2,销毁

vkDestroySurfaceKHR(instance, surface, nullptr);

二,呈现队列:将图像呈现到窗口表面,也是种能力,所以要有这个队列。

1,结构体

//队列族索引,同时支持绘制指令的队列族和支持表现的队列族
struct QueueFaminliyIndices
{
//-1表示没找到满足需求的队列族
int graphicsFamily = -1;
int presentFamily = -1;
bool isCompleted()
{
return graphicsFamily >= 0 && presentFamily >= 0;
}
};

2,检查是否支持

	VkBool32 presentSupport = false;vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);if (queueFamily.queueCount > 0 && presentSupport){indices.presentFamily = i;}

3,获取队列句柄
//呈现队列
VkQueue presentQueue;
vkGetDeviceQueue(device, indices.presentFamily, 0, &presentQueue);

三,与以前实现的图形能力队列的兼容

std::set<int> uniqueQueueFamilies = { indices.graphicsFamily, indices.presentFamily };std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
float queuePriority = 1.0f;//遍历各个队列族,
for (int queueFamily : uniqueQueueFamilies)
{VkDeviceQueueCreateInfo queueCreateInfo = {};queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;queueCreateInfo.queueFamilyIndex = queueFamily;queueCreateInfo.queueCount = 1;queueCreateInfo.pQueuePriorities = &queuePriority;queueCreateInfos.push_back(queueCreateInfo);
}
createInfo.pQueueCreateInfos = queueCreateInfos.data();
createInfo.queueCreateInfoCount = static_cast<uint32_t> (queueCreateInfos.size());

运行
在这里插入图片描述

完整代码如下:
MyApplication.h
#pragma once
#include <Windows.h>
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_win32.h>
#include
#include “D:/install/filament-v1.18.0/third_party/imgui/examples/libs/glfw/include/GLFW/glfw3.h”
#include
#include
#include
#include
#include

//队列族索引,同时支持绘制指令的队列族和支持表现的队列族
struct QueueFaminliyIndices
{
//-1表示没找到满足需求的队列族
int graphicsFamily = -1;
int presentFamily = -1;
bool isCompleted()
{
return graphicsFamily >= 0 && presentFamily >= 0;
}
};
class MyApplication
{
public:
void run();

private:
//初始化窗口
void initWindow();
//初始化Vulkan对象
void initVulkan();
//主循环进行渲染操作
void mainLoop();
//资源清理
void cleanUp();

//创建一个实例初始化Vulkan库,指定驱动程序需要使用的应用程序信息
void createInstance();
//查询显卡设备
void pickPhysicalDevice();//返回查找的队列族索引
QueueFaminliyIndices findQueueFamilies(VkPhysicalDevice device);
//确保选择的设备能执行需要的指令
bool isDeviceSuitable(VkPhysicalDevice device);
//创建逻辑设备
void createLogicalDevice();
//创建表面
void createSurface();

private:
//窗口
GLFWwindow* window = nullptr;

//实例句柄
VkInstance instance;
//存储显卡信息
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
//逻辑设备
VkDevice device;
//存储逻辑设备的队列句柄
VkQueue graphicsQueue;//窗口表面
VkSurfaceKHR surface;
//呈现队列
VkQueue presentQueue;

};
MyApplication.cpp
#include “MyApplication.h”

void MyApplication::run()
{
initWindow();
initVulkan();
mainLoop();
cleanUp();
}

void MyApplication::initWindow()
{

//初始化GLFW库,
glfwInit();
//阻止创建OpenGL上下文
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
//禁止窗口大小改变
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
//存储窗口句柄
const int WIDTH = 800;
const int HEIGHT = 600;
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan window", nullptr, nullptr);

}

void MyApplication::initVulkan()
{
createInstance();
createSurface();
pickPhysicalDevice();
createLogicalDevice();
}

void MyApplication::mainLoop()
{
//在没有错误和窗口没有被关闭下一直运行,事件循环
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
}
}

void MyApplication::cleanUp()
{
vkDestroyDevice(device, nullptr);
vkDestroySurfaceKHR(instance, surface, nullptr);
vkDestroyInstance(instance, nullptr);
glfwDestroyWindow(window);
glfwTerminate();
}

void MyApplication::createInstance()
{
//应用程序信息,便于优化
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = “Hello Triangle”;
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = “No Engine”;
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.apiVersion = VK_API_VERSION_1_0;

//创建Vulkan驱动程序需要的信息
VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;//返回需要的窗口交互扩展
uint32_t glfwExtensionCount = 0;
const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
createInfo.enabledExtensionCount = glfwExtensionCount;
createInfo.ppEnabledExtensionNames = glfwExtensions;//全局扩展层(对整个应用程序都有效,而不仅仅对一个设备有效)
//暂时设置为0,不使用全局扩展层
createInfo.enabledLayerCount = 0;//创建Vulkan实例
VkResult result = vkCreateInstance(&createInfo,	//包含创建信息的结构体指针nullptr,		//自定义的分配器回调函数,暂时设置为nullptr,不使用&instance);		//指向新对象句柄存储位置的指针。//检测扩展支持
//获取扩展数量
uint32_t extensionCount = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
//存储信息数组
std::vector<VkExtensionProperties> extensions(extensionCount);vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());

}

void MyApplication::pickPhysicalDevice()
{
//获取显卡设备数量
uint32_t deviceCount = 0;
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);

//获取显卡数组
std::vector<VkPhysicalDevice> devices(deviceCount);
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());//选择合适的
for (const auto& device : devices)
{if (isDeviceSuitable(device)){physicalDevice = device;break;}
}

}

QueueFaminliyIndices MyApplication::findQueueFamilies(VkPhysicalDevice device)
{
//获取设备的队列族个数
uint32_t queueFamilyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
//获取队列族数组
std::vector queueFamilies(queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());

QueueFaminliyIndices indices;
//支持
//1,图形指令
//2,呈现图像到窗口表面能力
int i = 0;
for (const auto& queueFamily : queueFamilies  )
{if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT){indices.graphicsFamily = i;}VkBool32 presentSupport = false;vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);if (queueFamily.queueCount > 0 && presentSupport){indices.presentFamily = i;}if (indices.isCompleted()){break;}i++;
}
return indices;

}

bool MyApplication::isDeviceSuitable(VkPhysicalDevice device)
{
QueueFaminliyIndices indices = findQueueFamilies(device);
return indices.isCompleted();
}

void MyApplication::createLogicalDevice()
{
//同时图形能力和呈现到表面能力
QueueFaminliyIndices indices = findQueueFamilies(physicalDevice);
std::set uniqueQueueFamilies = { indices.graphicsFamily, indices.presentFamily };

std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
float queuePriority = 1.0f;//遍历各个队列族,
for (int queueFamily : uniqueQueueFamilies)
{VkDeviceQueueCreateInfo queueCreateInfo = {};queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;queueCreateInfo.queueFamilyIndex = queueFamily;queueCreateInfo.queueCount = 1;queueCreateInfo.pQueuePriorities = &queuePriority;queueCreateInfos.push_back(queueCreateInfo);
}
//应用的设备特性
VkPhysicalDeviceFeatures deviceFeatures = {};//创建逻辑设备
VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.pQueueCreateInfos = queueCreateInfos.data();
createInfo.queueCreateInfoCount = static_cast<uint32_t> (queueCreateInfos.size());
createInfo.pEnabledFeatures = &deviceFeatures;
createInfo.enabledExtensionCount = 0;//暂时不用校验层
createInfo.enabledLayerCount = 0;
vkCreateDevice(physicalDevice, &createInfo, nullptr, &device);//获取队列族的队列句柄
vkGetDeviceQueue(device, indices.graphicsFamily, 0, &graphicsQueue);
vkGetDeviceQueue(device, indices.presentFamily, 0, &presentQueue);

}

void MyApplication::createSurface()
{
//创建窗口表面
glfwCreateWindowSurface(
instance, //vkInstance对象
window, //GLFW窗口指针
nullptr, //自定义内存分配器
&surface); //存储返回的表面的内存地址

}

调用
main.cpp
#define GLFW_INCLUDE_VULKAN
#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include “MyApplication.h”

int main()
{
MyApplication app;
app.run();
return 0;
}

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

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

相关文章

【零基础入门unity游戏开发——2D篇】SpriteEditor图片编辑器

考虑到每个人基础可能不一样,且并不是所有人都有同时做2D、3D开发的需求,所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】:主要讲解C#的基础语法,包括变量、数据类型、运算符、流程控制、面向对象等,适合没有编程基础的…

云巅之上:数字文明的重构与超越

序章&#xff1a;算力新纪元 2024年初春&#xff0c;当SpaceX的星舰将首批云计算节点送入近地轨道时&#xff0c;地球上的数字原住民们正通过云端AI助手规划着一天的行程。这场静默的革命已悄然进入新阶段——云计算不再只是工具&#xff0c;而是成为数字文明的"第六元素…

【面试篇】多线程

基础概念 线程的生命周期有哪些状态&#xff1f;它们是如何转换的&#xff1f; 答案&#xff1a;线程的生命周期有以下六种状态&#xff1a; 新建&#xff08;New&#xff09;&#xff1a;线程被创建但尚未启动&#xff0c;此时线程对象已被分配内存空间&#xff0c;相关属性已…

unity运行中场景指定模型回放功能(模型是地形并且可以加载预制体进行回放)

回放和加载脚本 using System.Collections.Generic; using UnityEngine;public class TerrainRecorder : MonoBehaviour {[Header("基本设置")]public Terrain targetTerrain;public bool isRecording false;public bool isPlayingBack false;[Range(0.02f, 1f)] …

基于SpringBoot的河道水情大数据可视化分析平台设计与实现(源码+论文+部署讲解等)

需要资料&#xff0c;请文末联系 一、平台介绍 水情监测数据大屏 - 平台首页 日均水位 日均水速 二、论文内容 摘要&#xff08;中文&#xff09; 本文针对河道水情监测领域的数据管理和可视化分析需求&#xff0c;设计并实现了一套河道水情大数据可视化分析平台。该平台基…

Knife4j文档请求异常 空指针

打开swagger文档报空指针异常 java.lang.NullPointerException: nullat springfox.documentation.oas.mappers.SchemaMapper.model(SchemaMapper.java:97)at springfox.documentation.oas.mappers.SchemaMapper.mapModel(SchemaMapper.java:85)at springfox.documentation.oas…

车辆选择解决方案

车辆选择解决方案 /* * Purpose: 添加车辆选择的功能 -> 用户在选择不同的车辆时&#xff0c;重新初始化系统状态&#xff0c;清除之前的定时器&#xff0c;并根据新选择的车辆设置新的定时器&#xff0c;以实现对新车辆状态的实时加载。 * File Name: 车辆选择解决方案 * …

魔塔社区使用llamafactory微调AI阅卷试题系统

启动 LLaMA-Factory 1. 安装 LLaMA-Factory 执行安装指令 git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip install -e ".[torch,metrics]"解决依赖冲突 如果遇到依赖冲突&#xff0c;可使用以下命令安装&#xff0c;不…

程序化广告行业(51/89):Cookie映射与移动设备ID映射解析

程序化广告行业&#xff08;51/89&#xff09;&#xff1a;Cookie映射与移动设备ID映射解析 在当今数字化营销的浪潮中&#xff0c;程序化广告已经成为企业精准触达目标客户的重要手段。作为一名对程序化广告充满兴趣的学习者&#xff0c;我希望通过这篇博客和大家一起深入探索…

内网服务器centos7安装jdk17

1. 下载 JDK 17 安装包&#xff08;在外网环境操作&#xff09; 在可联网的机器上下载 JDK 17 的压缩包&#xff08;推荐使用 OpenJDK&#xff09;&#xff1a; OpenJDK 官方源&#xff1a; Adoptium Eclipse Temurin Azul Zulu 直接下载命令示例&#xff08;在外网机器上执行…

【学Rust写CAD】21 2D 点(point.rs)

源码 //matrix/point.rs use std::ops::Mul; use super::algebraic_units::{Zero, One}; use super::generic::Matrix;/// 点坐标结构体 #[derive(Debug, Clone, Copy, PartialEq)] pub struct Point<X, Y>(Matrix<X, Y, One, Zero, Zero, One>);impl<X, Y>…

《AI大模型应知应会100篇》第7篇:Prompt Engineering基础:如何与大模型有效沟通

第7篇&#xff1a;Prompt Engineering基础&#xff1a;如何与大模型有效沟通 摘要 Prompt Engineering&#xff08;提示工程&#xff09;是与大模型高效沟通的关键技能。通过精心设计的Prompt&#xff0c;可以让模型生成更准确、更有用的结果。本文将从基础知识到高级策略&…

Java高频面试题1:Java SE

一、Java概述 1. Java语言的特点&#xff1f; 面向对象&#xff1a;封装、继承、多态。跨平台&#xff1a;通过JVM实现“一次编写&#xff0c;到处运行”。内存管理&#xff1a;自动垃圾回收&#xff08;GC&#xff09;&#xff0c;避免手动内存管理。多线程&#xff1a;内置…

基于RapidIO接口的DSP+GPU工业AI实时计算解决方案

基于RapidIO接口的DSPGPU工业AI实时计算解决方案是一种面向高性能、低延迟工业应用的异构计算架构&#xff0c;适用于工业自动化、机器视觉、预测性维护、机器人控制等场景。以下是该方案的核心设计思路和技术要点&#xff1a; 1. 方案背景与目标 工业需求&#xff1a; 工业…

SQL DB 数据类型

SQL DB 数据类型 引言 在数据库管理系统中,数据类型是定义和存储数据的方式。SQL(结构化查询语言)数据库中的数据类型决定了数据的存储格式、大小、取值范围以及如何处理数据。合理选择和使用数据类型对于确保数据库性能、数据完整性和应用程序的准确性至关重要。 SQL 数…

常见电源模块设计

目录 1. 5V电源模块 2. 3.3V电源模块 3. 1.9V电源模块 4. 220V转12V电源模块 1. 5V电源模块 参考电路 电路说明&#xff1a; 这个电路采用的是稳压芯片78L05&#xff0c;我是用的12V的电源模块转成为5V,为后续的供电。 2. 3.3V电源模块 参考电路&#xff1a; 电路说明…

python操作es

1、常用操作 ### 创建索引 bash curl -u elastic:123 -X PUT -H "Content-Type: application/json" -d mapping.json "http://0.0.0.0:9200/ai_kg_extraction_new_lower_tag_index" ### 删除索引 bash curl -u elastic:123 -X DELETE "http://0.0…

记一个.NET AOT交叉编译时的坑

记一个.NET AOT交叉编译时的坑 背景&#xff1a; 使用.NET9开发的Avalonia项目需要部署到Linux-arm64 踩坑&#xff1a; 根据官方AOT交叉编译文档配置后执行打包 dotnet publish -r linux-arm64提示error : The PrivateSdkAssemblies ItemGroup is required for _ComputeA…

【Linux篇】探索进程地址空间:计算机背后的虚拟世界

进程地址空间的奥秘&#xff1a;让你理解程序如何在计算机中生存 一. 程序地址空间1.1 基本概念1.2 虚拟内存管理1.3 为什么存在虚拟地址空间1.3.1 意义 2. 最后 本文将介绍进程地址空间的基本概念与结构&#xff0c;帮助读者理解操作系统如何管理和分配内存。进程地址空间指的…

17查询文档的方式

目录 1.鼠标放在你要查询的地方或者选中&#xff0c;按FnF1 2Assistant文档 3帮助菜单界面 1.鼠标放在你要查询的地方或者选中&#xff0c;按FnF1 2Assistant文档 3帮助菜单界面 大家一定要有 查询文档 的意识!! 未来实际开发中,一定会用到很多的第三方库和框架的. 很可能用到的…