2019-08-09 08:16:24 +02:00
|
|
|
tool
|
|
|
|
extends Viewport
|
|
|
|
class_name MMGenRenderer
|
|
|
|
|
2019-10-18 08:35:54 +02:00
|
|
|
export(String) var debug_path = ""
|
2019-08-09 08:16:24 +02:00
|
|
|
var debug_file_index : int = 0
|
|
|
|
|
2020-03-18 21:40:02 +01:00
|
|
|
var common_shader : String
|
|
|
|
|
2019-08-09 08:16:24 +02:00
|
|
|
var rendering : bool = false
|
2020-03-18 21:40:02 +01:00
|
|
|
|
2019-09-24 22:25:46 +02:00
|
|
|
signal done
|
2019-08-09 08:16:24 +02:00
|
|
|
|
2020-03-18 21:40:02 +01:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func _ready() -> void:
|
2019-08-09 08:16:24 +02:00
|
|
|
$ColorRect.material = $ColorRect.material.duplicate(true)
|
2020-03-18 21:40:02 +01:00
|
|
|
var file = File.new()
|
|
|
|
file.open("res://addons/material_maker/common.shader", File.READ)
|
|
|
|
common_shader = file.get_as_text()
|
2019-08-09 08:16:24 +02:00
|
|
|
|
2020-03-18 21:40:02 +01:00
|
|
|
func generate_shader(src_code) -> String:
|
2019-08-09 08:16:24 +02:00
|
|
|
var code
|
|
|
|
code = "shader_type canvas_item;\n"
|
|
|
|
code += "render_mode blend_disabled;\n"
|
2020-03-18 21:40:02 +01:00
|
|
|
code += common_shader
|
2019-08-09 08:16:24 +02:00
|
|
|
code += "\n"
|
2019-08-18 16:28:50 +02:00
|
|
|
if src_code.has("textures"):
|
|
|
|
for t in src_code.textures.keys():
|
|
|
|
code += "uniform sampler2D "+t+";\n"
|
2019-08-09 08:16:24 +02:00
|
|
|
if src_code.has("globals"):
|
|
|
|
for g in src_code.globals:
|
|
|
|
code += g
|
|
|
|
var shader_code = src_code.defs
|
2019-09-29 10:07:32 +02:00
|
|
|
shader_code += "\nvoid fragment() {\n"
|
2019-12-15 12:41:00 +01:00
|
|
|
shader_code += "vec2 uv = UV;\n"
|
2019-08-09 08:16:24 +02:00
|
|
|
shader_code += src_code.code
|
2019-12-15 12:41:00 +01:00
|
|
|
if src_code.has("rgba"):
|
|
|
|
shader_code += "COLOR = "+src_code.rgba+";\n"
|
|
|
|
else:
|
|
|
|
shader_code += "COLOR = vec4(1.0, 0.0, 0.0, 1.0);\n"
|
2019-08-09 08:16:24 +02:00
|
|
|
shader_code += "}\n"
|
|
|
|
#print("GENERATED SHADER:\n"+shader_code)
|
|
|
|
code += shader_code
|
|
|
|
return code
|
|
|
|
|
2020-03-18 21:40:02 +01:00
|
|
|
func generate_combined_shader(red_code, green_code, blue_code) -> String:
|
2019-08-09 08:16:24 +02:00
|
|
|
var code
|
|
|
|
code = "shader_type canvas_item;\n"
|
|
|
|
code += "render_mode blend_disabled;\n"
|
2020-03-18 21:40:02 +01:00
|
|
|
code += common_shader
|
2019-08-09 08:16:24 +02:00
|
|
|
code += "\n"
|
2019-10-18 08:35:54 +02:00
|
|
|
var globals = []
|
2019-11-14 08:47:21 +01:00
|
|
|
var textures = {}
|
2019-12-25 10:36:45 +01:00
|
|
|
var output = []
|
2019-10-18 08:35:54 +02:00
|
|
|
for c in [ red_code, green_code, blue_code ]:
|
2019-11-14 08:47:21 +01:00
|
|
|
if c.has("textures"):
|
|
|
|
for t in c.textures.keys():
|
|
|
|
textures[t] = c.textures[t]
|
2019-10-18 08:35:54 +02:00
|
|
|
if c.has("globals"):
|
|
|
|
for g in c.globals:
|
|
|
|
if globals.find(g) == -1:
|
|
|
|
globals.push_back(g)
|
2019-12-25 10:36:45 +01:00
|
|
|
if c.has("f"):
|
|
|
|
output.push_back(c.f)
|
|
|
|
else:
|
|
|
|
output.push_back("1.0")
|
2019-11-14 08:47:21 +01:00
|
|
|
for t in textures.keys():
|
|
|
|
code += "uniform sampler2D "+t+";\n"
|
2019-10-18 08:35:54 +02:00
|
|
|
for g in globals:
|
|
|
|
code += g
|
2019-08-09 08:16:24 +02:00
|
|
|
var shader_code = ""
|
|
|
|
shader_code += red_code.defs
|
|
|
|
shader_code += green_code.defs
|
|
|
|
shader_code += blue_code.defs
|
|
|
|
shader_code += "void fragment() {\n"
|
|
|
|
shader_code += red_code.code
|
|
|
|
shader_code += green_code.code
|
|
|
|
shader_code += blue_code.code
|
2019-12-25 10:36:45 +01:00
|
|
|
shader_code += "COLOR = vec4("+output[0]+", "+output[1]+", "+output[2]+", 1.0);\n"
|
2019-08-09 08:16:24 +02:00
|
|
|
shader_code += "}\n"
|
|
|
|
#print("GENERATED COMBINED SHADER:\n"+shader_code)
|
|
|
|
code += shader_code
|
|
|
|
return code
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func setup_material(shader_material, textures, shader_code) -> void:
|
2019-08-09 08:16:24 +02:00
|
|
|
for k in textures.keys():
|
|
|
|
shader_material.set_shader_param(k+"_tex", textures[k])
|
|
|
|
shader_material.shader.code = shader_code
|
|
|
|
|
2020-03-18 21:40:02 +01:00
|
|
|
func render_material(material, render_size) -> Object:
|
|
|
|
while rendering:
|
|
|
|
yield(self, "done")
|
|
|
|
rendering = true
|
|
|
|
var shader_material = $ColorRect.material
|
|
|
|
size = Vector2(render_size, render_size)
|
|
|
|
$ColorRect.rect_position = Vector2(0, 0)
|
|
|
|
$ColorRect.rect_size = size
|
|
|
|
$ColorRect.material = material
|
|
|
|
render_target_update_mode = Viewport.UPDATE_ONCE
|
|
|
|
update_worlds()
|
|
|
|
yield(get_tree(), "idle_frame")
|
|
|
|
yield(get_tree(), "idle_frame")
|
|
|
|
$ColorRect.material = shader_material
|
|
|
|
return self
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func render_shader(shader, textures, render_size) -> Object:
|
2019-08-09 08:16:24 +02:00
|
|
|
if debug_path != null and debug_path != "":
|
2019-10-18 08:35:54 +02:00
|
|
|
var file_name = debug_path+str(debug_file_index)+".shader"
|
2019-08-09 08:16:24 +02:00
|
|
|
var f = File.new()
|
|
|
|
f.open(debug_path+str(debug_file_index)+".shader", File.WRITE)
|
|
|
|
f.store_string(shader)
|
|
|
|
f.close()
|
|
|
|
debug_file_index += 1
|
2019-10-18 08:35:54 +02:00
|
|
|
print("shader saved as "+file_name)
|
|
|
|
while rendering:
|
|
|
|
yield(self, "done")
|
|
|
|
rendering = true
|
2019-08-09 08:16:24 +02:00
|
|
|
size = Vector2(render_size, render_size)
|
|
|
|
$ColorRect.rect_position = Vector2(0, 0)
|
|
|
|
$ColorRect.rect_size = size
|
|
|
|
var shader_material = $ColorRect.material
|
|
|
|
shader_material.shader.code = shader
|
|
|
|
if textures != null:
|
|
|
|
for k in textures.keys():
|
2019-08-18 16:28:50 +02:00
|
|
|
shader_material.set_shader_param(k, textures[k])
|
2019-12-21 10:11:39 +01:00
|
|
|
shader_material.set_shader_param("preview_size", render_size)
|
2019-08-09 08:16:24 +02:00
|
|
|
render_target_update_mode = Viewport.UPDATE_ONCE
|
|
|
|
update_worlds()
|
|
|
|
yield(get_tree(), "idle_frame")
|
2019-09-25 08:04:36 +02:00
|
|
|
yield(get_tree(), "idle_frame")
|
2019-10-05 11:04:50 +02:00
|
|
|
return self
|
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func copy_to_texture(t : ImageTexture) -> void:
|
2019-10-07 20:41:57 +02:00
|
|
|
var image : Image = get_texture().get_data()
|
2019-10-14 20:42:11 +02:00
|
|
|
if image != null:
|
|
|
|
image.lock()
|
|
|
|
t.create_from_image(get_texture().get_data())
|
|
|
|
image.unlock()
|
2019-10-07 20:41:57 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func save_to_file(fn : String) -> void:
|
2019-10-07 20:41:57 +02:00
|
|
|
var image : Image = get_texture().get_data()
|
|
|
|
image.lock()
|
|
|
|
image.save_png(fn)
|
|
|
|
image.unlock()
|
2019-10-05 11:04:50 +02:00
|
|
|
|
2019-10-20 16:22:06 +02:00
|
|
|
func release() -> void:
|
2019-08-09 08:16:24 +02:00
|
|
|
rendering = false
|
2019-09-24 22:25:46 +02:00
|
|
|
emit_signal("done")
|