diff --git a/cmake/compile_shaders.cmake b/cmake/compile_shaders.cmake index 8e40426..3bd1d8f 100644 --- a/cmake/compile_shaders.cmake +++ b/cmake/compile_shaders.cmake @@ -3,14 +3,18 @@ find_program(PYTHON_EXECUTABLE python) find_program(GLSLANG_VALIDATOR glslangValidator) find_program(SLANG_COMPILER slangc) +set(SHADER_PATH_FILE ${CMAKE_CURRENT_SOURCE_DIR}/scripts/shader_paths.txt) +# 删除文件 +file(REMOVE ${SHADER_PATH_FILE}) + function(shader_compile_target INPUT_DIR) - # 将路径拼接到全局着色器路径列表中 - list(APPEND SHADER_SOURCE_DIRS ${INPUT_DIR}) + # 将路径写到scripts/shader_paths.txt中 + file(WRITE ${SHADER_PATH_FILE} ${INPUT_DIR}) endfunction() # 添加自定义命令, 用于编译着色器, 调用scripts/compile_shaders.py -add_custom_target(compile_aorii_shaders - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/compile_shaders.py --input-dir ${SHADER_SOURCE_DIRS} --output-dir ${SHADER_OUTPUT_DIR} - COMMENT "Compiling shaders" +add_custom_target(aorii_compile_shaders + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/compile_shaders.py --output-dir ${SHADER_OUTPUT_DIR} + COMMENT "Compiling shaders" VERBATIM ) diff --git a/scripts/compile_shaders.py b/scripts/compile_shaders.py index f7ec6e5..75509b1 100644 --- a/scripts/compile_shaders.py +++ b/scripts/compile_shaders.py @@ -10,15 +10,27 @@ def find_shader_files(input_dir, extensions): if any(file.endswith(ext) for ext in extensions): yield os.path.join(root, file) +def has_glsl_main(input_file): + try: + with open(input_file, 'r', encoding='utf-8') as f: + content = f.read() + return "void main" in content + except Exception as e: + print(f"Error parsing {input_file}: {str(e)}") + return False + def compile_glsl(input_file, output_dir, glslang_validator): try: + if not has_glsl_main(input_file): + print(f"Skipping {input_file}: No main function found") + return True + base = os.path.splitext(os.path.basename(input_file))[0] ext = os.path.splitext(input_file)[1][1:] - relative_path = os.path.relpath(os.path.dirname(input_file), args.input_dir) - output_subdir = os.path.join(output_dir, relative_path) - output_file = os.path.join(output_subdir, f"{base}.{ext}.spv") + abs_path = os.path.abspath(output_dir) + output_file = os.path.join(abs_path, f"{base}.{ext}.spv") - os.makedirs(output_subdir, exist_ok=True) + os.makedirs(abs_path, exist_ok=True) cmd = [glslang_validator, "-V", input_file, "-o", output_file] result = subprocess.run(cmd, check=True, capture_output=True, text=True) @@ -34,7 +46,7 @@ def compile_glsl(input_file, output_dir, glslang_validator): def find_slang_entries(input_file): try: - with open(input_file, 'r') as f: + with open(input_file, 'r', encoding='utf-8') as f: content = f.read() pattern = r'\[shader\(\s*"(?:\w+)"\s*\)\]\s*\n\s*\w+\s+(\w+)\s*\(' return list(set(re.findall(pattern, content))) @@ -46,17 +58,18 @@ def compile_slang(input_file, output_dir, slangc): try: entries = find_slang_entries(input_file) if not entries: - print(f"No entries found in {input_file}") - return False + print(f"Skipping {input_file}: No shader entries found") + return True base = os.path.splitext(os.path.basename(input_file))[0] - relative_path = os.path.relpath(os.path.dirname(input_file), args.input_dir) - output_subdir = os.path.join(output_dir, relative_path) - os.makedirs(output_subdir, exist_ok=True) + + abs_path = os.path.abspath(output_dir) + + os.makedirs(abs_path, exist_ok=True) success = True for entry in entries: - output_file = os.path.join(output_subdir, f"{base}_{entry}.spv") + output_file = os.path.join(abs_path, f"{base}_{entry}.spv") cmd = [slangc, input_file, "-entry", entry, "-o", output_file, "-target", "spirv"] try: subprocess.run(cmd, check=True, capture_output=True, text=True) @@ -72,26 +85,32 @@ def compile_slang(input_file, output_dir, slangc): def main(): parser = argparse.ArgumentParser(description="Compile shaders to SPIR-V") - parser.add_argument("--input-dir", required=True, help="Input directory containing shaders") - parser.add_argument("--output-dir", required=True, help="Output directory for SPIR-V files") + parser.add_argument("--output-dir", help="Output directory for SPIR-V files") parser.add_argument("--glslang", default="glslangValidator", help="Path to glslangValidator") parser.add_argument("--slangc", default="slangc", help="Path to slangc") args = parser.parse_args() + output_dir = args.output_dir or "shaders" + + # 读取当前同级目录下的shader_paths.txt + with open("shader_paths.txt", 'r') as f: + shader_paths = f.readlines() + glsl_ext = [".vert", ".frag", ".comp", ".geom", ".tesc", ".tese", ".glsl"] slang_ext = [".slang"] all_success = True - # Compile GLSL - for file in find_shader_files(args.input_dir, glsl_ext): - if not compile_glsl(file, args.output_dir, args.glang): - all_success = False + for shader_path in shader_paths: + # Compile GLSL + for file in find_shader_files(shader_path, glsl_ext): + if not compile_glsl(file, output_dir, args.glslang): + all_success = False - # Compile Slang - for file in find_shader_files(args.input_dir, slang_ext): - if not compile_slang(file, args.output_dir, args.slangc): - all_success = False + # Compile Slang + for file in find_shader_files(shader_path, slang_ext): + if not compile_slang(file, output_dir, args.slangc): + all_success = False if not all_success: sys.exit(1) diff --git a/src/core/shader/SDF.slang b/src/core/shaders/SDF.slang similarity index 98% rename from src/core/shader/SDF.slang rename to src/core/shaders/SDF.slang index 03bfe00..f03562c 100644 --- a/src/core/shader/SDF.slang +++ b/src/core/shaders/SDF.slang @@ -115,7 +115,7 @@ float3 get_subpixel_to_edge_distances(VSOutput input) return distances * distance_multiplier; } -// ---- Vertex Shader ---- +[shader("vertex")] VSOutput vertex_main(VSInput input) { VSOutput output; @@ -131,7 +131,7 @@ VSOutput vertex_main(VSInput input) return output; } -// ---- Pixel Shader ---- +[shader("pixel")] PSOutput pixel_main(VSOutput input) { PSOutput output; diff --git a/src/core/shader/aorii_rect.slang b/src/core/shaders/aorii_rect.slang similarity index 93% rename from src/core/shader/aorii_rect.slang rename to src/core/shaders/aorii_rect.slang index efeb063..67780f6 100644 --- a/src/core/shader/aorii_rect.slang +++ b/src/core/shaders/aorii_rect.slang @@ -11,6 +11,7 @@ struct PSInput { float4 color : COLOR; // 颜色 }; +[shader("vertex")] PSInput vertex_main(VSInput input) { PSInput output; @@ -19,6 +20,7 @@ PSInput vertex_main(VSInput input) return output; } +[shader("pixel")] float4 pixel_main(PSInput input) : SV_TARGET { return input.color; diff --git a/src/core/shader/aorii_rounded_rect.slang b/src/core/shaders/aorii_rounded_rect.slang similarity index 100% rename from src/core/shader/aorii_rounded_rect.slang rename to src/core/shaders/aorii_rounded_rect.slang diff --git a/src/core/shader/aorii_sdf_text.slang b/src/core/shaders/aorii_sdf_text.slang similarity index 97% rename from src/core/shader/aorii_sdf_text.slang rename to src/core/shaders/aorii_sdf_text.slang index 938fa23..23bb473 100644 --- a/src/core/shader/aorii_sdf_text.slang +++ b/src/core/shaders/aorii_sdf_text.slang @@ -23,6 +23,7 @@ struct Constants { }; ParameterBlock param_buffer : register(b0); +[shader("vertex")] PSInput vertex_main(VSInput input) { float2 altas_uv = input.param_a.xy; float2 char_size = input.param_b.xy; @@ -41,6 +42,7 @@ PSInput vertex_main(VSInput input) { Texture2DArray atlas_texture : register(t0); SamplerState sampler_state : register(s0); +[shader("pixel")] float4 pixel_main(PSInput input) : SV_Target { float2 uv = input.altas_uv + input.char_size * input.uv; float distance = atlas_texture.Sample(sampler_state, float3(uv, input.altas_index)).r; diff --git a/src/core/shader/aorii_segment.slang b/src/core/shaders/aorii_segment.slang similarity index 97% rename from src/core/shader/aorii_segment.slang rename to src/core/shaders/aorii_segment.slang index 4ba8cf6..2188c65 100644 --- a/src/core/shader/aorii_segment.slang +++ b/src/core/shaders/aorii_segment.slang @@ -14,6 +14,7 @@ cbuffer segment_buffer : register(b0) { float thickness; // 线段的宽度 }; +[shader("vertex")] PSInput vertex_main(VSInput input) { PSInput output; output.position = mul(float4(input.position, 0.0, 1.0), transform); @@ -30,7 +31,7 @@ float sdf_line(float2 p, float2 a, float2 b) { return length(pa - ba * h); } -// 片段着色器 +[shader("pixel")] float4 pixel_main(PSInput input) : SV_TARGET { // 将屏幕空间坐标转化为归一化设备坐标 (NDC) float2 p = input.position.xy; // 归一化设备坐标 (NDC) diff --git a/src/core/shader/aorii_texture.slang b/src/core/shaders/aorii_texture.slang similarity index 94% rename from src/core/shader/aorii_texture.slang rename to src/core/shaders/aorii_texture.slang index ec2eb1a..d807bf4 100644 --- a/src/core/shader/aorii_texture.slang +++ b/src/core/shaders/aorii_texture.slang @@ -15,6 +15,7 @@ struct PSInput { Texture2D texture; SamplerState sampler; +[shader("vertex")] PSInput vertex_main(VSInput input) { PSInput output; @@ -24,6 +25,7 @@ PSInput vertex_main(VSInput input) return output; } +[shader("pixel")] float4 pixel_main(PSInput input) : SV_TARGET { return input.color * texture.Sample(sampler, input.uv); diff --git a/src/core/shader/aorii_util.slang b/src/core/shaders/aorii_util.slang similarity index 100% rename from src/core/shader/aorii_util.slang rename to src/core/shaders/aorii_util.slang diff --git a/src/core/shader/test.frag b/src/core/shaders/test.frag similarity index 100% rename from src/core/shader/test.frag rename to src/core/shaders/test.frag diff --git a/src/core/shader/test.vert b/src/core/shaders/test.vert similarity index 100% rename from src/core/shader/test.vert rename to src/core/shaders/test.vert diff --git a/src/core/shader/utils_vulkan.glsl b/src/core/shaders/utils_vulkan.glsl similarity index 100% rename from src/core/shader/utils_vulkan.glsl rename to src/core/shaders/utils_vulkan.glsl diff --git a/src/core/shader/utils_vulkan.slang b/src/core/shaders/utils_vulkan.slang similarity index 100% rename from src/core/shader/utils_vulkan.slang rename to src/core/shaders/utils_vulkan.slang