diff options
Diffstat (limited to 'scene/resources/visual_shader.cpp')
-rw-r--r-- | scene/resources/visual_shader.cpp | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 34129e35da..859546694f 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,6 +33,7 @@ #include "core/templates/vmap.h" #include "servers/rendering/shader_types.h" #include "visual_shader_nodes.h" +#include "visual_shader_sdf_nodes.h" bool VisualShaderNode::is_simple_decl() const { return simple_decl; @@ -486,6 +487,22 @@ void VisualShader::remove_node(Type p_type, int p_id) { _queue_update(); } +void VisualShader::replace_node(Type p_type, int p_id, const StringName &p_new_class) { + ERR_FAIL_INDEX(p_type, TYPE_MAX); + ERR_FAIL_COND(p_id < 2); + Graph *g = &graph[p_type]; + ERR_FAIL_COND(!g->nodes.has(p_id)); + + if (g->nodes[p_id].node->get_class_name() == p_new_class) { + return; + } + VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(p_new_class)); + vsn->connect("changed", callable_mp(this, &VisualShader::_queue_update)); + g->nodes[p_id].node = Ref<VisualShaderNode>(vsn); + + _queue_update(); +} + bool VisualShader::is_node_connection(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const { ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false); const Graph *g = &graph[p_type]; @@ -568,6 +585,12 @@ bool VisualShader::is_port_types_compatible(int p_a, int p_b) const { void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) { ERR_FAIL_INDEX(p_type, TYPE_MAX); Graph *g = &graph[p_type]; + + ERR_FAIL_COND(!g->nodes.has(p_from_node)); + ERR_FAIL_INDEX(p_from_port, g->nodes[p_from_node].node->get_output_port_count()); + ERR_FAIL_COND(!g->nodes.has(p_to_node)); + ERR_FAIL_INDEX(p_to_port, g->nodes[p_to_node].node->get_input_port_count()); + Connection c; c.from_node = p_from_node; c.from_port = p_from_port; @@ -658,6 +681,8 @@ void VisualShader::get_node_connections(Type p_type, List<Connection> *r_connect } void VisualShader::set_mode(Mode p_mode) { + ERR_FAIL_INDEX_MSG(p_mode, Mode::MODE_MAX, vformat("Invalid shader mode: %d.", p_mode)); + if (shader_mode == p_mode) { return; } @@ -713,7 +738,7 @@ void VisualShader::set_mode(Mode p_mode) { } _queue_update(); - _change_notify(); + notify_property_list_changed(); } void VisualShader::set_graph_offset(const Vector2 &p_offset) { @@ -1078,6 +1103,12 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const { return false; } +void VisualShader::reset_state() { +#ifndef _MSC_VER +#warning everything needs to be cleared here +#endif + emit_changed(); +} void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { //mode p_list->push_back(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Node3D,CanvasItem,Particles,Sky")); @@ -1375,11 +1406,11 @@ bool VisualShader::has_func_name(RenderingServer::ShaderMode p_mode, const Strin } void VisualShader::_update_shader() const { - if (!dirty) { + if (!dirty.is_set()) { return; } - dirty = false; + dirty.clear(); StringBuilder global_code; StringBuilder global_code_per_node; @@ -1565,15 +1596,16 @@ void VisualShader::_update_shader() const { } void VisualShader::_queue_update() { - if (dirty) { + if (dirty.is_set()) { return; } - dirty = true; + dirty.set(); call_deferred("_update_shader"); } void VisualShader::_input_type_changed(Type p_type, int p_id) { + ERR_FAIL_INDEX(p_type, TYPE_MAX); //erase connections using this input, as type changed Graph *g = &graph[p_type]; @@ -1588,7 +1620,7 @@ void VisualShader::_input_type_changed(Type p_type, int p_id) { } void VisualShader::rebuild() { - dirty = true; + dirty.set(); _update_shader(); } @@ -1605,6 +1637,7 @@ void VisualShader::_bind_methods() { ClassDB::bind_method(D_METHOD("get_valid_node_id", "type"), &VisualShader::get_valid_node_id); ClassDB::bind_method(D_METHOD("remove_node", "type", "id"), &VisualShader::remove_node); + ClassDB::bind_method(D_METHOD("replace_node", "type", "id", "new_class"), &VisualShader::replace_node); ClassDB::bind_method(D_METHOD("is_node_connection", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::is_node_connection); ClassDB::bind_method(D_METHOD("can_connect_nodes", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::can_connect_nodes); @@ -1641,6 +1674,7 @@ void VisualShader::_bind_methods() { } VisualShader::VisualShader() { + dirty.set(); for (int i = 0; i < TYPE_MAX; i++) { Ref<VisualShaderNodeOutput> output; output.instance(); @@ -2359,8 +2393,8 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "ao", "AO" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normalmap", "NORMALMAP" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "normalmap_depth", "NORMALMAP_DEPTH" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal_map", "NORMAL_MAP" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "normal_map_depth", "NORMAL_MAP_DEPTH" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "rim", "RIM" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "rim_tint", "RIM_TINT" }, @@ -2386,8 +2420,8 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normalmap", "NORMALMAP" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "normalmap_depth", "NORMALMAP_DEPTH" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal_map", "NORMAL_MAP" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "normal_map_depth", "NORMAL_MAP_DEPTH" }, // Canvas Item, Light { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_alpha", "LIGHT.a" }, @@ -3124,7 +3158,7 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad _expression = _expression.replace("\n", "\n\t\t"); static Vector<String> pre_symbols; - if (pre_symbols.empty()) { + if (pre_symbols.is_empty()) { pre_symbols.push_back("\t"); pre_symbols.push_back(","); pre_symbols.push_back(";"); @@ -3144,7 +3178,7 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad } static Vector<String> post_symbols; - if (post_symbols.empty()) { + if (post_symbols.is_empty()) { post_symbols.push_back("\t"); post_symbols.push_back("\n"); post_symbols.push_back(","); |