# compile_shader.cmake
# Compila un shader GLSL a header C++ embebible con datos SPIR-V.
# Funciona en Windows, Linux y macOS sin bash ni herramientas Unix.
#
# Variables requeridas (pasar con -D al invocar cmake -P):
#   GLSLC  - ruta al ejecutable glslc
#   SRC    - archivo fuente GLSL
#   OUT_H  - archivo header de salida
#   VAR    - nombre base de la variable C++ (e.g. "postfx_vert_spv")
#   STAGE  - (opcional) stage explícito para glslc (e.g. "fragment")

cmake_minimum_required(VERSION 3.10)

get_filename_component(SRC_NAME "${SRC}" NAME_WE)
get_filename_component(OUT_DIR  "${OUT_H}" DIRECTORY)
set(OUT_SPV "${OUT_DIR}/${SRC_NAME}.spv")

# Compilar GLSL → SPIR-V
if(DEFINED STAGE AND NOT STAGE STREQUAL "")
    execute_process(
        COMMAND "${GLSLC}" "-fshader-stage=${STAGE}" "${SRC}" -o "${OUT_SPV}"
        RESULT_VARIABLE RESULT
        ERROR_VARIABLE  ERROR_MSG
    )
else()
    execute_process(
        COMMAND "${GLSLC}" "${SRC}" -o "${OUT_SPV}"
        RESULT_VARIABLE RESULT
        ERROR_VARIABLE  ERROR_MSG
    )
endif()

if(NOT RESULT EQUAL 0)
    message(FATAL_ERROR "glslc falló compilando ${SRC}:\n${ERROR_MSG}")
endif()

# Leer binario SPIR-V como cadena hexadecimal
file(READ "${OUT_SPV}" SPV_HEX HEX)
file(REMOVE "${OUT_SPV}")

string(LENGTH "${SPV_HEX}" HEX_LEN)
math(EXPR BYTE_COUNT "${HEX_LEN} / 2")

# Convertir a array C++ con formato "    0xXX,\n" por byte
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "    0x\\1,\n" SPV_BYTES "${SPV_HEX}")
# Eliminar la última coma y sustituir por el "}" de cierre
string(REGEX REPLACE ",\n$" "}" SPV_BYTES "${SPV_BYTES}")

# Escribir el header
file(WRITE "${OUT_H}"
    "#pragma once\n"
    "#include <cstddef>\n"
    "#include <cstdint>\n"
    "static const uint8_t k${VAR}[] = {\n"
    "${SPV_BYTES};\n"
    "static const size_t k${VAR}_size = ${BYTE_COUNT};\n"
)
