Vulkan入门- Demo项目构建
2023-11-05 本文已影响0人
hjm1fb
-
下载学习的Demo
toy2d -
参考视频在Windows环境下运行Demo
【Vulkan 入门-补】在Windows下安装Vulkan
要注意的点:
a. 下载SDL时,要下载的包是SDL2-devel-2.0.22-VC,即用于开发用途,或者就在安装Vulkan的时候勾选上SDL2的选项,对把SDL2的相关文件分别下载到指定位置
b. CMake清缓存的话cmake-build和build文件夹都要删,或者用这篇文章里的方法:
CMake的变量与缓存(大坑点) -
CMake配置的知识
# FindSDL2.cmake
if (NOT TARGET SDL2) # 是否已经存在名为SDL2的TARGET
if (WIN32) # Windows, use clang or MSVC
#设置SDL2库的根目录路径,并使用`CACHE`关键字将其缓存起来,以便用户可以通过CMake的GUI或命令行工具进行配置。这个路径是SDL2库的安装路径
set(SDL2_ROOT "D:/3rd_party_libs/SDL2-devel-2.0.22-VC/SDL2-2.0.22" CACHE PATH "SDL2 root directory")
set(SDL2_INCLUDE_DIR "${SDL2_ROOT}/include")
set(SDL2_LIB_DIR "${SDL2_ROOT}/lib/x64")
# SDL2::SDL2是引入的共享库(SHARED IMPORTED ),可以在整个项目中使用(GLOBAL)
add_library(SDL2::SDL2 SHARED IMPORTED GLOBAL)#
set_target_properties(
SDL2::SDL2
PROPERTIES
# 可执行文件或者共享库的位置,比如dll动态库。无编译信息,运行时使用,动态链接
IMPORTED_LOCATION "${SDL2_LIB_DIR}/SDL2.dll"
# 导入库位置 一般用于window上配置.lib静态库。有编译信息可以用于调试代码,静态链接
IMPORTED_IMPLIB "${SDL2_LIB_DIR}/SDL2.lib"
# 库接口的include文件位置
INTERFACE_INCLUDE_DIRECTORIES ${SDL2_INCLUDE_DIR}
)
add_library(SDL2::SDL2main SHARED IMPORTED GLOBAL)
set_target_properties(
SDL2::SDL2main
PROPERTIES
IMPORTED_LOCATION "${SDL2_LIB_DIR}/SDL2.dll"
IMPORTED_IMPLIB "${SDL2_LIB_DIR}/SDL2main.lib"
INTERFACE_INCLUDE_DIRECTORIES ${SDL2_INCLUDE_DIR}
)
# 接口库,这类库不编译任何文件,可以理解为抽象的接口功能
add_library(SDL2 INTERFACE IMPORTED GLOBAL)
#配置接口库的包含子对象,参考(CMake 中的 PUBLIC,PRIVATE,INTERFACE)[https://www.jianshu.com/p/07761ff7838e]
target_link_libraries(SDL2 INTERFACE SDL2::SDL2 SDL2::SDL2main)
else() # Linux, MacOSX
#查找并指定 SDL2 库的位置和相关配置信息,失败时不生成错误消息
find_package(SDL2 QUIET)
# 以库的名称(如 "SDL2")加上 "_FOUND" 后缀来表示是否找到了该库
if (SDL2_FOUND)
# 以别名SDL2代指SDL2::SDL2
add_library(SDL2 ALIAS SDL2::SDL2)
else()
find_package(PkgConfig REQUIRED)
#查找SDL2::sdl2的库,作为导入库,如未找到则报错,
pkg_check_modules(SDL2 sdl2 REQUIRED IMPORTED_TARGET)
add_library(SDL2 ALIAS PkgConfig::SDL2)
endif()
endif()
endif()
CopyFiles.cmake
# 定义宏对象CopyDLL 的参数名为target_name
macro(CopyDLL target_name)
if (WIN32)
add_custom_command(
#执行命令的时机是target_name 构建后
TARGET ${target_name} POST_BUILD
# CMAKE_COMMAND表示当前CMake可执行文件列表的根路径,-E表示执行CMake内置命令,即后面的copy命令。TARGET_FILE_DIR表示当前target生成的文件路径,是绝对路径,与TARGET_FILE相比是不包括文件名,比如当前target里的RUNTIME_OUTPUT_DIRECTORY设置。冒号表示从属关系
# 尖括号表示是CMake的系统变量,大括号表示是用户自定义的变量
COMMAND ${CMAKE_COMMAND} -E copy ${SDL2_ROOT}/lib/x64/SDL2.dll $<TARGET_FILE_DIR:${target_name}>
# 打印结果为:C:/Users/hjm1f/Documents/code/toy2d-main/cmake-build/sandbox/Debug
COMMAND ${CMAKE_COMMAND} -E echo "TARGET_FILE_DIR: $<TARGET_FILE_DIR:${target_name}>"
)
# If you have selected SDL2 component when installed Vulkan SDK, the command as follows will work
# add_custom_command(
# TARGET ${target_name} POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy ${SDL2_BIN_DIR}/SDL2.dll $<TARGET_FILE_DIR:${target_name}>)
endif()
endmacro(CopyDLL)
#sandbox.cmake
#创建一个名为sandbox的可执行文件
add_executable(sandbox)
#在当前目录下查找所有的源文件,并将它们存储在SANDBOX_SRC中
aux_source_directory(./ SANDBOX_SRC)
# SANDBOX_SRC作为sandbox目标的源文件,为不暴露给外面的私有文件
target_sources(sandbox PRIVATE ${SANDBOX_SRC})
# 表示sandbox 会依赖toy2d 和SDL2库
target_link_libraries(sandbox PUBLIC toy2d SDL2)
#执行宏命令
CopyDLL(sandbox)
CopyShader(sandbox)
CopyTexture(sandbox)
# 根目录的CMakeLists.cmake
cmake_minimum_required(VERSION 3.15)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# 设置项目名称和使用的语言
project(Toy2D
LANGUAGES CXX
DESCRIPTION "a toy 2d renderer made in vulkan")
include(cmake/FindVulkan.cmake)
include(cmake/FindSDL2.cmake)
include(cmake/CopyFiles.cmake)
#查找名为glslc的程序,并将其路径保存在变量GLSLC_PROGRAM中。如果找不到该程序,则会报错
find_program(GLSLC_PROGRAM glslc REQUIRED)
message(STATUS "run glslc to compile shaders ...")
# 编译顶点着色器,-o 指定编译后文件名称,不设置的话输出的文件名为名称+".o"
execute_process(COMMAND ${GLSLC_PROGRAM} ${CMAKE_SOURCE_DIR}/shader/shader.vert -o ${CMAKE_SOURCE_DIR}/vert.spv)
execute_process(COMMAND ${GLSLC_PROGRAM} ${CMAKE_SOURCE_DIR}/shader/shader.frag -o ${CMAKE_SOURCE_DIR}/frag.spv)
message(STATUS "compile shader OK")
aux_source_directory(src SRC)
# 编译toy2d 为静态库,静态库的文件大小比动态库大,可以独立运行,不像动态库可能会依赖其他动态库
add_library(toy2d STATIC ${SRC})
# 将当前目录添加到toy2d库的包含目录中
target_include_directories(toy2d PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(toy2d PUBLIC Vulkan::Vulkan)
# 设置toy2d库的编译特性为C++17,以便在编译时可以使用C++17的新特性
target_compile_features(toy2d PUBLIC cxx_std_17)
# 指定一个子目录,子目录下应该包含CMakeLists.txt文件和代码文件。未跟随输出目录,则输出目录也为构建目录sandbox
add_subdirectory(sandbox)
在终端构建 CMake 项目的命令
#配置 CMake 项目。其中 `-S .` 表示源代码目录为当前目录,`-B cmake-build` 表示构建目录为 `cmake-build` 文件夹。通过这个命令,CMake 会根据项目中的 CMakeLists.txt 文件来生成构建系统所需的文件
cmake -S . -B cmake-build
#执行构建操作。它会根据配置生成的构建系统文件,使用相应的构建工具(如 make、ninja 等)来编译、链接和生成可执行文件或库
cmake --build cmake-build
-
运行Demo的效果:
屏幕截图 2023-11-03 171148.png