mirror of
https://github.com/Relintai/material-maker.git
synced 2024-11-13 06:27:18 +01:00
New preview menu, added support for expressions in float parameters
This commit is contained in:
parent
fe2c83a79a
commit
bd868d8a55
@ -1,3 +1,9 @@
|
|||||||
|
varying float elapsed_time;
|
||||||
|
|
||||||
|
void vertex() {
|
||||||
|
elapsed_time = TIME;
|
||||||
|
}
|
||||||
|
|
||||||
float rand(vec2 x) {
|
float rand(vec2 x) {
|
||||||
return fract(cos(dot(x, vec2(13.9898, 8.141))) * 43758.5453);
|
return fract(cos(dot(x, vec2(13.9898, 8.141))) * 43758.5453);
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ func set_parameter(n : String, v) -> void:
|
|||||||
if is_inside_tree():
|
if is_inside_tree():
|
||||||
var parameter_def : Dictionary = get_parameter_def(n)
|
var parameter_def : Dictionary = get_parameter_def(n)
|
||||||
if parameter_def.has("type"):
|
if parameter_def.has("type"):
|
||||||
if parameter_def.type == "float":
|
if parameter_def.type == "float" and v is float and old_value is float:
|
||||||
var parameter_name = "p_o"+str(get_instance_id())+"_"+n
|
var parameter_name = "p_o"+str(get_instance_id())+"_"+n
|
||||||
get_tree().call_group("preview", "on_float_parameters_changed", { parameter_name:v })
|
get_tree().call_group("preview", "on_float_parameters_changed", { parameter_name:v })
|
||||||
return
|
return
|
||||||
|
@ -149,27 +149,33 @@ func replace_input(string : String, context, input : String, type : String, src
|
|||||||
func is_word_letter(l) -> bool:
|
func is_word_letter(l) -> bool:
|
||||||
return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1
|
return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1
|
||||||
|
|
||||||
func replace_variable(string : String, variable : String, value : String) -> String:
|
func replace_variables(string : String, variables : Dictionary) -> String:
|
||||||
string = string.replace("$(%s)" % variable, value)
|
while true:
|
||||||
var keyword_size = variable.length()+1
|
var old_string = string
|
||||||
var new_string = ""
|
for variable in variables.keys():
|
||||||
while !string.empty():
|
string = string.replace("$(%s)" % variable, variables[variable])
|
||||||
var pos = string.find("$"+variable)
|
var keyword_size : int = variable.length()+1
|
||||||
if pos == -1:
|
var new_string : String = ""
|
||||||
new_string += string
|
while !string.empty():
|
||||||
|
var pos : int = string.find("$"+variable)
|
||||||
|
if pos == -1:
|
||||||
|
new_string += string
|
||||||
|
break
|
||||||
|
new_string += string.left(pos)
|
||||||
|
string = string.right(pos)
|
||||||
|
if string.length() > keyword_size and is_word_letter(string[keyword_size]):
|
||||||
|
new_string += string.left(keyword_size)
|
||||||
|
string = string.right(keyword_size)
|
||||||
|
continue
|
||||||
|
if string.empty() or !is_word_letter(string[0]):
|
||||||
|
new_string += variables[variable]
|
||||||
|
else:
|
||||||
|
new_string += "$"+variable
|
||||||
|
string = string.right(keyword_size)
|
||||||
|
string = new_string
|
||||||
|
if string == old_string:
|
||||||
break
|
break
|
||||||
new_string += string.left(pos)
|
return string
|
||||||
string = string.right(pos)
|
|
||||||
if string.length() > keyword_size and is_word_letter(string[keyword_size]):
|
|
||||||
new_string += string.left(keyword_size)
|
|
||||||
string = string.right(keyword_size)
|
|
||||||
continue
|
|
||||||
if string.empty() or !is_word_letter(string[0]):
|
|
||||||
new_string += value
|
|
||||||
else:
|
|
||||||
new_string += "$"+variable
|
|
||||||
string = string.right(keyword_size)
|
|
||||||
return new_string
|
|
||||||
|
|
||||||
func subst(string : String, context : MMGenContext, uv : String = "") -> Dictionary:
|
func subst(string : String, context : MMGenContext, uv : String = "") -> Dictionary:
|
||||||
var genname = "o"+str(get_instance_id())
|
var genname = "o"+str(get_instance_id())
|
||||||
@ -177,13 +183,13 @@ func subst(string : String, context : MMGenContext, uv : String = "") -> Diction
|
|||||||
var required_defs = ""
|
var required_defs = ""
|
||||||
var required_code = ""
|
var required_code = ""
|
||||||
var required_textures = {}
|
var required_textures = {}
|
||||||
string = replace_variable(string, "name", genname)
|
var variables = {}
|
||||||
|
variables["name"] = genname
|
||||||
if uv != "":
|
if uv != "":
|
||||||
var genname_uv = genname+"_"+str(context.get_variant(self, uv))
|
var genname_uv = genname+"_"+str(context.get_variant(self, uv))
|
||||||
string = replace_variable(string, "name_uv", genname_uv)
|
variables["name_uv"] = genname_uv
|
||||||
var tmp_string = replace_variable(string, "seed", "seed_"+genname)
|
variables["seed"] = "seed_"+genname
|
||||||
if tmp_string != string:
|
variables["node_id"] = str(get_instance_id())
|
||||||
string = tmp_string
|
|
||||||
if shader_model.has("parameters") and typeof(shader_model.parameters) == TYPE_ARRAY:
|
if shader_model.has("parameters") and typeof(shader_model.parameters) == TYPE_ARRAY:
|
||||||
for p in shader_model.parameters:
|
for p in shader_model.parameters:
|
||||||
if !p.has("name") or !p.has("type"):
|
if !p.has("name") or !p.has("type"):
|
||||||
@ -191,7 +197,10 @@ func subst(string : String, context : MMGenContext, uv : String = "") -> Diction
|
|||||||
var value = parameters[p.name]
|
var value = parameters[p.name]
|
||||||
var value_string = null
|
var value_string = null
|
||||||
if p.type == "float":
|
if p.type == "float":
|
||||||
value_string = "p_%s_%s" % [ genname, p.name ]
|
if parameters[p.name] is float:
|
||||||
|
value_string = "p_%s_%s" % [ genname, p.name ]
|
||||||
|
elif parameters[p.name] is String:
|
||||||
|
value_string = "("+parameters[p.name]+")"
|
||||||
elif p.type == "size":
|
elif p.type == "size":
|
||||||
value_string = "%.9f" % pow(2, value)
|
value_string = "%.9f" % pow(2, value)
|
||||||
elif p.type == "enum":
|
elif p.type == "enum":
|
||||||
@ -207,9 +216,11 @@ func subst(string : String, context : MMGenContext, uv : String = "") -> Diction
|
|||||||
else:
|
else:
|
||||||
print("Cannot replace parameter of type "+p.type)
|
print("Cannot replace parameter of type "+p.type)
|
||||||
if value_string != null:
|
if value_string != null:
|
||||||
string = replace_variable(string, p.name, value_string)
|
variables[p.name] = value_string
|
||||||
if uv != "":
|
if uv != "":
|
||||||
string = replace_variable(string, "uv", "("+uv+")")
|
variables["uv"] = "("+uv+")"
|
||||||
|
variables["time"] = "elapsed_time"
|
||||||
|
string = replace_variables(string, variables)
|
||||||
if shader_model.has("inputs") and typeof(shader_model.inputs) == TYPE_ARRAY:
|
if shader_model.has("inputs") and typeof(shader_model.inputs) == TYPE_ARRAY:
|
||||||
var cont = true
|
var cont = true
|
||||||
while cont:
|
while cont:
|
||||||
@ -252,7 +263,7 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
|
|||||||
if has_randomness():
|
if has_randomness():
|
||||||
rv.defs += "uniform int seed_%s = %d;\n" % [ genname, get_seed() ]
|
rv.defs += "uniform int seed_%s = %d;\n" % [ genname, get_seed() ]
|
||||||
for p in shader_model.parameters:
|
for p in shader_model.parameters:
|
||||||
if p.type == "float":
|
if p.type == "float" and parameters[p.name] is float:
|
||||||
rv.defs += "uniform float p_%s_%s = %.9f;\n" % [ genname, p.name, parameters[p.name] ]
|
rv.defs += "uniform float p_%s_%s = %.9f;\n" % [ genname, p.name, parameters[p.name] ]
|
||||||
elif p.type == "color":
|
elif p.type == "color":
|
||||||
rv.defs += "uniform float p_%s_%s_r = %.9f;\n" % [ genname, p.name, parameters[p.name].r ]
|
rv.defs += "uniform float p_%s_%s_r = %.9f;\n" % [ genname, p.name, parameters[p.name].r ]
|
||||||
@ -266,7 +277,7 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
|
|||||||
g.deserialize(parameters[p.name])
|
g.deserialize(parameters[p.name])
|
||||||
var params = g.get_shader_params(genname+"_"+p.name)
|
var params = g.get_shader_params(genname+"_"+p.name)
|
||||||
for sp in params.keys():
|
for sp in params.keys():
|
||||||
rv.defs += "uniform float "+sp+" = "+str(params[sp])+";\n"
|
rv.defs += "uniform float %s = %.9f;\n" % [ sp, params[sp] ]
|
||||||
rv.defs += g.get_shader(genname+"_"+p.name)
|
rv.defs += g.get_shader(genname+"_"+p.name)
|
||||||
# Generate functions for inputs
|
# Generate functions for inputs
|
||||||
if shader_model.has("inputs"):
|
if shader_model.has("inputs"):
|
||||||
|
@ -31,7 +31,21 @@ func _ready() -> void:
|
|||||||
add_valid_connection_type(42, t)
|
add_valid_connection_type(42, t)
|
||||||
|
|
||||||
func _gui_input(event) -> void:
|
func _gui_input(event) -> void:
|
||||||
if event is InputEventKey and event.pressed:
|
if event.is_action_pressed("ui_library_popup") && get_rect().has_point(get_local_mouse_position()):
|
||||||
|
node_popup.rect_global_position = get_global_mouse_position()
|
||||||
|
node_popup.show_popup()
|
||||||
|
elif event is InputEventMouseButton:
|
||||||
|
if event.button_index == BUTTON_WHEEL_DOWN and event.control:
|
||||||
|
zoom *= 1.1
|
||||||
|
print(zoom)
|
||||||
|
get_tree().set_input_as_handled()
|
||||||
|
elif event.button_index == BUTTON_WHEEL_UP and event.control:
|
||||||
|
zoom /= 1.1
|
||||||
|
print(zoom)
|
||||||
|
get_tree().set_input_as_handled()
|
||||||
|
else:
|
||||||
|
call_deferred("check_last_selected")
|
||||||
|
elif event is InputEventKey and event.pressed:
|
||||||
var scancode_with_modifiers = event.get_scancode_with_modifiers()
|
var scancode_with_modifiers = event.get_scancode_with_modifiers()
|
||||||
if scancode_with_modifiers == KEY_DELETE or scancode_with_modifiers == KEY_BACKSPACE:
|
if scancode_with_modifiers == KEY_DELETE or scancode_with_modifiers == KEY_BACKSPACE:
|
||||||
remove_selection()
|
remove_selection()
|
||||||
@ -390,13 +404,6 @@ func set_last_selected(node) -> void:
|
|||||||
else:
|
else:
|
||||||
last_selected = null
|
last_selected = null
|
||||||
|
|
||||||
func _on_GraphEdit_gui_input(event) -> void:
|
|
||||||
if event.is_action_pressed("ui_library_popup") && get_rect().has_point(get_local_mouse_position()):
|
|
||||||
node_popup.rect_global_position = get_global_mouse_position()
|
|
||||||
node_popup.show_popup()
|
|
||||||
if event is InputEventMouseButton:
|
|
||||||
call_deferred("check_last_selected")
|
|
||||||
|
|
||||||
func request_popup(from, from_slot, release_position) -> void:
|
func request_popup(from, from_slot, release_position) -> void:
|
||||||
# Check if the connector was actually dragged
|
# Check if the connector was actually dragged
|
||||||
var node : GraphNode = get_node(from)
|
var node : GraphNode = get_node(from)
|
||||||
@ -415,5 +422,3 @@ func check_last_selected() -> void:
|
|||||||
if last_selected != null and !(is_instance_valid(last_selected) and last_selected.selected):
|
if last_selected != null and !(is_instance_valid(last_selected) and last_selected.selected):
|
||||||
last_selected = null
|
last_selected = null
|
||||||
emit_signal("node_selected", null)
|
emit_signal("node_selected", null)
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,7 +83,6 @@ icon = SubResource( 4 )
|
|||||||
[connection signal="copy_nodes_request" from="." to="." method="copy"]
|
[connection signal="copy_nodes_request" from="." to="." method="copy"]
|
||||||
[connection signal="disconnection_request" from="." to="." method="disconnect_node"]
|
[connection signal="disconnection_request" from="." to="." method="disconnect_node"]
|
||||||
[connection signal="duplicate_nodes_request" from="." to="." method="duplicate_selected"]
|
[connection signal="duplicate_nodes_request" from="." to="." method="duplicate_selected"]
|
||||||
[connection signal="gui_input" from="." to="." method="_on_GraphEdit_gui_input"]
|
|
||||||
[connection signal="node_selected" from="." to="." method="_on_GraphEdit_node_selected"]
|
[connection signal="node_selected" from="." to="." method="_on_GraphEdit_node_selected"]
|
||||||
[connection signal="paste_nodes_request" from="." to="." method="paste"]
|
[connection signal="paste_nodes_request" from="." to="." method="paste"]
|
||||||
[connection signal="timeout" from="Timer" to="." method="do_send_changed_signal"]
|
[connection signal="timeout" from="Timer" to="." method="do_send_changed_signal"]
|
||||||
|
@ -147,7 +147,7 @@ func save_preview_widget() -> void:
|
|||||||
|
|
||||||
func restore_preview_widget() -> void:
|
func restore_preview_widget() -> void:
|
||||||
if preview == null:
|
if preview == null:
|
||||||
preview = preload("res://material_maker/preview/preview_2d.tscn").instance()
|
preview = preload("res://material_maker/preview/preview_2d_node.tscn").instance()
|
||||||
preview.shader = "uniform vec2 size;void fragment() {COLOR = preview_2d(UV);}"
|
preview.shader = "uniform vec2 size;void fragment() {COLOR = preview_2d(UV);}"
|
||||||
preview.visible = false
|
preview.visible = false
|
||||||
preview_position = get_child_count()
|
preview_position = get_child_count()
|
||||||
|
@ -23,17 +23,19 @@ func update_node() -> void:
|
|||||||
var color = Color(0.0, 0.5, 0.0, 0.5)
|
var color = Color(0.0, 0.5, 0.0, 0.5)
|
||||||
for p in generator.get_io_defs():
|
for p in generator.get_io_defs():
|
||||||
color = mm_io_types.types[p.type].color
|
color = mm_io_types.types[p.type].color
|
||||||
set_slot(get_child_count(), generator.name != "gen_inputs", 0, color, generator.name != "gen_outputs", 0, color)
|
var slot_type = mm_io_types.types[p.type].slot_type
|
||||||
|
set_slot(get_child_count(), generator.name != "gen_inputs", slot_type, color, generator.name != "gen_outputs", slot_type, color)
|
||||||
var port : Control
|
var port : Control
|
||||||
if generator.is_editable():
|
if generator.is_editable():
|
||||||
port = preload("res://material_maker/nodes/ios/port.tscn").instance()
|
port = preload("res://material_maker/nodes/ios/port.tscn").instance()
|
||||||
|
add_child(port)
|
||||||
if p.has("name"):
|
if p.has("name"):
|
||||||
port.set_label(p.name)
|
port.set_label(p.name)
|
||||||
port.set_type(p.type)
|
port.set_type(p.type)
|
||||||
else:
|
else:
|
||||||
port = Label.new()
|
port = Label.new()
|
||||||
|
add_child(port)
|
||||||
port.text = p.name
|
port.text = p.name
|
||||||
add_child(port)
|
|
||||||
if generator.is_editable():
|
if generator.is_editable():
|
||||||
var add_button : Button = preload("res://material_maker/nodes/ios/add.tscn").instance()
|
var add_button : Button = preload("res://material_maker/nodes/ios/add.tscn").instance()
|
||||||
add_child(add_button)
|
add_child(add_button)
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
[ext_resource path="res://material_maker/nodes/ios.gd" type="Script" id=1]
|
[ext_resource path="res://material_maker/nodes/ios.gd" type="Script" id=1]
|
||||||
|
|
||||||
|
|
||||||
[node name="IOs" type="GraphNode"]
|
[node name="IOs" type="GraphNode"]
|
||||||
margin_right = 32.0
|
margin_right = 32.0
|
||||||
margin_bottom = 29.0
|
margin_bottom = 29.0
|
||||||
script = ExtResource( 1 )
|
script = ExtResource( 1 )
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
extends HBoxContainer
|
extends HBoxContainer
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
$Type.clear()
|
||||||
|
for tn in mm_io_types.type_names:
|
||||||
|
var t = mm_io_types.types[tn]
|
||||||
|
$Type.add_item(t.label)
|
||||||
|
|
||||||
func set_label(l : String) -> void:
|
func set_label(l : String) -> void:
|
||||||
$Name.set_text(l)
|
$Name.set_text(l)
|
||||||
|
|
||||||
func set_type(t : String) -> void:
|
func set_type(t : String) -> void:
|
||||||
$Type.selected = mm_io_types.type_names.find(t)
|
$Type.select(mm_io_types.type_names.find(t))
|
||||||
|
|
||||||
func update_up_down_button() -> void:
|
func update_up_down_button() -> void:
|
||||||
var parent = get_parent()
|
var parent = get_parent()
|
||||||
|
@ -4,9 +4,6 @@
|
|||||||
[ext_resource path="res://material_maker/icons/icons.svg" type="Texture" id=2]
|
[ext_resource path="res://material_maker/icons/icons.svg" type="Texture" id=2]
|
||||||
[ext_resource path="res://material_maker/widgets/linked_widgets/editable_label.tscn" type="PackedScene" id=3]
|
[ext_resource path="res://material_maker/widgets/linked_widgets/editable_label.tscn" type="PackedScene" id=3]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[sub_resource type="AtlasTexture" id=1]
|
[sub_resource type="AtlasTexture" id=1]
|
||||||
flags = 4
|
flags = 4
|
||||||
atlas = ExtResource( 2 )
|
atlas = ExtResource( 2 )
|
||||||
@ -54,12 +51,11 @@ rect_min_size = Vector2( 30, 0 )
|
|||||||
|
|
||||||
[node name="Type" type="OptionButton" parent="."]
|
[node name="Type" type="OptionButton" parent="."]
|
||||||
margin_left = 118.0
|
margin_left = 118.0
|
||||||
margin_right = 222.0
|
margin_right = 220.0
|
||||||
margin_bottom = 20.0
|
margin_bottom = 20.0
|
||||||
rect_min_size = Vector2( 102, 0 )
|
rect_min_size = Vector2( 102, 0 )
|
||||||
hint_tooltip = "Input flag"
|
hint_tooltip = "Input flag"
|
||||||
text = "Greyscale"
|
text = "Greyscale"
|
||||||
items = [ "Greyscale", null, false, 0, null, "Color", null, false, 1, null, "RGBA", null, false, 2, null, "SDF2D", null, false, 3, null, "SDF3D", null, false, 4, null ]
|
|
||||||
selected = 0
|
selected = 0
|
||||||
[connection signal="pressed" from="Delete" to="." method="_on_Delete_pressed"]
|
[connection signal="pressed" from="Delete" to="." method="_on_Delete_pressed"]
|
||||||
[connection signal="pressed" from="Up" to="." method="_on_Up_pressed"]
|
[connection signal="pressed" from="Up" to="." method="_on_Up_pressed"]
|
||||||
|
@ -77,16 +77,24 @@ func get_value() -> Vector2:
|
|||||||
if is_instance_valid(generator):
|
if is_instance_valid(generator):
|
||||||
if is_xy:
|
if is_xy:
|
||||||
if parameter_x != "":
|
if parameter_x != "":
|
||||||
pos.x = generator.get_parameter(parameter_x)
|
var p = generator.get_parameter(parameter_x)
|
||||||
|
if p is float:
|
||||||
|
pos.x = p
|
||||||
if parameter_y != "":
|
if parameter_y != "":
|
||||||
pos.y = generator.get_parameter(parameter_y)
|
var p = generator.get_parameter(parameter_y)
|
||||||
|
if p is float:
|
||||||
|
pos.y = p
|
||||||
else:
|
else:
|
||||||
var r = 0.25
|
var r = 0.25
|
||||||
var a = 0
|
var a = 0
|
||||||
if parameter_r != "":
|
if parameter_r != "":
|
||||||
r = generator.get_parameter(parameter_r)
|
var p = generator.get_parameter(parameter_r)
|
||||||
|
if p is float:
|
||||||
|
r = p
|
||||||
if parameter_a != "":
|
if parameter_a != "":
|
||||||
a = generator.get_parameter(parameter_a)*0.01745329251
|
var p = generator.get_parameter(parameter_a)
|
||||||
|
if p is float:
|
||||||
|
a = p*0.01745329251
|
||||||
pos.x = r*cos(a)
|
pos.x = r*cos(a)
|
||||||
pos.y = r*sin(a)
|
pos.y = r*sin(a)
|
||||||
return pos
|
return pos
|
||||||
@ -101,8 +109,12 @@ func get_parent_value() -> Vector2:
|
|||||||
|
|
||||||
func on_parameter_changed(p, v) -> void:
|
func on_parameter_changed(p, v) -> void:
|
||||||
if !dragging and (p == parameter_x or p == parameter_y or p == parameter_r or p == parameter_a):
|
if !dragging and (p == parameter_x or p == parameter_y or p == parameter_r or p == parameter_a):
|
||||||
update_position(get_value())
|
if v is float:
|
||||||
update()
|
visible = true
|
||||||
|
update_position(get_value())
|
||||||
|
update()
|
||||||
|
else:
|
||||||
|
visible = false
|
||||||
|
|
||||||
func update_parameters(value : Vector2) -> void:
|
func update_parameters(value : Vector2) -> void:
|
||||||
if !is_instance_valid(generator):
|
if !is_instance_valid(generator):
|
||||||
|
@ -13,9 +13,6 @@ func set_generator(g : MMGenBase, o : int = 0) -> void:
|
|||||||
generator = g
|
generator = g
|
||||||
output = o
|
output = o
|
||||||
generator.connect("parameter_changed", self, "on_parameter_changed")
|
generator.connect("parameter_changed", self, "on_parameter_changed")
|
||||||
var param_defs : Array = generator.get_parameter_defs()
|
|
||||||
for c in get_children():
|
|
||||||
c.setup_control(generator, param_defs)
|
|
||||||
var gen_output_defs = generator.get_output_defs()
|
var gen_output_defs = generator.get_output_defs()
|
||||||
if ! gen_output_defs.empty():
|
if ! gen_output_defs.empty():
|
||||||
var context : MMGenContext = MMGenContext.new()
|
var context : MMGenContext = MMGenContext.new()
|
||||||
@ -25,9 +22,7 @@ func set_generator(g : MMGenBase, o : int = 0) -> void:
|
|||||||
if source.empty():
|
if source.empty():
|
||||||
source = MMGenBase.DEFAULT_GENERATED_SHADER
|
source = MMGenBase.DEFAULT_GENERATED_SHADER
|
||||||
else:
|
else:
|
||||||
g = null
|
generator = null
|
||||||
for c in get_children():
|
|
||||||
c.setup_control(generator, [])
|
|
||||||
# Update shader
|
# Update shader
|
||||||
material.shader.code = MMGenBase.generate_preview_shader(source, source.type, shader)
|
material.shader.code = MMGenBase.generate_preview_shader(source, source.type, shader)
|
||||||
# Get parameter values from the shader code
|
# Get parameter values from the shader code
|
||||||
@ -60,13 +55,30 @@ func on_float_parameters_changed(parameter_changes : Dictionary) -> void:
|
|||||||
|
|
||||||
func on_resized() -> void:
|
func on_resized() -> void:
|
||||||
material.set_shader_param("size", rect_size)
|
material.set_shader_param("size", rect_size)
|
||||||
set_generator(generator)
|
|
||||||
|
|
||||||
func value_to_pos(value : Vector2) -> Vector2:
|
func _on_Export_id_pressed(id):
|
||||||
return rect_size*0.5+value*min(rect_size.x, rect_size.y)/1.2
|
var dialog = FileDialog.new()
|
||||||
|
add_child(dialog)
|
||||||
|
dialog.rect_min_size = Vector2(500, 500)
|
||||||
|
dialog.access = FileDialog.ACCESS_FILESYSTEM
|
||||||
|
dialog.mode = FileDialog.MODE_SAVE_FILE
|
||||||
|
dialog.add_filter("*.png;PNG image file")
|
||||||
|
dialog.connect("file_selected", self, "export_as_png", [ 256 << id ])
|
||||||
|
dialog.popup_centered()
|
||||||
|
|
||||||
func value_to_offset(value : Vector2) -> Vector2:
|
func export_as_png(file_name : String, size : int) -> void:
|
||||||
return value*min(rect_size.x, rect_size.y)/1.2
|
var previous_size = material.get_shader_param("size")
|
||||||
|
var previous_margin = material.get_shader_param("margin")
|
||||||
|
var previous_show_tiling = material.get_shader_param("show_tiling")
|
||||||
|
material.set_shader_param("size", Vector2(size, size))
|
||||||
|
material.set_shader_param("margin", 0.0)
|
||||||
|
material.set_shader_param("show_tiling", false)
|
||||||
|
var result = mm_renderer.render_material(material, size, false)
|
||||||
|
while result is GDScriptFunctionState:
|
||||||
|
result = yield(result, "completed")
|
||||||
|
result.save_to_file(file_name)
|
||||||
|
result.release()
|
||||||
|
material.set_shader_param("size", previous_size)
|
||||||
|
material.set_shader_param("margin", previous_margin)
|
||||||
|
material.set_shader_param("show_tiling", previous_show_tiling)
|
||||||
|
|
||||||
func pos_to_value(pos : Vector2) -> Vector2:
|
|
||||||
return (pos - rect_size*0.5)*1.2/min(rect_size.x, rect_size.y)
|
|
||||||
|
9
material_maker/preview/preview_2d_node.gd
Normal file
9
material_maker/preview/preview_2d_node.gd
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
extends "res://material_maker/preview/preview_2d.gd"
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
$ContextMenu.add_submenu_item("Export", "Export")
|
||||||
|
|
||||||
|
func _on_gui_input(event):
|
||||||
|
if event is InputEventMouseButton:
|
||||||
|
if event.pressed and event.button_index == BUTTON_RIGHT:
|
||||||
|
$ContextMenu.popup(Rect2(get_global_mouse_position(), $ContextMenu.get_minimum_size()))
|
27
material_maker/preview/preview_2d_node.tscn
Normal file
27
material_maker/preview/preview_2d_node.tscn
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
[gd_scene load_steps=5 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://material_maker/preview/preview_2d.tscn" type="PackedScene" id=1]
|
||||||
|
[ext_resource path="res://material_maker/preview/preview_2d_node.gd" type="Script" id=2]
|
||||||
|
|
||||||
|
[sub_resource type="Shader" id=1]
|
||||||
|
resource_local_to_scene = true
|
||||||
|
|
||||||
|
[sub_resource type="ShaderMaterial" id=2]
|
||||||
|
resource_local_to_scene = true
|
||||||
|
shader = SubResource( 1 )
|
||||||
|
|
||||||
|
[node name="Preview2D" instance=ExtResource( 1 )]
|
||||||
|
material = SubResource( 2 )
|
||||||
|
script = ExtResource( 2 )
|
||||||
|
shader = ""
|
||||||
|
|
||||||
|
[node name="ContextMenu" type="PopupMenu" parent="." index="0"]
|
||||||
|
margin_right = 109.0
|
||||||
|
margin_bottom = 52.0
|
||||||
|
|
||||||
|
[node name="Export" type="PopupMenu" parent="ContextMenu" index="1"]
|
||||||
|
margin_right = 91.0
|
||||||
|
margin_bottom = 88.0
|
||||||
|
items = [ "256x256", null, 0, false, false, 0, 0, null, "", false, "512x512", null, 0, false, false, 1, 0, null, "", false, "1024x1024", null, 0, false, false, 2, 0, null, "", false, "2048x2048", null, 0, false, false, 3, 0, null, "", false ]
|
||||||
|
[connection signal="gui_input" from="." to="." method="_on_gui_input"]
|
||||||
|
[connection signal="id_pressed" from="ContextMenu/Export" to="." method="_on_Export_id_pressed"]
|
54
material_maker/preview/preview_2d_panel.gd
Normal file
54
material_maker/preview/preview_2d_panel.gd
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
extends "res://material_maker/preview/preview_2d.gd"
|
||||||
|
|
||||||
|
var shader_margin : float = 0
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
update_shader_options()
|
||||||
|
$ContextMenu.add_submenu_item("Export", "Export")
|
||||||
|
|
||||||
|
func set_generator(g : MMGenBase, o : int = 0) -> void:
|
||||||
|
.set_generator(g, o)
|
||||||
|
setup_controls()
|
||||||
|
update_shader_options()
|
||||||
|
|
||||||
|
func setup_controls() -> void:
|
||||||
|
var param_defs = generator.get_parameter_defs() if is_instance_valid(generator) else []
|
||||||
|
for c in get_children():
|
||||||
|
if c.has_method("setup_control"):
|
||||||
|
c.setup_control(generator, param_defs)
|
||||||
|
|
||||||
|
func value_to_pos(value : Vector2) -> Vector2:
|
||||||
|
return rect_size*0.5+value*min(rect_size.x, rect_size.y)/(1+shader_margin)
|
||||||
|
|
||||||
|
func value_to_offset(value : Vector2) -> Vector2:
|
||||||
|
return value*min(rect_size.x, rect_size.y)/(1+shader_margin)
|
||||||
|
|
||||||
|
func pos_to_value(pos : Vector2) -> Vector2:
|
||||||
|
return (pos - rect_size*0.5)*(1+shader_margin)/min(rect_size.x, rect_size.y)
|
||||||
|
|
||||||
|
func update_shader_options() -> void:
|
||||||
|
if $ContextMenu == null:
|
||||||
|
return
|
||||||
|
if $ContextMenu.is_item_checked(0):
|
||||||
|
shader_margin = 0.2
|
||||||
|
material.set_shader_param("show_tiling", true)
|
||||||
|
material.set_shader_param("margin", 0.2)
|
||||||
|
else:
|
||||||
|
shader_margin = 0
|
||||||
|
material.set_shader_param("show_tiling", false)
|
||||||
|
material.set_shader_param("margin", 0)
|
||||||
|
setup_controls()
|
||||||
|
|
||||||
|
func _on_gui_input(event):
|
||||||
|
if event is InputEventMouseButton:
|
||||||
|
if event.pressed and event.button_index == BUTTON_RIGHT:
|
||||||
|
$ContextMenu.popup(Rect2(get_global_mouse_position(), $ContextMenu.get_minimum_size()))
|
||||||
|
|
||||||
|
func _on_ContextMenu_id_pressed(id) -> void:
|
||||||
|
if $ContextMenu.is_item_checkable(id):
|
||||||
|
$ContextMenu.toggle_item_checked(id)
|
||||||
|
match id:
|
||||||
|
0:
|
||||||
|
update_shader_options()
|
||||||
|
_:
|
||||||
|
print("unsupported id "+str(id))
|
@ -1,30 +1,44 @@
|
|||||||
[gd_scene load_steps=8 format=2]
|
[gd_scene load_steps=9 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://material_maker/icons/icons.svg" type="Texture" id=1]
|
[ext_resource path="res://material_maker/icons/icons.svg" type="Texture" id=1]
|
||||||
[ext_resource path="res://material_maker/preview/control_point.tscn" type="PackedScene" id=2]
|
[ext_resource path="res://material_maker/preview/control_point.tscn" type="PackedScene" id=2]
|
||||||
[ext_resource path="res://material_maker/preview/preview_2d.tscn" type="PackedScene" id=3]
|
[ext_resource path="res://material_maker/preview/preview_2d.tscn" type="PackedScene" id=3]
|
||||||
|
[ext_resource path="res://material_maker/preview/preview_2d_panel.gd" type="Script" id=4]
|
||||||
|
|
||||||
[sub_resource type="Shader" id=1]
|
[sub_resource type="Shader" id=1]
|
||||||
code = "shader_type canvas_item;
|
code = "shader_type canvas_item;
|
||||||
|
|
||||||
uniform sampler2D tex;
|
uniform vec2 size = vec2(585.0, 453.0);
|
||||||
uniform vec2 size;
|
uniform bool show_tiling = false;
|
||||||
|
uniform float margin = 0.2;
|
||||||
|
|
||||||
|
vec4 preview_2d(vec2 uv) {
|
||||||
|
return vec4(0.8);
|
||||||
|
}
|
||||||
|
|
||||||
void fragment() {
|
void fragment() {
|
||||||
float ms = max(size.x, size.y);
|
float ms = max(size.x, size.y);
|
||||||
vec2 uv = fract(0.5+1.2*(UV-vec2(0.5))*ms/size.yx);
|
float margin_factor = 1.0+max(0.0, margin);
|
||||||
float is = min(size.x, size.y)/1.2;
|
vec2 uv = 0.5+margin_factor*(UV-vec2(0.5))*ms/size.yx;
|
||||||
vec2 m2 = min(fract(uv), 1.0-fract(uv));
|
float is = min(size.x, size.y)/margin_factor;
|
||||||
vec4 image = texture(tex, uv);
|
vec4 image = preview_2d(fract(uv));
|
||||||
vec3 image_with_background = mix(vec3(mod(floor(uv.x*32.0)+floor(uv.y*32.0), 2.0)), image.xyz, image.a);
|
float checkerboard = mod(floor(uv.x*32.0)+floor(uv.y*32.0), 2.0);
|
||||||
float lines_color = 0.5*(cos(5.0*TIME+100.0*(uv.x+uv.y))+1.0);
|
vec3 image_with_background = mix(vec3(checkerboard), image.xyz, image.a);
|
||||||
COLOR = vec4(mix(image_with_background, vec3(lines_color), step(is*min(m2.x, m2.y), 1.0)), 1.0);
|
if (show_tiling) {
|
||||||
|
vec2 m2 = min(fract(uv), 1.0-fract(uv));
|
||||||
|
float lines_color = 0.5*(cos(5.0*TIME+100.0*(uv.x+uv.y))+1.0);
|
||||||
|
COLOR = vec4(mix(image_with_background, vec3(lines_color), step(is*min(m2.x, m2.y), 1.0)), 1.0);
|
||||||
|
} else {
|
||||||
|
vec2 outside = step(abs(uv-vec2(0.5)), vec2(0.5));
|
||||||
|
COLOR = vec4(mix(vec3(0.0), image_with_background, outside.x*outside.y), 1.0);
|
||||||
|
}
|
||||||
}"
|
}"
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=2]
|
[sub_resource type="ShaderMaterial" id=2]
|
||||||
resource_local_to_scene = true
|
|
||||||
shader = SubResource( 1 )
|
shader = SubResource( 1 )
|
||||||
shader_param/size = Vector2( 585, 492 )
|
shader_param/size = Vector2( 585, 492 )
|
||||||
|
shader_param/show_tiling = false
|
||||||
|
shader_param/margin = 0.5
|
||||||
|
|
||||||
[sub_resource type="AtlasTexture" id=3]
|
[sub_resource type="AtlasTexture" id=3]
|
||||||
flags = 4
|
flags = 4
|
||||||
@ -38,7 +52,32 @@ region = Rect2( 16, 64, 16, 16 )
|
|||||||
|
|
||||||
[node name="Preview2D" instance=ExtResource( 3 )]
|
[node name="Preview2D" instance=ExtResource( 3 )]
|
||||||
material = SubResource( 2 )
|
material = SubResource( 2 )
|
||||||
|
margin_right = -758.0
|
||||||
|
margin_bottom = -267.0
|
||||||
rect_min_size = Vector2( 200, 200 )
|
rect_min_size = Vector2( 200, 200 )
|
||||||
|
script = ExtResource( 4 )
|
||||||
|
shader = "uniform vec2 size;
|
||||||
|
uniform bool show_tiling = true;
|
||||||
|
uniform float margin = 0.5;
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
float ms = max(size.x, size.y);
|
||||||
|
float margin_factor = 1.0+max(0.0, margin);
|
||||||
|
vec2 uv = 0.5+margin_factor*(UV-vec2(0.5))*ms/size.yx;
|
||||||
|
float is = min(size.x, size.y)/margin_factor;
|
||||||
|
vec4 image = preview_2d(fract(uv));
|
||||||
|
float checkerboard = mod(floor(uv.x*32.0)+floor(uv.y*32.0), 2.0);
|
||||||
|
vec3 image_with_background = mix(vec3(checkerboard), image.xyz, image.a);
|
||||||
|
if (show_tiling) {
|
||||||
|
vec2 m2 = min(fract(uv), 1.0-fract(uv));
|
||||||
|
float lines_color = 0.5*(cos(5.0*TIME+100.0*(uv.x+uv.y))+1.0);
|
||||||
|
COLOR = vec4(mix(image_with_background, vec3(lines_color), step(is*min(m2.x, m2.y), 1.0)), 1.0);
|
||||||
|
} else {
|
||||||
|
vec2 outside = step(abs(uv-vec2(0.5)), vec2(0.5));
|
||||||
|
COLOR = vec4(mix(vec3(0.0), image_with_background, outside.x*outside.y), 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
[node name="P1" parent="." index="0" instance=ExtResource( 2 )]
|
[node name="P1" parent="." index="0" instance=ExtResource( 2 )]
|
||||||
visible = false
|
visible = false
|
||||||
@ -128,3 +167,16 @@ mouse_default_cursor_shape = 10
|
|||||||
texture = SubResource( 4 )
|
texture = SubResource( 4 )
|
||||||
parent_control = "P1"
|
parent_control = "P1"
|
||||||
control_type = 2
|
control_type = 2
|
||||||
|
|
||||||
|
[node name="ContextMenu" type="PopupMenu" parent="." index="8"]
|
||||||
|
margin_right = 109.0
|
||||||
|
margin_bottom = 52.0
|
||||||
|
items = [ "Show tiling", null, 1, false, false, 0, 0, null, "", false ]
|
||||||
|
|
||||||
|
[node name="Export" type="PopupMenu" parent="ContextMenu" index="1"]
|
||||||
|
margin_right = 91.0
|
||||||
|
margin_bottom = 88.0
|
||||||
|
items = [ "256x256", null, 0, false, false, 0, 0, null, "", false, "512x512", null, 0, false, false, 1, 0, null, "", false, "1024x1024", null, 0, false, false, 2, 0, null, "", false, "2048x2048", null, 0, false, false, 3, 0, null, "", false ]
|
||||||
|
[connection signal="gui_input" from="." to="." method="_on_gui_input"]
|
||||||
|
[connection signal="id_pressed" from="ContextMenu" to="." method="_on_ContextMenu_id_pressed"]
|
||||||
|
[connection signal="id_pressed" from="ContextMenu/Export" to="." method="_on_Export_id_pressed"]
|
||||||
|
@ -5,6 +5,7 @@ export var value : float = 0.5 setget set_value
|
|||||||
export var min_value : float = 0.0 setget set_min_value
|
export var min_value : float = 0.0 setget set_min_value
|
||||||
export var max_value : float = 1.0 setget set_max_value
|
export var max_value : float = 1.0 setget set_max_value
|
||||||
export var step : float = 0.0 setget set_step
|
export var step : float = 0.0 setget set_step
|
||||||
|
export var float_only : bool = false
|
||||||
|
|
||||||
var sliding : bool = false
|
var sliding : bool = false
|
||||||
var start_position : float
|
var start_position : float
|
||||||
@ -17,14 +18,19 @@ var from_upper_bound : bool = false
|
|||||||
onready var slider = $Slider
|
onready var slider = $Slider
|
||||||
onready var cursor = $Slider/Cursor
|
onready var cursor = $Slider/Cursor
|
||||||
|
|
||||||
signal value_changed
|
signal value_changed(value)
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
do_update()
|
do_update()
|
||||||
|
|
||||||
func set_value(v : float) -> void:
|
func set_value(v) -> void:
|
||||||
value = v
|
if v is float:
|
||||||
do_update()
|
value = v
|
||||||
|
do_update()
|
||||||
|
$Slider.visible = true
|
||||||
|
elif v is String and !float_only:
|
||||||
|
text = v
|
||||||
|
$Slider.visible = false
|
||||||
|
|
||||||
func set_min_value(v : float) -> void:
|
func set_min_value(v : float) -> void:
|
||||||
min_value = v
|
min_value = v
|
||||||
@ -39,7 +45,7 @@ func set_step(v : float) -> void:
|
|||||||
do_update()
|
do_update()
|
||||||
|
|
||||||
func do_update(update_text : bool = true) -> void:
|
func do_update(update_text : bool = true) -> void:
|
||||||
if update_text:
|
if update_text and $Slider.visible:
|
||||||
text = str(value)
|
text = str(value)
|
||||||
if cursor != null:
|
if cursor != null:
|
||||||
if max_value != min_value:
|
if max_value != min_value:
|
||||||
@ -58,6 +64,8 @@ func get_modifiers(event):
|
|||||||
return modifiers
|
return modifiers
|
||||||
|
|
||||||
func _on_LineEdit_gui_input(event : InputEvent) -> void:
|
func _on_LineEdit_gui_input(event : InputEvent) -> void:
|
||||||
|
if !$Slider.visible:
|
||||||
|
return
|
||||||
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
|
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
|
||||||
if event.is_pressed():
|
if event.is_pressed():
|
||||||
last_position = event.position.x
|
last_position = event.position.x
|
||||||
@ -110,9 +118,12 @@ func _on_LineEdit_text_changed(new_text : String) -> void:
|
|||||||
func _on_LineEdit_text_entered(new_text : String) -> void:
|
func _on_LineEdit_text_entered(new_text : String) -> void:
|
||||||
if new_text.is_valid_float():
|
if new_text.is_valid_float():
|
||||||
value = new_text.to_float()
|
value = new_text.to_float()
|
||||||
do_update()
|
do_update()
|
||||||
emit_signal("value_changed", value)
|
emit_signal("value_changed", value)
|
||||||
|
$Slider.visible = true
|
||||||
|
else:
|
||||||
|
emit_signal("value_changed", new_text)
|
||||||
|
$Slider.visible = false
|
||||||
|
|
||||||
func _on_LineEdit_focus_exited() -> void:
|
func _on_LineEdit_focus_exited() -> void:
|
||||||
do_update()
|
_on_LineEdit_text_entered(text)
|
||||||
emit_signal("value_changed", value)
|
|
||||||
|
@ -10,7 +10,7 @@ margin_left = -1280.0
|
|||||||
margin_right = -1222.0
|
margin_right = -1222.0
|
||||||
margin_bottom = -696.0
|
margin_bottom = -696.0
|
||||||
text = "0.5"
|
text = "0.5"
|
||||||
max_length = 20
|
max_length = 100
|
||||||
context_menu_enabled = false
|
context_menu_enabled = false
|
||||||
caret_blink = true
|
caret_blink = true
|
||||||
script = ExtResource( 1 )
|
script = ExtResource( 1 )
|
||||||
|
Loading…
Reference in New Issue
Block a user