(六)窗口表面

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

一,窗口表面
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;
}

本项目采用C++编程语言结合ROS框架构建了完整的双机械臂控制系统,实现了Gazebo仿真环境下的协同运动模拟,并完成了两台实体UR10工业机器人的联动控制。该毕业设计在答辩环节获得98分的优异成绩,所有程序代码均通过系统性调试验证,保证可直接部署运行。 系统架构包含三个核心模块:基于ROS通信架构的双臂协调控制器、Gazebo物理引擎下的动力学仿真环境、以及真实UR10机器人的硬件接口层。在仿真验证阶段,开发了双臂碰撞检测算法和轨迹规划模块,通过ROS控制包实现了末端执行器的同步轨迹跟踪。硬件集成方面,建立了基于TCP/IP协议的实时通信链路,解决了双机数据同步和运动指令分发等关键技术问题。 本资源适用于自动化、机械电子、人工智能等专业方向的课程实践,可作为高年级课程设计、毕业课题的重要参考案例。系统采用模块化设计理念,控制核心与硬件接口分离架构便于功能扩展,具备工程实践能力的学习者可在现有框架基础上进行二次开发,例如集成视觉感知模块或优化运动规划算法。 项目文档详细记录了环境配置流程、参数调试方法和实验验证数据,特别说明了双机协同作业时的时序同步解决方案。所有功能模块均提供完整的API接口说明,便于使用者快速理解系统架构并进行定制化修改。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
【微电网】【创新点】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究(Matlab代码实现)内容概要:本文围绕基于非支配排序的蜣螂优化算法(NSDBO)在微电网多目标优化调度中的应用展开研究,提出了一种改进的智能优化算法以解决微电网系统中经济性、环保性和能源效率等多重目标之间的权衡问题。通过引入非支配排序机制,NSDBO能够有效处理多目标优化中的帕累托前沿搜索,提升解的多样性和收敛性,并结合Matlab代码实现仿真验证,展示了该算法在微电网调度中的优越性能和实际可行性。研究涵盖了微电网典型结构建模、目标函数构建及约束条件处理,实现了对风、光、储能及传统机组的协同优化调度。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事微电网、智能优化算法应用的工程技术人员;熟悉优化算法与能源系统调度的高年级本科生亦可参考。; 使用场景及目标:①应用于微电网多目标优化调度问题的研究与仿真,如成本最小化、碳排放最低与供电可靠性最高之间的平衡;②为新型智能优化算法(如蜣螂优化算法及其改进版本)的设计与验证提供实践案例,推动其在能源系统中的推广应用;③服务于学术论文复现、课题研究或毕业设计中的算法对比与性能测试。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注NSDBO算法的核心实现步骤与微电网模型的构建逻辑,同时可对比其他多目标算法(如NSGA-II、MOPSO)以深入理解其优势与局限,进一步开展算法改进或应用场景拓展。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值