开发环境
在本章中,我们将设置您的 Vulkan 应用程序开发环境,并安装一些有用的库。我们使用的所有工具,除了编译器之外,都与 Windows、Linux 和 MacOS 兼容,但安装步骤略有不同,这就是为什么在这里分别描述它们的原因。
Windows
如果您正在为 Windows 开发,那么我将假设您正在使用 Visual Studio 来编译您的代码。为了获得完整的 C++17 支持,您需要使用 Visual Studio 2017 或 2019。下面概述的步骤是为 VS 2017 编写的。
Vulkan SDK
开发 Vulkan 应用程序最重要的组件是 SDK。它包括头文件、标准验证层、调试工具和 Vulkan 函数的加载器。加载器在运行时查找驱动程序中的函数,类似于 OpenGL 的 GLEW - 如果您熟悉它的话。
可以从 LunarG 网站 使用页面底部的按钮下载 SDK。您不必创建帐户,但它将使您可以访问一些可能对您有用的其他文档。
继续完成安装,并注意 SDK 的安装位置。我们要做的第一件事是验证您的显卡和驱动程序是否正确支持 Vulkan。转到您安装 SDK 的目录,打开 Bin
目录并运行 vkcube.exe
演示程序。您应该看到以下内容
如果您收到错误消息,请确保您的驱动程序是最新的,包括 Vulkan 运行时,并且您的显卡受支持。请参阅简介章节,其中包含主要供应商的驱动程序链接。
此目录中还有另一个程序对开发很有用。glslangValidator.exe
和 glslc.exe
程序将用于将人类可读的 GLSL 编译为字节码。我们将在着色器模块章节中深入介绍这一点。Bin
目录还包含 Vulkan 加载器和验证层的二进制文件,而 Lib
目录包含库文件。
最后,还有 Include
目录,其中包含 Vulkan 头文件。您可以随意浏览其他文件,但本教程中我们不需要它们。
GLFW
如前所述,Vulkan 本身是一个平台无关的 API,不包含用于创建窗口以显示渲染结果的工具。为了利用 Vulkan 的跨平台优势并避免 Win32 的恐怖之处,我们将使用 GLFW 库 来创建一个窗口,它支持 Windows、Linux 和 MacOS。还有其他库可用于此目的,例如 SDL,但 GLFW 的优势在于,除了窗口创建之外,它还抽象出 Vulkan 中其他一些特定于平台的东西。
您可以在 官方网站 上找到 GLFW 的最新版本。在本教程中,我们将使用 64 位二进制文件,但您当然也可以选择以 32 位模式构建。在这种情况下,请确保链接到 Lib32
目录而不是 Lib
中的 Vulkan SDK 二进制文件。下载后,将存档解压缩到方便的位置。我选择在文档下的 Visual Studio 目录中创建一个 Libraries
目录。
GLM
与 DirectX 12 不同,Vulkan 不包含用于线性代数运算的库,因此我们需要下载一个。GLM 是一个不错的库,专为图形 API 设计,也常用于 OpenGL。
GLM 是一个仅包含头文件的库,因此只需下载 最新版本 并将其存储在方便的位置。您现在应该具有类似于以下的目录结构
设置 Visual Studio
现在您已经安装了所有依赖项,我们可以为 Vulkan 设置一个基本的 Visual Studio 项目,并编写少量代码以确保一切正常。
启动 Visual Studio 并创建一个新的 Windows 桌面向导
项目,输入名称并按 确定
。
确保选择 控制台应用程序(.exe)
作为应用程序类型,以便我们有一个地方可以打印调试消息,并选中 空项目
以防止 Visual Studio 添加样板代码。
按 确定
创建项目并添加一个 C++ 源文件。您应该已经知道如何做到这一点,但此处包含这些步骤是为了完整性。
现在将以下代码添加到文件中。现在不用担心尝试理解它;我们只是确保您可以编译和运行 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;
}
现在配置项目以消除错误。打开项目属性对话框,并确保选择 所有配置
,因为大多数设置都适用于 Debug
和 Release
模式。
转到 C++ -> 常规 -> 附加包含目录
,然后在下拉框中按 <编辑...>
。
添加 Vulkan、GLFW 和 GLM 的头文件目录
接下来,打开 链接器 -> 常规
下的库目录编辑器
并添加 Vulkan 和 GLFW 的目标文件位置
转到 链接器 -> 输入
,然后在 附加依赖项
下拉框中按 <编辑...>
。
输入 Vulkan 和 GLFW 目标文件的名称
最后,更改编译器以支持 C++17 功能
您现在可以关闭项目属性对话框。如果您做的一切都正确,那么您应该不再看到代码中突出显示任何错误。
最后,确保您实际上是以 64 位模式进行编译
按 F5
编译并运行项目,您应该看到一个命令提示符和一个窗口弹出,如下所示
扩展的数量应该是非零的。恭喜,您已准备好开始使用 Vulkan 了!
Linux
这些说明将针对 Ubuntu、Fedora 和 Arch Linux 用户,但您可以通过将特定于包管理器的命令更改为适合您的命令来跟随操作。您应该有一个支持 C++17 的编译器(GCC 7+ 或 Clang 5+)。您还需要 make
。
Vulkan 软件包
在 Linux 上开发 Vulkan 应用程序最重要的组件是 Vulkan 加载器、验证层以及一些命令行实用程序,用于测试您的机器是否支持 Vulkan
-
sudo apt install vulkan-tools
或sudo dnf install vulkan-tools
:命令行实用程序,最重要的是vulkaninfo
和vkcube
。运行这些命令以确认您的机器支持 Vulkan。 -
sudo apt install libvulkan-dev
或sudo dnf install vulkan-loader-devel
:安装 Vulkan 加载器。加载器在运行时查找驱动程序中的函数,类似于 OpenGL 的 GLEW - 如果您熟悉它的话。 -
sudo apt install vulkan-validationlayers-dev spirv-tools
或sudo dnf install mesa-vulkan-devel vulkan-validation-layers-devel
:安装标准验证层和所需的 SPIR-V 工具。这些对于调试 Vulkan 应用程序至关重要,我们将在接下来的章节中讨论它们。
在 Arch Linux 上,您可以运行 sudo pacman -S vulkan-devel
来安装上面所有必需的工具。
如果安装成功,您应该已完成 Vulkan 部分的设置。请记住运行 vkcube
并确保您看到以下窗口弹出
如果您收到错误消息,请确保您的驱动程序是最新的,包括 Vulkan 运行时,并且您的显卡受支持。请参阅简介章节,其中包含主要供应商的驱动程序链接。
GLFW
如前所述,Vulkan 本身是一个平台无关的 API,不包含用于创建窗口以显示渲染结果的工具。为了利用 Vulkan 的跨平台优势并避免 X11 的恐怖之处,我们将使用 GLFW 库 来创建一个窗口,它支持 Windows、Linux 和 MacOS。还有其他库可用于此目的,例如 SDL,但 GLFW 的优势在于,除了窗口创建之外,它还抽象出 Vulkan 中其他一些特定于平台的东西。
我们将通过以下命令安装 GLFW
sudo apt install libglfw3-dev
或
sudo dnf install glfw-devel
或
sudo pacman -S glfw-wayland # glfw-x11 for X11 users
GLM
与 DirectX 12 不同,Vulkan 不包含用于线性代数运算的库,因此我们需要下载一个。GLM 是一个不错的库,专为图形 API 设计,也常用于 OpenGL。
它是一个仅包含头文件的库,可以从 libglm-dev
或 glm-devel
软件包安装
sudo apt install libglm-dev
或
sudo dnf install glm-devel
或
sudo pacman -S glm
着色器编译器
我们几乎拥有了我们需要的一切,除了我们还需要一个程序来将人类可读的 GLSL 编译为字节码。
两个流行的着色器编译器是 Khronos Group 的 glslangValidator
和 Google 的 glslc
。后者具有熟悉的类似 GCC 和 Clang 的用法,因此我们将使用它:在 Ubuntu 上,下载 Google 的 非官方二进制文件 并将 glslc
复制到您的 /usr/local/bin
。请注意,您可能需要 sudo
,具体取决于您的权限。在 Fedora 上使用 sudo dnf install glslc
,而在 Arch Linux 上运行 sudo pacman -S shaderc
。要进行测试,请运行 glslc
,它应该理所当然地抱怨我们没有传递任何要编译的着色器
glslc:错误:没有输入文件
我们将在着色器模块章节中深入介绍 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
标志 -lglfw
用于 GLFW,-lvulkan
与 Vulkan 函数加载器链接,其余标志是 GLFW 需要的底层系统库。其余标志是 GLFW 本身的依赖项:线程和窗口管理。
您的系统可能尚未安装 Xxf68vm
和 Xi
库。您可以在以下软件包中找到它们
sudo apt install libxxf86vm-dev libxi-dev
或
sudo dnf install libXi-devel libXxf86vm-devel
或
sudo pacman -S libxi libxxf86vm
现在指定编译 VulkanTest
的规则非常简单。确保使用制表符而不是空格进行缩进。
VulkanTest: main.cpp
g++ $(CFLAGS) -o VulkanTest main.cpp $(LDFLAGS)
通过保存 makefile 并在包含 main.cpp
和 Makefile
的目录中运行 make
来验证此规则是否有效。这应该会生成一个 VulkanTest
可执行文件。
我们现在将定义另外两个规则 test
和 clean
,其中前者将运行可执行文件,后者将删除已构建的可执行文件
.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 - 如果您熟悉它的话。
可以从 LunarG 网站 使用页面底部的按钮下载 SDK。您不必创建帐户,但它将使您可以访问一些可能对您有用的其他文档。
MacOS 的 SDK 版本在内部使用 MoltenVK。MacOS 上没有对 Vulkan 的原生支持,因此 MoltenVK 实际上是一个层,它将 Vulkan API 调用转换为 Apple 的 Metal 图形框架。有了这个,您可以利用 Apple Metal 框架的调试和性能优势。
下载后,只需将内容解压缩到您选择的文件夹中(请记住,在 Xcode 上创建项目时需要引用它)。在解压缩的文件夹中,在 Applications
文件夹中,您应该有一些可执行文件,这些文件将使用 SDK 运行一些演示程序。运行 vkcube
可执行文件,您将看到以下内容
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。
选择 下一步
,为项目编写一个名称,并为 Language
选择 C++
。
按 下一步
,项目应该已经创建。现在,将生成的 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 应该已经显示一些错误,例如找不到库。我们现在将开始配置项目以消除这些错误。在项目导航器面板上,选择您的项目。打开构建设置选项卡,然后
- 找到 Header Search Paths 字段,并添加指向
/usr/local/include
的链接(这是 Homebrew 安装头文件的位置,因此 glm 和 glfw3 头文件应该在那里)以及指向vulkansdk/macOS/include
的 Vulkan 头文件的链接。 - 找到 Library Search Paths 字段,并添加指向
/usr/local/lib
的链接(同样,这是 Homebrew 安装库的位置,因此 glm 和 glfw3 lib 文件应该在那里)以及指向vulkansdk/macOS/lib
的链接。
它应该看起来像这样(显然,路径会因您放置文件的位置而异)
现在,在构建阶段选项卡上,在 Link Binary With Libraries 中,我们将添加 glfw3
和 vulkan
框架。为了使事情更容易,我们将动态库添加到项目中(如果您想使用静态框架,可以查看这些库的文档)。
- 对于 glfw,打开文件夹
/usr/local/lib
,您将在其中找到一个文件名,例如libglfw.3.x.dylib
(“x”是库的版本号,根据您从 Homebrew 下载软件包的时间,它可能会有所不同)。只需将该文件拖到 Xcode 上的 Linked Frameworks and Libraries 选项卡。 - 对于 vulkan,转到
vulkansdk/macOS/lib
。对libvulkan.1.dylib
和libvulkan.1.x.xx.dylib
这两个文件执行相同的操作(其中“x”将是您下载的 SDK 的版本号)。
添加这些库后,在同一选项卡上的 Copy Files 中,将 Destination
更改为“Frameworks”,清除子路径,然后取消选择“Copy only when installing”。单击“+”号,并将所有这三个框架也添加到此处。
您的 Xcode 配置应如下所示
您需要设置的最后一件事是几个环境变量。在 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
它应该看起来像这样
最后,您应该一切就绪!现在,如果您运行项目(记住将构建配置设置为 Debug 或 Release,具体取决于您选择的配置),您应该看到以下内容
扩展的数量应该是非零的。其他日志来自库,您可能会从这些库中获得不同的消息,具体取决于您的配置。
您现在已准备好开始真正的开始。