#!/usr/bin/env -S godot -s --headless # To be called with args "++ basename, basename, ..." # Fragile script # Relies on instantiating instead of using set_script # Godot ignores exported properties unless you reload script # Can't call methods directly because it's a parse error # Also can't use .set() because then the properties aren't exported. @tool extends SceneTree var bundle_name := "bundle.res" func _init(): var script := GDScript.new() var basenames := OS.get_cmdline_user_args() script.source_code = make_all_headers(basenames, true) script.reload() var res: Resource = script.new() res.basenames = basenames for basename in basenames: add_images(res, basename) var shader := ShaderInclude.new() for basename in basenames: shader.code += make_shader(basename) script.source_code = make_all_headers(basenames, false) # Cannot use built-in scripts # See: https://github.com/godotengine/godot/issues/85876 script.resource_path = "res://bundle/bundle.gd" ResourceSaver.save(script, "res://bundle/bundle.gd") res.shader = shader res.shader.resource_name = "shader" shader.resource_path = "res://bundle/bundle.gdshaderinc" ResourceSaver.save(shader, "res://bundle/bundle.gdshaderinc", ResourceSaver.FLAG_CHANGE_PATH) ResourceSaver.save(res, "res://bundle/" + bundle_name, ResourceSaver.FLAG_CHANGE_PATH) quit() func make_all_shaders(basenames): for basename in basenames: pass func make_shader(basename: String): var code = "\nuniform sampler2D image_" + basename + ": repeat_disable;\n" code += "uniform sampler2D image_mask_" + basename + ": repeat_disable;\n" code += "uniform bool enabled_" + basename + " = false;\n" code += "uniform int start_time_" + basename + ";\n" return code func make_all_headers(basenames, include_setters): var header := "extends Resource\n" header += "@export var basenames: PackedStringArray\n" header += "@export var shader: ShaderInclude\n" for basename in basenames: header += make_header(basename) if include_setters: header += make_setters(basename) return header + attach_code(basenames) func attach_code(basenames): var code := "\nfunc attach(mat: ShaderMaterial):\n" for basename in basenames: code += " mat.set_shader_parameter('image_"+basename+"', image_"+basename+")\n" code += " mat.set_shader_parameter('image_mask_"+basename+"', image_mask_"+basename+")\n" return code func make_header(basename: String): var header := "@export var image_" + basename + ": Texture2D\n" header += "@export var image_mask_" + basename + ": Texture2D\n" return header func make_setters(basename: String): var body := """ func set_image_"""+basename+"""(image):\n image_""" + basename + """ = image func set_image_mask_"""+basename+"""(image):\n image_mask_""" + basename + """ = image """ return body func add_images(res, basename: String): var img := Image.new() img.load(basename + ".exr") var tex := ImageTexture.create_from_image(img) res.call("set_image_"+basename, tex) img = Image.new() img.load(basename + "_mask.exr") tex = ImageTexture.create_from_image(img) res.call("set_image_mask_"+basename, tex)