From ec81950139cd241e541a67ee3efd43aefcfc97ba Mon Sep 17 00:00:00 2001 From: OverloadedOrama <35376950+OverloadedOrama@users.noreply.github.com> Date: Tue, 28 Jul 2020 04:11:06 +0300 Subject: [PATCH] Experimental shader feature: Expose shader's float uniforms to the UI If the loaded shader has uniforms, they will be exposed to the UI, so the users will be able to modify the shader parameters easily. Currently only works with float uniforms. --- src/Autoload/HTML5FileExchange.gd | 3 +- src/UI/Dialogs/ShaderEffect.gd | 73 ++++++++++++++++++++++++++++--- src/UI/Dialogs/ShaderEffect.tscn | 32 ++++++++------ 3 files changed, 86 insertions(+), 22 deletions(-) diff --git a/src/Autoload/HTML5FileExchange.gd b/src/Autoload/HTML5FileExchange.gd index 96b380271..500f0acc5 100644 --- a/src/Autoload/HTML5FileExchange.gd +++ b/src/Autoload/HTML5FileExchange.gd @@ -226,6 +226,5 @@ func load_shader() -> void: shader.code = file_data var shader_effect_dialog = Global.control.get_node("Dialogs/ImageEffects/ShaderEffect") - shader_effect_dialog.preview.material.shader = shader - shader_effect_dialog.shader_loaded_label.text = tr("Shader loaded:") + " " + file_name.get_basename() + shader_effect_dialog.change_shader(shader, file_name.get_basename()) diff --git a/src/UI/Dialogs/ShaderEffect.gd b/src/UI/Dialogs/ShaderEffect.gd index b9a161dd5..4cf428ad4 100644 --- a/src/UI/Dialogs/ShaderEffect.gd +++ b/src/UI/Dialogs/ShaderEffect.gd @@ -6,14 +6,15 @@ var current_cel : Image onready var viewport : Viewport = $VBoxContainer/ViewportContainer/Viewport onready var preview : TextureRect = viewport.get_node("Preview") onready var shader_loaded_label : Label = $VBoxContainer/ShaderLoadedLabel +onready var shader_params : BoxContainer = $VBoxContainer/ShaderParams func _on_ShaderEffect_about_to_show() -> void: current_cel = Global.current_project.frames[Global.current_project.current_frame].cels[Global.current_project.current_layer].image current_cel.unlock() - viewport.size = current_cel.get_size() - var viewport_texture = viewport.get_texture().get_data() - viewport_texture.convert(Image.FORMAT_RGBA8) + viewport.size = Global.current_project.size +# var viewport_texture = viewport.get_texture().get_data() +# viewport_texture.convert(Image.FORMAT_RGBA8) var preview_image := Image.new() preview_image.copy_from(current_cel) @@ -23,7 +24,11 @@ func _on_ShaderEffect_about_to_show() -> void: func _on_ShaderEffect_confirmed() -> void: - var viewport_texture = viewport.get_texture().get_data() + var viewport_texture := Image.new() + viewport_texture.copy_from(viewport.get_texture().get_data()) + var viewport_texture_size = viewport_texture.get_size() + if viewport_texture_size == Vector2.ZERO: + return viewport_texture.flip_y() viewport_texture.convert(Image.FORMAT_RGBA8) print(viewport_texture.get_size()) @@ -45,12 +50,68 @@ func _on_ChooseShader_pressed() -> void: if OS.get_name() == "HTML5": Html5FileExchange.load_shader() else: - $FileDialog.popup_centered(Vector2(200, 340)) + $FileDialog.popup_centered(Vector2(300, 340)) func _on_FileDialog_file_selected(path : String) -> void: var shader = load(path) if !shader is Shader: return + change_shader(shader, path.get_file().get_basename()) + + +func change_shader(shader : Shader, name : String) -> void: preview.material.shader = shader - shader_loaded_label.text = tr("Shader loaded:") + " " + path.get_file().get_basename() + shader_loaded_label.text = tr("Shader loaded:") + " " + name + 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 = uniform.split("=") + var u_value := "" + if uniform_split.size() > 1: + u_value = uniform_split[1].replace(";", "").strip_edges() + + var u_left_side = uniform_split[0].split(":") + var u_hint := "" + if u_left_side.size() > 1: + u_hint = u_left_side[1].strip_edges() + + var u_init = u_left_side[0].split(" ") + var u_type = u_init[1] + var u_name = u_init[2] + + if u_type == "float": + var label := Label.new() + label.text = u_name + var spinbox := SpinBox.new() + spinbox.min_value = 0.01 + spinbox.max_value = 255 + spinbox.step = 0.01 + if u_value != "": + spinbox.value = float(u_value) + 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) + +# 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: + preview.material.set_shader_param(param, value) diff --git a/src/UI/Dialogs/ShaderEffect.tscn b/src/UI/Dialogs/ShaderEffect.tscn index f34128008..ad17d5097 100644 --- a/src/UI/Dialogs/ShaderEffect.tscn +++ b/src/UI/Dialogs/ShaderEffect.tscn @@ -7,7 +7,7 @@ [node name="ShaderEffect" type="ConfirmationDialog"] margin_right = 200.0 margin_bottom = 228.0 -rect_min_size = Vector2( 0, 0 ) +rect_min_size = Vector2( 400, 300 ) resizable = true script = ExtResource( 2 ) __meta__ = { @@ -26,15 +26,15 @@ __meta__ = { } [node name="Label" type="Label" parent="VBoxContainer"] -margin_right = 255.0 -margin_bottom = 48.0 +margin_right = 384.0 +margin_bottom = 31.0 text = "This is an experimental feature and may not be included in the stable version" autowrap = true [node name="ViewportContainer" type="ViewportContainer" parent="VBoxContainer"] -margin_top = 52.0 -margin_right = 255.0 -margin_bottom = 53.0 +margin_top = 35.0 +margin_right = 384.0 +margin_bottom = 36.0 __meta__ = { "_edit_use_anchors_": false } @@ -54,24 +54,28 @@ anchor_right = 1.0 anchor_bottom = 1.0 [node name="ChooseShader" type="Button" parent="VBoxContainer"] -margin_top = 57.0 -margin_right = 255.0 -margin_bottom = 77.0 +margin_top = 40.0 +margin_right = 384.0 +margin_bottom = 60.0 mouse_default_cursor_shape = 2 text = "Choose Shader" [node name="ShaderLoadedLabel" type="Label" parent="VBoxContainer"] -margin_top = 81.0 -margin_right = 255.0 -margin_bottom = 95.0 +margin_top = 64.0 +margin_right = 384.0 +margin_bottom = 78.0 text = "No shader loaded!" autowrap = true +[node name="ShaderParams" type="VBoxContainer" parent="VBoxContainer"] +margin_right = 40.0 +margin_bottom = 40.0 + [node name="FileDialog" type="FileDialog" parent="."] margin_left = 8.0 margin_top = 8.0 -margin_right = 263.0 -margin_bottom = 192.0 +margin_right = 392.0 +margin_bottom = 264.0 window_title = "Open a File" resizable = true mode = 0