mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-02-12 16:53:07 +00:00
264 lines
7.6 KiB
GDScript
264 lines
7.6 KiB
GDScript
extends ImageEffect
|
|
|
|
var shader: Shader
|
|
var param_names := [] # String[]
|
|
|
|
onready var shader_loaded_label: Label = $VBoxContainer/ShaderLoadedLabel
|
|
onready var shader_params: BoxContainer = $VBoxContainer/ShaderParams
|
|
|
|
|
|
func _about_to_show() -> void:
|
|
Global.canvas.selection.transform_content_confirm()
|
|
var frame: Frame = Global.current_project.frames[Global.current_project.current_frame]
|
|
current_cel = frame.cels[Global.current_project.current_layer].image
|
|
|
|
preview_image.copy_from(current_cel)
|
|
preview_texture.create_from_image(preview_image, 0)
|
|
preview.texture = preview_texture
|
|
|
|
|
|
func commit_action(cel: Image, project: Project = Global.current_project) -> void:
|
|
if !shader:
|
|
return
|
|
|
|
var params := {}
|
|
for param in param_names:
|
|
var param_data = preview.material.get_shader_param(param)
|
|
params[param] = param_data
|
|
var gen := ShaderImageEffect.new()
|
|
gen.generate_image(cel, shader, params, project.size)
|
|
current_cel.unlock()
|
|
yield(gen, "done")
|
|
|
|
|
|
func _on_ChooseShader_pressed() -> void:
|
|
if OS.get_name() == "HTML5":
|
|
Html5FileExchange.load_shader()
|
|
else:
|
|
$FileDialog.popup_centered(Vector2(300, 340))
|
|
|
|
|
|
func _on_FileDialog_file_selected(path: String) -> void:
|
|
var shader_tmp = load(path)
|
|
if !shader_tmp is Shader:
|
|
return
|
|
change_shader(shader_tmp, path.get_file().get_basename())
|
|
|
|
|
|
func set_nodes() -> void:
|
|
preview = $VBoxContainer/Preview
|
|
|
|
|
|
func change_shader(shader_tmp: Shader, name: String) -> void:
|
|
shader = shader_tmp
|
|
preview.material.shader = shader_tmp
|
|
shader_loaded_label.text = tr("Shader loaded:") + " " + name
|
|
param_names.clear()
|
|
for child in shader_params.get_children():
|
|
child.queue_free()
|
|
|
|
var code := shader.code.split("\n")
|
|
var uniforms := []
|
|
for line in code:
|
|
if line.begins_with("uniform"):
|
|
uniforms.append(line)
|
|
|
|
for uniform in uniforms:
|
|
# Example uniform:
|
|
# uniform float parameter_name : hint_range(0, 255) = 100.0;
|
|
var uniform_split: PoolStringArray = uniform.split("=")
|
|
var u_value := ""
|
|
if uniform_split.size() > 1:
|
|
u_value = uniform_split[1].replace(";", "").strip_edges()
|
|
else:
|
|
uniform_split[0] = uniform_split[0].replace(";", "").strip_edges()
|
|
|
|
var u_left_side: PoolStringArray = uniform_split[0].split(":")
|
|
var u_hint := ""
|
|
if u_left_side.size() > 1:
|
|
u_hint = u_left_side[1].strip_edges()
|
|
u_hint = u_hint.replace(";", "")
|
|
|
|
var u_init: PoolStringArray = u_left_side[0].split(" ")
|
|
var u_type: String = u_init[1]
|
|
var u_name: String = u_init[2]
|
|
param_names.append(u_name)
|
|
|
|
if u_type == "float" or u_type == "int":
|
|
var label := Label.new()
|
|
label.text = u_name
|
|
var spinbox := SpinBox.new()
|
|
var min_value := 0.0
|
|
var max_value := 255.0
|
|
var step := 1.0
|
|
var range_values_array: PoolStringArray
|
|
if "hint_range" in u_hint:
|
|
var range_values: String = u_hint.replace("hint_range(", "")
|
|
range_values = range_values.replace(")", "").strip_edges()
|
|
range_values_array = range_values.split(",")
|
|
|
|
if u_type == "float":
|
|
if range_values_array.size() >= 1:
|
|
min_value = float(range_values_array[0])
|
|
else:
|
|
min_value = 0.01
|
|
|
|
if range_values_array.size() >= 2:
|
|
max_value = float(range_values_array[1])
|
|
|
|
if range_values_array.size() >= 3:
|
|
step = float(range_values_array[2])
|
|
else:
|
|
step = 0.01
|
|
|
|
if u_value != "":
|
|
spinbox.value = float(u_value)
|
|
else:
|
|
if range_values_array.size() >= 1:
|
|
min_value = int(range_values_array[0])
|
|
|
|
if range_values_array.size() >= 2:
|
|
max_value = int(range_values_array[1])
|
|
|
|
if range_values_array.size() >= 3:
|
|
step = int(range_values_array[2])
|
|
|
|
if u_value != "":
|
|
spinbox.value = int(u_value)
|
|
spinbox.min_value = min_value
|
|
spinbox.max_value = max_value
|
|
spinbox.step = step
|
|
spinbox.connect("value_changed", self, "set_shader_param", [u_name])
|
|
var hbox := HBoxContainer.new()
|
|
hbox.add_child(label)
|
|
hbox.add_child(spinbox)
|
|
shader_params.add_child(hbox)
|
|
elif u_type == "vec2":
|
|
var label := Label.new()
|
|
label.text = u_name
|
|
var vector2 := _vec2str_to_vector2(u_value)
|
|
var spinbox1 := SpinBox.new()
|
|
spinbox1.value = vector2.x
|
|
spinbox1.connect("value_changed", self, "_set_vector2_shader_param", [u_name, true])
|
|
var spinbox2 := SpinBox.new()
|
|
spinbox2.value = vector2.y
|
|
spinbox2.connect("value_changed", self, "_set_vector2_shader_param", [u_name, false])
|
|
var hbox := HBoxContainer.new()
|
|
hbox.add_child(label)
|
|
hbox.add_child(spinbox1)
|
|
hbox.add_child(spinbox2)
|
|
shader_params.add_child(hbox)
|
|
elif u_type == "vec4":
|
|
if "hint_color" in u_hint:
|
|
var label := Label.new()
|
|
label.text = u_name
|
|
var color := _vec4str_to_color(u_value)
|
|
var color_button := ColorPickerButton.new()
|
|
color_button.rect_min_size = Vector2(20, 20)
|
|
color_button.color = color
|
|
color_button.connect("color_changed", self, "set_shader_param", [u_name])
|
|
var hbox := HBoxContainer.new()
|
|
hbox.add_child(label)
|
|
hbox.add_child(color_button)
|
|
shader_params.add_child(hbox)
|
|
elif u_type == "sampler2D":
|
|
var label := Label.new()
|
|
label.text = u_name
|
|
var file_dialog := FileDialog.new()
|
|
file_dialog.mode = FileDialog.MODE_OPEN_FILE
|
|
file_dialog.access = FileDialog.ACCESS_FILESYSTEM
|
|
file_dialog.resizable = true
|
|
file_dialog.rect_min_size = Vector2(200, 70)
|
|
file_dialog.rect_size = Vector2(384, 281)
|
|
file_dialog.connect("file_selected", self, "_load_texture", [u_name])
|
|
var button := Button.new()
|
|
button.text = "Load texture"
|
|
button.connect("pressed", file_dialog, "popup_centered")
|
|
var hbox := HBoxContainer.new()
|
|
hbox.add_child(label)
|
|
hbox.add_child(button)
|
|
shader_params.add_child(hbox)
|
|
shader_params.add_child(file_dialog)
|
|
elif u_type == "bool":
|
|
var label := Label.new()
|
|
label.text = u_name
|
|
var checkbox := CheckBox.new()
|
|
checkbox.text = "On"
|
|
if u_value == "true":
|
|
checkbox.pressed = true
|
|
checkbox.connect("toggled", self, "set_shader_param", [u_name])
|
|
var hbox := HBoxContainer.new()
|
|
hbox.add_child(label)
|
|
hbox.add_child(checkbox)
|
|
shader_params.add_child(hbox)
|
|
|
|
|
|
# print("---")
|
|
# print(uniform_split)
|
|
# print(u_type)
|
|
# print(u_name)
|
|
# print(u_hint)
|
|
# print(u_value)
|
|
# print("--")
|
|
|
|
|
|
func set_shader_param(value, param: String) -> void:
|
|
var mat: ShaderMaterial = preview.material
|
|
mat.set_shader_param(param, value)
|
|
|
|
|
|
func _set_vector2_shader_param(value: float, param: String, x: bool) -> void:
|
|
var mat: ShaderMaterial = preview.material
|
|
var vector2: Vector2 = mat.get_shader_param(param)
|
|
if x:
|
|
vector2.x = value
|
|
else:
|
|
vector2.y = value
|
|
set_shader_param(vector2, param)
|
|
|
|
|
|
func _vec2str_to_vector2(vec2: String) -> Vector2:
|
|
vec2 = vec2.replace("vec2(", "")
|
|
vec2 = vec2.replace(")", "")
|
|
var vec_values: PoolStringArray = vec2.split(",")
|
|
if vec_values.size() == 0:
|
|
return Vector2.ZERO
|
|
var y := float(vec_values[0])
|
|
if vec_values.size() == 2:
|
|
y = float(vec_values[1])
|
|
var vector2 := Vector2(float(vec_values[0]), y)
|
|
return vector2
|
|
|
|
|
|
func _vec4str_to_color(vec4: String) -> Color:
|
|
vec4 = vec4.replace("vec4(", "")
|
|
vec4 = vec4.replace(")", "")
|
|
var rgba_values: PoolStringArray = vec4.split(",")
|
|
var red := float(rgba_values[0])
|
|
|
|
var green := float(rgba_values[0])
|
|
if rgba_values.size() >= 2:
|
|
green = float(rgba_values[1])
|
|
|
|
var blue := float(rgba_values[0])
|
|
if rgba_values.size() >= 3:
|
|
blue = float(rgba_values[2])
|
|
|
|
var alpha := float(rgba_values[0])
|
|
if rgba_values.size() == 4:
|
|
alpha = float(rgba_values[3])
|
|
var color: Color = Color(red, green, blue, alpha)
|
|
return color
|
|
|
|
|
|
func _load_texture(path: String, param: String) -> void:
|
|
var image := Image.new()
|
|
image.load(path)
|
|
if !image:
|
|
print("Error loading texture")
|
|
return
|
|
var image_tex := ImageTexture.new()
|
|
image_tex.create_from_image(image, 0)
|
|
image_tex.flags = ImageTexture.FLAG_REPEAT
|
|
set_shader_param(image_tex, param)
|