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) {
|
||||
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():
|
||||
var parameter_def : Dictionary = get_parameter_def(n)
|
||||
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
|
||||
get_tree().call_group("preview", "on_float_parameters_changed", { parameter_name:v })
|
||||
return
|
||||
|
@ -149,27 +149,33 @@ func replace_input(string : String, context, input : String, type : String, src
|
||||
func is_word_letter(l) -> bool:
|
||||
return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1
|
||||
|
||||
func replace_variable(string : String, variable : String, value : String) -> String:
|
||||
string = string.replace("$(%s)" % variable, value)
|
||||
var keyword_size = variable.length()+1
|
||||
var new_string = ""
|
||||
while !string.empty():
|
||||
var pos = string.find("$"+variable)
|
||||
if pos == -1:
|
||||
new_string += string
|
||||
func replace_variables(string : String, variables : Dictionary) -> String:
|
||||
while true:
|
||||
var old_string = string
|
||||
for variable in variables.keys():
|
||||
string = string.replace("$(%s)" % variable, variables[variable])
|
||||
var keyword_size : int = variable.length()+1
|
||||
var 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
|
||||
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 += value
|
||||
else:
|
||||
new_string += "$"+variable
|
||||
string = string.right(keyword_size)
|
||||
return new_string
|
||||
return string
|
||||
|
||||
func subst(string : String, context : MMGenContext, uv : String = "") -> Dictionary:
|
||||
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_code = ""
|
||||
var required_textures = {}
|
||||
string = replace_variable(string, "name", genname)
|
||||
var variables = {}
|
||||
variables["name"] = genname
|
||||
if uv != "":
|
||||
var genname_uv = genname+"_"+str(context.get_variant(self, uv))
|
||||
string = replace_variable(string, "name_uv", genname_uv)
|
||||
var tmp_string = replace_variable(string, "seed", "seed_"+genname)
|
||||
if tmp_string != string:
|
||||
string = tmp_string
|
||||
variables["name_uv"] = genname_uv
|
||||
variables["seed"] = "seed_"+genname
|
||||
variables["node_id"] = str(get_instance_id())
|
||||
if shader_model.has("parameters") and typeof(shader_model.parameters) == TYPE_ARRAY:
|
||||
for p in shader_model.parameters:
|
||||
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_string = null
|
||||
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":
|
||||
value_string = "%.9f" % pow(2, value)
|
||||
elif p.type == "enum":
|
||||
@ -207,9 +216,11 @@ func subst(string : String, context : MMGenContext, uv : String = "") -> Diction
|
||||
else:
|
||||
print("Cannot replace parameter of type "+p.type)
|
||||
if value_string != null:
|
||||
string = replace_variable(string, p.name, value_string)
|
||||
variables[p.name] = value_string
|
||||
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:
|
||||
var cont = true
|
||||
while cont:
|
||||
@ -252,7 +263,7 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
|
||||
if has_randomness():
|
||||
rv.defs += "uniform int seed_%s = %d;\n" % [ genname, get_seed() ]
|
||||
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] ]
|
||||
elif p.type == "color":
|
||||
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])
|
||||
var params = g.get_shader_params(genname+"_"+p.name)
|
||||
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)
|
||||
# Generate functions for inputs
|
||||
if shader_model.has("inputs"):
|
||||
|
@ -31,7 +31,21 @@ func _ready() -> void:
|
||||
add_valid_connection_type(42, t)
|
||||
|
||||
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()
|
||||
if scancode_with_modifiers == KEY_DELETE or scancode_with_modifiers == KEY_BACKSPACE:
|
||||
remove_selection()
|
||||
@ -390,13 +404,6 @@ func set_last_selected(node) -> void:
|
||||
else:
|
||||
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:
|
||||
# Check if the connector was actually dragged
|
||||
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):
|
||||
last_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="disconnection_request" from="." to="." method="disconnect_node"]
|
||||
[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="paste_nodes_request" from="." to="." method="paste"]
|
||||
[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:
|
||||
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.visible = false
|
||||
preview_position = get_child_count()
|
||||
|
@ -23,17 +23,19 @@ func update_node() -> void:
|
||||
var color = Color(0.0, 0.5, 0.0, 0.5)
|
||||
for p in generator.get_io_defs():
|
||||
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
|
||||
if generator.is_editable():
|
||||
port = preload("res://material_maker/nodes/ios/port.tscn").instance()
|
||||
add_child(port)
|
||||
if p.has("name"):
|
||||
port.set_label(p.name)
|
||||
port.set_type(p.type)
|
||||
else:
|
||||
port = Label.new()
|
||||
add_child(port)
|
||||
port.text = p.name
|
||||
add_child(port)
|
||||
if generator.is_editable():
|
||||
var add_button : Button = preload("res://material_maker/nodes/ios/add.tscn").instance()
|
||||
add_child(add_button)
|
||||
|
@ -2,8 +2,10 @@
|
||||
|
||||
[ext_resource path="res://material_maker/nodes/ios.gd" type="Script" id=1]
|
||||
|
||||
|
||||
[node name="IOs" type="GraphNode"]
|
||||
margin_right = 32.0
|
||||
margin_bottom = 29.0
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
@ -1,10 +1,16 @@
|
||||
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:
|
||||
$Name.set_text(l)
|
||||
|
||||
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:
|
||||
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/widgets/linked_widgets/editable_label.tscn" type="PackedScene" id=3]
|
||||
|
||||
|
||||
|
||||
|
||||
[sub_resource type="AtlasTexture" id=1]
|
||||
flags = 4
|
||||
atlas = ExtResource( 2 )
|
||||
@ -54,12 +51,11 @@ rect_min_size = Vector2( 30, 0 )
|
||||
|
||||
[node name="Type" type="OptionButton" parent="."]
|
||||
margin_left = 118.0
|
||||
margin_right = 222.0
|
||||
margin_right = 220.0
|
||||
margin_bottom = 20.0
|
||||
rect_min_size = Vector2( 102, 0 )
|
||||
hint_tooltip = "Input flag"
|
||||
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
|
||||
[connection signal="pressed" from="Delete" to="." method="_on_Delete_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_xy:
|
||||
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 != "":
|
||||
pos.y = generator.get_parameter(parameter_y)
|
||||
var p = generator.get_parameter(parameter_y)
|
||||
if p is float:
|
||||
pos.y = p
|
||||
else:
|
||||
var r = 0.25
|
||||
var a = 0
|
||||
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 != "":
|
||||
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.y = r*sin(a)
|
||||
return pos
|
||||
@ -101,8 +109,12 @@ func get_parent_value() -> Vector2:
|
||||
|
||||
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):
|
||||
update_position(get_value())
|
||||
update()
|
||||
if v is float:
|
||||
visible = true
|
||||
update_position(get_value())
|
||||
update()
|
||||
else:
|
||||
visible = false
|
||||
|
||||
func update_parameters(value : Vector2) -> void:
|
||||
if !is_instance_valid(generator):
|
||||
|
@ -13,9 +13,6 @@ func set_generator(g : MMGenBase, o : int = 0) -> void:
|
||||
generator = g
|
||||
output = o
|
||||
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()
|
||||
if ! gen_output_defs.empty():
|
||||
var context : MMGenContext = MMGenContext.new()
|
||||
@ -25,9 +22,7 @@ func set_generator(g : MMGenBase, o : int = 0) -> void:
|
||||
if source.empty():
|
||||
source = MMGenBase.DEFAULT_GENERATED_SHADER
|
||||
else:
|
||||
g = null
|
||||
for c in get_children():
|
||||
c.setup_control(generator, [])
|
||||
generator = null
|
||||
# Update shader
|
||||
material.shader.code = MMGenBase.generate_preview_shader(source, source.type, shader)
|
||||
# Get parameter values from the shader code
|
||||
@ -60,13 +55,30 @@ func on_float_parameters_changed(parameter_changes : Dictionary) -> void:
|
||||
|
||||
func on_resized() -> void:
|
||||
material.set_shader_param("size", rect_size)
|
||||
set_generator(generator)
|
||||
|
||||
func value_to_pos(value : Vector2) -> Vector2:
|
||||
return rect_size*0.5+value*min(rect_size.x, rect_size.y)/1.2
|
||||
func _on_Export_id_pressed(id):
|
||||
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:
|
||||
return value*min(rect_size.x, rect_size.y)/1.2
|
||||
func export_as_png(file_name : String, size : int) -> void:
|
||||
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/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_panel.gd" type="Script" id=4]
|
||||
|
||||
[sub_resource type="Shader" id=1]
|
||||
code = "shader_type canvas_item;
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 size;
|
||||
uniform vec2 size = vec2(585.0, 453.0);
|
||||
uniform bool show_tiling = false;
|
||||
uniform float margin = 0.2;
|
||||
|
||||
vec4 preview_2d(vec2 uv) {
|
||||
return vec4(0.8);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
float ms = max(size.x, size.y);
|
||||
vec2 uv = fract(0.5+1.2*(UV-vec2(0.5))*ms/size.yx);
|
||||
float is = min(size.x, size.y)/1.2;
|
||||
vec2 m2 = min(fract(uv), 1.0-fract(uv));
|
||||
vec4 image = texture(tex, 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 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);
|
||||
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);
|
||||
}
|
||||
}"
|
||||
|
||||
[sub_resource type="ShaderMaterial" id=2]
|
||||
resource_local_to_scene = true
|
||||
shader = SubResource( 1 )
|
||||
shader_param/size = Vector2( 585, 492 )
|
||||
shader_param/show_tiling = false
|
||||
shader_param/margin = 0.5
|
||||
|
||||
[sub_resource type="AtlasTexture" id=3]
|
||||
flags = 4
|
||||
@ -38,7 +52,32 @@ region = Rect2( 16, 64, 16, 16 )
|
||||
|
||||
[node name="Preview2D" instance=ExtResource( 3 )]
|
||||
material = SubResource( 2 )
|
||||
margin_right = -758.0
|
||||
margin_bottom = -267.0
|
||||
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 )]
|
||||
visible = false
|
||||
@ -128,3 +167,16 @@ mouse_default_cursor_shape = 10
|
||||
texture = SubResource( 4 )
|
||||
parent_control = "P1"
|
||||
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 max_value : float = 1.0 setget set_max_value
|
||||
export var step : float = 0.0 setget set_step
|
||||
export var float_only : bool = false
|
||||
|
||||
var sliding : bool = false
|
||||
var start_position : float
|
||||
@ -17,14 +18,19 @@ var from_upper_bound : bool = false
|
||||
onready var slider = $Slider
|
||||
onready var cursor = $Slider/Cursor
|
||||
|
||||
signal value_changed
|
||||
signal value_changed(value)
|
||||
|
||||
func _ready() -> void:
|
||||
do_update()
|
||||
|
||||
func set_value(v : float) -> void:
|
||||
value = v
|
||||
do_update()
|
||||
func set_value(v) -> void:
|
||||
if v is float:
|
||||
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:
|
||||
min_value = v
|
||||
@ -39,7 +45,7 @@ func set_step(v : float) -> void:
|
||||
do_update()
|
||||
|
||||
func do_update(update_text : bool = true) -> void:
|
||||
if update_text:
|
||||
if update_text and $Slider.visible:
|
||||
text = str(value)
|
||||
if cursor != null:
|
||||
if max_value != min_value:
|
||||
@ -58,6 +64,8 @@ func get_modifiers(event):
|
||||
return modifiers
|
||||
|
||||
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_pressed():
|
||||
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:
|
||||
if new_text.is_valid_float():
|
||||
value = new_text.to_float()
|
||||
do_update()
|
||||
emit_signal("value_changed", value)
|
||||
do_update()
|
||||
emit_signal("value_changed", value)
|
||||
$Slider.visible = true
|
||||
else:
|
||||
emit_signal("value_changed", new_text)
|
||||
$Slider.visible = false
|
||||
|
||||
func _on_LineEdit_focus_exited() -> void:
|
||||
do_update()
|
||||
emit_signal("value_changed", value)
|
||||
_on_LineEdit_text_entered(text)
|
||||
|
@ -10,7 +10,7 @@ margin_left = -1280.0
|
||||
margin_right = -1222.0
|
||||
margin_bottom = -696.0
|
||||
text = "0.5"
|
||||
max_length = 20
|
||||
max_length = 100
|
||||
context_menu_enabled = false
|
||||
caret_blink = true
|
||||
script = ExtResource( 1 )
|
||||
|
Loading…
Reference in New Issue
Block a user