Improve performance for Show/Hide port preview in visual shaders
This commit is contained in:
parent
36e2c39f0c
commit
14a24fa19c
|
@ -60,6 +60,88 @@ void VisualShaderNodePlugin::_bind_methods() {
|
||||||
|
|
||||||
///////////////////
|
///////////////////
|
||||||
|
|
||||||
|
VisualShaderGraphPlugin::VisualShaderGraphPlugin() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisualShaderGraphPlugin::_bind_methods() {
|
||||||
|
ClassDB::bind_method("show_port_preview", &VisualShaderGraphPlugin::show_port_preview);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisualShaderGraphPlugin::register_shader(VisualShader *p_shader) {
|
||||||
|
visual_shader = Ref<VisualShader>(p_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisualShaderGraphPlugin::show_port_preview(int p_port_id, int p_node_id) {
|
||||||
|
if (links.has(p_node_id) && links[p_node_id].type == visual_shader->get_shader_type()) {
|
||||||
|
for (Map<int, Port>::Element *E = links[p_node_id].output_ports.front(); E; E = E->next()) {
|
||||||
|
E->value().preview_button->set_pressed(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (links[p_node_id].preview_visible && !is_dirty()) {
|
||||||
|
links[p_node_id].graph_node->remove_child(links[p_node_id].preview_box);
|
||||||
|
links[p_node_id].graph_node->set_size(Vector2(-1, -1));
|
||||||
|
links[p_node_id].preview_visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_port_id != -1) {
|
||||||
|
if (is_dirty()) {
|
||||||
|
links[p_node_id].preview_pos = links[p_node_id].graph_node->get_child_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
VBoxContainer *vbox = memnew(VBoxContainer);
|
||||||
|
links[p_node_id].graph_node->add_child(vbox);
|
||||||
|
if (links[p_node_id].preview_pos != -1) {
|
||||||
|
links[p_node_id].graph_node->move_child(vbox, links[p_node_id].preview_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
Control *offset = memnew(Control);
|
||||||
|
offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE));
|
||||||
|
vbox->add_child(offset);
|
||||||
|
|
||||||
|
VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview);
|
||||||
|
port_preview->setup(visual_shader, visual_shader->get_shader_type(), p_node_id, p_port_id);
|
||||||
|
port_preview->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
|
||||||
|
vbox->add_child(port_preview);
|
||||||
|
links[p_node_id].preview_visible = true;
|
||||||
|
links[p_node_id].preview_box = vbox;
|
||||||
|
links[p_node_id].output_ports[p_port_id].preview_button->set_pressed(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VisualShaderGraphPlugin::is_preview_visible(int p_id) const {
|
||||||
|
return links[p_id].preview_visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisualShaderGraphPlugin::clear_links() {
|
||||||
|
links.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VisualShaderGraphPlugin::is_dirty() const {
|
||||||
|
return dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisualShaderGraphPlugin::make_dirty(bool p_enabled) {
|
||||||
|
dirty = p_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node) {
|
||||||
|
links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1 });
|
||||||
|
|
||||||
|
if (!p_visual_node->is_connected("show_port_preview", callable_mp(this, &VisualShaderGraphPlugin::show_port_preview))) {
|
||||||
|
p_visual_node->connect("show_port_preview", callable_mp(this, &VisualShaderGraphPlugin::show_port_preview), varray(p_id), CONNECT_DEFERRED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, TextureButton *p_button) {
|
||||||
|
links[p_node_id].output_ports.insert(p_port, { p_button });
|
||||||
|
}
|
||||||
|
|
||||||
|
VisualShaderGraphPlugin::~VisualShaderGraphPlugin() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
|
||||||
void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
|
void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
if (p_visual_shader) {
|
if (p_visual_shader) {
|
||||||
|
@ -71,6 +153,7 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
visual_shader = Ref<VisualShader>(p_visual_shader);
|
visual_shader = Ref<VisualShader>(p_visual_shader);
|
||||||
|
graph_plugin->register_shader(visual_shader.ptr());
|
||||||
if (!visual_shader->is_connected("changed", callable_mp(this, &VisualShaderEditor::_update_preview))) {
|
if (!visual_shader->is_connected("changed", callable_mp(this, &VisualShaderEditor::_update_preview))) {
|
||||||
visual_shader->connect("changed", callable_mp(this, &VisualShaderEditor::_update_preview));
|
visual_shader->connect("changed", callable_mp(this, &VisualShaderEditor::_update_preview));
|
||||||
}
|
}
|
||||||
|
@ -528,6 +611,9 @@ void VisualShaderEditor::_update_graph() {
|
||||||
|
|
||||||
Control *offset;
|
Control *offset;
|
||||||
|
|
||||||
|
graph_plugin->clear_links();
|
||||||
|
graph_plugin->make_dirty(true);
|
||||||
|
|
||||||
for (int n_i = 0; n_i < nodes.size(); n_i++) {
|
for (int n_i = 0; n_i < nodes.size(); n_i++) {
|
||||||
Vector2 position = visual_shader->get_node_position(type, nodes[n_i]);
|
Vector2 position = visual_shader->get_node_position(type, nodes[n_i]);
|
||||||
Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, nodes[n_i]);
|
Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, nodes[n_i]);
|
||||||
|
@ -542,6 +628,7 @@ void VisualShaderEditor::_update_graph() {
|
||||||
|
|
||||||
GraphNode *node = memnew(GraphNode);
|
GraphNode *node = memnew(GraphNode);
|
||||||
visual_shader->set_graph_node(type, nodes[n_i], node);
|
visual_shader->set_graph_node(type, nodes[n_i], node);
|
||||||
|
graph_plugin->register_link(type, nodes[n_i], vsnode.ptr(), node);
|
||||||
|
|
||||||
if (is_group) {
|
if (is_group) {
|
||||||
size = group_node->get_size();
|
size = group_node->get_size();
|
||||||
|
@ -813,9 +900,7 @@ void VisualShaderEditor::_update_graph() {
|
||||||
preview->set_pressed_texture(get_theme_icon("GuiVisibilityVisible", "EditorIcons"));
|
preview->set_pressed_texture(get_theme_icon("GuiVisibilityVisible", "EditorIcons"));
|
||||||
preview->set_v_size_flags(SIZE_SHRINK_CENTER);
|
preview->set_v_size_flags(SIZE_SHRINK_CENTER);
|
||||||
|
|
||||||
if (vsnode->get_output_port_for_preview() == i) {
|
graph_plugin->register_output_port(nodes[n_i], i, preview);
|
||||||
preview->set_pressed(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
preview->connect("pressed", callable_mp(this, &VisualShaderEditor::_preview_select_port), varray(nodes[n_i], i), CONNECT_DEFERRED);
|
preview->connect("pressed", callable_mp(this, &VisualShaderEditor::_preview_select_port), varray(nodes[n_i], i), CONNECT_DEFERRED);
|
||||||
hb->add_child(preview);
|
hb->add_child(preview);
|
||||||
|
@ -834,18 +919,7 @@ void VisualShaderEditor::_update_graph() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vsnode->get_output_port_for_preview() >= 0) {
|
if (vsnode->get_output_port_for_preview() >= 0) {
|
||||||
int port_type = vsnode->get_output_port_type(vsnode->get_output_port_for_preview());
|
graph_plugin->show_port_preview(vsnode->get_output_port_for_preview(), nodes[n_i]);
|
||||||
|
|
||||||
if (port_type != VisualShaderNode::PORT_TYPE_TRANSFORM && port_type != VisualShaderNode::PORT_TYPE_SAMPLER) {
|
|
||||||
offset = memnew(Control);
|
|
||||||
offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE));
|
|
||||||
node->add_child(offset);
|
|
||||||
|
|
||||||
VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview);
|
|
||||||
port_preview->setup(visual_shader, type, nodes[n_i], vsnode->get_output_port_for_preview());
|
|
||||||
port_preview->set_h_size_flags(SIZE_SHRINK_CENTER);
|
|
||||||
node->add_child(port_preview);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = memnew(Control);
|
offset = memnew(Control);
|
||||||
|
@ -908,6 +982,8 @@ void VisualShaderEditor::_update_graph() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
graph_plugin->make_dirty(false);
|
||||||
|
|
||||||
for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) {
|
for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) {
|
||||||
int from = E->get().from_node;
|
int from = E->get().from_node;
|
||||||
int from_idx = E->get().from_port;
|
int from_idx = E->get().from_port;
|
||||||
|
@ -1208,11 +1284,9 @@ void VisualShaderEditor::_preview_select_port(int p_node, int p_port) {
|
||||||
if (node->get_output_port_for_preview() == p_port) {
|
if (node->get_output_port_for_preview() == p_port) {
|
||||||
p_port = -1; //toggle it
|
p_port = -1; //toggle it
|
||||||
}
|
}
|
||||||
undo_redo->create_action(TTR("Set Uniform Name"));
|
undo_redo->create_action(p_port == -1 ? TTR("Hide Port Preview") : TTR("Show Port Preview"));
|
||||||
undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", p_port);
|
undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", p_port);
|
||||||
undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", node->get_output_port_for_preview());
|
undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", node->get_output_port_for_preview());
|
||||||
undo_redo->add_do_method(this, "_update_graph");
|
|
||||||
undo_redo->add_undo_method(this, "_update_graph");
|
|
||||||
undo_redo->commit_action();
|
undo_redo->commit_action();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3030,12 +3104,16 @@ VisualShaderEditor::VisualShaderEditor() {
|
||||||
default_plugin.instance();
|
default_plugin.instance();
|
||||||
add_plugin(default_plugin);
|
add_plugin(default_plugin);
|
||||||
|
|
||||||
|
graph_plugin.instance();
|
||||||
|
|
||||||
property_editor = memnew(CustomPropertyEditor);
|
property_editor = memnew(CustomPropertyEditor);
|
||||||
add_child(property_editor);
|
add_child(property_editor);
|
||||||
|
|
||||||
property_editor->connect("variant_changed", callable_mp(this, &VisualShaderEditor::_port_edited));
|
property_editor->connect("variant_changed", callable_mp(this, &VisualShaderEditor::_port_edited));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
|
||||||
void VisualShaderEditorPlugin::edit(Object *p_object) {
|
void VisualShaderEditorPlugin::edit(Object *p_object) {
|
||||||
visual_shader_editor->edit(Object::cast_to<VisualShader>(p_object));
|
visual_shader_editor->edit(Object::cast_to<VisualShader>(p_object));
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,50 @@ public:
|
||||||
virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node);
|
virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VisualShaderGraphPlugin : public Reference {
|
||||||
|
GDCLASS(VisualShaderGraphPlugin, Reference);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Port {
|
||||||
|
TextureButton *preview_button;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Link {
|
||||||
|
VisualShader::Type type;
|
||||||
|
VisualShaderNode *visual_node;
|
||||||
|
GraphNode *graph_node;
|
||||||
|
bool preview_visible;
|
||||||
|
int preview_pos;
|
||||||
|
Map<int, Port> output_ports;
|
||||||
|
VBoxContainer *preview_box;
|
||||||
|
};
|
||||||
|
|
||||||
|
Ref<VisualShader> visual_shader;
|
||||||
|
Map<int, Link> links;
|
||||||
|
bool dirty = false;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void register_shader(VisualShader *p_visual_shader);
|
||||||
|
void register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node);
|
||||||
|
void register_output_port(int p_id, int p_port, TextureButton *p_button);
|
||||||
|
void clear_links();
|
||||||
|
void set_shader_type(VisualShader::Type p_type);
|
||||||
|
bool is_preview_visible(int p_id) const;
|
||||||
|
bool is_dirty() const;
|
||||||
|
void make_dirty(bool p_enabled);
|
||||||
|
|
||||||
|
void show_port_preview(int p_node_id, int p_port_id);
|
||||||
|
|
||||||
|
VisualShaderGraphPlugin();
|
||||||
|
~VisualShaderGraphPlugin();
|
||||||
|
};
|
||||||
|
|
||||||
class VisualShaderEditor : public VBoxContainer {
|
class VisualShaderEditor : public VBoxContainer {
|
||||||
GDCLASS(VisualShaderEditor, VBoxContainer);
|
GDCLASS(VisualShaderEditor, VBoxContainer);
|
||||||
|
friend class VisualShaderGraphPlugin;
|
||||||
|
|
||||||
CustomPropertyEditor *property_editor;
|
CustomPropertyEditor *property_editor;
|
||||||
int editing_node;
|
int editing_node;
|
||||||
|
@ -242,6 +284,7 @@ class VisualShaderEditor : public VBoxContainer {
|
||||||
void _paste_nodes(bool p_use_custom_position = false, const Vector2 &p_custom_position = Vector2());
|
void _paste_nodes(bool p_use_custom_position = false, const Vector2 &p_custom_position = Vector2());
|
||||||
|
|
||||||
Vector<Ref<VisualShaderNodePlugin>> plugins;
|
Vector<Ref<VisualShaderNodePlugin>> plugins;
|
||||||
|
Ref<VisualShaderGraphPlugin> graph_plugin;
|
||||||
|
|
||||||
void _mode_selected(int p_id);
|
void _mode_selected(int p_id);
|
||||||
void _rebuild();
|
void _rebuild();
|
||||||
|
|
|
@ -40,6 +40,7 @@ bool VisualShaderNode::is_simple_decl() const {
|
||||||
|
|
||||||
void VisualShaderNode::set_output_port_for_preview(int p_index) {
|
void VisualShaderNode::set_output_port_for_preview(int p_index) {
|
||||||
port_preview = p_index;
|
port_preview = p_index;
|
||||||
|
emit_signal("show_port_preview", p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
int VisualShaderNode::get_output_port_for_preview() const {
|
int VisualShaderNode::get_output_port_for_preview() const {
|
||||||
|
@ -161,6 +162,7 @@ void VisualShaderNode::_bind_methods() {
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "output_port_for_preview"), "set_output_port_for_preview", "get_output_port_for_preview");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "output_port_for_preview"), "set_output_port_for_preview", "get_output_port_for_preview");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_default_input_values", "get_default_input_values");
|
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_default_input_values", "get_default_input_values");
|
||||||
ADD_SIGNAL(MethodInfo("editor_refresh_request"));
|
ADD_SIGNAL(MethodInfo("editor_refresh_request"));
|
||||||
|
ADD_SIGNAL(MethodInfo("show_port_preview", PropertyInfo(Variant::INT, "port_id")));
|
||||||
|
|
||||||
BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR);
|
BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR);
|
||||||
BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR_INT);
|
BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR_INT);
|
||||||
|
@ -328,6 +330,10 @@ void VisualShader::set_shader_type(Type p_type) {
|
||||||
current_type = p_type;
|
current_type = p_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VisualShader::Type VisualShader::get_shader_type() const {
|
||||||
|
return current_type;
|
||||||
|
}
|
||||||
|
|
||||||
void VisualShader::set_version(const String &p_version) {
|
void VisualShader::set_version(const String &p_version) {
|
||||||
version = p_version;
|
version = p_version;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,7 @@ protected:
|
||||||
public: // internal methods
|
public: // internal methods
|
||||||
void set_graph_node(Type p_type, int p_id, GraphNode *p_graph_node);
|
void set_graph_node(Type p_type, int p_id, GraphNode *p_graph_node);
|
||||||
void set_shader_type(Type p_type);
|
void set_shader_type(Type p_type);
|
||||||
|
Type get_shader_type() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void set_version(const String &p_version);
|
void set_version(const String &p_version);
|
||||||
|
|
Loading…
Reference in a new issue