diff --git a/cmake/Modules/AXBuildHelpers.cmake b/cmake/Modules/AXBuildHelpers.cmake index 827bae8b73..19903e9c72 100644 --- a/cmake/Modules/AXBuildHelpers.cmake +++ b/cmake/Modules/AXBuildHelpers.cmake @@ -588,3 +588,84 @@ macro(ax_config_pred target_name pred) target_compile_definitions(${target_name} PUBLIC ${pred}=1) endif() endmacro() + +# glslcc +find_program(GLSLCC_EXE NAMES glslcc + PATHS ${_AX_ROOT_PATH}/tools/external/glslcc +) + +if (NOT GLSLCC_EXE) + message("glslcc not found.") + message(FATAL_ERROR "Please run setup.ps1 again to download glslcc, and run CMake again.") +endif() + +# This function allow make shader files (.frag, .vert) compiled with glslcc +# usage: +# - ax_add_shader(${FILE}): output compiled shader to ${CMAKE_BINARY_DIR}/runtime/shaders/${SC_LANG}/xxx_fs.bin +# - ax_add_shader(${FILE} CUSTOM): output compiled shader to ${CMAKE_BINARY_DIR}/runtime/shaders/${SC_LANG}/xxx_fs.bin +# - ax_add_shader(${FILE} CVAR): the shader will compiled to c hex header for embed include by C/C++ use +function (ax_add_shader FILE) + set(options CUSTOM CVAR) + cmake_parse_arguments(opt "${options}" "" "" ${ARGN}) + + get_filename_component(FILE_EXT ${FILE} LAST_EXT) + get_filename_component(FILE_NAME ${FILE} NAME_WE) + string(TOLOWER "${FILE_EXT}" FILE_EXT) + + # silent when compile shader success + set(SC_FLAGS "--silent") + + # shader lang + if(NOT opt_CUSTOM) + set(SHADER_CATALOG "runtime") + else() + set(SHADER_CATALOG "custom") + endif() + if(ANDROID OR WINRT OR AX_USE_ANGLE) + # version 300 es + set(OUT_DIR "${CMAKE_BINARY_DIR}/${SHADER_CATALOG}/shaders/essl") + set(OUT_LANG "ESSL") + list(APPEND SC_FLAGS "--lang=gles" "--profile=300") + elseif (WIN32 OR LINUX) + # version 330 + set(OUT_DIR "${CMAKE_BINARY_DIR}/${SHADER_CATALOG}/shaders/glsl") + set(OUT_LANG "GLSL") + list(APPEND SC_FLAGS "--lang=glsl" "--profile=330") + elseif (APPLE) + set(OUT_DIR "${CMAKE_BINARY_DIR}/${SHADER_CATALOG}/shaders/msl") + set(OUT_LANG "MSL") + list(APPEND SC_FLAGS "--lang=msl" "--defines=METAL") + endif() + + # input + if (FILE_EXT STREQUAL ".frag") + list(APPEND SC_FLAGS "--frag=${FILE}") + set(TYPE "fs") + elseif(FILE_EXT STREQUAL ".vert") + set(TYPE "vs") + list(APPEND SC_FLAGS "--vert=${FILE}") + else() + message(FATAL_ERROR "Invalid shader source, the file extesion must be one of .frag;.vert") + endif() + + # output + file(MAKE_DIRECTORY ${OUT_DIR}) + if (NOT opt_CVAR) + list(APPEND SC_FLAGS "--output=${OUT_DIR}/${FILE_NAME}.bin" ) + + # glscc will auto insert ${FILE_NAME}_vs.bin or ${FILE_NAME}_fs.bin + # so we set OUTPUT to match with it, otherwise will cause cause incremental build to work incorrectly. + set(OUTPUT_FILE "${OUT_DIR}/${FILE_NAME}_${TYPE}.bin") + else() + set(OUTPUT_FILE "${OUT_DIR}/${FILE_NAME}_${TYPE}.bin.h") + list(APPEND SC_FLAGS "${OUT_FILE}" "--cvar=shader_rt_${FILE_NAME}" "--output=${OUTPUT_FILE}") + endif() + + # "Compiling ${SHADER_CATALOG} shader ${FILE} for ${OUT_LANG} ..." + set(compileCmdLine ${GLSLCC_EXE} ${SC_FLAGS}) + string(REPLACE ";" " " SC_COMMENT "${compileCmdLine} ...") + add_custom_command( + MAIN_DEPENDENCY ${FILE} OUTPUT ${OUTPUT_FILE} COMMAND ${compileCmdLine} + COMMENT "${SC_COMMENT}" + ) +endfunction()