New gradient editor, more image node progress

Added a gradient editor (should be ready for integration in Colorize node)
The image in the Image node can be modified (but will not be saved yet)
This commit is contained in:
RodZill4 2018-07-27 08:49:54 +02:00
parent d04a319944
commit 46adb434bf
8 changed files with 301 additions and 13 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@ -1,14 +1,17 @@
tool tool
extends "res://addons/procedural_material/node_base.gd" extends "res://addons/procedural_material/node_base.gd"
var rows var file_path
func _ready(): func _ready():
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1)) set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
func set_texture(path): func set_texture(path):
file_path = path
var texture = ImageTexture.new() var texture = ImageTexture.new()
texture.load(path) texture.load(path)
$TextureButton.texture_normal = texture
get_parent().get_parent().generate_shader()
func get_textures(): func get_textures():
var list = {} var list = {}
@ -26,3 +29,13 @@ func _get_shader_code(uv):
rv.code = "vec3 "+name+"_"+str(variant_index)+"_rgb = texture("+name+"_tex, "+uv+").rgb;\n" rv.code = "vec3 "+name+"_"+str(variant_index)+"_rgb = texture("+name+"_tex, "+uv+").rgb;\n"
rv.rgb = name+"_"+str(variant_index)+"_rgb" rv.rgb = name+"_"+str(variant_index)+"_rgb"
return rv return rv
func _on_TextureButton_pressed():
var dialog = EditorFileDialog.new()
add_child(dialog)
dialog.access = EditorFileDialog.ACCESS_FILESYSTEM
dialog.mode = EditorFileDialog.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

@ -6,7 +6,7 @@
[sub_resource type="Theme" id=1] [sub_resource type="Theme" id=1]
[node name="Image" type="GraphNode" index="0"] [node name="Image" type="GraphNode"]
anchor_left = 0.0 anchor_left = 0.0
anchor_top = 0.0 anchor_top = 0.0
@ -22,6 +22,7 @@ mouse_filter = 1
mouse_default_cursor_shape = 0 mouse_default_cursor_shape = 0
size_flags_horizontal = 1 size_flags_horizontal = 1
size_flags_vertical = 1 size_flags_vertical = 1
size_flags_stretch_ratio = 0.13
theme = SubResource( 1 ) theme = SubResource( 1 )
title = "Image" title = "Image"
offset = Vector2( 0, 0 ) offset = Vector2( 0, 0 )
@ -37,7 +38,7 @@ 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.5, 0.5, 1, 1 )
script = ExtResource( 1 ) script = ExtResource( 1 )
_sections_unfolded = [ "Theme", "slot" ] _sections_unfolded = [ "Mouse", "Size Flags", "Theme" ]
[node name="TextureButton" type="TextureButton" parent="." index="0"] [node name="TextureButton" type="TextureButton" parent="." index="0"]
@ -51,7 +52,7 @@ margin_right = 80.0
margin_bottom = 88.0 margin_bottom = 88.0
rect_min_size = Vector2( 64, 64 ) rect_min_size = Vector2( 64, 64 )
rect_pivot_offset = Vector2( 0, 0 ) rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false rect_clip_content = true
focus_mode = 2 focus_mode = 2
mouse_filter = 0 mouse_filter = 0
mouse_default_cursor_shape = 0 mouse_default_cursor_shape = 0
@ -62,9 +63,12 @@ enabled_focus_mode = 2
shortcut = null shortcut = null
group = null group = null
texture_normal = ExtResource( 2 ) texture_normal = ExtResource( 2 )
expand = true
stretch_mode = 5 stretch_mode = 5
_sections_unfolded = [ "Rect", "Textures" ] _sections_unfolded = [ "Rect", "Textures" ]
[connection signal="close_request" from="." to="." method="queue_free"] [connection signal="close_request" from="." to="." method="queue_free"]
[connection signal="pressed" from="TextureButton" to="." method="_on_TextureButton_pressed"]

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,122 @@
extends Control
class GradientCursor:
extends ColorRect
const WIDTH = 10
func _ready():
rect_position = Vector2(0, 15)
rect_size = Vector2(WIDTH, 20)
func _gui_input(ev):
if ev is InputEventMouseButton && ev.button_index == 1 && ev.doubleclick:
get_parent().select_color(self)
elif ev is InputEventMouseMotion && (ev.button_mask & 1) != 0:
rect_position.x += ev.relative.x
rect_position.x = min(max(0, rect_position.x), get_parent().rect_size.x-rect_size.x)
get_parent().update_shader()
func get_position():
return rect_position.x / (get_parent().rect_size.x - WIDTH)
func set_color(c):
color = c
get_parent().update_shader()
static func sort(a, b):
if a.get_position() < b.get_position():
return true
return false
func _ready():
$Gradient.material = $Gradient.material.duplicate(true)
add_cursor(0, Color(0, 0, 0))
add_cursor(rect_size.x-GradientCursor.WIDTH, Color(1, 1, 1))
func add_cursor(x, color):
var cursor = GradientCursor.new()
add_child(cursor)
cursor.rect_position.x = x
cursor.color = color
update_shader()
func _gui_input(ev):
if ev is InputEventMouseButton && ev.button_index == 1 && ev.doubleclick && ev.position.y > 15:
add_cursor(ev.position.x, get_color(ev.position.x))
# Showing a color picker popup to change a cursor's color
var active_cursor
func select_color(cursor):
active_cursor = cursor
$Gradient/Popup/ColorPicker.connect("color_changed", cursor, "set_color")
$Gradient/Popup.popup()
func _on_Popup_popup_hide():
$Gradient/Popup/ColorPicker.disconnect("color_changed", active_cursor, "set_color")
# Calculating a color from the gradient and generating the shader
func get_sorted_cursors():
var array = get_children()
array.erase($Gradient)
array.sort_custom(GradientCursor, "sort")
return array
func get_color(x):
var array = get_sorted_cursors()
x = x / (rect_size.x - array[0].rect_size.x)
if x < array[0].get_position():
return array[0].color
for i in range(array.size()-1):
if x < array[i+1].get_position():
var p0 = array[i].get_position()
var c0 = array[i].color
var p1 = array[i+1].get_position()
var c1 = array[i+1].color
return c0 + (c1-c0) * (x-p0) / (p1-p0)
return array[array.size()-1].color
# get_color_in_shader
func gcis(color):
return "vec3(%.1f,%.1f,%.1f)" % [color.r, color.g, color.b]
func get_shader(name):
var array = get_sorted_cursors()
var shader
shader = "vec3 "+name+"(float x) {\n"
shader += " if (x < %.1f) {\n" % array[0].get_position()
shader += " return "+gcis(array[0].color)+";\n"
for i in range(array.size()-1):
var p0 = array[i].get_position()
var c0 = array[i].color
var p1mp0 = array[i+1].get_position()-p0
var c1mc0 = array[i+1].color-c0
if p1mp0 > 0:
shader += " } else if (x < %.1f) {\n" % array[i+1].get_position()
shader += " return %s+x*%s;\n" % [gcis(c0-c1mc0*(p0/p1mp0)), gcis(c1mc0/p1mp0)]
shader += " }\n"
shader += " return "+gcis(array[array.size()-1].color)+";\n"
shader += "}\n"
return shader
func update_shader():
var shader
shader = "shader_type canvas_item;\n"
shader += get_shader("gradient")
shader += "void fragment() { COLOR = vec4(gradient((UV.x-%.1f)*%.1f), 1.0); }" % [ 0.5*GradientCursor.WIDTH/rect_size.x, (rect_size.x-GradientCursor.WIDTH)/rect_size.x ]
$Gradient.material.shader.set_code(shader)
func serialize():
var rv = []
for c in get_sorted_cursors():
rv.append({ pos= c.get_position(), r= c.color.r, g= c.color.g, b= c.color.b })
return rv
func deserialize(v):
for c in get_sorted_cursors():
queue_free(c)
for i in v:
add_cursor(i.pos*(rect_size.x-GradientCursor.WIDTH), Color(i.r, i.g, i.b))

View File

@ -0,0 +1,109 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://addons/procedural_material/widgets/gradient_editor.gd" type="Script" id=1]
[sub_resource type="Shader" id=1]
code = "shader_type canvas_item;
vec3 gradient(float x) {
if (x < 0.2) {
return vec3(0.1);
} else if (x < 0.8) {
return vec3(0.1)+(x-0.2)*vec3(0.7);
}
return vec3(0.5);
}
void fragment() { COLOR = vec4(gradient(UV.x), 1.0); }
"
[sub_resource type="ShaderMaterial" id=2]
render_priority = 0
shader = SubResource( 1 )
[node name="Control" type="Control" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 24.0
margin_top = 14.0
margin_right = 144.0
margin_bottom = 44.0
rect_min_size = Vector2( 100, 30 )
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
script = ExtResource( 1 )
_sections_unfolded = [ "Rect" ]
[node name="Gradient" type="ColorRect" parent="." index="0"]
material = SubResource( 2 )
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 120.0
margin_bottom = 20.0
rect_min_size = Vector2( 120, 20 )
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
color = Color( 1, 1, 1, 1 )
_sections_unfolded = [ "Material" ]
[node name="Popup" type="Popup" parent="Gradient" index="0"]
visible = false
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 47.0
margin_top = 33.0
margin_right = 353.0
margin_bottom = 475.0
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
popup_exclusive = false
[node name="ColorPicker" type="ColorPicker" parent="Gradient/Popup" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 4.0
margin_top = 4.0
margin_right = 302.0
margin_bottom = 462.0
rect_scale = Vector2( 0.75, 0.75 )
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
color = Color( 1, 1, 1, 1 )
edit_alpha = false
raw_mode = false
_sections_unfolded = [ "Rect" ]
[connection signal="popup_hide" from="Gradient/Popup" to="." method="_on_Popup_popup_hide"]

View File

@ -0,0 +1,14 @@
tool
extends ColorRect
func _ready():
pass
func _on_gui_input(ev):
if ev is InputEventMouseButton && ev.button_index == 1 && ev.doubleclick:
var dialog = ColorPicker.new()
add_child(dialog)
elif ev is InputEventMouseMotion && (ev.button_mask & 1) != 0:
rect_position.x += ev.relative.x
rect_position.x = min(max(0, rect_position.x), get_parent().rect_size.x-rect_size.x)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 14 KiB