Vulkan入門- Demo項目構(gòu)建

  • 下載學(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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容