#!/bin/bash # Shader compilation script for Vulkan # Sets up environment and compiles GLSL shaders to SPIR-V SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" SHADERS_DIR="$SCRIPT_DIR/shaders" OUTPUT_DIR="$SCRIPT_DIR/src/shaders_spirv" # Find glslang compiler GLSLANG="" # Check custom paths first if [ -x "$HOME/VulkanSDK/1.4.328.1/macOS/bin/glslang" ]; then GLSLANG="$HOME/VulkanSDK/1.4.328.1/macOS/bin/glslang" echo "Found glslang at: $GLSLANG" elif [ -x "$HOME/VulkanSDK/1.4.328.1/macOS/bin/glslangValidator" ]; then GLSLANG="$HOME/VulkanSDK/1.4.328.1/macOS/bin/glslangValidator" echo "Found glslangValidator at: $GLSLANG" elif command -v glslc &> /dev/null; then GLSLANG="glslc" echo "Using system glslc" elif command -v glslangValidator &> /dev/null; then GLSLANG="glslangValidator" echo "Using system glslangValidator" elif command -v glslang &> /dev/null; then GLSLANG="glslang" echo "Using system glslang" else echo "ERROR: No GLSL compiler found!" echo "Please install:" echo " - Vulkan SDK (provides glslc)" echo " - or glslang to ~/VulkanSDK/1.4.328.1/macOS/bin/" exit 1 fi # Create output directory mkdir -p "$OUTPUT_DIR" # Compilation function compile_shader() { local shader_file="$1" local output_name="$2" local spirv_file="$OUTPUT_DIR/${shader_file}.spv" local inc_file="$OUTPUT_DIR/${output_name}" echo "Compiling $shader_file..." # Determine compiler command if [[ "$GLSLANG" == *"glslc"* ]]; then "$GLSLANG" "$SHADERS_DIR/$shader_file" -o "$spirv_file" else "$GLSLANG" -V "$SHADERS_DIR/$shader_file" -o "$spirv_file" fi if [ $? -ne 0 ]; then echo " FAILED to compile $shader_file" return 1 fi echo " SUCCESS - Generated $spirv_file" # Generate C++ include file echo " Generating $inc_file..." generate_include "$spirv_file" "$inc_file" return 0 } # Generate C++ include file from SPIR-V generate_include() { local spirv_file="$1" local inc_file="$2" # Use Python if available for better formatting if command -v python3 &> /dev/null; then python3 -c " import struct import sys with open('$spirv_file', 'rb') as f: data = f.read() num_words = len(data) // 4 words = struct.unpack('<{}I'.format(num_words), data[:num_words*4]) print('// Auto-generated from $(basename $spirv_file)') print('// Size: {} bytes ({} words)'.format(len(data), num_words)) for i in range(0, num_words, 8): chunk = words[i:i+8] if i == 0: sys.stdout.write(' ') else: sys.stdout.write(',\n ') sys.stdout.write(', '.join('0x{:08x}u'.format(w) for w in chunk)) print() " > "$inc_file" else # Fallback: simple hexdump echo "// Auto-generated from $(basename $spirv_file)" > "$inc_file" xxd -i < "$spirv_file" | sed 's/unsigned char/uint32_t/' >> "$inc_file" fi echo " Generated $inc_file" } echo "========================================" echo "Compiling Vulkan Shaders" echo "========================================" echo "Shaders directory: $SHADERS_DIR" echo "Output directory: $OUTPUT_DIR" echo "Compiler: $GLSLANG" echo "========================================" echo "" # Compile all shaders SUCCESS=0 FAILED=0 # Background shaders if compile_shader "background.vert" "background_vert.inc"; then ((SUCCESS++)) else ((FAILED++)) fi if compile_shader "background.frag" "background_frag.inc"; then ((SUCCESS++)) else ((FAILED++)) fi # Geometry shaders if compile_shader "geometry.vert" "geometry_vert.inc"; then ((SUCCESS++)) else ((FAILED++)) fi if compile_shader "geometry.frag" "geometry_frag.inc"; then ((SUCCESS++)) else ((FAILED++)) fi # Text shaders if compile_shader "text.vert" "text_vert.inc"; then ((SUCCESS++)) else ((FAILED++)) fi if compile_shader "text.frag" "text_frag.inc"; then ((SUCCESS++)) else ((FAILED++)) fi echo "" echo "========================================" echo "Compilation Summary" echo "========================================" echo "Success: $SUCCESS" echo "Failed: $FAILED" echo "========================================" if [ $FAILED -gt 0 ]; then exit 1 fi echo "" echo "All shaders compiled successfully!" exit 0