More refactoring and added image "generator"

This commit is contained in:
Rodolphe Suescun 2019-08-25 23:27:07 +02:00
parent 9d650c98a1
commit 0bcdbb2204
12 changed files with 138 additions and 257 deletions

View File

@ -2,6 +2,10 @@ tool
extends Node extends Node
class_name MMGenBase class_name MMGenBase
"""
Base class for texture generators, that defines their API
"""
class OutputPort: class OutputPort:
var generator : MMGenBase = null var generator : MMGenBase = null
var output_index : int = 0 var output_index : int = 0
@ -21,7 +25,6 @@ func _ready():
func init_parameters(): func init_parameters():
for p in get_parameter_defs(): for p in get_parameter_defs():
print(p)
if !parameters.has(p.name): if !parameters.has(p.name):
if p.has("default"): if p.has("default"):
parameters[p.name] = MMType.deserialize_value(p.default) parameters[p.name] = MMType.deserialize_value(p.default)
@ -40,6 +43,9 @@ func get_type_name():
func get_parameter_defs(): func get_parameter_defs():
return [] return []
func set_parameter(n : String, v):
parameters[n] = v
func get_input_defs(): func get_input_defs():
return [] return []

View File

@ -1,8 +1,11 @@
tool tool
extends MMGenBase extends MMGenTexture
class_name MMGenBuffer 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(): func _ready():
if !parameters.has("size"): if !parameters.has("size"):
@ -20,9 +23,6 @@ func get_parameter_defs():
func get_input_defs(): func get_input_defs():
return [ { name="in", type="rgba" } ] return [ { name="in", type="rgba" } ]
func get_output_defs():
return [ { rgba="" } ]
func _get_shader_code(uv : String, output_index : int, context : MMGenContext): func _get_shader_code(uv : String, output_index : int, context : MMGenContext):
var source = get_source(0) var source = get_source(0)
if source != null: 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() var image : Image = context.renderer.get_texture().get_data()
texture.create_from_image(image) texture.create_from_image(image)
texture.flags = 0 texture.flags = 0
var rv = { defs="" } var rv = ._get_shader_code(uv, output_index, context)
var variant_index = context.get_variant(self, uv) while rv is GDScriptFunctionState:
if variant_index == -1: rv = yield(rv, "completed")
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 return rv

View File

@ -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)

View File

@ -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

View File

@ -40,6 +40,8 @@ func create_gen(data) -> MMGenBase:
generator = MMGenMaterial.new() generator = MMGenMaterial.new()
elif data.type == "buffer": elif data.type == "buffer":
generator = MMGenBuffer.new() generator = MMGenBuffer.new()
elif data.type == "image":
generator = MMGenImage.new()
else: else:
var file = File.new() var file = File.new()
if file.open("res://addons/material_maker/library/"+data.type+".mml", File.READ) == OK: if file.open("res://addons/material_maker/library/"+data.type+".mml", File.READ) == OK:

View File

@ -7,7 +7,6 @@ self_modulate = Color( 1, 1, 1, 0 )
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
right_disconnects = true right_disconnects = true
scroll_offset = Vector2( -325, -250 )
use_snap = false use_snap = false
script = ExtResource( 1 ) script = ExtResource( 1 )

View File

@ -4,18 +4,13 @@ var generator = null setget set_generator
var controls = [] var controls = []
var uses_seed : bool = false
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready(): func _ready():
pass # Replace with function body. pass # Replace with function body.
func set_generator(g): func set_generator(g):
generator = g generator = g
if g.get("shader_model") != null: update_node()
update_node(g.shader_model)
else:
update_node({})
func initialize_properties(): func initialize_properties():
for o in controls: for o in controls:
@ -69,9 +64,7 @@ func _on_gradient_changed(new_gradient, variable):
generator.parameters[variable] = new_gradient generator.parameters[variable] = new_gradient
update_shaders() update_shaders()
func update_node(data): func update_node():
if typeof(data) != TYPE_DICTIONARY:
return
# Clean node # Clean node
var custom_node_buttons = null var custom_node_buttons = null
for c in get_children(): for c in get_children():
@ -82,9 +75,6 @@ func update_node(data):
custom_node_buttons = c custom_node_buttons = c
# Rebuild node # Rebuild node
title = generator.get_type_name() title = generator.get_type_name()
uses_seed = false
if data.has("instance") and data.instance.find("$(seed)"):
uses_seed = true
# Parameters # Parameters
controls = [] controls = []
var sizer = null var sizer = null

View File

@ -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()

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=4 format=2] [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] [ext_resource path="res://addons/material_maker/nodes/image/godot_logo.png" type="Texture" id=2]
[sub_resource type="Theme" id=1] [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/left_color = Color( 0.5, 0.5, 1, 1 )
slot/0/right_enabled = true slot/0/right_enabled = true
slot/0/right_type = 0 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 ) script = ExtResource( 1 )
[node name="TextureButton" type="TextureButton" parent="."] [node name="TextureButton" type="TextureButton" parent="."]
@ -33,5 +33,4 @@ rect_clip_content = true
texture_normal = ExtResource( 2 ) texture_normal = ExtResource( 2 )
expand = true expand = true
stretch_mode = 5 stretch_mode = 5
[connection signal="pressed" from="TextureButton" to="." method="_on_TextureButton_pressed"] [connection signal="pressed" from="TextureButton" to="." method="_on_TextureButton_pressed"]

View File

@ -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)

View File

@ -2,34 +2,17 @@
[ext_resource path="res://addons/material_maker/nodes/switch/switch.gd" type="Script" id=1] [ext_resource path="res://addons/material_maker/nodes/switch/switch.gd" type="Script" id=1]
[sub_resource type="Theme" id=1] [sub_resource type="Theme" id=1]
[node name="Switch" type="GraphNode"]
[node name="Switch" type="GraphNode" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 1.0 margin_left = 1.0
margin_top = 1.0 margin_top = 1.0
margin_right = 87.0 margin_right = 100.0
margin_bottom = 89.0 margin_bottom = 110.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1 mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = SubResource( 1 ) theme = SubResource( 1 )
title = "Switch" title = "Switch"
offset = Vector2( 0, 0 )
show_close = true show_close = true
resizable = false
selected = false
comment = false
overlay = 0
slot/0/left_enabled = false slot/0/left_enabled = false
slot/0/left_type = 0 slot/0/left_type = 0
slot/0/left_color = Color( 0.498039, 0.498039, 1, 1 ) 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_type = 0
slot/4/right_color = Color( 1, 0, 0, 1 ) slot/4/right_color = Color( 1, 0, 0, 1 )
script = ExtResource( 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"] [node name="source" type="OptionButton" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0 margin_left = 16.0
margin_top = 24.0 margin_top = 24.0
margin_right = 70.0 margin_right = 83.0
margin_bottom = 44.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" text = "1"
flat = false
align = 0
items = [ "1", null, false, 0, null, "2", null, false, 1, null ] items = [ "1", null, false, 0, null, "2", null, false, 1, null ]
selected = 0 selected = 0
[node name="Label1" type="Label" parent="." index="1"] [node name="Label1" type="Label" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0 margin_left = 16.0
margin_top = 44.0 margin_top = 44.0
margin_right = 70.0 margin_right = 83.0
margin_bottom = 58.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" text = "A1"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="HBoxContainer1" type="HBoxContainer" parent="." index="2"] [node name="HBoxContainer1" type="HBoxContainer" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0 margin_left = 16.0
margin_top = 59.0 margin_top = 59.0
margin_right = 70.0 margin_right = 83.0
margin_bottom = 73.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"] [node name="Label1" type="Label" parent="HBoxContainer1"]
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
margin_right = 54.0 margin_right = 54.0
margin_bottom = 14.0 margin_bottom = 14.0
rect_pivot_offset = Vector2( 0, 0 ) size_flags_horizontal = 3
rect_clip_content = false text = "B1"
mouse_filter = 2
mouse_default_cursor_shape = 0 [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_horizontal = 9
size_flags_vertical = 4
text = "A" text = "A"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="HBoxContainer2" type="HBoxContainer" parent="." index="3"] [node name="HBoxContainer2" type="HBoxContainer" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0 margin_left = 16.0
margin_top = 74.0 margin_top = 74.0
margin_right = 70.0 margin_right = 83.0
margin_bottom = 88.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"] [node name="Label1" type="Label" parent="HBoxContainer2"]
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
margin_right = 54.0 margin_right = 54.0
margin_bottom = 14.0 margin_bottom = 14.0
rect_pivot_offset = Vector2( 0, 0 ) size_flags_horizontal = 3
rect_clip_content = false text = "A2"
mouse_filter = 2
mouse_default_cursor_shape = 0 [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_horizontal = 9
size_flags_vertical = 4
text = "B" text = "B"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Label2" type="Label" parent="." index="4"] [node name="Label2" type="Label" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 16.0 margin_left = 16.0
margin_top = 89.0 margin_top = 89.0
margin_right = 70.0 margin_right = 83.0
margin_bottom = 103.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" text = "B2"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1

View File

@ -14,7 +14,7 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://addons/material_maker/engine/gen_base.gd" "path": "res://addons/material_maker/engine/gen_base.gd"
}, { }, {
"base": "MMGenBase", "base": "MMGenTexture",
"class": "MMGenBuffer", "class": "MMGenBuffer",
"language": "GDScript", "language": "GDScript",
"path": "res://addons/material_maker/engine/gen_buffer.gd" "path": "res://addons/material_maker/engine/gen_buffer.gd"
@ -34,6 +34,11 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://addons/material_maker/engine/gen_graph.gd" "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", "base": "Object",
"class": "MMGenLoader", "class": "MMGenLoader",
"language": "GDScript", "language": "GDScript",
@ -54,6 +59,11 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://addons/material_maker/engine/gen_shader.gd" "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", "base": "Object",
"class": "MMGradient", "class": "MMGradient",
"language": "GDScript", "language": "GDScript",
@ -70,10 +80,12 @@ _global_script_class_icons={
"MMGenContext": "", "MMGenContext": "",
"MMGenConvolution": "", "MMGenConvolution": "",
"MMGenGraph": "", "MMGenGraph": "",
"MMGenImage": "",
"MMGenLoader": "", "MMGenLoader": "",
"MMGenMaterial": "", "MMGenMaterial": "",
"MMGenRenderer": "", "MMGenRenderer": "",
"MMGenShader": "", "MMGenShader": "",
"MMGenTexture": "",
"MMGradient": "", "MMGradient": "",
"MMType": "" "MMType": ""
} }