diff --git a/addons/material_maker/engine/gen_base.gd b/addons/material_maker/engine/gen_base.gd index b2be44b..936ef64 100644 --- a/addons/material_maker/engine/gen_base.gd +++ b/addons/material_maker/engine/gen_base.gd @@ -2,6 +2,10 @@ tool extends Node class_name MMGenBase +""" +Base class for texture generators, that defines their API +""" + class OutputPort: var generator : MMGenBase = null var output_index : int = 0 @@ -21,7 +25,6 @@ func _ready(): func init_parameters(): for p in get_parameter_defs(): - print(p) if !parameters.has(p.name): if p.has("default"): parameters[p.name] = MMType.deserialize_value(p.default) @@ -40,6 +43,9 @@ func get_type_name(): func get_parameter_defs(): return [] +func set_parameter(n : String, v): + parameters[n] = v + func get_input_defs(): return [] diff --git a/addons/material_maker/engine/gen_buffer.gd b/addons/material_maker/engine/gen_buffer.gd index 58bcce8..92efdfa 100644 --- a/addons/material_maker/engine/gen_buffer.gd +++ b/addons/material_maker/engine/gen_buffer.gd @@ -1,8 +1,11 @@ tool -extends MMGenBase +extends MMGenTexture class_name MMGenBuffer -var texture : ImageTexture = ImageTexture.new() +""" +Texture generator buffers, that render their input in a specific resolution and provide the result as output. +This is useful when using generators that sample their inputs several times (such as convolutions) +""" func _ready(): if !parameters.has("size"): @@ -20,9 +23,6 @@ func get_parameter_defs(): func get_input_defs(): return [ { name="in", type="rgba" } ] -func get_output_defs(): - return [ { rgba="" } ] - func _get_shader_code(uv : String, output_index : int, context : MMGenContext): var source = get_source(0) if source != null: @@ -34,12 +34,7 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext): var image : Image = context.renderer.get_texture().get_data() texture.create_from_image(image) texture.flags = 0 - var rv = { defs="" } - var variant_index = context.get_variant(self, uv) - if variant_index == -1: - variant_index = context.get_variant(self, uv) - var texture_name = name+"_tex" - rv.code = "vec4 %s_%d = texture(%s, %s);\n" % [ name, variant_index, texture_name, uv ] - rv.rgba = "%s_%d" % [ name, variant_index ] - rv.textures = { texture_name:texture } - return rv \ No newline at end of file + var rv = ._get_shader_code(uv, output_index, context) + while rv is GDScriptFunctionState: + rv = yield(rv, "completed") + return rv diff --git a/addons/material_maker/engine/gen_image.gd b/addons/material_maker/engine/gen_image.gd new file mode 100644 index 0000000..9d89b9e --- /dev/null +++ b/addons/material_maker/engine/gen_image.gd @@ -0,0 +1,21 @@ +tool +extends MMGenTexture +class_name MMGenImage + +""" +Texture generator from image +""" + +func get_type(): + return "image" + +func get_type_name(): + return "Image" + +func get_parameter_defs(): + return [ { name="image", type="path" } ] + +func set_parameter(n : String, v): + .set_parameter(n, v) + if n == "image": + texture.load(v) diff --git a/addons/material_maker/engine/gen_texture.gd b/addons/material_maker/engine/gen_texture.gd new file mode 100644 index 0000000..dafb901 --- /dev/null +++ b/addons/material_maker/engine/gen_texture.gd @@ -0,0 +1,23 @@ +tool +extends MMGenBase +class_name MMGenTexture + +""" +Base class for texture generators that provide a texture as output +""" + +var texture : ImageTexture = ImageTexture.new() + +func get_output_defs(): + return [ { rgba="" } ] + +func _get_shader_code(uv : String, output_index : int, context : MMGenContext): + var rv = { defs="" } + var variant_index = context.get_variant(self, uv) + if variant_index == -1: + variant_index = context.get_variant(self, uv) + var texture_name = name+"_tex" + rv.code = "vec4 %s_%d = texture(%s, %s);\n" % [ name, variant_index, texture_name, uv ] + rv.rgba = "%s_%d" % [ name, variant_index ] + rv.textures = { texture_name:texture } + return rv \ No newline at end of file diff --git a/addons/material_maker/engine/loader.gd b/addons/material_maker/engine/loader.gd index a225295..a4253dd 100644 --- a/addons/material_maker/engine/loader.gd +++ b/addons/material_maker/engine/loader.gd @@ -40,6 +40,8 @@ func create_gen(data) -> MMGenBase: generator = MMGenMaterial.new() elif data.type == "buffer": generator = MMGenBuffer.new() + elif data.type == "image": + generator = MMGenImage.new() else: var file = File.new() if file.open("res://addons/material_maker/library/"+data.type+".mml", File.READ) == OK: diff --git a/addons/material_maker/graph_edit.tscn b/addons/material_maker/graph_edit.tscn index 04a242f..2b611c3 100644 --- a/addons/material_maker/graph_edit.tscn +++ b/addons/material_maker/graph_edit.tscn @@ -7,7 +7,6 @@ self_modulate = Color( 1, 1, 1, 0 ) anchor_right = 1.0 anchor_bottom = 1.0 right_disconnects = true -scroll_offset = Vector2( -325, -250 ) use_snap = false script = ExtResource( 1 ) diff --git a/addons/material_maker/nodes/generic.gd b/addons/material_maker/nodes/generic.gd index f515c8e..cb8bfb8 100644 --- a/addons/material_maker/nodes/generic.gd +++ b/addons/material_maker/nodes/generic.gd @@ -4,18 +4,13 @@ var generator = null setget set_generator var controls = [] -var uses_seed : bool = false - # Called when the node enters the scene tree for the first time. func _ready(): pass # Replace with function body. func set_generator(g): generator = g - if g.get("shader_model") != null: - update_node(g.shader_model) - else: - update_node({}) + update_node() func initialize_properties(): for o in controls: @@ -69,9 +64,7 @@ func _on_gradient_changed(new_gradient, variable): generator.parameters[variable] = new_gradient update_shaders() -func update_node(data): - if typeof(data) != TYPE_DICTIONARY: - return +func update_node(): # Clean node var custom_node_buttons = null for c in get_children(): @@ -82,9 +75,6 @@ func update_node(data): custom_node_buttons = c # Rebuild node title = generator.get_type_name() - uses_seed = false - if data.has("instance") and data.instance.find("$(seed)"): - uses_seed = true # Parameters controls = [] var sizer = null diff --git a/addons/material_maker/nodes/image.gd b/addons/material_maker/nodes/image.gd new file mode 100644 index 0000000..45d1313 --- /dev/null +++ b/addons/material_maker/nodes/image.gd @@ -0,0 +1,30 @@ +tool +extends "res://addons/material_maker/node_base.gd" + +var generator = null + +func _ready(): + set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1)) + +func set_texture(path): + if path == null: + return + if generator != null: + generator.set_parameter("image", path) + $TextureButton.texture_normal = generator.texture + +func get_textures(): + var list = {} + list[name] = $TextureButton.texture_normal + return list + +func _on_TextureButton_pressed(): + var dialog = FileDialog.new() + add_child(dialog) + dialog.rect_min_size = Vector2(500, 500) + dialog.access = FileDialog.ACCESS_FILESYSTEM + dialog.mode = FileDialog.MODE_OPEN_FILE + dialog.add_filter("*.png;PNG image") + dialog.add_filter("*.jpg;JPG image") + dialog.connect("file_selected", self, "set_texture") + dialog.popup_centered() diff --git a/addons/material_maker/nodes/image/image.tscn b/addons/material_maker/nodes/image.tscn similarity index 87% rename from addons/material_maker/nodes/image/image.tscn rename to addons/material_maker/nodes/image.tscn index 7eafbfb..ceea37f 100644 --- a/addons/material_maker/nodes/image/image.tscn +++ b/addons/material_maker/nodes/image.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/material_maker/nodes/image/image.gd" type="Script" id=1] +[ext_resource path="res://addons/material_maker/nodes/image.gd" type="Script" id=1] [ext_resource path="res://addons/material_maker/nodes/image/godot_logo.png" type="Texture" id=2] [sub_resource type="Theme" id=1] @@ -20,7 +20,7 @@ slot/0/left_type = 0 slot/0/left_color = Color( 0.5, 0.5, 1, 1 ) slot/0/right_enabled = true slot/0/right_type = 0 -slot/0/right_color = Color( 0.5, 0.5, 1, 1 ) +slot/0/right_color = Color( 0, 1, 0, 0.501961 ) script = ExtResource( 1 ) [node name="TextureButton" type="TextureButton" parent="."] @@ -33,5 +33,4 @@ rect_clip_content = true texture_normal = ExtResource( 2 ) expand = true stretch_mode = 5 - [connection signal="pressed" from="TextureButton" to="." method="_on_TextureButton_pressed"] diff --git a/addons/material_maker/nodes/image/image.gd b/addons/material_maker/nodes/image/image.gd deleted file mode 100644 index 746c75c..0000000 --- a/addons/material_maker/nodes/image/image.gd +++ /dev/null @@ -1,53 +0,0 @@ -tool -extends "res://addons/material_maker/node_base.gd" - -var file_path = null - -func _ready(): - set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1)) - -func set_texture(path): - file_path = path - var texture = ImageTexture.new() - if path != null: - texture.load(path) - $TextureButton.texture_normal = texture - update_shaders() - -func get_textures(): - var list = {} - list[name] = $TextureButton.texture_normal - return list - -func _get_shader_code(uv, slot = 0): - var rv = { defs="", code="" } - if generated_variants.empty(): - rv.defs = "uniform sampler2D %s_tex;\n" % [ name ] - var variant_index = generated_variants.find(uv) - if variant_index == -1: - variant_index = generated_variants.size() - generated_variants.append(uv) - rv.code = "vec4 %s_%d_rgba = texture(%s_tex, %s);\n" % [ name, variant_index, name, uv ] - rv.rgba = "%s_%d_rgba" % [ name, variant_index ] - return rv - -func _on_TextureButton_pressed(): - var dialog = FileDialog.new() - add_child(dialog) - dialog.rect_min_size = Vector2(500, 500) - dialog.access = FileDialog.ACCESS_FILESYSTEM - dialog.mode = FileDialog.MODE_OPEN_FILE - dialog.add_filter("*.png;PNG image") - dialog.add_filter("*.jpg;JPG image") - dialog.connect("file_selected", self, "set_texture") - dialog.popup_centered() - -func serialize(): - var data = .serialize() - data.file_path = file_path - return data - -func deserialize(data): - if data.has("file_path"): - set_texture(data.file_path) - .deserialize(data) diff --git a/addons/material_maker/nodes/switch/switch.tscn b/addons/material_maker/nodes/switch/switch.tscn index c676ab2..34ed4a1 100644 --- a/addons/material_maker/nodes/switch/switch.tscn +++ b/addons/material_maker/nodes/switch/switch.tscn @@ -2,34 +2,17 @@ [ext_resource path="res://addons/material_maker/nodes/switch/switch.gd" type="Script" id=1] - [sub_resource type="Theme" id=1] - -[node name="Switch" type="GraphNode" index="0"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 +[node name="Switch" type="GraphNode"] margin_left = 1.0 margin_top = 1.0 -margin_right = 87.0 -margin_bottom = 89.0 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false +margin_right = 100.0 +margin_bottom = 110.0 mouse_filter = 1 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 theme = SubResource( 1 ) title = "Switch" -offset = Vector2( 0, 0 ) show_close = true -resizable = false -selected = false -comment = false -overlay = 0 slot/0/left_enabled = false slot/0/left_type = 0 slot/0/left_color = Color( 0.498039, 0.498039, 1, 1 ) @@ -61,190 +44,64 @@ slot/4/right_enabled = false slot/4/right_type = 0 slot/4/right_color = Color( 1, 0, 0, 1 ) script = ExtResource( 1 ) -_sections_unfolded = [ "Theme", "slot", "slot/0", "slot/1", "slot/2", "slot/3", "slot/4" ] -[node name="source" type="OptionButton" parent="." index="0"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 +[node name="source" type="OptionButton" parent="."] margin_left = 16.0 margin_top = 24.0 -margin_right = 70.0 +margin_right = 83.0 margin_bottom = 44.0 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false -focus_mode = 2 -mouse_filter = 0 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 -toggle_mode = false -action_mode = 0 -enabled_focus_mode = 2 -shortcut = null -group = null text = "1" -flat = false -align = 0 items = [ "1", null, false, 0, null, "2", null, false, 1, null ] selected = 0 -[node name="Label1" type="Label" parent="." index="1"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 +[node name="Label1" type="Label" parent="."] margin_left = 16.0 margin_top = 44.0 -margin_right = 70.0 +margin_right = 83.0 margin_bottom = 58.0 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false -mouse_filter = 2 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 4 text = "A1" -percent_visible = 1.0 -lines_skipped = 0 -max_lines_visible = -1 -[node name="HBoxContainer1" type="HBoxContainer" parent="." index="2"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 +[node name="HBoxContainer1" type="HBoxContainer" parent="."] margin_left = 16.0 margin_top = 59.0 -margin_right = 70.0 +margin_right = 83.0 margin_bottom = 73.0 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false -mouse_filter = 1 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 -alignment = 0 -[node name="Label1" type="Label" parent="HBoxContainer1" index="0"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_right = 41.0 -margin_bottom = 14.0 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false -mouse_filter = 2 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 3 -size_flags_vertical = 4 -text = "B1" -percent_visible = 1.0 -lines_skipped = 0 -max_lines_visible = -1 - -[node name="Label2" type="Label" parent="HBoxContainer1" index="1"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_left = 45.0 +[node name="Label1" type="Label" parent="HBoxContainer1"] margin_right = 54.0 margin_bottom = 14.0 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false -mouse_filter = 2 -mouse_default_cursor_shape = 0 +size_flags_horizontal = 3 +text = "B1" + +[node name="Label2" type="Label" parent="HBoxContainer1"] +margin_left = 58.0 +margin_right = 67.0 +margin_bottom = 14.0 size_flags_horizontal = 9 -size_flags_vertical = 4 text = "A" -percent_visible = 1.0 -lines_skipped = 0 -max_lines_visible = -1 -[node name="HBoxContainer2" type="HBoxContainer" parent="." index="3"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 +[node name="HBoxContainer2" type="HBoxContainer" parent="."] margin_left = 16.0 margin_top = 74.0 -margin_right = 70.0 +margin_right = 83.0 margin_bottom = 88.0 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false -mouse_filter = 1 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 -alignment = 0 -[node name="Label1" type="Label" parent="HBoxContainer2" index="0"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_right = 41.0 -margin_bottom = 14.0 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false -mouse_filter = 2 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 3 -size_flags_vertical = 4 -text = "A2" -percent_visible = 1.0 -lines_skipped = 0 -max_lines_visible = -1 - -[node name="Label2" type="Label" parent="HBoxContainer2" index="1"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_left = 45.0 +[node name="Label1" type="Label" parent="HBoxContainer2"] margin_right = 54.0 margin_bottom = 14.0 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false -mouse_filter = 2 -mouse_default_cursor_shape = 0 +size_flags_horizontal = 3 +text = "A2" + +[node name="Label2" type="Label" parent="HBoxContainer2"] +margin_left = 58.0 +margin_right = 67.0 +margin_bottom = 14.0 size_flags_horizontal = 9 -size_flags_vertical = 4 text = "B" -percent_visible = 1.0 -lines_skipped = 0 -max_lines_visible = -1 -[node name="Label2" type="Label" parent="." index="4"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 +[node name="Label2" type="Label" parent="."] margin_left = 16.0 margin_top = 89.0 -margin_right = 70.0 +margin_right = 83.0 margin_bottom = 103.0 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = false -mouse_filter = 2 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 4 text = "B2" -percent_visible = 1.0 -lines_skipped = 0 -max_lines_visible = -1 - - diff --git a/project.godot b/project.godot index 42fc611..8442bec 100644 --- a/project.godot +++ b/project.godot @@ -14,7 +14,7 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://addons/material_maker/engine/gen_base.gd" }, { -"base": "MMGenBase", +"base": "MMGenTexture", "class": "MMGenBuffer", "language": "GDScript", "path": "res://addons/material_maker/engine/gen_buffer.gd" @@ -34,6 +34,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://addons/material_maker/engine/gen_graph.gd" }, { +"base": "MMGenTexture", +"class": "MMGenImage", +"language": "GDScript", +"path": "res://addons/material_maker/engine/gen_image.gd" +}, { "base": "Object", "class": "MMGenLoader", "language": "GDScript", @@ -54,6 +59,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://addons/material_maker/engine/gen_shader.gd" }, { +"base": "MMGenBase", +"class": "MMGenTexture", +"language": "GDScript", +"path": "res://addons/material_maker/engine/gen_texture.gd" +}, { "base": "Object", "class": "MMGradient", "language": "GDScript", @@ -70,10 +80,12 @@ _global_script_class_icons={ "MMGenContext": "", "MMGenConvolution": "", "MMGenGraph": "", +"MMGenImage": "", "MMGenLoader": "", "MMGenMaterial": "", "MMGenRenderer": "", "MMGenShader": "", +"MMGenTexture": "", "MMGradient": "", "MMType": "" }