一个跨平台的Vulkan渲染器
A cross platform vulkan renderer
-
- 【Vulkan渲染引擎 31 支持Windows平台+运行环境配置】
- https://www.bilibili.com/video/BV13v421C7hq
-
- 【Vulkan渲染引擎 32 Linux平台运行环境配置】
- https://www.bilibili.com/video/BV1VW421N7j9
git clone https://github.com/HeaoYe/Match
cd Match
git submodule update --init --recursive
cd thirdparty/glslang
python ./update_glslang_sources.py
- 用VSCode打开Match
- Windows需要修改CMakeLists.txt第86行,修改为set(BASH_EXECUTABLE "你安装的Git中的bash.exe的完整路径")
- F7编译
- 点击左侧Run And Debug按钮
- 选择要运行的程序
- F5运行
- VSCode默认会在程序抛出异常时中断
- 但是Vulkan的C++API在需要重建交换链时也会抛异常
- 导致窗口大小改变时,程序会中断
- 取消勾选 C++: on throw 即可
- 新建MyProject文件夹并进入
mkdir MyProject
cd MyProject
- 克隆Match并根据上述步骤初始化仓库
- 在MyProject文件夹下,新建CMakeLists.txt
cmake_minimum_required(VERSION 3.27)
project(MyProject)
# 不构建案例代码
set(MATCH_BUILD_EXAMPLES OFF)
if (WIN32)
# set(BASH_EXECUTABLE "你安装的Git中的bash.exe的完整路径")
# 如果你把xxx\Git\bin加入了环境变量,可以省略这步
# * 注意!如果你的Windows启用了Linux子系统功能
# * 那么C:\Windows\System32目录下会有bash.exe文件
# * 这种情况下无论如何都不能省略这步
set(BASH_EXECUTABLE "D:\\Git\\bin\\bash.exe")
endif()
add_subdirectory(Match)
add_executable(MyProject main.cpp)
target_link_libraries(MyProject Match)
if (WIN32)
# COPYDLL(TARGET_NAME 在当前CMakeLists.txt的目录下,与Match仓库的相对路径)
COPYDLL(MyProject ./Match)
endif()
- 在MyProject文件夹下,新建main.cpp
#include <Match/Match.hpp>
int main() {
// +++ 初始化Match
auto &ctx = Match::Initialize();
// +++ GameLoop
while (Match::window->is_alive()) {
// +++ 处理事件
Match::window->poll_events();
}
// +++ 销毁Match
Match::Destroy();
return 0;
}
#include <Match/Match.hpp>
int main() {
// 初始化Match
auto &ctx = Match::Initialize();
{
// +++ 创建资源工厂
auto factory = ctx.create_resource_factory("");
// +++ 启用8xMSAA抗锯齿
Match::runtime_setting->set_multisample_count(Match::SampleCount::e8);
// +++ 创建RenderPass
auto render_pass_builder = factory->create_render_pass_builder();
auto &main_subpass = render_pass_builder->add_subpass("Main Subpass");
main_subpass.attach_output_attachment(Match::SWAPCHAIN_IMAGE_ATTACHMENT);
// +++ 创建Renderer
auto renderer = factory->create_renderer(render_pass_builder);
// +++ 设置背景颜色
renderer->set_clear_value(Match::SWAPCHAIN_IMAGE_ATTACHMENT, { { 0.3f, 0.7f, 0.4f, 1.0f } });
// GameLoop
while (Match::window->is_alive()) {
// 处理事件
Match::window->poll_events();
// +++ 开始渲染
renderer->begin_render();
// +++ 结束渲染
renderer->end_render();
}
// +++ 等待销毁
renderer->wait_for_destroy();
}
// 销毁Match
Match::Destroy();
return 0;
}
#include <Match/Match.hpp>
// +++
#include <imgui.h>
int main() {
// +++ 设置字体大小
Match::setting.font_size = 30.0f;
// 初始化Match
auto &ctx = Match::Initialize();
{
// 创建资源工厂
auto factory = ctx.create_resource_factory("");
// 启用8xMSAA抗锯齿
Match::runtime_setting->set_multisample_count(Match::SampleCount::e8);
// 创建RenderPass
auto render_pass_builder = factory->create_render_pass_builder();
auto &main_subpass = render_pass_builder->add_subpass("Main Subpass");
main_subpass.attach_output_attachment(Match::SWAPCHAIN_IMAGE_ATTACHMENT);
// 创建Renderer
auto renderer = factory->create_renderer(render_pass_builder);
// +++ 附加ImGui渲染层
renderer->attach_render_layer<Match::ImGuiLayer>("My ImGui Layer");
// 设置背景颜色
renderer->set_clear_value(Match::SWAPCHAIN_IMAGE_ATTACHMENT, { { 0.3f, 0.7f, 0.4f, 1.0f } });
// GameLoop
while (Match::window->is_alive()) {
// 处理事件
Match::window->poll_events();
// 开始渲染
renderer->begin_render();
// +++ 开始My ImGui Layer渲染
renderer->begin_layer_render("My ImGui Layer");
// +++ 绘制ImGui
ImGui::Begin("My First Frame");
ImGui::Text("Hello World !");
ImGui::End();
// +++ 结束My ImGui Layer渲染
renderer->end_layer_render("My ImGui Layer");
// 结束渲染
renderer->end_render();
}
// 等待销毁
renderer->wait_for_destroy();
}
// 销毁Match
Match::Destroy();
return 0;
}
#include <Match/Match.hpp>
#include <imgui.h>
int main() {
// 设置字体大小
Match::setting.font_size = 30.0f;
// 初始化Match
auto &ctx = Match::Initialize();
{
// 创建资源工厂
auto factory = ctx.create_resource_factory("");
// 启用8xMSAA抗锯齿
Match::runtime_setting->set_multisample_count(Match::SampleCount::e8);
// 创建RenderPass
auto render_pass_builder = factory->create_render_pass_builder();
auto &main_subpass = render_pass_builder->add_subpass("Main Subpass");
main_subpass.attach_output_attachment(Match::SWAPCHAIN_IMAGE_ATTACHMENT);
// 创建Renderer
auto renderer = factory->create_rende
8000
rer(render_pass_builder);
// 附加ImGui渲染层
renderer->attach_render_layer<Match::ImGuiLayer>("My ImGui Layer");
// 设置背景颜色
renderer->set_clear_value(Match::SWAPCHAIN_IMAGE_ATTACHMENT, { { 0.3f, 0.7f, 0.4f, 1.0f } });
// +++ 从字符串编译 顶点着色器
auto vert_shader = factory->compile_shader_from_string(
"#version 450\n"
"void main() {\n"
" vec2 pos = vec2(-0.8, -0.5);\n"
" if (gl_VertexIndex == 1) pos = vec2(0.8, -0.5);\n"
" if (gl_VertexIndex == 2) pos = vec2(0, 0.5);\n"
" gl_Position = vec4(pos, 0, 1);\n"
"}",
Match::ShaderStage::eVertex
);
// +++ 从字符串编译 片段着色器
auto frag_shader = factory->compile_shader_from_string(
"#version 450\n"
"layout (location = 0) out vec4 out_color;\n"
"void main() {\n"
" out_color = vec4(0.1, 0.3, 0.8, 1);\n"
"}",
Match::ShaderStage::eFragment
);
// +++ 创建着色器程序
auto shader_program = factory->create_shader_program(renderer, "Main Subpass");
// +++ 附加顶点着色器
shader_program->attach_vertex_shader(vert_shader);
// +++ 附加片段着色器
shader_program->attach_fragment_shader(frag_shader);
// +++ 编译着色器程序,禁用三角形剔除
shader_program->compile({
.cull_mode = Match::CullMode::eNone
});
// GameLoop
while (Match::window->is_alive()) {
// 处理事件
Match::window->poll_events();
// 开始渲染
renderer->begin_render();
// +++ 绑定着色器程序并绘制三角形
renderer->bind_shader_program(shader_program);
renderer->draw(3, 1, 0, 0);
// 开始My ImGui Layer渲染
renderer->begin_layer_render("My ImGui Layer");
// 绘制ImGui
ImGui::Begin("My First Frame");
ImGui::Text("Hello World !");
ImGui::End();
// 结束My ImGui Layer渲染
renderer->end_layer_render("My ImGui Layer");
// 结束渲染
renderer->end_render();
}
// 等待销毁
renderer->wait_for_destroy();
}
// 销毁Match
Match::Destroy();
return 0;
}
- Win+r 输入cmd
- 在cmd输入
python --version
- 如果输出python版本信息,说明python安装成功
- 建议python版本 >= 3.7
- 点击Download
- 下载Windows x64 ZIP cmake-x.xx.x-rc1-windows-x86_64.zip
- 解压到一个文件夹中并记住
- 下载最新的Release版Clang+LLVM: clang+llvm-xx.x.x-x86_64-pc-windows-msvc.tar.xz
- 解压到一个文件夹中并记住
- 点击Downloads
- 点击Windows
- 点击64-bit Git for Windows Setup.
- 运行安装程序,一直Next就行,记得设置安装位置并记下来
- 也可以根据自己的需求进行配置
- 点击SDK
- 下载并运行 VulkanSDK-x.x.xxx.x-Installer.exe (160MB)
- 设置安装位置并记下来
- 根据需求选择要安装的组件
- 设置 -> 系统 -> 关于 -> 高级系统设置 -> 环境变量
- 需要在Path中添加 CMake的bin目录 & Clang+LLVM的bin目录 & VulkanSDK的Bin目录
- CMake的bin目录:
例如
E:\CMake\cmake-3.29.0-rc1-windows-x86_64\bin
- Clang+LLVM的bin目录:
例如
E:\clang+llvm-18.1.8-x86_64-pc-windows-msvc\bin
- VulkanSDK的Bin目录:
例如
E:\VulkanSDK\1.3.275.0\Bin
- 点击新建 -> 输入路径 -> 点击上移 移动到最上面
- 设置好后,Win+r 输入cmd
- 输入命令验证安装是否成功
cmake --version
clang --version
clang++ --version
vkcube
sudo pacman -S code vulkan-devel cmake clang git python
- 安装插件
- CMake
- CMake Tools
- CodeLLDB
- clangd
- Gruvbox Theme (可选)
- Markdown Preview (可选)
- 配置插件
- 进入Settings界面
- 搜索clangd
- 找到Clangd:Arguments
- 点击Add Item 分别添加两项
- --compile-commands-dir=build
- --header-insertion=never
- 如何编译
- 按F7编译带有CMakeLists.txt的项目。
- 如果按F7没反应,确认打开的文件夹中有CMakeLists.txt,然后重启VSCode
- 第一次编译需要选择C++编译器,Windows和Linux用户统一选择Clang
- 如何运行
- 在项目的CPP文件或头文件中,按F5运行
- 第一次运行会生成.vscode/launch.json
- 按照需求填写就行
{ "version": "0.2.0", "configurations": [ { "type": "lldb", "request": "launch", "name": "Debug", "program": "${workspaceFolder}/可执行文件", "args": [], "cwd": "${workspaceFolder}/可执行文件运行目录" } ] }