From fbb01724a4d8bbbe0bdd678442d6589d4da59928 Mon Sep 17 00:00:00 2001 From: Nanako <469449812@qq.com> Date: Mon, 19 Feb 2024 21:17:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=87=AA=E5=8A=A8=E5=8C=96?= =?UTF-8?q?=E7=BC=96=E8=AF=91shader?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 35 +++++++++++++++++++ cmake/GenerateShaderCPPFile.cmake | 25 ++++++++++++++ core/CMakeLists.txt | 56 ------------------------------- 3 files changed, 60 insertions(+), 56 deletions(-) create mode 100644 cmake/GenerateShaderCPPFile.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 78f7959..752c88a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,41 @@ function(retrieve_files out_files) set(${out_files} ${RESULT} PARENT_SCOPE) endfunction() +set(SHADER_CPP_GENERATED_CMAKE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateShaderCPPFile.cmake" CACHE STRING "" FORCE) + +function(compile_shader TARGET_NAME OUTPUT SHADER_INCLUDE_DIR) + set(working_dir "${CMAKE_CURRENT_SOURCE_DIR}") + set(GLSLANG_BIN $ENV{VULKAN_SDK}/Bin/glslangValidator.exe) # 设置glslangValidator的位置 + set(ALL_SHADER_FILE "") + # get files in SHADER_INCLUDE_DIR + file(GLOB_RECURSE ALL_SHADER_FILE "${SHADER_INCLUDE_DIR}/*.vert" "${SHADER_INCLUDE_DIR}/*.frag" "${SHADER_INCLUDE_DIR}/*.comp" "${SHADER_INCLUDE_DIR}/*.tesc" "${SHADER_INCLUDE_DIR}/*.tese" "${SHADER_INCLUDE_DIR}/*.geom") + + + foreach(SHADER ${ALL_SHADER_FILE}) # 遍历每一个shader源文件 + get_filename_component(SHADER_NAME ${SHADER} NAME) # 获取shader的名字 + string(REPLACE "." "_" HEADER_NAME ${SHADER_NAME}) # 在生成的.h文件中将文件名的'.'换成'_' + string(TOUPPER ${HEADER_NAME} GLOBAL_SHADER_VAR) # 将存储二进制内容的全局vector对象名改为全部大写 + set(SPV_FILE "${OUTPUT}/spv/${SHADER_NAME}.spv") # 生成的.spv文件 + set(CPP_FILE "${OUTPUT}/cpp/${HEADER_NAME}.h") # 生成的.h文件 + add_custom_command( + OUTPUT ${SPV_FILE} + COMMAND ${GLSLANG_BIN} -I${SHADER_INCLUDE_DIR} -V100 -o ${SPV_FILE} ${SHADER} + DEPENDS ${SHADER} + WORKING_DIRECTORY "${working_dir}") # 添加编译命令,在项目生成时执行 + list(APPEND ALL_GENERATED_SPV_FILES ${SPV_FILE}) + add_custom_command( + OUTPUT ${CPP_FILE} + COMMAND ${CMAKE_COMMAND} -DPATH=${SPV_FILE} -DHEADER="${CPP_FILE}" + -DGLOBAL="${GLOBAL_SHADER_VAR}" -P "${SHADER_CPP_GENERATED_CMAKE}" + DEPENDS ${SPV_FILE} + WORKING_DIRECTORY "${working_dir}") # 添加执行将spv转换为h文件的cmake函数的命令 + list(APPEND ALL_GENERATED_CPP_FILES ${CPP_FILE}) + endforeach() + add_custom_target(${TARGET_NAME} # 将上述过程添加到一个生成目标中 + DEPENDS ${ALL_GENERATED_SPV_FILES} ${ALL_GENERATED_CPP_FILES} SOURCES ${SHADERS}) +endfunction() + + add_subdirectory(core) add_subdirectory(third_party/imgui) add_subdirectory(third_party/portaudio) diff --git a/cmake/GenerateShaderCPPFile.cmake b/cmake/GenerateShaderCPPFile.cmake new file mode 100644 index 0000000..9a89ef3 --- /dev/null +++ b/cmake/GenerateShaderCPPFile.cmake @@ -0,0 +1,25 @@ +function(embed_resource resource_file_name source_file_name variable_name) + if(EXISTS "${source_file_name}") + if("${source_file_name}" IS_NEWER_THAN "${resource_file_name}") + return() + endif() + endif() + if(EXISTS "${resource_file_name}") + file(REMOVE "${source_file_name}") + file(READ "${resource_file_name}" hex_content HEX) + string(REPEAT "[0-9a-f]" 32 pattern) + string(REGEX REPLACE "(${pattern})" "\\1\n" content "${hex_content}") + string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " content "${content}") + string(REGEX REPLACE ", $" "" content "${content}") + set(array_definition "static const uint8_t ${variable_name} []=\n{\n${content}\n};") + get_filename_component(file_name ${source_file_name} NAME) + set(source "#pragma once\n/**\n * @file ${file_name}\n * @brief Auto generated file.\n */\n${array_definition}\n") + file(WRITE "${source_file_name}" "${source}") + else() + message("ERROR: ${resource_file_name} doesn't exist") + return() + endif() +endfunction() +if(EXISTS "${PATH}") + embed_resource("${PATH}" "${HEADER}" "${GLOBAL}") +endif() \ No newline at end of file diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 881362e..11a7666 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -15,59 +15,3 @@ target_link_libraries(${PROJECT_NAME} PUBLIC imgui spdlog glfw) target_precompile_headers(${PROJECT_NAME} PUBLIC extern.h) add_definitions(-Dcore_EXPORTS -DSTB_IMAGE_IMPLEMENTATION -DSTBI_WINDOWS_UTF8) - -function(compile_shader TARGET_NAME OUTPUT SHADER_INCLUDE_DIR) - set(working_dir "${CMAKE_CURRENT_SOURCE_DIR}") - set(GLSLANG_BIN $ENV{VULKAN_SDK}/Bin/glslangValidator.exe) # 设置glslangValidator的位置 - set(ALL_SHADER_FILE "") - # get files in SHADER_INCLUDE_DIR - file(GLOB_RECURSE ALL_SHADER_FILE "${SHADER_INCLUDE_DIR}/*.vert" "${SHADER_INCLUDE_DIR}/*.frag" "${SHADER_INCLUDE_DIR}/*.comp" "${SHADER_INCLUDE_DIR}/*.tesc" "${SHADER_INCLUDE_DIR}/*.tese" "${SHADER_INCLUDE_DIR}/*.geom") - - foreach(SHADER ${ALL_SHADER_FILE}) # 遍历每一个shader源文件 - get_filename_component(SHADER_NAME ${SHADER} NAME) # 获取shader的名字 - string(REPLACE "." "_" HEADER_NAME ${SHADER_NAME}) # 在生成的.h文件中将文件名的'.'换成'_' - string(TOUPPER ${HEADER_NAME} GLOBAL_SHADER_VAR) # 将存储二进制内容的全局vector对象名改为全部大写 - set(SPV_FILE "${OUTPUT}/spv/${SHADER_NAME}.spv") # 生成的.spv文件 - set(CPP_FILE "${OUTPUT}/cpp/${HEADER_NAME}.h") # 生成的.h文件 - add_custom_command( - OUTPUT ${SPV_FILE} - COMMAND ${GLSLANG_BIN} -I${SHADER_INCLUDE_DIR} -V100 -o ${SPV_FILE} ${SHADER} - DEPENDS ${SHADER} - WORKING_DIRECTORY "${working_dir}") # 添加编译命令,在项目生成时执行 - list(APPEND ALL_GENERATED_SPV_FILES ${SPV_FILE}) - add_custom_command( - OUTPUT ${CPP_FILE} - COMMAND ${CMAKE_COMMAND} -DPATH=${SPV_FILE} -DHEADER="${CPP_FILE}" - -DGLOBAL="${GLOBAL_SHADER_VAR}" -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateShaderCPPFile.cmake" - DEPENDS ${SPV_FILE} - WORKING_DIRECTORY "${working_dir}") # 添加执行将spv转换为h文件的cmake函数的命令 - list(APPEND ALL_GENERATED_CPP_FILES ${CPP_FILE}) - endforeach() - add_custom_target(${TARGET_NAME} # 将上述过程添加到一个生成目标中 - DEPENDS ${ALL_GENERATED_SPV_FILES} ${ALL_GENERATED_CPP_FILES} SOURCES ${SHADERS}) -endfunction() -# GenerateShaderCPPFile.cmake -function(embed_resource resource_file_name source_file_name variable_name) - if(EXISTS "${source_file_name}") - if("${source_file_name}" IS_NEWER_THAN "${resource_file_name}") - return() - endif() - endif() - if(EXISTS "${resource_file_name}") - file(READ "${resource_file_name}" hex_content HEX) - string(REPEAT "[0-9a-f]" 32 pattern) - string(REGEX REPLACE "(${pattern})" "\\1\n" content "${hex_content}") - string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " content "${content}") - string(REGEX REPLACE ", $" "" content "${content}") - set(array_definition "static const std::vector ${variable_name} =\n{\n${content}\n};") - get_filename_component(file_name ${source_file_name} NAME) - set(source "/**\n * @file ${file_name}\n * @brief Auto generated file.\n */\n#include \n${array_definition}\n") - file(WRITE "${source_file_name}" "${source}") - else() - message("ERROR: ${resource_file_name} doesn't exist") - return() - endif() -endfunction() -if(EXISTS "${PATH}") - embed_resource("${PATH}" "${HEADER}" "${GLOBAL}") -endif() \ No newline at end of file