下載學(xué)習(xí)的Demo
toy2d參考視頻在Windows環(huán)境下運行Demo
【Vulkan 入門-補】在Windows下安裝Vulkan
要注意的點:
a. 下載SDL時,要下載的包是SDL2-devel-2.0.22-VC,即用于開發(fā)用途,或者就在安裝Vulkan的時候勾選上SDL2的選項,對把SDL2的相關(guān)文件分別下載到指定位置
b. CMake清緩存的話cmake-build和build文件夾都要刪,或者用這篇文章里的方法:
CMake的變量與緩存(大坑點)CMake配置的知識
# FindSDL2.cmake
if (NOT TARGET SDL2) # 是否已經(jīng)存在名為SDL2的TARGET
if (WIN32) # Windows, use clang or MSVC
#設(shè)置SDL2庫的根目錄路徑,并使用`CACHE`關(guān)鍵字將其緩存起來,以便用戶可以通過CMake的GUI或命令行工具進(jìn)行配置。這個路徑是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
# 可執(zhí)行文件或者共享庫的位置,比如dll動態(tài)庫。無編譯信息,運行時使用,動態(tài)鏈接
IMPORTED_LOCATION "${SDL2_LIB_DIR}/SDL2.dll"
# 導(dǎo)入庫位置 一般用于window上配置.lib靜態(tài)庫。有編譯信息可以用于調(diào)試代碼,靜態(tài)鏈接
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)[http://www.itdecent.cn/p/07761ff7838e]
target_link_libraries(SDL2 INTERFACE SDL2::SDL2 SDL2::SDL2main)
else() # Linux, MacOSX
#查找并指定 SDL2 庫的位置和相關(guān)配置信息,失敗時不生成錯誤消息
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的庫,作為導(dǎo)入庫,如未找到則報錯,
pkg_check_modules(SDL2 sdl2 REQUIRED IMPORTED_TARGET)
add_library(SDL2 ALIAS PkgConfig::SDL2)
endif()
endif()
endif()
CopyFiles.cmake
# 定義宏對象CopyDLL 的參數(shù)名為target_name
macro(CopyDLL target_name)
if (WIN32)
add_custom_command(
#執(zhí)行命令的時機是target_name 構(gòu)建后
TARGET ${target_name} POST_BUILD
# CMAKE_COMMAND表示當(dāng)前CMake可執(zhí)行文件列表的根路徑,-E表示執(zhí)行CMake內(nèi)置命令,即后面的copy命令。TARGET_FILE_DIR表示當(dāng)前target生成的文件路徑,是絕對路徑,與TARGET_FILE相比是不包括文件名,比如當(dāng)前target里的RUNTIME_OUTPUT_DIRECTORY設(shè)置。冒號表示從屬關(guān)系
# 尖括號表示是CMake的系統(tǒng)變量,大括號表示是用戶自定義的變量
COMMAND ${CMAKE_COMMAND} -E copy ${SDL2_ROOT}/lib/x64/SDL2.dll $<TARGET_FILE_DIR:${target_name}>
# 打印結(jié)果為: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
#創(chuàng)建一個名為sandbox的可執(zhí)行文件
add_executable(sandbox)
#在當(dāng)前目錄下查找所有的源文件,并將它們存儲在SANDBOX_SRC中
aux_source_directory(./ SANDBOX_SRC)
# SANDBOX_SRC作為sandbox目標(biāo)的源文件,為不暴露給外面的私有文件
target_sources(sandbox PRIVATE ${SANDBOX_SRC})
# 表示sandbox 會依賴toy2d 和SDL2庫
target_link_libraries(sandbox PUBLIC toy2d SDL2)
#執(zhí)行宏命令
CopyDLL(sandbox)
CopyShader(sandbox)
CopyTexture(sandbox)
# 根目錄的CMakeLists.cmake
cmake_minimum_required(VERSION 3.15)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# 設(shè)置項目名稱和使用的語言
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 指定編譯后文件名稱,不設(shè)置的話輸出的文件名為名稱+".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 為靜態(tài)庫,靜態(tài)庫的文件大小比動態(tài)庫大,可以獨立運行,不像動態(tài)庫可能會依賴其他動態(tài)庫
add_library(toy2d STATIC ${SRC})
# 將當(dāng)前目錄添加到toy2d庫的包含目錄中
target_include_directories(toy2d PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(toy2d PUBLIC Vulkan::Vulkan)
# 設(shè)置toy2d庫的編譯特性為C++17,以便在編譯時可以使用C++17的新特性
target_compile_features(toy2d PUBLIC cxx_std_17)
# 指定一個子目錄,子目錄下應(yīng)該包含CMakeLists.txt文件和代碼文件。未跟隨輸出目錄,則輸出目錄也為構(gòu)建目錄sandbox
add_subdirectory(sandbox)
在終端構(gòu)建 CMake 項目的命令
#配置 CMake 項目。其中 `-S .` 表示源代碼目錄為當(dāng)前目錄,`-B cmake-build` 表示構(gòu)建目錄為 `cmake-build` 文件夾。通過這個命令,CMake 會根據(jù)項目中的 CMakeLists.txt 文件來生成構(gòu)建系統(tǒng)所需的文件
cmake -S . -B cmake-build
#執(zhí)行構(gòu)建操作。它會根據(jù)配置生成的構(gòu)建系統(tǒng)文件,使用相應(yīng)的構(gòu)建工具(如 make、ninja 等)來編譯、鏈接和生成可執(zhí)行文件或庫
cmake --build cmake-build
-
運行Demo的效果:
屏幕截圖 2023-11-03 171148.png
