Vulkan学习笔记1—环境搭建
一、Vulkan SDK环境配置
我在Windows11下开发,显卡是RTX2060M 6GB,IDE使用VSCode,使用CMake进行项目构建。从网站 LunarXchange 下载vulkan sdk安装,由于安装的是Windows exe,环境变量是自动设置的,如果是通过压缩包解压放到某个目录需要自行配置环境变量。
运行安装目录D:\VulkanSDK\1.4.313.2\Bin下的vkcube.exe,如果看到正常旋转的立方体表示一切OK。
二、HelloVulkan学习项目搭建
1、项目选择跨平台库GLFW作为图形显示,从网站 https://www.glfw.org/download.html 可以下载到Windows预编译的文件,也可以自己下载源码编译,我这里是之前用CMake工具编译的文件,依赖包放到extern目录下统一管理。
2、使用GLM库进行矩阵类计算,glm库是header-only库,就是只包含头文件,不需要依赖lib、dill文件,很方便,我用 git submodule add https://github.com/g-truc/glm.git extern/glm 添加 glm 子模块,这样提交代码不会把glm整个源码都提交到仓库从而节省空间和下载速度,但是clone项目时要加上参数 --recurse-submodules,忘记加参数clone的项目glm目录是空的,也可以再运行命令git submodule update --init --recursive 拉取子模块。如果嫌这样麻烦,你可以单独把glm库clone下来复制到extern目录下,但是不会自动加入当前项目的子模块管理中,提交代码时如果不在.gitignore中标记忽略会把整个子模块源码提交了。
3、使用std_image处理纹理图片读取。
4、使用CMake进行构建,满足可能的跨平台编译需求,CMake配置文件如下:
cmake_minimum_required(VERSION 3.20)
project(HelloVulkan LANGUAGES CXX C)set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)if(WIN32)set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
endif()set(EXTERNAL_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extern)
set(GLFW_ROOT ${EXTERNAL_LIB_DIR}/glfw)
set(GLM_ROOT ${EXTERNAL_LIB_DIR}/glm)file(GLOB_RECURSE SOURCE_FILES src/*.cpp src/*.c)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})target_include_directories(${PROJECT_NAME} PRIVATE${CMAKE_CURRENT_SOURCE_DIR}/include${GLM_ROOT}${EXTERNAL_LIB_DIR}${GLFW_ROOT}/include
)if(MSVC)target_compile_options(${PROJECT_NAME} PRIVATE "$<$<CONFIG:Debug>:/Zi>" "$<$<CONFIG:Debug>:/Od>")target_link_options(${PROJECT_NAME} PRIVATE "/IGNORE:4099")# Use /MDd for Debug, /MD for otherstarget_compile_options(${PROJECT_NAME} PRIVATE "$<$<CONFIG:Debug>:/MDd>" "$<$<NOT:$<CONFIG:Debug>>:/MD>")
else()target_compile_options(${PROJECT_NAME} PRIVATE "$<$<CONFIG:Debug>:-g>" "$<$<CONFIG:Debug>:-O0>")
endif()find_library(GLFW_LIB glfw3 PATHS ${GLFW_ROOT}/lib NO_DEFAULT_PATH)
if(NOT GLFW_LIB)message(FATAL_ERROR "GLFW library not found in: ${GLFW_ROOT}/lib")
endif()add_library(stb_image INTERFACE)
target_include_directories(stb_image INTERFACE ${EXTERNAL_LIB_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE stb_image)find_package(Vulkan REQUIRED)target_link_libraries(${PROJECT_NAME} PRIVATEVulkan::Vulkan${GLFW_LIB}
)set(OUTPUT_DIR $<TARGET_FILE_DIR:${PROJECT_NAME}>)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILDCOMMAND ${CMAKE_COMMAND} -E copy_directory${CMAKE_CURRENT_SOURCE_DIR}/assets/shaders${OUTPUT_DIR}/assets/shadersCOMMAND ${CMAKE_COMMAND} -E copy_directory${CMAKE_CURRENT_SOURCE_DIR}/assets${OUTPUT_DIR}/assetsCOMMENT "Copying shaders and assets to build directory..."
)
5、VSCode IDE配置
c_cpp_properties.json
{"configurations": [{"name": "Win32","includePath": ["${workspaceFolder}/**","D:/VulkanSDK/1.4.313.2/Include"],"defines": ["_DEBUG", "UNICODE", "_UNICODE"],// "compilerPath": "D:\\DevelopApps\\mingw64\\bin\\gcc.exe","compilerPath": "D:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.37.32822\\bin\\Hostx64\\x64\\cl.exe","cStandard": "c17","cppStandard": "c++20"}],"version": 4
}
tasks.json
{"version": "2.0.0","tasks": [{"label": "Build","type": "shell","command": "cmake","args": ["--build","${workspaceFolder}/build","--config","Debug","--parallel"],"group": {"kind": "build","isDefault": true},"problemMatcher": ["$gcc"],"detail": "Build Debug Configuration"},{"label": "Configure","type": "shell","command": "cmake","args": ["-S","${workspaceFolder}","-B","${workspaceFolder}/build","-G \"Visual Studio 17 2022\"",],"group": {"kind": "build","isDefault": false},"problemMatcher": ["$gcc"],"detail": "Configure the project using CMake"}]
}
launch.json
{"version": "0.2.0","configurations": [{"name": "Debug HelloVulkan","type": "cppvsdbg","request": "launch","program": "${workspaceFolder}/bin/Debug/HelloVulkan.exe","args": [],"stopAtEntry": false,"cwd": "${workspaceFolder}",}]
}
settings.json
{"nuxt.isNuxtApp": false,"cmake.sourceDirectory": "${workspaceFolder}","cmake.buildDirectory": "${workspaceFolder}/build","cmake.generator": "Ninja","cmake.configureOnOpen": true,"C_Cpp.clang_format_path": "D:/DevelopApps/clang+llvm-18.1.8-x86_64-pc-windows-msvc/bin/clang-format.exe","C_Cpp.formatting": "clangFormat","editor.formatOnSave": false,"C_Cpp.clang_format_style": "file","files.associations": {"*.tcc": "cpp","*.h": "cpp",...}
}
项目结构大致是这样:
HELLO-VULKAN
├── .vscode
├── assets
│ ├── shaders
│ └── textures
├── bin\Debug
│ ├── assets
│ ├── HelloVulkan.exe
│ └── HelloVulkan.pdb
├── build
├── extern
│ ├── glfw
│ ├── glm
│ └── stb
├── include
│ ├── common.hpp
│ └── HelloTriangle.h
├── src
│ ├── HelloTriangle.cpp
│ ├── main.cpp
│ └── stb.cpp
├── .clang-format
├── .gitignore
├── .gitmodules
├── CMakeLists.txt
├── LICENSE
└── README.md
三、编写GLFW代码显示窗口
第一个例子是用Vulkan绘制一个三角形,显示三角形需要先完成主循环窗口的渲染。下面是main.cpp代码:
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>#include <cstdlib>
#include <iostream>
#include <stdexcept>GLFWwindow* window;
const uint32_t WIDTH = 800;
const uint32_t HEIGHT = 600;/*** 初始化GLFW窗口
*/
void initWindow() {glfwInit();glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);window = glfwCreateWindow(WIDTH, HEIGHT, "Hello Vulkan", nullptr, nullptr);
}int main() {initWindow();try {// 主循环while (!glfwWindowShouldClose(window)) {glfwPollEvents();}// 销毁资源glfwDestroyWindow(window);glfwTerminate();} catch (const std::exception& e) {std::cerr << e.what() << std::endl;return EXIT_FAILURE;}return EXIT_SUCCESS;
}
按 F5 运行,可以看到一个白色的窗口了。