summaryrefslogtreecommitdiff
path: root/scene/resources/visual_shader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/visual_shader.cpp')
-rw-r--r--scene/resources/visual_shader.cpp116
1 files changed, 94 insertions, 22 deletions
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 38b7c5cda0..556d299198 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -32,6 +32,7 @@
#include "core/vmap.h"
#include "servers/visual/shader_types.h"
+#include "visual_shader_nodes.h"
bool VisualShaderNode::is_simple_decl() const {
return simple_decl;
@@ -127,6 +128,7 @@ void VisualShaderNode::_bind_methods() {
ADD_SIGNAL(MethodInfo("editor_refresh_request"));
BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR);
+ BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR_INT);
BIND_ENUM_CONSTANT(PORT_TYPE_VECTOR);
BIND_ENUM_CONSTANT(PORT_TYPE_BOOLEAN);
BIND_ENUM_CONSTANT(PORT_TYPE_TRANSFORM);
@@ -266,14 +268,13 @@ void VisualShaderNodeCustom::_bind_methods() {
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_name"));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_description"));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_subcategory"));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_return_icon_type"));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_count"));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_type", PropertyInfo(Variant::INT, "port")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_input_port_name", PropertyInfo(Variant::INT, "port")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING_NAME, "_get_input_port_name", PropertyInfo(Variant::INT, "port")));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_count"));
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_type", PropertyInfo(Variant::INT, "port")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_port_name", PropertyInfo(Variant::INT, "port")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING_NAME, "_get_output_port_name", PropertyInfo(Variant::INT, "port")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_code", PropertyInfo(Variant::ARRAY, "input_vars"), PropertyInfo(Variant::ARRAY, "output_vars"), PropertyInfo(Variant::INT, "mode"), PropertyInfo(Variant::INT, "type")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_global_code", PropertyInfo(Variant::INT, "mode")));
BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_highend"));
@@ -285,6 +286,49 @@ VisualShaderNodeCustom::VisualShaderNodeCustom() {
/////////////////////////////////////////////////////////
+void VisualShader::set_version(const String &p_version) {
+ version = p_version;
+}
+
+String VisualShader::get_version() const {
+ return version;
+}
+
+void VisualShader::update_version(const String &p_new_version) {
+ if (version == "") {
+ for (int i = 0; i < TYPE_MAX; i++) {
+ for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
+ Ref<VisualShaderNodeExpression> expression = Object::cast_to<VisualShaderNodeExpression>(E->get().node.ptr());
+ if (expression.is_valid()) {
+ for (int j = 0; j < expression->get_input_port_count(); j++) {
+ int type = expression->get_input_port_type(j);
+ if (type > 0) { // + PORT_TYPE_SCALAR_INT
+ type += 1;
+ }
+ expression->set_input_port_type(j, type);
+ }
+ for (int j = 0; j < expression->get_output_port_count(); j++) {
+ int type = expression->get_output_port_type(j);
+ if (type > 0) { // + PORT_TYPE_SCALAR_INT
+ type += 1;
+ }
+ expression->set_output_port_type(j, type);
+ }
+ }
+ Ref<VisualShaderNodeCompare> compare = Object::cast_to<VisualShaderNodeCompare>(E->get().node.ptr());
+ if (compare.is_valid()) {
+ int ctype = int(compare->get_comparison_type());
+ if (int(ctype) > 0) { // + PORT_TYPE_SCALAR_INT
+ ctype += 1;
+ }
+ compare->set_comparison_type(VisualShaderNodeCompare::ComparisonType(ctype));
+ }
+ }
+ }
+ }
+ set_version(p_new_version);
+}
+
void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, const Vector2 &p_position, int p_id) {
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(p_id < 2);
@@ -305,10 +349,10 @@ void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, co
if (input.is_valid()) {
input->shader_mode = shader_mode;
input->shader_type = p_type;
- input->connect("input_type_changed", this, "_input_type_changed", varray(p_type, p_id));
+ input->connect_compat("input_type_changed", this, "_input_type_changed", varray(p_type, p_id));
}
- n.node->connect("changed", this, "_queue_update");
+ n.node->connect_compat("changed", this, "_queue_update");
Ref<VisualShaderNodeCustom> custom = n.node;
if (custom.is_valid()) {
@@ -375,10 +419,10 @@ void VisualShader::remove_node(Type p_type, int p_id) {
Ref<VisualShaderNodeInput> input = g->nodes[p_id].node;
if (input.is_valid()) {
- input->disconnect("input_type_changed", this, "_input_type_changed");
+ input->disconnect_compat("input_type_changed", this, "_input_type_changed");
}
- g->nodes[p_id].node->disconnect("changed", this, "_queue_update");
+ g->nodes[p_id].node->disconnect_compat("changed", this, "_queue_update");
g->nodes.erase(p_id);
@@ -470,7 +514,7 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po
}
bool VisualShader::is_port_types_compatible(int p_a, int p_b) const {
- return MAX(0, p_a - 2) == (MAX(0, p_b - 2));
+ return MAX(0, p_a - 3) == (MAX(0, p_b - 3));
}
void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
@@ -698,9 +742,11 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port
ERR_FAIL_COND_V(err != OK, String());
if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR) {
- code += "\tCOLOR.rgb = vec3( n_out" + itos(p_node) + "p" + itos(p_port) + " );\n";
+ code += "\tCOLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " );\n";
+ } else if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
+ code += "\tCOLOR.rgb = vec3(float(n_out" + itos(p_node) + "p" + itos(p_port) + "));\n";
} else if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_BOOLEAN) {
- code += "\tCOLOR.rgb = vec3( n_out" + itos(p_node) + "p" + itos(p_port) + " ? 1.0 : 0.0 );\n";
+ code += "\tCOLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " ? 1.0 : 0.0);\n";
} else {
code += "\tCOLOR.rgb = n_out" + itos(p_node) + "p" + itos(p_port) + ";\n";
}
@@ -985,8 +1031,8 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const {
}
return false;
}
-void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
+void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
//mode
p_list->push_back(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Spatial,CanvasItem,Particles"));
//render modes
@@ -995,7 +1041,6 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
Set<String> toggles;
for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode)).size(); i++) {
-
String mode = ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode))[i];
int idx = 0;
bool in_enum = false;
@@ -1020,7 +1065,6 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
}
for (Map<String, String>::Element *E = blend_mode_enums.front(); E; E = E->next()) {
-
p_list->push_back(PropertyInfo(Variant::INT, "modes/" + E->key(), PROPERTY_HINT_ENUM, E->get()));
}
@@ -1050,7 +1094,7 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::STRING, prop_name + "/expression", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
}
- p_list->push_back(PropertyInfo(Variant::PACKED_INT_ARRAY, "nodes/" + String(type_string[i]) + "/connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, "nodes/" + String(type_string[i]) + "/connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
}
@@ -1113,24 +1157,40 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
inputs[i] = src_var;
} else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_VECTOR) {
inputs[i] = "dot(" + src_var + ", vec3(0.333333, 0.333333, 0.333333))";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_VECTOR) {
+ inputs[i] = "dot(float(" + src_var + "), vec3(0.333333, 0.333333, 0.333333))";
} else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
inputs[i] = "vec3(" + src_var + ")";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
+ inputs[i] = "vec3(float(" + src_var + "))";
} else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_VECTOR) {
inputs[i] = "all(bvec3(" + src_var + "))";
} else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
inputs[i] = src_var + " > 0.0 ? true : false";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
+ inputs[i] = src_var + " > 0 ? true : false";
} else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) {
inputs[i] = src_var + " ? 1.0 : 0.0";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) {
+ inputs[i] = src_var + " ? 1 : 0";
} else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) {
inputs[i] = "vec3(" + src_var + " ? 1.0 : 0.0)";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
+ inputs[i] = "float(" + src_var + ")";
+ } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
+ inputs[i] = "int(" + src_var + ")";
}
} else {
Variant defval = vsnode->get_input_port_default_value(i);
- if (defval.get_type() == Variant::REAL || defval.get_type() == Variant::INT) {
+ if (defval.get_type() == Variant::FLOAT) {
float val = defval;
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
code += "\tfloat " + inputs[i] + " = " + vformat("%.5f", val) + ";\n";
+ } else if (defval.get_type() == Variant::INT) {
+ int val = defval;
+ inputs[i] = "n_in" + itos(node) + "p" + itos(i);
+ code += "\tint " + inputs[i] + " = " + itos(val) + ";\n";
} else if (defval.get_type() == Variant::BOOL) {
bool val = defval;
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
@@ -1170,6 +1230,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
String var_name = "n_out" + itos(node) + "p" + itos(i);
switch (vsnode->get_output_port_type(i)) {
case VisualShaderNode::PORT_TYPE_SCALAR: outputs[i] = "float " + var_name; break;
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT: outputs[i] = "int " + var_name; break;
case VisualShaderNode::PORT_TYPE_VECTOR: outputs[i] = "vec3 " + var_name; break;
case VisualShaderNode::PORT_TYPE_BOOLEAN: outputs[i] = "bool " + var_name; break;
case VisualShaderNode::PORT_TYPE_TRANSFORM: outputs[i] = "mat4 " + var_name; break;
@@ -1183,6 +1244,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
outputs[i] = "n_out" + itos(node) + "p" + itos(i);
switch (vsnode->get_output_port_type(i)) {
case VisualShaderNode::PORT_TYPE_SCALAR: code += String() + "\tfloat " + outputs[i] + ";\n"; break;
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT: code += String() + "\tint " + outputs[i] + ";\n"; break;
case VisualShaderNode::PORT_TYPE_VECTOR: code += String() + "\tvec3 " + outputs[i] + ";\n"; break;
case VisualShaderNode::PORT_TYPE_BOOLEAN: code += String() + "\tbool " + outputs[i] + ";\n"; break;
case VisualShaderNode::PORT_TYPE_TRANSFORM: code += String() + "\tmat4 " + outputs[i] + ";\n"; break;
@@ -1412,6 +1474,9 @@ void VisualShader::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_node_connections", "type"), &VisualShader::_get_node_connections);
+ ClassDB::bind_method(D_METHOD("set_version", "version"), &VisualShader::set_version);
+ ClassDB::bind_method(D_METHOD("get_version"), &VisualShader::get_version);
+
ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &VisualShader::set_graph_offset);
ClassDB::bind_method(D_METHOD("get_graph_offset"), &VisualShader::get_graph_offset);
@@ -1421,6 +1486,7 @@ void VisualShader::_bind_methods() {
ClassDB::bind_method(D_METHOD("_input_type_changed"), &VisualShader::_input_type_changed);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_graph_offset", "get_graph_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_version", "get_version");
BIND_ENUM_CONSTANT(TYPE_VERTEX);
BIND_ENUM_CONSTANT(TYPE_FRAGMENT);
@@ -1576,7 +1642,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "index", "float(INDEX)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
@@ -1684,17 +1750,20 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T
switch (get_output_port_type(0)) {
case PORT_TYPE_SCALAR: {
code = "\t" + p_output_vars[0] + " = 0.0;\n";
- } break; //default (none found) is scalar
+ } break;
+ case PORT_TYPE_SCALAR_INT: {
+ code = "\t" + p_output_vars[0] + " = 0;\n";
+ } break;
case PORT_TYPE_VECTOR: {
code = "\t" + p_output_vars[0] + " = vec3(0.0);\n";
- } break; //default (none found) is scalar
+ } break;
case PORT_TYPE_TRANSFORM: {
code = "\t" + p_output_vars[0] + " = mat4( vec4(1.0,0.0,0.0,0.0), vec4(0.0,1.0,0.0,0.0), vec4(0.0,0.0,1.0,0.0), vec4(0.0,0.0,0.0,1.0) );\n";
- } break; //default (none found) is scalar
+ } break;
case PORT_TYPE_BOOLEAN: {
code = "\t" + p_output_vars[0] + " = false;\n";
} break;
- default:
+ default: //default (none found) is scalar
break;
}
}
@@ -1847,7 +1916,7 @@ void VisualShaderNodeInput::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_input_name"), &VisualShaderNodeInput::get_input_name);
ClassDB::bind_method(D_METHOD("get_input_real_name"), &VisualShaderNodeInput::get_input_real_name);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "input_name", PROPERTY_HINT_ENUM, ""), "set_input_name", "get_input_name");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "input_name", PROPERTY_HINT_ENUM, ""), "set_input_name", "get_input_name");
ADD_SIGNAL(MethodInfo("input_type_changed"));
}
VisualShaderNodeInput::VisualShaderNodeInput() {
@@ -2047,7 +2116,7 @@ void VisualShaderNodeUniform::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniform::set_uniform_name);
ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniform::get_uniform_name);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "uniform_name"), "set_uniform_name", "get_uniform_name");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name"), "set_uniform_name", "get_uniform_name");
}
VisualShaderNodeUniform::VisualShaderNodeUniform() {
@@ -2626,6 +2695,9 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
case PORT_TYPE_SCALAR:
tk = "0.0";
break;
+ case PORT_TYPE_SCALAR_INT:
+ tk = "0";
+ break;
case PORT_TYPE_VECTOR:
tk = "vec3(0.0, 0.0, 0.0)";
break;