本文档是对Vulkan Tutorial教程的翻译,非官方翻译,仅供vulkan爱好者参考学习。如果有翻译错误,请留言指出,或者联系占航(hangliebe@163.com)进行修正,感谢。建议英文好的朋友直接读原文档。

关注我的微博主页

2022-02-20 v1.0

开发环境

在这一章中,我们将设置您开发Vulkan应用程序的环境,并安装一些有用的库。除了编译器之外,我们将使用的所有工具都与Windows、Linux和MacOS兼容,但安装它们的步骤有些不同,这就是为什么它们在这里被单独描述。

Windows

如果你在为Windows开发,那么我将假设你正在使用Visual Studio来编译你的代码。为了完全支持C++17,你需要使用Visual Studio 2017或2019。下面概述的步骤是为VS 2017编写的。

Vulkan SDK

开发Vulkan应用程序所需的最重要组件是SDK。它包括头文件、标准验证层、调试工具和Vulkan函数的加载器。该加载器在运行时查找驱动程序中的函数,类似于OpenGL的GLEW–如果你熟悉的话。

SDK可以通过页面底部的按钮从LunarG网站下载。你不需要创建一个账户,但它会让你访问一些可能对你有用的额外文档。

vulkan_sdk_download_buttons

继续进行安装,并注意SDK的安装位置。我们要做的第一件事是验证你的显卡和驱动是否正确支持Vulkan。进入你安装SDK的目录,打开Bin目录,运行vkcube.exe演示。你应该看到以下情况。

cube_demo

如果你收到一个错误信息,那么请确保你的驱动程序是最新的,包括Vulkan运行时间,并且你的显卡被支持。有关主要供应商的驱动程序的链接,请参见介绍章节。

这个目录中还有一个程序对开发很有用。glslangValidator.exeglslc.exe程序将被用来把着色器从人类可读的GLSL编译成字节码。我们将在着色器模块一章中深入介绍这个问题。Bin目录还包含Vulkan加载器和验证层的二进制文件,而Lib目录包含库。

最后是Include目录,包含Vulkan头文件。请自由探索其他文件,但我们在本教程中不需要它们。

GLFW

如前所述,Vulkan本身是一个与平台无关的API,不包括创建窗口来显示渲染结果的工具。为了受益于Vulkan的跨平台优势并避免Win32的恐怖,我们将使用GLFW库来创建一个窗口,它支持Windows、Linux和MacOS。还有其他的库可以用于这个目的,比如SDL,但是GLFW的优势在于它还抽象出了Vulkan中除了创建窗口之外的一些其他平台特有的东西。

你可以在官方网站上找到GLFW的最新版本。在本教程中,我们将使用64位二进制文件,但你当然也可以选择以32位模式构建。在这种情况下,请确保与Lib32目录下的Vulkan SDK二进制文件链接,而不是Lib。下载后,解压到一个方便的位置。我选择在Visual Studio目录下的文档中创建一个Libraries目录。

glfw_directory

GLM

与DirectX 12不同,Vulkan不包括一个用于线性代数操作的库,所以我们必须下载一个。GLM是一个不错的库,它是为图形API设计的,也常用于OpenGL。

GLM是一个只有头的库,所以只要下载最新版本并把它存放在一个方便的位置。你现在应该有一个类似于以下的目录结构:

img

设置Visual Studio

现在你已经安装了所有的依赖项,我们可以为Vulkan设置一个基本的Visual Studio项目,并写一点代码以确保一切正常。

启动Visual Studio并创建一个新的 “Windows Desktop Wizard”项目,输入一个名称并按 “OK”键。

img

Make sure that Console Application (.exe) is selected as application type so that we have a place to print debug messages to, and check Empty Project to prevent Visual Studio from adding boilerplate code.

确保Console Application (.exe)被选为应用程序类型,这样我们就有一个地方可以打印调试信息,并选中 Empty Project以防止Visual Studio添加模板代码。

img

OK键,创建项目并添加一个C++源文件。你应该已经知道如何做了,但为了完整起见,这里包括了这些步骤。

img
img

现在在文件中加入以下代码。现在不要担心要去理解它;我们只是要确保你可以编译和运行Vulkan应用程序。我们将在下一章中从头开始。

#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>

#include <iostream>

int main() {
    glfwInit();

    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    GLFWwindow* window = glfwCreateWindow(800, 600, "Vulkan window", nullptr, nullptr);

    uint32_t extensionCount = 0;
    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);

    std::cout << extensionCount << " extensions supported\n";

    glm::mat4 matrix;
    glm::vec4 vec;
    auto test = matrix * vec;

    while(!glfwWindowShouldClose(window)) {
        glfwPollEvents();
    }

    glfwDestroyWindow(window);

    glfwTerminate();

    return 0;
}

现在让我们来配置项目以消除错误。打开项目属性对话框,确保选择All Configurations,因为大多数设置适用于DebugRelease模式。

img
img

进入 C++ -> General -> Additional Include Directories 在下拉框中按 <Edit...>.

img

添加Vulkan、GLFW和GLM的头文件目录:img

接下来,在 Linker -> General下打开库目录的编辑器:

img

并添加Vulkan和GLFW的对象文件的位置:img

进入 Linker -> InputAdditional Dependencies下拉框中按 <Edit...>

img

输入Vulkan和GLFW对象文件的名称:img

最后改变编译器以支持C++17的特性。img

现在你可以关闭项目属性对话框。如果你所做的一切是正确的,那么你应该不再看到代码中突出显示的任何错误。

最后,确保你实际上是在64位模式下编译的:

img

F5编译并运行该项目,你应该看到一个命令提示符和一个弹出的窗口,像这样。

img

扩展的数量应该是非零的。恭喜你,你已经为玩转Vulkan做好了一切准备!

Linux

这些说明将针对Ubuntu、Fedora和Arch Linux用户,但你也可以通过将软件包管理器的特定命令改为适合你的命令来进行学习。你应该有一个支持C++17的编译器(GCC 7+或Clang 5+)。你还需要make

Vulkan 工具包

在Linux上开发Vulkan应用程序,你需要的最重要的组件是Vulkan加载器、验证层和几个命令行工具,以测试你的机器是否具备Vulkan功能。

  • sudo apt install vulkan-toolssudo dnf install vulkan-tools。命令行实用程序,最重要的是vulkaninfovkcube。运行这些工具以确认你的机器支持Vulkan。
  • sudo apt install libvulkan-devsudo dnf install vulkan-loader-devel:安装Vulkan加载器。该加载器在运行时查找驱动中的函数,类似于OpenGL的GLEW–如果你熟悉它。
  • sudo apt install vulkan-validationlayers-dev spirv-toolssudo dnf install mesa-vulkan-devel vulkan-validation-layers-devel。安装标准验证层和必要的SPIR-V工具。这些在调试Vulkan应用程序时至关重要,我们将在接下来的章节中讨论它们。

在Arch Linux上,你可以运行sudo pacman -S vulkan-devel来安装上述所有需要的工具。

如果安装成功,你应该已经完成了Vulkan部分的安装。记得运行vkcube并确保你在窗口中看到以下内容:

img

如果你收到错误信息,那么请确保你的驱动程序是最新的,包括Vulkan运行时间,并且你的显卡被支持。参见简介章节,以获得主要供应商的驱动程序链接。

GLFW

如前所述,Vulkan本身是一个与平台无关的API,并不包括创建窗口来显示渲染结果的工具。为了受益于Vulkan的跨平台优势并避免X11的恐怖,我们将使用GLFW库来创建一个窗口,它支持Windows、Linux和MacOS。还有其他的库可以用于这个目的,比如SDL,但是GLFW的优势在于它还抽象出了Vulkan中除了创建窗口之外的一些其他平台特有的东西。

我们将通过以下命令来安装GLFW:

sudo apt install libglfw3-dev

or

sudo dnf install glfw-devel

or

sudo pacman -S glfw-wayland # glfw-x11 for X11 users

GLM

与DirectX 12不同,Vulkan不包括一个用于线性代数操作的库,所以我们必须下载一个。GLM是一个不错的库,它是为图形API设计的,也常用于OpenGL。

它是一个纯头文件库,可以从libglm-devglm-devel软件包中安装:

sudo apt install libglm-dev

or

sudo dnf install glm-devel

or

sudo pacman -S glm

着色器编译器

我们已经拥有了我们所需要的一切,除了我们需要一个程序来将着色器从人类可读的GLSL编译成字节码。

两个流行的着色器编译器是Khronos Group的glslangValidator和Google的glslc。后者有一个熟悉的类似GCC和Clang的用法,所以我们就用它:在Ubuntu上,下载Google的unofficial binaries,然后复制glslc到你的/usr/local/bin。注意你可能需要sudo,这取决于你的权限。在Fedora上使用sudo dnf install glslc,而在Arch Linux上运行sudo pacman -S shaderc。为了测试,运行glslc,它应该正确地抱怨我们没有传递任何着色器来编译.

glslc: error: no input files

我们将在着色器模块章节中深入介绍glslc

启动第一个makefile项目

现在你已经安装了所有的依赖项,我们可以为Vulkan建立一个基本的makefile项目,并写一点代码以确保一切正常。

在一个方便的位置创建一个新的目录,名称为VulkanTest。创建一个名为main.cpp的源文件并插入以下代码。现在不要担心试图理解它;我们只是要确保你可以编译和运行Vulkan应用程序。我们将在下一章中从头开始。

#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>

#include <iostream>

int main() {
    glfwInit();

    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    GLFWwindow* window = glfwCreateWindow(800, 600, "Vulkan window", nullptr, nullptr);

    uint32_t extensionCount = 0;
    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);

    std::cout << extensionCount << " extensions supported\n";

    glm::mat4 matrix;
    glm::vec4 vec;
    auto test = matrix * vec;

    while(!glfwWindowShouldClose(window)) {
        glfwPollEvents();
    }

    glfwDestroyWindow(window);

    glfwTerminate();

    return 0;
}

接下来,我们将编写一个makefile来编译和运行这个基本的Vulkan代码。创建一个名为Makefile的新的空文件。我将假设你已经有一些关于makefile的基本经验,比如变量和规则如何工作。如果没有,你可以通过这个教程快速上手。

我们将首先定义几个变量,以简化文件的其余部分。定义一个CFLAGS变量,它将指定基本的编译器标志。

CFLAGS = -std=c++17 -O2

我们将使用现代C++(-std=c++17),并将优化级别设置为O2。我们可以去掉-O2,以便更快地编译程序,但我们应该记得在发布构建时把它放回去。

同样地,在LDFLAGS变量中定义链接器标志:

LDFLAGS = -lglfw -lvulkan -ldl -lpthread -lX11 -lXxf86vm -lXrandr -lXi

标志-glfw是用于GLFW,-lvulkan与Vulkan函数加载器链接,其余的标志是GLFW需要的低级系统库。剩下的标志是GLFW本身的依赖:线程和窗口管理。

你的系统可能还没有安装Xxf68vmXi库。你可以在以下软件包中找到它们:

sudo apt install libxxf86vm-dev libxi-dev

or

sudo dnf install libXi libXxf86vm

or

sudo pacman -S libxi libxxf86vm

指定编译VulkanTest的规则现在很简单了。请确保使用制表符来缩进,而不是空格。

VulkanTest: main.cpp
    g++ $(CFLAGS) -o VulkanTest main.cpp $(LDFLAGS)

通过保存makefile并在有main.cppMakefile的目录下运行make来验证这一规则是否有效。这应该会产生一个VulkanTest可执行文件。

我们现在再定义两条规则,testclean,前者将运行可执行文件,后者将删除已建的可执行文件。

.PHONY: test clean

test: VulkanTest
    ./VulkanTest

clean:
    rm -f VulkanTest

运行make test应该显示程序成功运行,并显示Vulkan扩展的数量。当你关闭空窗口时,该程序应该以成功返回代码(0)退出。你现在应该有一个完整的makefile,类似于以下内容。

CFLAGS = -std=c++17 -O2
LDFLAGS = -lglfw -lvulkan -ldl -lpthread -lX11 -lXxf86vm -lXrandr -lXi

VulkanTest: main.cpp
    g++ $(CFLAGS) -o VulkanTest main.cpp $(LDFLAGS)

.PHONY: test clean

test: VulkanTest
    ./VulkanTest

clean:
    rm -f VulkanTest

现在你可以使用这个目录作为你的Vulkan项目的模板。复制一份,重命名为 “HelloTriangle”并删除 “main.cpp”中的所有代码。

现在你已经为真正的冒险做好了一切准备。

MacOS

这些说明将假设你使用Xcode和Homebrew软件包管理器。另外,请记住,你至少需要MacOS 10.11版本,而且你的设备需要支持Metal API

Vulkan SDK

在开发Vulkan应用程序时,你需要的最重要的组件是SDK。它包括头文件、标准验证层、调试工具和Vulkan函数的加载器。装载器在运行时查找驱动程序中的函数,类似于OpenGL的GLEW–如果你对它很熟悉的话。

SDK可以从LunarG网站使用页面底部的按钮下载。你不需要创建一个账户,但它会让你访问一些可能对你有用的额外文档。

img

MacOS的SDK版本内部使用MoltenVK。在MacOS上没有对Vulkan的本地支持,所以MoltenVK实际上是作为一个层,将Vulkan的API调用翻译成苹果的Metal图形框架。有了它,你可以利用苹果的Metal框架的调试和性能优势。

下载后,只需将内容解压到您选择的文件夹中(请记住,当您在Xcode上创建项目时需要参考它)。在解压后的文件夹中,在 “Applications”文件夹中,你应该有一些可执行文件,可以使用SDK运行一些演示。运行vkcube可执行文件,你会看到以下内容:

img

GLFW

如前所述,Vulkan本身是一个与平台无关的API,并不包括创建窗口来显示渲染结果的工具。我们将使用GLFW库来创建一个窗口,它支持Windows、Linux和MacOS。还有其他的库可以用于这个目的,比如SDL,但是GLFW的优势在于它还抽象出了Vulkan中除了创建窗口之外的一些其他平台特有的东西。

为了在MacOS上安装GLFW,我们将使用Homebrew包管理器来获取glfw包。

brew install glfw

GLM

Vulkan不包括线性代数操作的库,所以我们必须下载一个。GLM是一个不错的库,它是为图形API设计的,也常用于OpenGL。

它是一个只包含头文件的库,可以从glm包中安装:

brew install glm

启动 Xcode

现在所有的依赖都已经安装完毕,我们可以为Vulkan设置一个基本的Xcode项目。这里的大部分说明基本上都是一些 “管道”,这样我们就可以把所有的依赖项链接到项目中。另外,请记住,在下面的说明中,当我们提到vulkansdk文件夹时,我们指的是你提取Vulkan SDK的文件夹。

启动Xcode并创建一个新的Xcode项目。在打开的窗口中选择Application > Command Line Tool。

img

选择 Next,为项目写一个名称,“Language”选择 “C++”。

img

Next,项目应该已经创建。现在,让我们把生成的main.cpp文件中的代码改为以下代码。

#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>

#include <iostream>

int main() {
    glfwInit();

    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    GLFWwindow* window = glfwCreateWindow(800, 600, "Vulkan window", nullptr, nullptr);

    uint32_t extensionCount = 0;
    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);

    std::cout << extensionCount << " extensions supported\n";

    glm::mat4 matrix;
    glm::vec4 vec;
    auto test = matrix * vec;

    while(!glfwWindowShouldClose(window)) {
        glfwPollEvents();
    }

    glfwDestroyWindow(window);

    glfwTerminate();

    return 0;
}

请记住,你不需要理解所有这些代码的作用,我们只是设置一些API调用,以确保一切都在工作。

Xcode应该已经显示了一些错误,如找不到库。我们现在将开始配置项目以摆脱这些错误。在项目导航仪面板上选择你的项目。打开Build Settings标签,然后:

  • 找到Header Search Paths字段,添加一个链接到/usr/local/include(这是Homebrew安装头文件的地方,所以glm和glfw3头文件应该在那里),并添加一个链接到vulkansdk/macOS/include以获取Vulkan头文件。
  • 找到Library Search Paths栏,添加一个链接到/usr/local/lib(同样,这是Homebrew安装库的地方,所以glm和glfw3库文件应该在那里)和一个链接到vulkansdk/macOS/lib

它应该看起来像这样(显然,路径会有所不同,这取决于你在你的文件上放置的位置):

img
  • 现在,在Build Phases标签,在Link Binary With Libraries上,我们将添加glfw3vulkan框架。为了方便起见,我们将在项目中添加动态库(如果你想使用静态框架,你可以查看这些库的文档)。

    • 对于glfw来说,打开/usr/local/lib文件夹,你会发现一个文件名是libglfw.3.x.dylib(“x”是库的版本号,它可能不同,取决于你何时从Homebrew下载包)。只需将该文件拖到Xcode的链接框架和库选项卡中。
    • 对于vulkan,进入vulkansdk/macOS/lib。对libvulkan.1.dyliblibvulkan.1.x.xx.dylib(其中 “x”将是你下载的SDK的版本号)这两个文件做同样的操作。

添加完这些库后,在同一标签上的Copy Files将 “Destination”改为 “Frameworks”,清除子路径并取消选择 “Copy only when installing”。点击 “+”号,在这里也添加所有这三个框架。

你的Xcode配置应该看起来像:

img

你需要设置的最后一件事是几个环境变量。在Xcode的工具栏上,进入 “Product”>“Scheme”>“Edit Scheme…”,在 “Arguments”选项卡中添加以下两个环境变量。

  • VK_ICD_FILENAMES = vulkansdk/macOS/share/vulkan/icd.d/MoltenVK_icd.json
  • VK_LAYER_PATH = vulkansdk/macOS/share/vulkan/explicit_layer.d

它应该看起来像这样:

img

最后,你应该都准备好了! 现在,如果你运行该项目(记得根据你选择的配置,将构建配置设置为Debug或Release),你应该看到以下内容:

img

扩展的数量应该是非零的。其他日志来自库,你可能会从这些日志中得到不同的信息,这取决于你的配置。

你现在已经为真正的东西做好了所有准备。

留言板