Skip to content

门泊吴船亦已谋

Vulkan 画三角形 第三章 创建窗体表面

Vulkan 是一个跨平台的 API,它不能够直接与不同平台的窗体系统进行交互。为了在 Vulkan 与窗体系统之间建立连接来把渲染结果展示到屏幕上,我们需要使用一些 WSI 扩展。本文将会介绍 VK_KHR_surface 扩展。它暴露一个 VkSurfaceKHR 对象,这个对象代表一个我们可以把图像渲染上去的抽象表面

这个 VK_KHR_surface 是一个实例等级的扩展,并且我们其实在上一篇文章中就已经启用了它,因为它已经被包含在前文所用到的 glfwGetRequiredInstanceExtensions 所返回的列表中。这个列表同时还包含一些其他的 WSI 扩展,不过我们可以先不管这些

另外需要注意的是,窗体表面其实并不一定需要创建,因为你可能只是要离屏渲染而不用把结果显示到屏幕上

创建窗体表面

首先跟上一篇文章一样,我们先添加一个私有成员变量用于保存创建好的窗体表面

VkSurfaceKHR surface;

然后添加一个 createSurface 成员函数,并在 initVulkan 中调用它

void initVulkan() {
    createInstance();
    createSurface();
}

然后是这个成员函数的定义

void createSurface() {
    if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS)
        throw std::runtime_error("failed to create window surface!");
}

可以看到非常简单,而且是调了 GLFW 的 API 来实现的,说明 GLFW 对 Vulkan 有一定的支持。需要注意的是 vulkan/vulkan.h 这个头文件一定要写在 GLFW/glfw3.h 之前,因为 GLFW 会根据 Vulkan 的宏进行条件编译,头文件顺序不对的话将会无法使用 glfwCreateWindowSurface 这个函数

销毁窗体表面

最后我们要在 cleanup 中销毁掉窗体表面

void cleanup() {
    vkDestroySurfaceKHR(instance, surface, nullptr);
    vkDestroyInstance(instance, nullptr);

    glfwDestroyWindow(window);
    glfwTerminate();
}

当然销毁表面需要写在销毁实例之前