Started refactoring to build an export_plugin and separate UI from texture generation

This commit is contained in:
RodZill4 2019-07-31 20:53:00 +02:00
parent 6984088b78
commit cfae489ad0
15 changed files with 190 additions and 334 deletions

View File

@ -0,0 +1,4 @@
extends Node
class_name MMGenBase

View File

@ -0,0 +1,2 @@
extends MMGenBase
class_name MMGenBuffer

View File

@ -0,0 +1,2 @@
extends MMGenBase
class_name MMGenConvolution

View File

@ -0,0 +1,2 @@
extends MMGenBase
class_name MMGenGraph

View File

@ -0,0 +1,11 @@
extends MMGenBase
class_name MMGenMaterial
func generate_material():
print("Generating material")
var material = SpatialMaterial.new()
return material
func initialize(data: Dictionary):
if data.has("name"):
name = data.name

View File

@ -0,0 +1,14 @@
extends MMGenBase
class_name MMGenShader
var config
var parameters
func configure(c: Dictionary):
config = c
func initialize(data: Dictionary):
if data.has("name"):
name = data.name
if data.has("parameters"):
parameters = data.parameters

View File

@ -0,0 +1,33 @@
extends Object
class_name MMGenLoader
func load_gen(filename: String) -> MMGenBase:
var file = File.new()
if file.open(filename, File.READ) == OK:
var data = parse_json(file.get_as_text())
return create_gen(data)
return null
func create_gen(data) -> MMGenBase:
var generator = null
if data.has("connections") and data.has("nodes"):
generator = MMGenGraph.new()
for n in data.nodes:
var g = create_gen(n)
if g != null:
generator.add_child(g)
elif data.has("type"):
if data.type == "material":
generator = MMGenMaterial.new()
else:
generator = MMGenShader.new()
var file = File.new()
if file.open("res://addons/material_maker/nodes/"+data.type+".mmn", File.READ) == OK:
var config = parse_json(file.get_as_text())
print("loaded description "+data.type+".mmn")
generator.configure(config)
else:
print("Cannot find description for "+data.type)
if generator != null and data.has("parameters"):
generator.initialize(data)
return generator

View File

@ -0,0 +1,48 @@
extends EditorImportPlugin
var plugin = null
func _init(p):
plugin = p
func _ready():
pass # Replace with function body.
func get_import_options(preset : int):
return []
func get_import_order():
return 1
func get_importer_name():
return "MaterialMakerImporter"
func get_option_visibility(option: String, options: Dictionary):
return false
func get_preset_count():
return 1
func get_preset_name(preset: int) -> String:
return "Default"
func get_priority():
return 1
func get_recognized_extensions():
return [ "ptex" ]
func get_resource_type():
return "Material"
func get_save_extension():
return "tres"
func get_visible_name():
return "Material Maker Importer"
func import(source_file: String, save_path: String, options: Dictionary, platform_variants: Array, gen_files: Array) -> int:
var material = SpatialMaterial.new()
var filename = save_path + "." + get_save_extension()
ResourceSaver.save(filename, plugin.generate_material(source_file))
return OK

View File

@ -21,7 +21,7 @@ size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
[node name="Menu" type="HBoxContainer" parent="VBoxContainer"] [node name="Menu" type="HBoxContainer" parent="VBoxContainer"]
margin_right = 1024.0 margin_right = 1280.0
margin_bottom = 20.0 margin_bottom = 20.0
[node name="File" type="MenuButton" parent="VBoxContainer/Menu"] [node name="File" type="MenuButton" parent="VBoxContainer/Menu"]
@ -53,19 +53,19 @@ items = [ "User manual", null, 0, false, false, 17, 0, null, "", false, "Report
[node name="HBoxContainer" type="HSplitContainer" parent="VBoxContainer"] [node name="HBoxContainer" type="HSplitContainer" parent="VBoxContainer"]
margin_top = 24.0 margin_top = 24.0
margin_right = 1024.0 margin_right = 1280.0
margin_bottom = 600.0 margin_bottom = 720.0
size_flags_vertical = 3 size_flags_vertical = 3
[node name="VBoxContainer" type="VSplitContainer" parent="VBoxContainer/HBoxContainer"] [node name="VBoxContainer" type="VSplitContainer" parent="VBoxContainer/HBoxContainer"]
margin_right = 250.0 margin_right = 314.0
margin_bottom = 576.0 margin_bottom = 696.0
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
[node name="Library" type="Tree" parent="VBoxContainer/HBoxContainer/VBoxContainer"] [node name="Library" type="Tree" parent="VBoxContainer/HBoxContainer/VBoxContainer"]
margin_right = 250.0 margin_right = 314.0
margin_bottom = 282.0 margin_bottom = 342.0
rect_min_size = Vector2( 100, 100 ) rect_min_size = Vector2( 100, 100 )
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
@ -76,21 +76,21 @@ script = ExtResource( 2 )
anchor_left = 0.0 anchor_left = 0.0
anchor_right = 0.0 anchor_right = 0.0
margin_left = 0.0 margin_left = 0.0
margin_top = 294.0 margin_top = 354.0
margin_right = 250.0 margin_right = 314.0
margin_bottom = 576.0 margin_bottom = 696.0
[node name="Projects" type="Panel" parent="VBoxContainer/HBoxContainer"] [node name="Projects" type="Panel" parent="VBoxContainer/HBoxContainer"]
margin_left = 262.0 margin_left = 326.0
margin_right = 1024.0 margin_right = 1280.0
margin_bottom = 576.0 margin_bottom = 696.0
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
size_flags_stretch_ratio = 3.0 size_flags_stretch_ratio = 3.0
script = ExtResource( 4 ) script = ExtResource( 4 )
[node name="Tabs" type="Tabs" parent="VBoxContainer/HBoxContainer/Projects"] [node name="Tabs" type="Tabs" parent="VBoxContainer/HBoxContainer/Projects"]
margin_right = 762.0 margin_right = 954.0
margin_bottom = 24.0 margin_bottom = 24.0
tab_align = 0 tab_align = 0
tab_close_display_policy = 1 tab_close_display_policy = 1
@ -105,7 +105,6 @@ debug_path = "D:/Dev/mmdebug_"
[node name="NodeFactory" type="Node" parent="."] [node name="NodeFactory" type="Node" parent="."]
script = ExtResource( 6 ) script = ExtResource( 6 )
[connection signal="no_more_tabs" from="VBoxContainer/HBoxContainer/Projects" to="." method="new_material"] [connection signal="no_more_tabs" from="VBoxContainer/HBoxContainer/Projects" to="." method="new_material"]
[connection signal="resized" from="VBoxContainer/HBoxContainer/Projects" to="VBoxContainer/HBoxContainer/Projects" method="_on_Projects_resized"] [connection signal="resized" from="VBoxContainer/HBoxContainer/Projects" to="VBoxContainer/HBoxContainer/Projects" method="_on_Projects_resized"]
[connection signal="tab_changed" from="VBoxContainer/HBoxContainer/Projects" to="." method="_on_Projects_tab_changed"] [connection signal="tab_changed" from="VBoxContainer/HBoxContainer/Projects" to="." method="_on_Projects_tab_changed"]

View File

@ -3,9 +3,12 @@ extends EditorPlugin
var mm_button = null var mm_button = null
var material_maker = null var material_maker = null
var importer = null
func _enter_tree(): func _enter_tree():
add_tool_menu_item("Material Maker", self, "open_material_maker") add_tool_menu_item("Material Maker", self, "open_material_maker")
importer = preload("res://addons/material_maker/import_plugin/ptex_import.gd").new(self)
add_import_plugin(importer)
func _exit_tree(): func _exit_tree():
remove_tool_menu_item("Material Maker") remove_tool_menu_item("Material Maker")
@ -13,6 +16,9 @@ func _exit_tree():
material_maker.hide() material_maker.hide()
material_maker.queue_free() material_maker.queue_free()
material_maker = null material_maker = null
if importer != null:
remove_import_plugin(importer)
importer = null
func _get_state(): func _get_state():
var s = { mm_button=mm_button, material_maker=material_maker } var s = { mm_button=mm_button, material_maker=material_maker }
@ -36,3 +42,9 @@ func close_material_maker():
material_maker.hide() material_maker.hide()
material_maker.queue_free() material_maker.queue_free()
material_maker = null material_maker = null
func generate_material(ptex_filename: String) -> Material:
var loader = MMGenLoader.new()
var generator = loader.load_gen(ptex_filename)
add_child(generator)
return generator.get_node("Material").generate_material()

View File

@ -1,124 +0,0 @@
tool
extends Container
var popup_menu = null
var popup_position = Vector2(0, 0)
var texture_preview_material = null
var preview_maximized = false
const MENU = [
{ command="new_texture", description="New material" },
{ command="load_texture", description="Load material" },
{ command="save_texture", description="Save material" },
{ command="save_texture_as", description="Save material as..." },
{ command="export_texture", description="Export material" },
{ },
{ submenu="generator", description="Generator" },
{ name="image", description="Image", in_submenu="generator" },
{ name="pattern", description="Pattern", in_submenu="generator" },
{ name="bricks", description="Bricks", in_submenu="generator" },
{ name="perlin", description="Perlin noise", in_submenu="generator" },
{ name="voronoi", description="Voronoi Noise", in_submenu="generator" },
{ submenu="filter", description="Filter" },
{ name="colorize", description="Colorize", in_submenu="filter" },
{ name="blend", description="Blend", in_submenu="filter" },
{ name="transform", description="Transform", in_submenu="filter" },
{ name="warp", description="Warp", in_submenu="filter" },
{ name="normal_map", description="Normal Map", in_submenu="filter" }
]
func _ready():
# Duplicate the material we'll modify and store the shaders
$Preview/Preview/SelectedPreview.material = $Preview/Preview/SelectedPreview.material.duplicate(true)
texture_preview_material = $Preview/Preview/SelectedPreview.material
$GraphEdit.add_valid_connection_type(0, 0)
# create or update popup menu
if popup_menu != null:
popup_menu.queue_free()
popup_menu = create_menu()
$GraphEdit.add_child(popup_menu)
func create_menu(in_submenu = null):
var menu = PopupMenu.new()
menu.connect("id_pressed", self, "_on_PopupMenu_id_pressed")
for i in MENU.size():
if MENU[i].has("in_submenu"):
if in_submenu != MENU[i].in_submenu:
continue
elif in_submenu != null:
continue
if MENU[i].has("submenu"):
var submenu = create_menu(MENU[i].submenu)
menu.add_child(submenu)
menu.add_submenu_item(MENU[i].description, submenu.get_name())
elif MENU[i].has("description"):
menu.add_item(MENU[i].description, i)
else:
menu.add_separator()
return menu
func _on_GraphEdit_popup_request(position):
popup_position = position
popup_menu.popup(Rect2(position, popup_menu.rect_size))
func _on_PopupMenu_id_pressed(id):
var node_type = null
if MENU[id].has("command"):
call(MENU[id].command)
elif MENU[id].has("name"):
$GraphEdit.create_node({type=MENU[id].name}, popup_position)
func set_save_path(graph_edit, path):
if !Engine.editor_hint:
if path != null:
OS.set_window_title("Procedural textures (%s)" % path)
else:
OS.set_window_title("Procedural textures")
func new_texture():
$GraphEdit.new_material()
func load_texture():
$GraphEdit.load_file()
func save_texture():
$GraphEdit.save_file()
func save_texture_as():
$GraphEdit.save_file_as()
func export_texture():
$GraphEdit.export_textures()
func get_selected_node():
var rv = null
for c in $GraphEdit.get_children():
if c is GraphNode && c.selected:
if rv != null:
return null
else:
rv = c
return rv
func generate_shader():
var selected_node = get_selected_node()
if $GraphEdit/Material != null:
$GraphEdit/Material.update_materials($Preview/Preview.get_materials())
if selected_node != null:
$GraphEdit.setup_material($Preview/Preview.get_2d_material(), selected_node.get_textures(), selected_node.generate_shader())
func _on_GraphEdit_node_selected(node):
var selected_node = get_selected_node()
if selected_node != null:
$GraphEdit.setup_material($Preview/Preview.get_2d_material(), selected_node.get_textures(), selected_node.generate_shader())
func _on_SelectedPreview_gui_input(ev):
if ev is InputEventMouseButton && ev.button_index == 1 && ev.doubleclick:
if preview_maximized:
$Preview/Preview/SelectedPreview/SelectedPreviewAnimation.play("minimize")
else:
$Preview/Preview/SelectedPreview/SelectedPreviewAnimation.play("maximize")
preview_maximized = !preview_maximized

View File

@ -1,192 +0,0 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://addons/material_maker/pm_editor.gd" type="Script" id=1]
[ext_resource path="res://addons/material_maker/graph_edit.tscn" type="PackedScene" id=2]
[ext_resource path="res://addons/material_maker/preview.tscn" type="PackedScene" id=3]
[sub_resource type="Shader" id=5]
code = "shader_type canvas_item;
void fragment() {
COLOR = vec4(1.0);
}
"
_sections_unfolded = [ "Resource" ]
[sub_resource type="ShaderMaterial" id=6]
render_priority = 0
shader = SubResource( 5 )
[sub_resource type="Animation" id=3]
length = 0.2
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath(".:rect_position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.2 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Vector2( 3, 251 ), Vector2( 2, 2 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath(".:rect_size")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0, 0.2 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Vector2( 96, 96 ), Vector2( 346, 346 ) ]
}
tracks/2/type = "value"
tracks/2/path = NodePath("MaterialPreview:render_target_update_mode")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0.2 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ 0 ]
}
[sub_resource type="Animation" id=4]
length = 0.2
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath(".:rect_position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.2 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Vector2( 2, 2 ), Vector2( 2, 252 ) ]
}
tracks/1/type = "value"
tracks/1/path = NodePath(".:rect_size")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/keys = {
"times": PoolRealArray( 0, 0.2 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Vector2( 346, 346 ), Vector2( 96, 96 ) ]
}
tracks/2/type = "value"
tracks/2/path = NodePath("MaterialPreview:render_target_update_mode")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ 3 ]
}
[node name="ProceduralMaterialEditor" type="MarginContainer" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_bottom = -2.0
rect_min_size = Vector2( 500, 300 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
custom_constants/margin_left = 0
script = ExtResource( 1 )
_sections_unfolded = [ "Rect" ]
[node name="GraphEdit" parent="." index="0" instance=ExtResource( 2 )]
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 1280.0
margin_bottom = 718.0
[node name="Preview" type="Container" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 1280.0
margin_bottom = 718.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 = 1
_sections_unfolded = [ "Mouse" ]
[node name="Preview" parent="Preview" index="0" instance=ExtResource( 3 )]
[node name="SelectedPreview" type="ColorRect" parent="Preview/Preview" index="4"]
visible = false
material = SubResource( 6 )
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 2.0
margin_top = 2.0
margin_right = 348.0
margin_bottom = 348.0
rect_min_size = Vector2( 96, 96 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 8
size_flags_vertical = 0
color = Color( 1, 1, 1, 1 )
_sections_unfolded = [ "Material", "Mouse", "Rect" ]
[node name="SelectedPreviewAnimation" type="AnimationPlayer" parent="Preview/Preview/SelectedPreview" index="0"]
root_node = NodePath("..")
autoplay = ""
playback_process_mode = 1
playback_default_blend_time = 0.0
playback_speed = 1.0
anims/maximize = SubResource( 3 )
anims/minimize = SubResource( 4 )
blend_times = [ ]
[connection signal="graph_changed" from="GraphEdit" to="." method="generate_shader"]
[connection signal="node_selected" from="GraphEdit" to="." method="_on_GraphEdit_node_selected"]
[connection signal="popup_request" from="GraphEdit" to="." method="_on_GraphEdit_popup_request"]
[connection signal="save_path_changed" from="GraphEdit" to="." method="set_save_path"]
[connection signal="gui_input" from="Preview/Preview/SelectedPreview" to="." method="_on_SelectedPreview_gui_input"]

View File

@ -11,4 +11,3 @@ ground_curve = 0.01
[resource] [resource]
background_mode = 2 background_mode = 2
background_sky = SubResource( 1 ) background_sky = SubResource( 1 )

View File

@ -3,6 +3,9 @@
importer="texture" importer="texture"
type="StreamTexture" type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps] [deps]
@ -14,6 +17,7 @@ dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
compress/mode=0 compress/mode=0
compress/lossy_quality=0.7 compress/lossy_quality=0.7
compress/hdr_mode=0 compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0 compress/normal_map=0
flags/repeat=0 flags/repeat=0
flags/filter=true flags/filter=true
@ -23,6 +27,7 @@ flags/srgb=2
process/fix_alpha_border=true process/fix_alpha_border=true
process/premult_alpha=false process/premult_alpha=false
process/HDR_as_SRGB=false process/HDR_as_SRGB=false
process/invert_color=false
stream=false stream=false
size_limit=0 size_limit=0
detect_3d=true detect_3d=true

View File

@ -8,9 +8,50 @@
config_version=4 config_version=4
_global_script_classes=[ ] _global_script_classes=[ {
"base": "Node",
"class": "MMGenBase",
"language": "GDScript",
"path": "res://addons/material_maker/engine/gen_base.gd"
}, {
"base": "MMGenBase",
"class": "MMGenBuffer",
"language": "GDScript",
"path": "res://addons/material_maker/engine/gen_buffer.gd"
}, {
"base": "MMGenBase",
"class": "MMGenConvolution",
"language": "GDScript",
"path": "res://addons/material_maker/engine/gen_convolution.gd"
}, {
"base": "MMGenBase",
"class": "MMGenGraph",
"language": "GDScript",
"path": "res://addons/material_maker/engine/gen_graph.gd"
}, {
"base": "Object",
"class": "MMGenLoader",
"language": "GDScript",
"path": "res://addons/material_maker/engine/loader.gd"
}, {
"base": "MMGenBase",
"class": "MMGenMaterial",
"language": "GDScript",
"path": "res://addons/material_maker/engine/gen_material.gd"
}, {
"base": "MMGenBase",
"class": "MMGenShader",
"language": "GDScript",
"path": "res://addons/material_maker/engine/gen_shader.gd"
} ]
_global_script_class_icons={ _global_script_class_icons={
"MMGenBase": "",
"MMGenBuffer": "",
"MMGenConvolution": "",
"MMGenGraph": "",
"MMGenLoader": "",
"MMGenMaterial": "",
"MMGenShader": ""
} }
[application] [application]