Started updating export to support multiple target game engines

This commit is contained in:
RodZill4 2020-02-17 08:54:46 +01:00
parent 3c44a034ac
commit c9aab3e831
10 changed files with 449 additions and 190 deletions

View File

@ -1,5 +1,5 @@
tool tool
extends MMGenBase extends MMGenShader
class_name MMGenMaterial class_name MMGenMaterial
var material : SpatialMaterial var material : SpatialMaterial
@ -7,13 +7,22 @@ var generated_textures = {}
const TEXTURE_LIST = [ const TEXTURE_LIST = [
{ port=0, texture="albedo" }, { port=0, texture="albedo" },
{ port=3, texture="emission" }, { port=1, texture="orm" },
{ port=4, texture="normal" }, { port=2, texture="emission" },
{ ports=[5, 2, 1], default_values=["1.0", "1.0", "1.0"], texture="orm" }, { port=3, texture="normal" },
{ port=6, texture="depth" }, { port=4, texture="depth" },
{ port=7, texture="subsurf_scatter" } { port=5, texture="sss" }
] ]
const INPUT_ALBEDO : int = 0
const INPUT_METALLIC : int = 1
const INPUT_ROUGHNESS : int = 2
const INPUT_EMISSION : int = 3
const INPUT_NORMAL : int = 4
const INPUT_OCCLUSION : int = 5
const INPUT_DEPTH : int = 6
const INPUT_SSS : int = 7
# The minimum allowed texture size as a power-of-two exponent # The minimum allowed texture size as a power-of-two exponent
const TEXTURE_SIZE_MIN = 4 # 16x16 const TEXTURE_SIZE_MIN = 4 # 16x16
@ -23,6 +32,7 @@ const TEXTURE_SIZE_MAX = 12 # 4096x4096
# The default texture size as a power-of-two exponent # The default texture size as a power-of-two exponent
const TEXTURE_SIZE_DEFAULT = 10 # 1024x1024 const TEXTURE_SIZE_DEFAULT = 10 # 1024x1024
func _ready() -> void: func _ready() -> void:
for t in TEXTURE_LIST: for t in TEXTURE_LIST:
generated_textures[t.texture] = null generated_textures[t.texture] = null
@ -37,30 +47,8 @@ func get_type() -> String:
func get_type_name() -> String: func get_type_name() -> String:
return "Material" return "Material"
func get_parameter_defs() -> Array: func get_output_defs__() -> Array:
return [ return []
{ name="albedo_color", label="Albedo", type="color", default={ r=1.0, g=1.0, b=1.0, a=1.0} },
{ name="metallic", label="Metallic", type="float", min=0.0, max=1.0, step=0.05, default=1.0 },
{ name="roughness", label="Roughness", type="float", min=0.0, max=1.0, step=0.05, default=1.0 },
{ name="emission_energy", label="Emission", type="float", min=0.0, max=8.0, step=0.05, default=1.0 },
{ name="normal_scale", label="Normal", type="float", min=0.0, max=8.0, step=0.05, default=1.0 },
{ name="ao_light_affect", label="Ambient occlusion", type="float", min=0.0, max=1.0, step=0.05, default=1.0 },
{ name="depth_scale", label="Depth", type="float", min=0.0, max=1.0, step=0.05, default=1.0 },
{ name="subsurf_scatter_strength", label="Subsurf. Scatter.", type="float", min=0.0, max=1.0, step=0.05, default=0.0 },
{ name="size", label="Size", type="size", first=TEXTURE_SIZE_MIN, last=TEXTURE_SIZE_MAX, default=TEXTURE_SIZE_DEFAULT }
]
func get_input_defs() -> Array:
return [
{ name="albedo_texture", label="", type="rgb" },
{ name="metallic_texture", label="", type="f" },
{ name="roughness_texture", label="", type="f" },
{ name="emission_texture", label="", type="rgb" },
{ name="normal_texture", label="", type="rgb" },
{ name="ao_texture", label="", type="f" },
{ name="depth_texture", label="", type="f" },
{ name="subsurf_scatter_texture", label="", type="f" }
]
func get_image_size() -> int: func get_image_size() -> int:
var rv : int var rv : int
@ -96,37 +84,10 @@ func render_textures() -> void:
if t.has("port"): if t.has("port"):
if generated_textures[t.texture] != null: if generated_textures[t.texture] != null:
continue continue
var source = get_source(t.port) result = render(t.port, get_image_size())
if source == null:
generated_textures[t.texture] = null
continue
result = source.generator.render(source.output_index, get_image_size())
elif t.has("ports"):
var context : MMGenContext = MMGenContext.new()
var code = []
var shader_textures = {}
var sources = 0
for i in range(t.ports.size()):
var source = get_source(t.ports[i])
if source != null:
var status = source.generator.get_shader_code("UV", source.output_index, context)
while status is GDScriptFunctionState:
status = yield(status, "completed")
code.push_back(status)
for t in status.textures.keys():
shader_textures[t] = status.textures[t]
sources += 1
else:
code.push_back({ defs="", code="", f=t.default_values[i] })
if sources == 0:
generated_textures[t.texture] = null
continue
var shader : String = mm_renderer.generate_combined_shader(code[0], code[1], code[2])
result = mm_renderer.render_shader(shader, shader_textures, get_image_size())
else: else:
generated_textures[t.texture] = null generated_textures[t.texture] = null
continue continue
while result is GDScriptFunctionState: while result is GDScriptFunctionState:
result = yield(result, "completed") result = yield(result, "completed")
texture = ImageTexture.new() texture = ImageTexture.new()
@ -144,7 +105,7 @@ func render_textures() -> void:
func update_materials(material_list) -> void: func update_materials(material_list) -> void:
for m in material_list: for m in material_list:
update_spatial_material(m) update_material(m)
func get_generated_texture(slot, file_prefix = null) -> ImageTexture: func get_generated_texture(slot, file_prefix = null) -> ImageTexture:
if file_prefix != null: if file_prefix != null:
@ -157,62 +118,62 @@ func get_generated_texture(slot, file_prefix = null) -> ImageTexture:
else: else:
return generated_textures[slot] return generated_textures[slot]
func update_spatial_material(m, file_prefix = null) -> void: func update_material(m, file_prefix = null) -> void:
var texture var texture
if m is SpatialMaterial: if m is SpatialMaterial:
# Make the material double-sided for better visiblity in the preview # Make the material double-sided for better visiblity in the preview
m.params_cull_mode = SpatialMaterial.CULL_DISABLED m.params_cull_mode = SpatialMaterial.CULL_DISABLED
# Albedo # Albedo
m.albedo_color = parameters.albedo_color m.albedo_color = parameters.albedo
m.albedo_texture = get_generated_texture("albedo", file_prefix) m.albedo_texture = get_generated_texture("albedo", file_prefix)
m.metallic = parameters.metallic
m.roughness = parameters.roughness
# Metallic
texture = get_generated_texture("orm", file_prefix)
m.metallic_texture = texture
m.metallic_texture_channel = SpatialMaterial.TEXTURE_CHANNEL_BLUE
# Roughness
m.roughness_texture = texture
m.roughness_texture_channel = SpatialMaterial.TEXTURE_CHANNEL_GREEN
# Emission
texture = get_generated_texture("emission", file_prefix)
if texture != null:
m.emission_enabled = true
m.emission_energy = parameters.emission_energy
m.emission_texture = texture
else:
m.emission_enabled = false
# Normal map
texture = get_generated_texture("normal", file_prefix)
if texture != null:
m.normal_enabled = true
m.normal_texture = texture
else:
m.normal_enabled = false
# Ambient occlusion # Ambient occlusion
if get_source(5) != null: if get_source(INPUT_OCCLUSION) != null:
m.ao_enabled = true m.ao_enabled = true
m.ao_light_affect = parameters.ao_light_affect m.ao_light_affect = parameters.ao
m.ao_texture = m.metallic_texture m.ao_texture = get_generated_texture("orm", file_prefix)
m.ao_texture_channel = SpatialMaterial.TEXTURE_CHANNEL_RED m.ao_texture_channel = SpatialMaterial.TEXTURE_CHANNEL_RED
else: else:
m.ao_enabled = false m.ao_enabled = false
# Roughness
m.roughness = parameters.roughness
if get_source(INPUT_ROUGHNESS) != null:
m.roughness_texture = get_generated_texture("orm", file_prefix)
m.roughness_texture_channel = SpatialMaterial.TEXTURE_CHANNEL_GREEN
else:
m.roughness_texture = null
# Metallic
m.metallic = parameters.metallic
if get_source(INPUT_ROUGHNESS) != null:
m.metallic_texture = get_generated_texture("orm", file_prefix)
m.metallic_texture_channel = SpatialMaterial.TEXTURE_CHANNEL_BLUE
else:
m.metallic_texture = null
# Emission
if get_source(INPUT_EMISSION) != null:
m.emission_enabled = true
m.emission_energy = parameters.emission
m.emission_texture = get_generated_texture("emission", file_prefix)
else:
m.emission_enabled = false
# Normal map
if get_source(INPUT_NORMAL) != null:
m.normal_enabled = true
m.normal_texture = get_generated_texture("normal", file_prefix)
else:
m.normal_enabled = false
# Depth # Depth
texture = get_generated_texture("depth", file_prefix) if get_source(INPUT_DEPTH) != null and parameters.depth > 0:
if texture != null and parameters.depth_scale > 0:
m.depth_enabled = true m.depth_enabled = true
m.depth_deep_parallax = true m.depth_deep_parallax = true
m.depth_scale = parameters.depth_scale * 0.2 m.depth_scale = parameters.depth * 0.2
m.depth_texture = texture m.depth_texture = get_generated_texture("depth", file_prefix)
else: else:
m.depth_enabled = false m.depth_enabled = false
# Subsurface scattering # Subsurface scattering
texture = get_generated_texture("subsurf_scatter", file_prefix) if get_source(INPUT_SSS) != null:
if texture != null:
m.subsurf_scatter_enabled = true m.subsurf_scatter_enabled = true
m.subsurf_scatter_strength = parameters.subsurf_scatter_strength m.subsurf_scatter_strength = parameters.sss
m.subsurf_scatter_texture = texture m.subsurf_scatter_texture = get_generated_texture("sss", file_prefix)
else: else:
m.subsurf_scatter_enabled = false m.subsurf_scatter_enabled = false
else: else:
@ -231,25 +192,37 @@ func update_spatial_material(m, file_prefix = null) -> void:
m.set_shader_param("depth_scale", parameters.depth_scale * 0.2) m.set_shader_param("depth_scale", parameters.depth_scale * 0.2)
m.set_shader_param("texture_depth", get_generated_texture("depth", file_prefix)) m.set_shader_param("texture_depth", get_generated_texture("depth", file_prefix))
func export_textures(prefix, editor_interface = null) -> SpatialMaterial: # Export
for t in TEXTURE_LIST:
var texture = generated_textures[t.texture]
if texture != null:
var image = texture.get_data()
image.save_png("%s_%s.png" % [ prefix, t.texture ])
if Engine.editor_hint and editor_interface != null:
var resource_filesystem = editor_interface.get_resource_filesystem()
resource_filesystem.scan()
yield(resource_filesystem, "resources_reimported")
print("resources_reimported")
var new_material = SpatialMaterial.new()
update_spatial_material(new_material, prefix)
var file_name : String = "%s.tres" % [ prefix ]
ResourceSaver.save(file_name, new_material)
resource_filesystem.update_file(file_name)
return new_material
return null func get_export_profiles() -> Array:
return shader_model.exports.keys()
func get_export_extension(profile : String) -> String:
return shader_model.exports[profile].export_extension
func export_material(prefix, profile) -> void:
for f in shader_model.exports[profile].files:
match f.type:
"texture":
var file_name = f.file_name.replace("$(file_prefix)", prefix)
if f.has("conditions"):
var condition = f.conditions
for input_index in range(shader_model.inputs.size()):
var input = shader_model.inputs[input_index]
var is_input_connected = "true" if get_source(input_index) != null else "false"
condition = condition.replace("$(connected:"+input.name+")", is_input_connected)
var expr = Expression.new()
var error = expr.parse(condition, [])
if error != OK:
print("Error in expression: "+expr.get_error_text())
continue
if !expr.execute():
continue
var result = render(f.output, get_image_size())
while result is GDScriptFunctionState:
result = yield(result, "completed")
result.save_to_file(file_name)
result.release()
func _serialize(data: Dictionary) -> Dictionary: func _serialize(data: Dictionary) -> Dictionary:
return data return data

View File

@ -157,6 +157,10 @@ func replace_variable(string : String, variable : String, value : String) -> Str
break break
new_string += string.left(pos) new_string += string.left(pos)
string = string.right(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]): if string.empty() or !is_word_letter(string[0]):
new_string += value new_string += value
else: else:

View File

@ -56,6 +56,8 @@ func add_to_gen_graph(gen_graph, generators, connections) -> Dictionary:
func create_gen(data) -> MMGenBase: func create_gen(data) -> MMGenBase:
var guess = [ var guess = [
{ keyword="export", type=MMGenMaterial },
{ keyword="connections", type=MMGenGraph },
{ keyword="connections", type=MMGenGraph }, { keyword="connections", type=MMGenGraph },
{ keyword="nodes", type=MMGenGraph }, { keyword="nodes", type=MMGenGraph },
{ keyword="shader_model", type=MMGenShader }, { keyword="shader_model", type=MMGenShader },
@ -65,7 +67,7 @@ func create_gen(data) -> MMGenBase:
{ keyword="widgets", type=MMGenRemote } { keyword="widgets", type=MMGenRemote }
] ]
var types = { var types = {
material = MMGenMaterial, material_export = MMGenMaterial,
buffer = MMGenBuffer, buffer = MMGenBuffer,
image = MMGenImage, image = MMGenImage,
ios = MMGenIOs, ios = MMGenIOs,

View File

@ -23,6 +23,6 @@ func update_texture() -> void:
var status = mm_material.render_textures() var status = mm_material.render_textures()
while status is GDScriptFunctionState: while status is GDScriptFunctionState:
status = yield(status, "completed") status = yield(status, "completed")
mm_material.update_spatial_material(self) mm_material.update_material(self)
mm_graph.queue_free() mm_graph.queue_free()

View File

@ -0,0 +1,253 @@
{
"name": "material",
"node_position": {
"x": 0,
"y": 0
},
"parameters": {
"albedo": {
"a": 1,
"b": 1,
"g": 1,
"r": 1,
"type": "Color"
},
"ao": 1,
"depth": 0.5,
"emission": 1,
"metallic": 1,
"normal": 1,
"roughness": 1,
"size": 11,
"sss": 0
},
"export": {
},
"shader_model": {
"code": "",
"global": "",
"inputs": [
{
"default": "vec3(1.0)",
"label": "",
"name": "albedo_tex",
"type": "rgb"
},
{
"default": "1",
"label": "",
"name": "metallic_tex",
"type": "f"
},
{
"default": "1",
"label": "",
"name": "roughness_tex",
"type": "f"
},
{
"default": "vec3(0.0)",
"label": "",
"name": "emission_tex",
"type": "rgb"
},
{
"default": "vec3(0.5)",
"label": "",
"name": "normal_tex",
"type": "rgb"
},
{
"default": "1.0",
"label": "",
"name": "ao_tex",
"type": "f"
},
{
"default": "0.0",
"label": "",
"name": "depth_tex",
"type": "f"
},
{
"default": "0.0",
"label": "",
"name": "sss_tex",
"type": "f"
}
],
"instance": "",
"name": "Material",
"outputs": [
{
"desc":"0: albedo",
"rgb": "$albedo_tex($uv)",
"type": "rgb"
},
{
"desc":"1: ambient occlusion, roughness, metallic",
"rgb": "vec3($ao_tex($uv), $roughness_tex($uv), $metallic_tex($uv))",
"type": "rgb"
},
{
"desc":"2: emission",
"rgb": "$emission_tex($uv)",
"type": "rgb"
},
{
"desc":"3: normal map for Godot",
"rgb": "$normal_tex($uv)",
"type": "rgb"
},
{
"desc":"4: normal map for Godot",
"f": "$depth_tex($uv)",
"type": "f"
},
{
"desc":"5: sub surface scattering",
"f": "$sss_tex($uv)",
"type": "f"
}
],
"exports": {
"Godot": {
"export_extension":"tres",
"files": [
{
"type":"texture",
"file_name":"$(file_prefix)_albedo.png",
"output":0,
"conditions":"$(connected:albedo_tex)"
},
{
"type":"texture",
"file_name":"$(file_prefix)_orm.png",
"output":1,
"conditions":"$(connected:ao_tex) or $(connected:roughness_tex) or $(connected:metallic_tex)"
},
{
"type":"texture",
"file_name":"$(file_prefix)_emission.png",
"output":2,
"conditions":"$(connected:emission_tex)"
},
{
"type":"texture",
"file_name":"$(file_prefix)_normal.png",
"output":3,
"conditions":"$(connected:normal_tex)"
},
{
"type":"texture",
"file_name":"$(file_prefix)_depth.png",
"output":4,
"conditions":"$(connected:depth_tex)"
},
{
"type":"texture",
"file_name":"$(file_prefix)_sss.png",
"output":5,
"conditions":"$(connected:sss_tex)"
}
]
},
"Unity": {
},
"Unreal": {
}
},
"parameters": [
{
"default": {
"a": 1,
"b": 1,
"g": 1,
"r": 1
},
"label": "Albedo",
"name": "albeco_color",
"type": "color"
},
{
"control": "None",
"default": 1,
"label": "Metallic",
"max": 1,
"min": 0,
"name": "metallic",
"step": 0.01,
"type": "float"
},
{
"control": "None",
"default": 1,
"label": "Roughness",
"max": 1,
"min": 0,
"name": "roughness",
"step": 0.01,
"type": "float"
},
{
"control": "None",
"default": 1,
"label": "Emission",
"max": 1,
"min": 0,
"name": "emission",
"step": 0.01,
"type": "float"
},
{
"control": "None",
"default": 1,
"label": "Normal",
"max": 10,
"min": 0,
"name": "normal",
"step": 0.01,
"type": "float"
},
{
"control": "None",
"default": 1,
"label": "Ambient occlusion",
"max": 1,
"min": 0,
"name": "ao",
"step": 0.01,
"type": "float"
},
{
"control": "None",
"default": 0.5,
"label": "Depth",
"max": 1,
"min": 0,
"name": "depth",
"step": 0.01,
"type": "float"
},
{
"control": "None",
"default": 0,
"label": "Subsurf. scatter.",
"max": 1,
"min": 0,
"name": "sss",
"step": 0.01,
"type": "float"
},
{
"default": 11,
"first": 6,
"label": "Size",
"last": 12,
"name": "size",
"type": "size"
}
]
},
"type": "material_export"
}

View File

@ -72,24 +72,12 @@
"to": "blend_0", "to": "blend_0",
"to_port": 1 "to_port": 1
}, },
{
"from": "colorize_0",
"from_port": 0,
"to": "combine_0",
"to_port": 1
},
{ {
"from": "blend_0", "from": "blend_0",
"from_port": 0, "from_port": 0,
"to": "colorize_2", "to": "colorize_2",
"to_port": 0 "to_port": 0
}, },
{
"from": "blend_0",
"from_port": 0,
"to": "combine_0",
"to_port": 0
},
{ {
"from": "colorize_2", "from": "colorize_2",
"from_port": 0, "from_port": 0,
@ -121,8 +109,8 @@
{ {
"name": "perlin_1", "name": "perlin_1",
"node_position": { "node_position": {
"x": -424, "x": -635,
"y": 343.5 "y": 341.5
}, },
"parameters": { "parameters": {
"iterations": 3, "iterations": 3,
@ -135,8 +123,8 @@
{ {
"name": "perlin_0", "name": "perlin_0",
"node_position": { "node_position": {
"x": -424, "x": -635,
"y": 212.5 "y": 210.5
}, },
"parameters": { "parameters": {
"iterations": 3, "iterations": 3,
@ -149,21 +137,20 @@
{ {
"name": "warp_0", "name": "warp_0",
"node_position": { "node_position": {
"x": -180, "x": -311,
"y": 317.5 "y": 280.5
}, },
"parameters": { "parameters": {
"amount": 0.1, "amount": 0.1,
"eps": 0.05, "eps": 0.05
"epsilon": 0
}, },
"type": "warp" "type": "warp"
}, },
{ {
"name": "colorize_1", "name": "colorize_1",
"node_position": { "node_position": {
"x": -194, "x": -340,
"y": 466.5 "y": 402.5
}, },
"parameters": { "parameters": {
"gradient": { "gradient": {
@ -192,21 +179,20 @@
{ {
"name": "warp_1", "name": "warp_1",
"node_position": { "node_position": {
"x": -31, "x": -89,
"y": 349.5 "y": 325.5
}, },
"parameters": { "parameters": {
"amount": 0.1, "amount": 0.1,
"eps": 0.045, "eps": 0.045
"epsilon": 0
}, },
"type": "warp" "type": "warp"
}, },
{ {
"name": "voronoi_0", "name": "voronoi_0",
"node_position": { "node_position": {
"x": -437, "x": -648,
"y": 484.5 "y": 482.5
}, },
"parameters": { "parameters": {
"intensity": 1, "intensity": 1,
@ -221,8 +207,8 @@
{ {
"name": "blend_0", "name": "blend_0",
"node_position": { "node_position": {
"x": 83, "x": 101,
"y": 245.5 "y": 250.5
}, },
"parameters": { "parameters": {
"amount": 1, "amount": 1,
@ -230,29 +216,11 @@
}, },
"type": "blend" "type": "blend"
}, },
{
"name": "combine_0",
"node_position": {
"x": 515.35144,
"y": -15.818176
},
"parameters": {
"color": {
"a": 1,
"b": 1,
"g": 1,
"r": 1,
"type": "Color"
},
"name": 0
},
"type": "combine"
},
{ {
"name": "Material", "name": "Material",
"node_position": { "node_position": {
"x": 544, "x": 687,
"y": 79 "y": 172
}, },
"parameters": { "parameters": {
"albedo_color": { "albedo_color": {
@ -267,7 +235,6 @@
"emission_energy": 1, "emission_energy": 1,
"metallic": 1, "metallic": 1,
"normal_scale": 1, "normal_scale": 1,
"resolution": 1,
"roughness": 1, "roughness": 1,
"size": 11, "size": 11,
"subsurf_scatter_strength": 0 "subsurf_scatter_strength": 0
@ -277,25 +244,46 @@
{ {
"name": "colorize_2", "name": "colorize_2",
"node_position": { "node_position": {
"x": 305.35144, "x": 407.35144,
"y": 76.181824 "y": 127.181824
}, },
"parameters": { "parameters": {
"gradient": { "gradient": {
"interpolation": 1, "interpolation": 2,
"points": [ "points": [
{ {
"a": 1, "a": 1,
"b": 0.071126, "b": 0.071126,
"g": 0.34877, "g": 0.34877,
"pos": 0, "pos": 0.120364,
"r": 0.59375 "r": 0.59375
}, },
{ {
"a": 1, "a": 1,
"b": 0.013021, "b": 0.013021,
"g": 0.144043, "g": 0.144043,
"pos": 1, "pos": 0.263636,
"r": 0.3125
},
{
"a": 1,
"b": 0.071126,
"g": 0.34877,
"pos": 0.402182,
"r": 0.59375
},
{
"a": 1,
"b": 0.071126,
"g": 0.34877,
"pos": 0.663636,
"r": 0.59375
},
{
"a": 1,
"b": 0.013021,
"g": 0.144043,
"pos": 0.893091,
"r": 0.3125 "r": 0.3125
} }
], ],
@ -307,25 +295,22 @@
{ {
"name": "normal_map_0", "name": "normal_map_0",
"node_position": { "node_position": {
"x": 319, "x": 431,
"y": 265.5 "y": 423.5
}, },
"parameters": { "parameters": {
"amount": 0.1,
"param0": 11, "param0": 11,
"param1": 0.99, "param1": 0.99,
"param2": 0, "param2": 0,
"param3": 0, "param4": 1
"param4": 1,
"size": 5
}, },
"type": "normal_map" "type": "normal_map"
}, },
{ {
"name": "colorize_0", "name": "colorize_0",
"node_position": { "node_position": {
"x": 313, "x": 423,
"y": 176.5 "y": 306.5
}, },
"parameters": { "parameters": {
"gradient": { "gradient": {

View File

@ -231,6 +231,12 @@ func save_file(filename) -> void:
set_save_path(filename) set_save_path(filename)
set_need_save(false) set_need_save(false)
func get_material_node() -> MMGenMaterial:
for g in top_generator.get_children():
if g.has_method("get_export_profiles"):
return g
return null
func export_textures() -> void: func export_textures() -> void:
if save_path != null: if save_path != null:
var prefix = save_path.left(save_path.rfind(".")) var prefix = save_path.left(save_path.rfind("."))

View File

@ -31,7 +31,8 @@ const MENU = [
{ menu="File", command="save_material_as", shortcut="Control+Shift+S", description="Save material as..." }, { menu="File", command="save_material_as", shortcut="Control+Shift+S", description="Save material as..." },
{ menu="File", command="save_all_materials", description="Save all materials..." }, { menu="File", command="save_all_materials", description="Save all materials..." },
{ menu="File" }, { menu="File" },
{ menu="File", command="export_material", shortcut="Control+E", description="Export material" }, { menu="File", submenu="export_material", description="Export material" },
#{ menu="File", command="export_material", shortcut="Control+E", description="Export material" },
{ menu="File" }, { menu="File" },
{ menu="File", command="close_material", description="Close material" }, { menu="File", command="close_material", description="Close material" },
{ menu="File", command="quit", shortcut="Control+Q", description="Quit" }, { menu="File", command="quit", shortcut="Control+Q", description="Quit" },
@ -53,7 +54,7 @@ const MENU = [
{ menu="Tools", command="add_to_user_library", description="Add selected node to user library" }, { menu="Tools", command="add_to_user_library", description="Add selected node to user library" },
{ menu="Tools", command="export_library", description="Export the nodes library" }, { menu="Tools", command="export_library", description="Export the nodes library" },
{ menu="Tools", command="generate_screenshots", description="Generate screenshots for the library nodes" }, #{ menu="Tools", command="generate_screenshots", description="Generate screenshots for the library nodes" },
@ -206,6 +207,45 @@ func add_recent(path) -> void:
f.store_string(to_json(recent_files)) f.store_string(to_json(recent_files))
f.close() f.close()
func create_menu_export_material(menu) -> void:
menu.clear()
var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null:
var material_node = graph_edit.get_material_node()
for p in material_node.get_export_profiles():
menu.add_item(p)
if !menu.is_connected("id_pressed", self, "_on_ExportMaterial_id_pressed"):
menu.connect("id_pressed", self, "_on_ExportMaterial_id_pressed")
func export_material(file_path : String, profile : String) -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit == null:
return
var material_node = graph_edit.get_material_node()
if material_node == null:
return
material_node.export_material(file_path.trim_suffix("."+file_path.get_extension()), profile)
func _on_ExportMaterial_id_pressed(id) -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit == null:
return
var material_node = graph_edit.get_material_node()
if material_node == null:
return
var profile = material_node.get_export_profiles()[id]
print("Exporting for "+profile)
var dialog : FileDialog = 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("*."+material_node.get_export_extension(profile)+";"+profile+" Material")
dialog.connect("file_selected", self, "export_material", [ profile ])
dialog.popup_centered()
func create_menu_set_theme(menu) -> void: func create_menu_set_theme(menu) -> void:
menu.clear() menu.clear()
for t in THEMES: for t in THEMES:
@ -312,11 +352,6 @@ func save_material_as() -> void:
func close_material() -> void: func close_material() -> void:
projects.close_tab() projects.close_tab()
func export_material() -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null :
graph_edit.export_textures()
func export_material_is_disabled() -> bool: func export_material_is_disabled() -> bool:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
return graph_edit == null or graph_edit.save_path == null return graph_edit == null or graph_edit.save_path == null

View File

@ -64,7 +64,7 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://addons/material_maker/engine/gen_image.gd" "path": "res://addons/material_maker/engine/gen_image.gd"
}, { }, {
"base": "MMGenBase", "base": "MMGenShader",
"class": "MMGenMaterial", "class": "MMGenMaterial",
"language": "GDScript", "language": "GDScript",
"path": "res://addons/material_maker/engine/gen_material.gd" "path": "res://addons/material_maker/engine/gen_material.gd"
@ -179,6 +179,7 @@ boot_splash/image="res://rodz_labs_logo.png"
boot_splash/fullsize=false boot_splash/fullsize=false
boot_splash/bg_color=Color( 0.0901961, 0.0941176, 0.141176, 1 ) boot_splash/bg_color=Color( 0.0901961, 0.0941176, 0.141176, 1 )
config/icon="res://icon.png" config/icon="res://icon.png"
config/windows_native_icon="res://icon.ico"
config/release="0.8" config/release="0.8"
[autoload] [autoload]

View File

@ -21,7 +21,7 @@ compress/lossy_quality=0.7
compress/hdr_mode=0 compress/hdr_mode=0
compress/bptc_ldr=0 compress/bptc_ldr=0
compress/normal_map=0 compress/normal_map=0
flags/repeat=true flags/repeat=0
flags/filter=true flags/filter=true
flags/mipmaps=true flags/mipmaps=true
flags/anisotropic=false flags/anisotropic=false