使用GLFW创建窗口
首先包含两个库的头文件
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
定义Application的基本结构:run ( init(),loop(),clean() )
在main loop创建Application obj,通过try catch异常处理,检测在程序执行时是否有错误信息
调用GLFWAPI创建窗口
void initVulkan() {glfwInit();//创建GLFW库glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);glfwWindowHint(GLFW_RELEASE, GLFW_FALSE);//暂时禁用调整窗口window = glfwCreateWindow(WIDTH, HEIGHT,"Sen's Valkan demo", nullptr, nullptr);//设置窗口信息
}void mainLoop() {while (!glfwWindowShouldClose(window)) {glfwPollEvents();}
}void cleanup() {glfwDestroyWindow(window);glfwTerminate();
}
创建VkInstance
VkInstance instance;
首先创建可选的VkApplicationInfo结构体,填充一些 有关我们应用程序的信息
Vulkan 中的许多结构要求您明确指定 成员中的类型,比如sType = STRUCTURE TYPE APPLICATION INFO结构类型应用信息
Vulkan 中的很多信息都是通过结构体而不是函数parameters 参数传递的
其中VkApplicationInfo appInfo{};是列表初始化struct对象,对于struct
聚合类型来说,列表初始化具有特殊的意义:
列表初始化会逐个初始化其成员,按照它们在类中声明的顺序,如果列表中的元素少于聚合类型的成员数量,那么剩余的成员会被值初始化(对于内置类型,这通常意味着它们被初始化为0或nullptr)而非默认初始化
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;
必须创建VkInstanceCreateInfo:它告诉 Vulkan 驱动程序,我们要使用的全局扩展和验证层
VkInstanceCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;
Vulkan 是一个 与平台无关的 API,因此需要一个Extension扩展来与 窗口系统交互,而GLFW 有一个方便的内置函数,它返回扩展,以及获取扩展数量
uint32_t glfwExtensionCount = 0;
const char** glfwExtensions;glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);createInfo.enabledExtensionCount = glfwExtensionCount;
createInfo.ppEnabledExtensionNames = glfwExtensions;
全局验证层 我们暂时不使用
createInfo.enabledLayerCount = 0;
们已经指定了 Vulkan 创建实例所需的一切, 可以使用 vkCreateInstancevkCreateInstance创建VkInstance
- 指向包含创建信息的结构的指针
- 指向自定义分配器回调的指针,始终在本教程中
nullptr
- 指向存储新对象句柄的变量的指针
几乎所有 Vulkan 函数都返回 VkResultVkResult VkResult 类型的值,要检查 instance 创建成功使用 check()!= VK_SUCCESS
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {throw std::runtime_error("failed to create instance!");
}
清理
vkDestroyInstance(instance, nullptr);
现在运行程序以确保实例创建成功
VK_ERROR_INCOMPATIBLE_DRIVER
如果使用苹果的MacOS操作系统与最新的 MoltenVK SDK 一起使用,可能会有VK_ERROR_INCOMPATIBLE_DRIVER不兼容的驱动程序错误……
检查扩展支持
要在创建实例之前检索支持的扩展列表,可以使用 vkEnumerateInstanceExtensionProperties
函数
- 可选的 first 参数,允许我们按特定的 验证层
- 存储扩展数量的变量
- 存储扩展详细信息的 VkExtensionProperties
数组
首次的vkEnumerateInstanceExtensionProperties是初始化数组的元素数量
uint32_t extensionCount = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
std::vector<VkExtensionProperties> extensions(extensionCount);
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());
std::cout << "available extensions:\n";
for (const auto& extension : extensions) {std::cout << '\t' << extension.extensionName << '\n';
}