|
@@ -30,118 +30,249 @@
|
|
|
|
|
|
|
|
|
|
|
|
-# if 0
|
|
|
-void ShaderGraph::_set(const String& p_name, const Variant& p_value) {
|
|
|
+Array ShaderGraph::_get_node_list(ShaderType p_type) const {
|
|
|
|
|
|
- if (p_name.begins_with("nodes/")) {
|
|
|
- int idx=p_name.get_slice("/",1).to_int();
|
|
|
- Dictionary data=p_value;
|
|
|
+ List<int> nodes;
|
|
|
+ get_node_list(p_type,&nodes);
|
|
|
+ Array arr(true);
|
|
|
+ for (List<int>::Element *E=nodes.front();E;E=E->next())
|
|
|
+ arr.push_back(E->get());
|
|
|
+ return arr;
|
|
|
+}
|
|
|
+Array ShaderGraph::_get_connections(ShaderType p_type) const {
|
|
|
|
|
|
- ERR_FAIL_COND(!data.has("type"));
|
|
|
- String type=data["type"];
|
|
|
+ List<Connection> connections;
|
|
|
+ get_node_connections(p_type,&connections);
|
|
|
+ Array arr(true);
|
|
|
+ for (List<Connection>::Element *E=connections.front();E;E=E->next()) {
|
|
|
|
|
|
- VS::NodeType node_type=VS::NODE_TYPE_MAX;
|
|
|
- for(int i=0;i<NODE_TYPE_MAX;i++) {
|
|
|
+ Dictionary d(true);
|
|
|
+ d["src_id"]=E->get().src_id;
|
|
|
+ d["src_slot"]=E->get().src_slot;
|
|
|
+ d["dst_id"]=E->get().dst_id;
|
|
|
+ d["dst_slot"]=E->get().dst_slot;
|
|
|
+ arr.push_back(d);
|
|
|
|
|
|
- if (type==VisualServer::shader_node_get_type_info((VS::NodeType)i).name)
|
|
|
- node_type=(VS::NodeType)i;
|
|
|
- }
|
|
|
+ }
|
|
|
+ return arr;
|
|
|
+}
|
|
|
|
|
|
- ERR_FAIL_COND(node_type==VS::NODE_TYPE_MAX);
|
|
|
+void ShaderGraph::_bind_methods() {
|
|
|
|
|
|
- node_add( (NodeType)node_type, idx );
|
|
|
- if (data.has("param"))
|
|
|
- node_set_param(idx,data["param"]);
|
|
|
- if (data.has("pos"))
|
|
|
- node_set_pos(idx,data["pos"]);
|
|
|
- }
|
|
|
+ ObjectTypeDB::bind_method(_MD("_update_shader"),&ShaderGraph::_update_shader);
|
|
|
|
|
|
- if (p_name.begins_with("conns/")) {
|
|
|
- Dictionary data=p_value;
|
|
|
- ERR_FAIL_COND( !data.has("src_id") );
|
|
|
- ERR_FAIL_COND( !data.has("src_slot") );
|
|
|
- ERR_FAIL_COND( !data.has("dst_id") );
|
|
|
- ERR_FAIL_COND( !data.has("dst_slot") );
|
|
|
+ ObjectTypeDB::bind_method(_MD("node_add","shader_type","node_type","id"),&ShaderGraph::node_add);
|
|
|
+ ObjectTypeDB::bind_method(_MD("node_remove","shader_type","id"),&ShaderGraph::node_remove);
|
|
|
+ ObjectTypeDB::bind_method(_MD("node_set_pos","shader_type","id","pos"),&ShaderGraph::node_set_pos);
|
|
|
+ ObjectTypeDB::bind_method(_MD("node_get_pos","shader_type","id"),&ShaderGraph::node_get_pos);
|
|
|
|
|
|
- connect(data["src_id"],data["src_slot"],data["dst_id"],data["dst_slot"]);
|
|
|
- }
|
|
|
+ ObjectTypeDB::bind_method(_MD("node_get_type","shader_type","id"),&ShaderGraph::node_get_type);
|
|
|
|
|
|
- return false;
|
|
|
-}
|
|
|
-Variant ShaderGraph::_get(const String& p_name) const {
|
|
|
+ ObjectTypeDB::bind_method(_MD("get_node_list","shader_type"),&ShaderGraph::_get_node_list);
|
|
|
|
|
|
- if (p_name.begins_with("nodes/")) {
|
|
|
- int idx=p_name.get_slice("/",1).to_int();
|
|
|
- Dictionary data;
|
|
|
- data["type"]=VisualServer::shader_node_get_type_info((VS::NodeType)node_get_type(idx)).name;
|
|
|
- data["pos"]=node_get_pos(idx);
|
|
|
- data["param"]=node_get_param(idx);
|
|
|
- return data;
|
|
|
- }
|
|
|
- if (p_name.begins_with("conns/")) {
|
|
|
- int idx=p_name.get_slice("/",1).to_int();
|
|
|
- Dictionary data;
|
|
|
-
|
|
|
- List<Connection> connections;
|
|
|
- get_connections(&connections);
|
|
|
- ERR_FAIL_INDEX_V( idx,connections.size(), Variant() );
|
|
|
- Connection c = connections[idx];
|
|
|
-
|
|
|
- data["src_id"]=c.src_id;
|
|
|
- data["src_slot"]=c.src_slot;
|
|
|
- data["dst_id"]=c.dst_id;
|
|
|
- data["dst_slot"]=c.dst_slot;
|
|
|
- return data;
|
|
|
- }
|
|
|
+ ObjectTypeDB::bind_method(_MD("scalar_const_node_set_value","shader_type","id","value"),&ShaderGraph::scalar_const_node_set_value);
|
|
|
+ ObjectTypeDB::bind_method(_MD("scalar_const_node_get_value","shader_type","id"),&ShaderGraph::scalar_const_node_set_value);
|
|
|
|
|
|
- return Variant();
|
|
|
-}
|
|
|
-void ShaderGraph::_get_property_list( List<PropertyInfo> *p_list) const {
|
|
|
+ ObjectTypeDB::bind_method(_MD("vec_const_node_set_value","shader_type","id","value"),&ShaderGraph::vec_const_node_set_value);
|
|
|
+ ObjectTypeDB::bind_method(_MD("vec_const_node_get_value","shader_type","id"),&ShaderGraph::vec_const_node_set_value);
|
|
|
|
|
|
- List<int> nodes;
|
|
|
- get_node_list(&nodes);
|
|
|
+ ObjectTypeDB::bind_method(_MD("rgb_const_node_set_value","shader_type","id","value"),&ShaderGraph::rgb_const_node_set_value);
|
|
|
+ ObjectTypeDB::bind_method(_MD("rgb_const_node_get_value","shader_type","id"),&ShaderGraph::rgb_const_node_set_value);
|
|
|
|
|
|
- for(List<int>::Element *E=nodes.front();E;E=E->next()) {
|
|
|
+ ObjectTypeDB::bind_method(_MD("xform_const_node_set_value","shader_type","id","value"),&ShaderGraph::xform_const_node_set_value);
|
|
|
+ ObjectTypeDB::bind_method(_MD("xform_const_node_get_value","shader_type","id"),&ShaderGraph::xform_const_node_set_value);
|
|
|
|
|
|
- int idx=E->get();
|
|
|
- p_list->push_back(PropertyInfo( Variant::DICTIONARY , "nodes/"+itos(idx),PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NETWORK|PROPERTY_USAGE_STORAGE ) );
|
|
|
- }
|
|
|
|
|
|
- List<Connection> connections;
|
|
|
- get_connections(&connections);
|
|
|
- int idx=0;
|
|
|
- for(List<Connection>::Element *E=connections.front();E;E=E->next()) {
|
|
|
- p_list->push_back(PropertyInfo( Variant::DICTIONARY , "conns/"+itos(idx++),PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NETWORK|PROPERTY_USAGE_STORAGE ) );
|
|
|
- }
|
|
|
+// void get_node_list(ShaderType p_which,List<int> *p_node_list) const;
|
|
|
|
|
|
-}
|
|
|
+ ObjectTypeDB::bind_method(_MD("texture_node_set_filter_size","shader_type","id","filter_size"),&ShaderGraph::texture_node_set_filter_size);
|
|
|
+ ObjectTypeDB::bind_method(_MD("texture_node_get_filter_size","shader_type","id"),&ShaderGraph::texture_node_set_filter_size);
|
|
|
|
|
|
-#endif
|
|
|
-#if 0
|
|
|
-Array ShaderGraph::_get_connections_helper() const {
|
|
|
+ ObjectTypeDB::bind_method(_MD("texture_node_set_filter_strength","shader_type","id","filter_strength"),&ShaderGraph::texture_node_set_filter_strength);
|
|
|
+ ObjectTypeDB::bind_method(_MD("texture_node_get_filter_strength","shader_type","id"),&ShaderGraph::texture_node_set_filter_strength);
|
|
|
|
|
|
- Array connections_ret;
|
|
|
- List<Connection> connections;
|
|
|
- get_connections(&connections);
|
|
|
- connections_ret.resize(connections.size());
|
|
|
-
|
|
|
- int idx=0;
|
|
|
- for(List<Connection>::Element *E=connections.front();E;E=E->next()) {
|
|
|
-
|
|
|
- Connection c = E->get();
|
|
|
- Dictionary data;
|
|
|
- data["src_id"]=c.src_id;
|
|
|
- data["src_slot"]=c.src_slot;
|
|
|
- data["dst_id"]=c.dst_id;
|
|
|
- data["dst_slot"]=c.dst_slot;
|
|
|
- connections_ret.set(idx++,data);
|
|
|
- }
|
|
|
+ ObjectTypeDB::bind_method(_MD("scalar_op_node_set_op","shader_type","id","op"),&ShaderGraph::scalar_op_node_set_op);
|
|
|
+ ObjectTypeDB::bind_method(_MD("scalar_op_node_get_op","shader_type","id"),&ShaderGraph::scalar_op_node_get_op);
|
|
|
|
|
|
- return connections_ret;
|
|
|
-}
|
|
|
+ ObjectTypeDB::bind_method(_MD("vec_op_node_set_op","shader_type","id","op"),&ShaderGraph::vec_op_node_set_op);
|
|
|
+ ObjectTypeDB::bind_method(_MD("vec_op_node_get_op","shader_type","id"),&ShaderGraph::vec_op_node_get_op);
|
|
|
|
|
|
-void ShaderGraph::_bind_methods() {
|
|
|
+ ObjectTypeDB::bind_method(_MD("vec_scalar_op_node_set_op","shader_type","id","op"),&ShaderGraph::vec_scalar_op_node_set_op);
|
|
|
+ ObjectTypeDB::bind_method(_MD("vec_scalar_op_node_get_op","shader_type","id"),&ShaderGraph::vec_scalar_op_node_get_op);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("rgb_op_node_set_op","shader_type","id","op","c"),&ShaderGraph::rgb_op_node_set_op);
|
|
|
+ ObjectTypeDB::bind_method(_MD("rgb_op_node_get_op","shader_type","id"),&ShaderGraph::rgb_op_node_get_op);
|
|
|
+ ObjectTypeDB::bind_method(_MD("rgb_op_node_get_c","shader_type","id"),&ShaderGraph::rgb_op_node_get_c);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("xform_vec_mult_node_set_no_translation","shader_type","id","disable"),&ShaderGraph::xform_vec_mult_node_set_no_translation);
|
|
|
+ ObjectTypeDB::bind_method(_MD("xform_vec_mult_node_get_no_translation","shader_type","id"),&ShaderGraph::xform_vec_mult_node_get_no_translation);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("scalar_func_node_set_function","shader_type","id","func"),&ShaderGraph::scalar_func_node_set_function);
|
|
|
+ ObjectTypeDB::bind_method(_MD("scalar_func_node_get_function","shader_type","id"),&ShaderGraph::scalar_func_node_get_function);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("vec_func_node_set_function","shader_type","id","func"),&ShaderGraph::vec_func_node_set_function);
|
|
|
+ ObjectTypeDB::bind_method(_MD("vec_func_node_get_function","shader_type","id"),&ShaderGraph::vec_func_node_get_function);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("input_node_set_name","shader_type","id","name"),&ShaderGraph::input_node_set_name);
|
|
|
+ ObjectTypeDB::bind_method(_MD("input_node_get_name","shader_type","id"),&ShaderGraph::input_node_get_name);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("scalar_input_node_set_value","shader_type","id","value"),&ShaderGraph::scalar_input_node_set_value);
|
|
|
+ ObjectTypeDB::bind_method(_MD("scalar_input_node_get_value","shader_type","id"),&ShaderGraph::scalar_input_node_get_value);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("vec_input_node_set_value","shader_type","id","value"),&ShaderGraph::vec_input_node_set_value);
|
|
|
+ ObjectTypeDB::bind_method(_MD("vec_input_node_get_value","shader_type","id"),&ShaderGraph::vec_input_node_get_value);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("rgb_input_node_set_value","shader_type","id","value"),&ShaderGraph::rgb_input_node_set_value);
|
|
|
+ ObjectTypeDB::bind_method(_MD("rgb_input_node_get_value","shader_type","id"),&ShaderGraph::rgb_input_node_get_value);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("xform_input_node_set_value","shader_type","id","value"),&ShaderGraph::xform_input_node_set_value);
|
|
|
+ ObjectTypeDB::bind_method(_MD("xform_input_node_get_value","shader_type","id"),&ShaderGraph::xform_input_node_get_value);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("texture_input_node_set_value","shader_type","id","value:Texture"),&ShaderGraph::texture_input_node_set_value);
|
|
|
+ ObjectTypeDB::bind_method(_MD("texture_input_node_get_value:Texture","shader_type","id"),&ShaderGraph::texture_input_node_get_value);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("cubemap_input_node_set_value","shader_type","id","value:CubeMap"),&ShaderGraph::cubemap_input_node_set_value);
|
|
|
+ ObjectTypeDB::bind_method(_MD("cubemap_input_node_get_value:CubeMap","shader_type","id"),&ShaderGraph::cubemap_input_node_get_value);
|
|
|
|
|
|
+ ObjectTypeDB::bind_method(_MD("comment_node_set_text","shader_type","id","text"),&ShaderGraph::comment_node_set_text);
|
|
|
+ ObjectTypeDB::bind_method(_MD("comment_node_get_text","shader_type","id"),&ShaderGraph::comment_node_get_text);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("connect_node:Error","shader_type","src_id","src_slot","dst_id","dst_slot"),&ShaderGraph::connect_node);
|
|
|
+ ObjectTypeDB::bind_method(_MD("is_node_connected","shader_type","src_id","src_slot","dst_id","dst_slot"),&ShaderGraph::is_node_connected);
|
|
|
+ ObjectTypeDB::bind_method(_MD("disconnect_node","shader_type","src_id","src_slot","dst_id","dst_slot"),&ShaderGraph::disconnect_node);
|
|
|
+ ObjectTypeDB::bind_method(_MD("get_node_connections","shader_type"),&ShaderGraph::_get_connections);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("clear","shader_type"),&ShaderGraph::clear);
|
|
|
+
|
|
|
+ ObjectTypeDB::bind_method(_MD("node_set_state","shader_type","id","state"),&ShaderGraph::node_set_state);
|
|
|
+ ObjectTypeDB::bind_method(_MD("node_get_state:var","shader_type","id"),&ShaderGraph::node_get_state);
|
|
|
+
|
|
|
+ //void get_connections(ShaderType p_which,List<Connection> *p_connections) const;
|
|
|
+
|
|
|
+
|
|
|
+ BIND_CONSTANT( NODE_INPUT ); // all inputs (shader type dependent)
|
|
|
+ BIND_CONSTANT( NODE_SCALAR_CONST ); //scalar constant
|
|
|
+ BIND_CONSTANT( NODE_VEC_CONST ); //vec3 constant
|
|
|
+ BIND_CONSTANT( NODE_RGB_CONST ); //rgb constant (shows a color picker instead)
|
|
|
+ BIND_CONSTANT( NODE_XFORM_CONST ); // 4x4 matrix constant
|
|
|
+ BIND_CONSTANT( NODE_TIME ); // time in seconds
|
|
|
+ BIND_CONSTANT( NODE_SCREEN_TEX ); // screen texture sampler (takes UV) (only usable in fragment shader)
|
|
|
+ BIND_CONSTANT( NODE_SCALAR_OP ); // scalar vs scalar op (mul ); add ); div ); etc)
|
|
|
+ BIND_CONSTANT( NODE_VEC_OP ); // vec3 vs vec3 op (mul );ad );div );crossprod );etc)
|
|
|
+ BIND_CONSTANT( NODE_VEC_SCALAR_OP ); // vec3 vs scalar op (mul ); add ); div ); etc)
|
|
|
+ BIND_CONSTANT( NODE_RGB_OP ); // vec3 vs vec3 rgb op (with scalar amount) ); like brighten ); darken ); burn ); dodge ); multiply ); etc.
|
|
|
+ BIND_CONSTANT( NODE_XFORM_MULT ); // mat4 x mat4
|
|
|
+ BIND_CONSTANT( NODE_XFORM_VEC_MULT ); // mat4 x vec3 mult (with no-translation option)
|
|
|
+ BIND_CONSTANT( NODE_XFORM_VEC_INV_MULT ); // mat4 x vec3 inverse mult (with no-translation option)
|
|
|
+ BIND_CONSTANT( NODE_SCALAR_FUNC ); // scalar function (sin ); cos ); etc)
|
|
|
+ BIND_CONSTANT( NODE_VEC_FUNC ); // vector function (normalize ); negate ); reciprocal ); rgb2hsv ); hsv2rgb ); etc ); etc)
|
|
|
+ BIND_CONSTANT( NODE_VEC_LEN ); // vec3 length
|
|
|
+ BIND_CONSTANT( NODE_DOT_PROD ); // vec3 . vec3 (dot product -> scalar output)
|
|
|
+ BIND_CONSTANT( NODE_VEC_TO_SCALAR ); // 1 vec3 input ); 3 scalar outputs
|
|
|
+ BIND_CONSTANT( NODE_SCALAR_TO_VEC ); // 3 scalar input ); 1 vec3 output
|
|
|
+ BIND_CONSTANT( NODE_VEC_TO_XFORM ); // 3 vec input ); 1 xform output
|
|
|
+ BIND_CONSTANT( NODE_XFORM_TO_VEC ); // 3 vec input ); 1 xform output
|
|
|
+ BIND_CONSTANT( NODE_SCALAR_INTERP ); // scalar interpolation (with optional curve)
|
|
|
+ BIND_CONSTANT( NODE_VEC_INTERP ); // vec3 interpolation (with optional curve)
|
|
|
+ BIND_CONSTANT( NODE_SCALAR_INPUT ); // scalar uniform (assignable in material)
|
|
|
+ BIND_CONSTANT( NODE_VEC_INPUT ); // vec3 uniform (assignable in material)
|
|
|
+ BIND_CONSTANT( NODE_RGB_INPUT ); // color uniform (assignable in material)
|
|
|
+ BIND_CONSTANT( NODE_XFORM_INPUT ); // mat4 uniform (assignable in material)
|
|
|
+ BIND_CONSTANT( NODE_TEXTURE_INPUT ); // texture input (assignable in material)
|
|
|
+ BIND_CONSTANT( NODE_CUBEMAP_INPUT ); // cubemap input (assignable in material)
|
|
|
+ BIND_CONSTANT( NODE_OUTPUT ); // output (shader type dependent)
|
|
|
+ BIND_CONSTANT( NODE_COMMENT ); // comment
|
|
|
+ BIND_CONSTANT( NODE_TYPE_MAX );
|
|
|
+
|
|
|
+ BIND_CONSTANT( SLOT_TYPE_SCALAR );
|
|
|
+ BIND_CONSTANT( SLOT_TYPE_VEC );
|
|
|
+ BIND_CONSTANT( SLOT_TYPE_XFORM );
|
|
|
+ BIND_CONSTANT( SLOT_TYPE_TEXTURE );
|
|
|
+ BIND_CONSTANT( SLOT_MAX );
|
|
|
+
|
|
|
+ BIND_CONSTANT( SHADER_TYPE_VERTEX );
|
|
|
+ BIND_CONSTANT( SHADER_TYPE_FRAGMENT );
|
|
|
+ BIND_CONSTANT( SHADER_TYPE_LIGHT );
|
|
|
+ BIND_CONSTANT( SHADER_TYPE_MAX );
|
|
|
+
|
|
|
+
|
|
|
+ BIND_CONSTANT( SLOT_IN );
|
|
|
+ BIND_CONSTANT( SLOT_OUT );
|
|
|
+
|
|
|
+ BIND_CONSTANT( GRAPH_OK );
|
|
|
+ BIND_CONSTANT( GRAPH_ERROR_CYCLIC );
|
|
|
+ BIND_CONSTANT( GRAPH_ERROR_MISSING_CONNECTIONS );
|
|
|
+
|
|
|
+ BIND_CONSTANT( SCALAR_OP_ADD );
|
|
|
+ BIND_CONSTANT( SCALAR_OP_SUB );
|
|
|
+ BIND_CONSTANT( SCALAR_OP_MUL );
|
|
|
+ BIND_CONSTANT( SCALAR_OP_DIV );
|
|
|
+ BIND_CONSTANT( SCALAR_OP_MOD );
|
|
|
+ BIND_CONSTANT( SCALAR_OP_POW );
|
|
|
+ BIND_CONSTANT( SCALAR_OP_MAX );
|
|
|
+ BIND_CONSTANT( SCALAR_OP_MIN );
|
|
|
+ BIND_CONSTANT( SCALAR_OP_ATAN2 );
|
|
|
+ BIND_CONSTANT( SCALAR_MAX_OP );
|
|
|
+
|
|
|
+ BIND_CONSTANT( VEC_OP_ADD );
|
|
|
+ BIND_CONSTANT( VEC_OP_SUB );
|
|
|
+ BIND_CONSTANT( VEC_OP_MUL );
|
|
|
+ BIND_CONSTANT( VEC_OP_DIV );
|
|
|
+ BIND_CONSTANT( VEC_OP_MOD );
|
|
|
+ BIND_CONSTANT( VEC_OP_POW );
|
|
|
+ BIND_CONSTANT( VEC_OP_MAX );
|
|
|
+ BIND_CONSTANT( VEC_OP_MIN );
|
|
|
+ BIND_CONSTANT( VEC_OP_CROSS );
|
|
|
+ BIND_CONSTANT( VEC_MAX_OP );
|
|
|
+
|
|
|
+ BIND_CONSTANT( VEC_SCALAR_OP_MUL );
|
|
|
+ BIND_CONSTANT( VEC_SCALAR_OP_DIV );
|
|
|
+ BIND_CONSTANT( VEC_SCALAR_OP_POW );
|
|
|
+ BIND_CONSTANT( VEC_SCALAR_MAX_OP );
|
|
|
+
|
|
|
+ BIND_CONSTANT( RGB_OP_SCREEN );
|
|
|
+ BIND_CONSTANT( RGB_OP_DIFFERENCE );
|
|
|
+ BIND_CONSTANT( RGB_OP_DARKEN );
|
|
|
+ BIND_CONSTANT( RGB_OP_LIGHTEN );
|
|
|
+ BIND_CONSTANT( RGB_OP_OVERLAY );
|
|
|
+ BIND_CONSTANT( RGB_OP_DODGE );
|
|
|
+ BIND_CONSTANT( RGB_OP_BURN );
|
|
|
+ BIND_CONSTANT( RGB_OP_SOFT_LIGHT );
|
|
|
+ BIND_CONSTANT( RGB_OP_HARD_LIGHT );
|
|
|
+ BIND_CONSTANT( RGB_MAX_OP );
|
|
|
+
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_SIN );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_COS );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_TAN );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_ASIN );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_ACOS );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_ATAN );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_SINH );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_COSH );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_TANH );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_LOG );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_EXP );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_SQRT );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_ABS );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_SIGN );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_FLOOR );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_ROUND );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_CEIL );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_FRAC );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_SATURATE );
|
|
|
+ BIND_CONSTANT( SCALAR_FUNC_NEGATE );
|
|
|
+ BIND_CONSTANT( SCALAR_MAX_FUNC );
|
|
|
+
|
|
|
+ BIND_CONSTANT( VEC_FUNC_NORMALIZE );
|
|
|
+ BIND_CONSTANT( VEC_FUNC_SATURATE );
|
|
|
+ BIND_CONSTANT( VEC_FUNC_NEGATE );
|
|
|
+ BIND_CONSTANT( VEC_FUNC_RECIPROCAL );
|
|
|
+ BIND_CONSTANT( VEC_FUNC_RGB2HSV );
|
|
|
+ BIND_CONSTANT( VEC_FUNC_HSV2RGB );
|
|
|
+ BIND_CONSTANT( VEC_MAX_FUNC );
|
|
|
+
|
|
|
+
|
|
|
+#if 0
|
|
|
ObjectTypeDB::bind_method(_MD("node_add"),&ShaderGraph::node_add );
|
|
|
ObjectTypeDB::bind_method(_MD("node_remove"),&ShaderGraph::node_remove );
|
|
|
ObjectTypeDB::bind_method(_MD("node_set_param"),&ShaderGraph::node_set_param );
|
|
@@ -212,73 +343,154 @@ void ShaderGraph::_bind_methods() {
|
|
|
BIND_CONSTANT( NODE_TEXTURE_2D_PARAMETER );
|
|
|
BIND_CONSTANT( NODE_TEXTURE_CUBE_PARAMETER );
|
|
|
BIND_CONSTANT( NODE_TYPE_MAX );
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
-void ShaderGraph::node_add(NodeType p_type,int p_id) {
|
|
|
|
|
|
+String ShaderGraph::_find_unique_name(ShaderType p_which, const String& p_base) {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ int idx=1;
|
|
|
+ while(true) {
|
|
|
+ String tocmp=p_base;
|
|
|
+ if (idx>1) {
|
|
|
+ tocmp+="_"+itos(idx);
|
|
|
+ }
|
|
|
+ bool valid=true;
|
|
|
+ for (Map<int,Node>::Element *E=shader[p_which].node_map.front();E;E=E->next()) {
|
|
|
+ if (E->get().type!=NODE_SCALAR_INPUT && E->get().type!=NODE_VEC_INPUT && E->get().type==NODE_RGB_INPUT && E->get().type==NODE_XFORM_INPUT && E->get().type==NODE_TEXTURE_INPUT && E->get().type==NODE_CUBEMAP_INPUT)
|
|
|
+ continue;
|
|
|
+ String name = E->get().param1;
|
|
|
+ if (name==tocmp) {
|
|
|
+ valid=false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!valid) {
|
|
|
+ idx++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ return tocmp;
|
|
|
+ }
|
|
|
+ return String();
|
|
|
+}
|
|
|
|
|
|
- ERR_FAIL_COND( node_map.has(p_id ) );
|
|
|
- ERR_FAIL_INDEX( p_type, NODE_TYPE_MAX );
|
|
|
+void ShaderGraph::node_add(ShaderType p_type, NodeType p_node_type,int p_id) {
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(p_id==0);
|
|
|
+ ERR_FAIL_COND(p_node_type==NODE_OUTPUT); //can't create output
|
|
|
+ ERR_FAIL_COND( shader[p_type].node_map.has(p_id ) );
|
|
|
+ ERR_FAIL_INDEX( p_node_type, NODE_TYPE_MAX );
|
|
|
Node node;
|
|
|
|
|
|
- node.type=p_type;
|
|
|
+ if (p_node_type==NODE_INPUT) {
|
|
|
+ //see if it already exists
|
|
|
+ for(Map<int,Node>::Element *E=shader[p_type].node_map.front();E;E=E->next()) {
|
|
|
+ if (E->get().type==NODE_INPUT) {
|
|
|
+ ERR_EXPLAIN("Only one input node can be added to the graph.");
|
|
|
+ ERR_FAIL_COND(E->get().type==NODE_INPUT);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ node.type=p_node_type;
|
|
|
node.id=p_id;
|
|
|
- node.x=0;
|
|
|
- node.y=0;
|
|
|
|
|
|
- node_map[p_id]=node;
|
|
|
+ switch(p_node_type) {
|
|
|
+ case NODE_INPUT: {} break; // all inputs (shader type dependent)
|
|
|
+ case NODE_SCALAR_CONST: { node.param1=0;} break; //scalar constant
|
|
|
+ case NODE_VEC_CONST: {node.param1=Vector3();} break; //vec3 constant
|
|
|
+ case NODE_RGB_CONST: {node.param1=Color();} break; //rgb constant (shows a color picker instead)
|
|
|
+ case NODE_XFORM_CONST: {node.param1=Transform();} break; // 4x4 matrix constant
|
|
|
+ case NODE_TIME: {} break; // time in seconds
|
|
|
+ case NODE_SCREEN_TEX: {Array arr; arr.push_back(0); arr.push_back(0); node.param2=arr;} break; // screen texture sampler (takes UV) (only usable in fragment shader)
|
|
|
+ case NODE_SCALAR_OP: {node.param1=SCALAR_OP_ADD;} break; // scalar vs scalar op (mul: {} break; add: {} break; div: {} break; etc)
|
|
|
+ case NODE_VEC_OP: {node.param1=VEC_OP_ADD;} break; // vec3 vs vec3 op (mul: {} break;ad: {} break;div: {} break;crossprod: {} break;etc)
|
|
|
+ case NODE_VEC_SCALAR_OP: {node.param1=VEC_SCALAR_OP_MUL;} break; // vec3 vs scalar op (mul: {} break; add: {} break; div: {} break; etc)
|
|
|
+ case NODE_RGB_OP: {node.param1=RGB_OP_SCREEN;} break; // vec3 vs vec3 rgb op (with scalar amount): {} break; like brighten: {} break; darken: {} break; burn: {} break; dodge: {} break; multiply: {} break; etc.
|
|
|
+ case NODE_XFORM_MULT: {} break; // mat4 x mat4
|
|
|
+ case NODE_XFORM_VEC_MULT: {} break; // mat4 x vec3 mult (with no-translation option)
|
|
|
+ case NODE_XFORM_VEC_INV_MULT: {} break; // mat4 x vec3 inverse mult (with no-translation option)
|
|
|
+ case NODE_SCALAR_FUNC: {node.param1=SCALAR_FUNC_SIN;} break; // scalar function (sin: {} break; cos: {} break; etc)
|
|
|
+ case NODE_VEC_FUNC: {node.param1=VEC_FUNC_NORMALIZE;} break; // vector function (normalize: {} break; negate: {} break; reciprocal: {} break; rgb2hsv: {} break; hsv2rgb: {} break; etc: {} break; etc)
|
|
|
+ case NODE_VEC_LEN: {} break; // vec3 length
|
|
|
+ case NODE_DOT_PROD: {} break; // vec3 . vec3 (dot product -> scalar output)
|
|
|
+ case NODE_VEC_TO_SCALAR: {} break; // 1 vec3 input: {} break; 3 scalar outputs
|
|
|
+ case NODE_SCALAR_TO_VEC: {} break; // 3 scalar input: {} break; 1 vec3 output
|
|
|
+ case NODE_VEC_TO_XFORM: {} break; // 3 scalar input: {} break; 1 vec3 output
|
|
|
+ case NODE_XFORM_TO_VEC: {} break; // 3 scalar input: {} break; 1 vec3 output
|
|
|
+ case NODE_SCALAR_INTERP: {} break; // scalar interpolation (with optional curve)
|
|
|
+ case NODE_VEC_INTERP: {} break; // vec3 interpolation (with optional curve)
|
|
|
+ case NODE_SCALAR_INPUT: {node.param1=_find_unique_name(p_type,"Scalar"); node.param2=0;} break; // scalar uniform (assignable in material)
|
|
|
+ case NODE_VEC_INPUT: {node.param1=_find_unique_name(p_type,"Vec3");node.param2=Vector3();} break; // vec3 uniform (assignable in material)
|
|
|
+ case NODE_RGB_INPUT: {node.param1=_find_unique_name(p_type,"Color");node.param2=Color();} break; // color uniform (assignable in material)
|
|
|
+ case NODE_XFORM_INPUT: {node.param1=_find_unique_name(p_type,"XForm"); node.param2=Transform();} break; // mat4 uniform (assignable in material)
|
|
|
+ case NODE_TEXTURE_INPUT: {node.param1=_find_unique_name(p_type,"Tex"); } break; // texture input (assignable in material)
|
|
|
+ case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name(p_type,"Cube"); } break; // cubemap input (assignable in material)
|
|
|
+ case NODE_OUTPUT: {} break; // output (shader type dependent)
|
|
|
+ case NODE_COMMENT: {} break; // comment
|
|
|
+ case NODE_TYPE_MAX: {};
|
|
|
+ }
|
|
|
|
|
|
+ shader[p_type].node_map[p_id]=node;
|
|
|
+ _request_update();
|
|
|
}
|
|
|
|
|
|
-void ShaderGraph::node_set_pos(int p_id, const Vector2& p_pos) {
|
|
|
+void ShaderGraph::node_set_pos(ShaderType p_type,int p_id, const Vector2& p_pos) {
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ shader[p_type].node_map[p_id].pos=p_pos;
|
|
|
+ _request_update();
|
|
|
|
|
|
- ERR_FAIL_COND(!node_map.has(p_id));
|
|
|
- node_map[p_id].x=p_pos.x;
|
|
|
- node_map[p_id].y=p_pos.y;
|
|
|
}
|
|
|
-Vector2 ShaderGraph::node_get_pos(int p_id) const {
|
|
|
+Vector2 ShaderGraph::node_get_pos(ShaderType p_type,int p_id) const {
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,Vector2());
|
|
|
|
|
|
- ERR_FAIL_COND_V(!node_map.has(p_id),Vector2());
|
|
|
- return Vector2(node_map[p_id].x,node_map[p_id].y);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Vector2());
|
|
|
+ return shader[p_type].node_map[p_id].pos;
|
|
|
}
|
|
|
|
|
|
|
|
|
-void ShaderGraph::node_remove(int p_id) {
|
|
|
+void ShaderGraph::node_remove(ShaderType p_type,int p_id) {
|
|
|
+
|
|
|
+ ERR_FAIL_COND(p_id==0);
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
|
|
|
- ERR_FAIL_COND(!node_map.has(p_id));
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
|
|
|
//erase connections associated with node
|
|
|
- List<Connection>::Element *N,*E=connections.front();
|
|
|
- while(E) {
|
|
|
- N=E->next();
|
|
|
- const Connection &c = E->get();
|
|
|
- if (c.src_id==p_id || c.dst_id==p_id) {
|
|
|
+ for(Map<int,Node>::Element *E=shader[p_type].node_map.front();E;E=E->next()) {
|
|
|
+ if (E->key()==p_id)
|
|
|
+ continue; //no self
|
|
|
|
|
|
- connections.erase(E);
|
|
|
- }
|
|
|
- E=N;
|
|
|
- }
|
|
|
+ for (Map<int,SourceSlot>::Element *F=E->get().connections.front();F;) {
|
|
|
+ Map<int,SourceSlot>::Element *N=F->next();
|
|
|
|
|
|
- node_map.erase(p_id);
|
|
|
-}
|
|
|
+ if (F->get().id==p_id) {
|
|
|
+ E->get().connections.erase(F);
|
|
|
+ }
|
|
|
|
|
|
-void ShaderGraph::node_change_type(int p_id, NodeType p_type) {
|
|
|
+ F=N;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- ERR_FAIL_COND(!node_map.has(p_id));
|
|
|
- node_map[p_id].type=p_type;
|
|
|
- node_map[p_id].param=Variant();
|
|
|
+ shader[p_type].node_map.erase(p_id);
|
|
|
+ print_line("erased node, amount left: "+itos(shader[p_type].node_map.size()));
|
|
|
+ _request_update();
|
|
|
|
|
|
}
|
|
|
|
|
|
-void ShaderGraph::node_set_param(int p_id, const Variant& p_value) {
|
|
|
|
|
|
- ERR_FAIL_COND(!node_map.has(p_id));
|
|
|
- node_map[p_id].param=p_value;
|
|
|
-}
|
|
|
|
|
|
-void ShaderGraph::get_node_list(List<int> *p_node_list) const {
|
|
|
+void ShaderGraph::get_node_list(ShaderType p_type,List<int> *p_node_list) const {
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
|
|
|
- Map<int,Node>::Element *E = node_map.front();
|
|
|
+ Map<int,Node>::Element *E = shader[p_type].node_map.front();
|
|
|
|
|
|
while(E) {
|
|
|
|
|
@@ -288,740 +500,1275 @@ void ShaderGraph::get_node_list(List<int> *p_node_list) const {
|
|
|
}
|
|
|
|
|
|
|
|
|
-ShaderGraph::NodeType ShaderGraph::node_get_type(int p_id) const {
|
|
|
+ShaderGraph::NodeType ShaderGraph::node_get_type(ShaderType p_type,int p_id) const {
|
|
|
|
|
|
- ERR_FAIL_COND_V(!node_map.has(p_id),NODE_TYPE_MAX);
|
|
|
- return node_map[p_id].type;
|
|
|
-}
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,NODE_TYPE_MAX);
|
|
|
|
|
|
-Variant ShaderGraph::node_get_param(int p_id) const {
|
|
|
-
|
|
|
- ERR_FAIL_COND_V(!node_map.has(p_id),Variant());
|
|
|
- return node_map[p_id].param;
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),NODE_TYPE_MAX);
|
|
|
+ return shader[p_type].node_map[p_id].type;
|
|
|
}
|
|
|
|
|
|
|
|
|
-Error ShaderGraph::connect(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) {
|
|
|
+Error ShaderGraph::connect_node(ShaderType p_type,int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) {
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,ERR_INVALID_PARAMETER);
|
|
|
|
|
|
ERR_FAIL_COND_V(p_src_id==p_dst_id, ERR_INVALID_PARAMETER);
|
|
|
- ERR_FAIL_COND_V(!node_map.has(p_src_id), ERR_INVALID_PARAMETER);
|
|
|
- ERR_FAIL_COND_V(!node_map.has(p_dst_id), ERR_INVALID_PARAMETER);
|
|
|
- NodeType type_src=node_map[p_src_id].type;
|
|
|
- NodeType type_dst=node_map[p_dst_id].type;
|
|
|
- //ERR_FAIL_INDEX_V( p_src_slot, VisualServer::shader_get_output_count(type_src), ERR_INVALID_PARAMETER );
|
|
|
- //ERR_FAIL_INDEX_V( p_dst_slot, VisualServer::shader_get_input_count(type_dst), ERR_INVALID_PARAMETER );
|
|
|
- //ERR_FAIL_COND_V(VisualServer::shader_is_output_vector(type_src,p_src_slot) != VisualServer::shader_is_input_vector(type_dst,p_dst_slot), ERR_INVALID_PARAMETER );
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_src_id), ERR_INVALID_PARAMETER);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_dst_id), ERR_INVALID_PARAMETER);
|
|
|
+ NodeType type_src=shader[p_type].node_map[p_src_id].type;
|
|
|
+ NodeType type_dst=shader[p_type].node_map[p_dst_id].type;
|
|
|
+ ERR_FAIL_INDEX_V( p_src_slot, get_node_output_slot_count(get_mode(),p_type,type_src), ERR_INVALID_PARAMETER );
|
|
|
+ ERR_FAIL_INDEX_V( p_dst_slot, get_node_input_slot_count(get_mode(),p_type,type_dst), ERR_INVALID_PARAMETER );
|
|
|
+ ERR_FAIL_COND_V(get_node_output_slot_type(get_mode(),p_type,type_src,p_src_slot) != get_node_input_slot_type(get_mode(),p_type,type_dst,p_dst_slot), ERR_INVALID_PARAMETER );
|
|
|
|
|
|
|
|
|
- List<Connection>::Element *E=connections.front();
|
|
|
- while(E) {
|
|
|
- const Connection &c = E->get();
|
|
|
- ERR_FAIL_COND_V(c.dst_slot==p_dst_slot && c.dst_id == p_dst_id, ERR_ALREADY_EXISTS);
|
|
|
+ SourceSlot ts;
|
|
|
+ ts.id=p_src_id;
|
|
|
+ ts.slot=p_src_slot;
|
|
|
+ shader[p_type].node_map[p_dst_id].connections[p_dst_slot]=ts;
|
|
|
+ _request_update();
|
|
|
|
|
|
- E=E->next();
|
|
|
- }
|
|
|
+ return OK;
|
|
|
+}
|
|
|
|
|
|
- Connection c;
|
|
|
- c.src_slot=p_src_slot;
|
|
|
- c.src_id=p_src_id;
|
|
|
- c.dst_slot=p_dst_slot;
|
|
|
- c.dst_id=p_dst_id;
|
|
|
+bool ShaderGraph::is_node_connected(ShaderType p_type,int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) const {
|
|
|
|
|
|
- connections.push_back(c);
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,false);
|
|
|
|
|
|
- return OK;
|
|
|
+ SourceSlot ts;
|
|
|
+ ts.id=p_src_id;
|
|
|
+ ts.slot=p_src_slot;
|
|
|
+ return shader[p_type].node_map.has(p_dst_id) && shader[p_type].node_map[p_dst_id].connections.has(p_dst_slot) &&
|
|
|
+ shader[p_type].node_map[p_dst_id].connections[p_dst_slot]==ts;
|
|
|
}
|
|
|
|
|
|
-bool ShaderGraph::is_connected(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) const {
|
|
|
+void ShaderGraph::disconnect_node(ShaderType p_type,int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) {
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
|
|
|
- const List<Connection>::Element *E=connections.front();
|
|
|
- while(E) {
|
|
|
- const Connection &c = E->get();
|
|
|
- if (c.dst_slot==p_dst_slot && c.dst_id == p_dst_id && c.src_slot==p_src_slot && c.src_id == p_src_id)
|
|
|
- return true;
|
|
|
+ print_line("** dsisconnect");
|
|
|
+ SourceSlot ts;
|
|
|
+ ts.id=p_src_id;
|
|
|
+ ts.slot=p_src_slot;
|
|
|
+ if (shader[p_type].node_map.has(p_dst_id) && shader[p_type].node_map[p_dst_id].connections.has(p_dst_slot) &&
|
|
|
+ shader[p_type].node_map[p_dst_id].connections[p_dst_slot]==ts) {
|
|
|
+ shader[p_type].node_map[p_dst_id].connections.erase(p_dst_slot);
|
|
|
|
|
|
- E=E->next();
|
|
|
}
|
|
|
+ _request_update();
|
|
|
|
|
|
- return false;
|
|
|
}
|
|
|
|
|
|
-void ShaderGraph::disconnect(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) {
|
|
|
+void ShaderGraph::get_node_connections(ShaderType p_type,List<Connection> *p_connections) const {
|
|
|
|
|
|
- List<Connection>::Element *N,*E=connections.front();
|
|
|
- while(E) {
|
|
|
- N=E->next();
|
|
|
- const Connection &c = E->get();
|
|
|
- if (c.src_slot==p_src_slot && c.src_id==p_src_id && c.dst_slot==p_dst_slot && c.dst_id == p_dst_id) {
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
|
|
|
- connections.erase(E);
|
|
|
+ for(const Map<int,Node>::Element *E=shader[p_type].node_map.front();E;E=E->next()) {
|
|
|
+ for (const Map<int,SourceSlot>::Element *F=E->get().connections.front();F;F=F->next()) {
|
|
|
+
|
|
|
+ Connection c;
|
|
|
+ c.dst_id=E->key();
|
|
|
+ c.dst_slot=F->key();
|
|
|
+ c.src_id=F->get().id;
|
|
|
+ c.src_slot=F->get().slot;
|
|
|
+ p_connections->push_back(c);
|
|
|
}
|
|
|
- E=N;
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void ShaderGraph::clear(ShaderType p_type) {
|
|
|
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ shader[p_type].node_map.clear();
|
|
|
+ Node out;
|
|
|
+ out.pos=Vector2(300,300);
|
|
|
+ out.type=NODE_OUTPUT;
|
|
|
+ shader[p_type].node_map.insert(0,out);
|
|
|
+
|
|
|
+ _request_update();
|
|
|
|
|
|
}
|
|
|
|
|
|
-void ShaderGraph::get_connections(List<Connection> *p_connections) const {
|
|
|
|
|
|
- const List<Connection>::Element*E=connections.front();
|
|
|
- while(E) {
|
|
|
- p_connections->push_back(E->get());
|
|
|
- E=E->next();
|
|
|
- }
|
|
|
+void ShaderGraph::scalar_const_node_set_value(ShaderType p_type,int p_id,float p_value) {
|
|
|
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_SCALAR_CONST);
|
|
|
+ n.param1=p_value;
|
|
|
+ _request_update();
|
|
|
|
|
|
}
|
|
|
|
|
|
+float ShaderGraph::scalar_const_node_get_value(ShaderType p_type,int p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,0);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),0);
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_SCALAR_CONST,0);
|
|
|
+ return n.param1;
|
|
|
+}
|
|
|
+
|
|
|
+void ShaderGraph::vec_const_node_set_value(ShaderType p_type,int p_id,const Vector3& p_value){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_VEC_CONST);
|
|
|
+ n.param1=p_value;
|
|
|
+ _request_update();
|
|
|
|
|
|
-void ShaderGraph::clear() {
|
|
|
|
|
|
- connections.clear();
|
|
|
- node_map.clear();
|
|
|
}
|
|
|
+Vector3 ShaderGraph::vec_const_node_get_value(ShaderType p_type,int p_id) const{
|
|
|
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,Vector3());
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Vector3());
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_VEC_CONST,Vector3());
|
|
|
+ return n.param1;
|
|
|
|
|
|
-#if 0
|
|
|
-void ShaderGraph::node_add(NodeType p_type,int p_id) {
|
|
|
+}
|
|
|
+
|
|
|
+void ShaderGraph::rgb_const_node_set_value(ShaderType p_type,int p_id,const Color& p_value){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_RGB_CONST);
|
|
|
+ n.param1=p_value;
|
|
|
+ _request_update();
|
|
|
+
|
|
|
+}
|
|
|
+Color ShaderGraph::rgb_const_node_get_value(ShaderType p_type,int p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,Color());
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Color());
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_RGB_CONST,Color());
|
|
|
+ return n.param1;
|
|
|
|
|
|
- ShaderNode sn;
|
|
|
- sn.type=p_type;
|
|
|
- nodes[p_id]=sn;
|
|
|
- version++;
|
|
|
}
|
|
|
-void ShaderGraph::node_remove(int p_id) {
|
|
|
|
|
|
- nodes.erase(p_id);
|
|
|
+void ShaderGraph::xform_const_node_set_value(ShaderType p_type,int p_id,const Transform& p_value){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_XFORM_CONST);
|
|
|
+ n.param1=p_value;
|
|
|
+ _request_update();
|
|
|
|
|
|
}
|
|
|
-void ShaderGraph::node_set_param( int p_id, const Variant& p_value) {
|
|
|
+Transform ShaderGraph::xform_const_node_get_value(ShaderType p_type,int p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,Transform());
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Transform());
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_XFORM_CONST,Transform());
|
|
|
+ return n.param1;
|
|
|
|
|
|
- VisualServer::get_singleton()->shader_node_set_param(shader,p_id,p_value);
|
|
|
- version++;
|
|
|
}
|
|
|
|
|
|
-void ShaderGraph::get_node_list(List<int> *p_node_list) const {
|
|
|
+void ShaderGraph::texture_node_set_filter_size(ShaderType p_type,int p_id,int p_size){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_TEXTURE_INPUT && n.type!=NODE_SCREEN_TEX);
|
|
|
+ Array arr = n.param2;
|
|
|
+ arr[0]=p_size;
|
|
|
+ n.param2=arr;
|
|
|
+ _request_update();
|
|
|
|
|
|
- VisualServer::get_singleton()->shader_get_node_list(shader,p_node_list);
|
|
|
}
|
|
|
-ShaderGraph::NodeType ShaderGraph::node_get_type(int p_id) const {
|
|
|
+int ShaderGraph::texture_node_get_filter_size(ShaderType p_type,int p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,0);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),0);
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_TEXTURE_INPUT && n.type!=NODE_SCREEN_TEX,0);
|
|
|
+ Array arr = n.param2;
|
|
|
+ return arr[0];
|
|
|
|
|
|
- return (NodeType)VisualServer::get_singleton()->shader_node_get_type(shader,p_id);
|
|
|
}
|
|
|
-Variant ShaderGraph::node_get_param(int p_id) const {
|
|
|
|
|
|
- return VisualServer::get_singleton()->shader_node_get_param(shader,p_id);
|
|
|
+void ShaderGraph::texture_node_set_filter_strength(ShaderType p_type,float p_id,float p_strength){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_TEXTURE_INPUT && n.type!=NODE_SCREEN_TEX);
|
|
|
+ Array arr = n.param2;
|
|
|
+ arr[1]=p_strength;
|
|
|
+ n.param2=arr;
|
|
|
+ _request_update();
|
|
|
+
|
|
|
+}
|
|
|
+float ShaderGraph::texture_node_get_filter_strength(ShaderType p_type,float p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,0);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),0);
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_TEXTURE_INPUT && n.type!=NODE_SCREEN_TEX,0);
|
|
|
+ Array arr = n.param2;
|
|
|
+ return arr[1];
|
|
|
}
|
|
|
|
|
|
-void ShaderGraph::connect(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) {
|
|
|
|
|
|
- VisualServer::get_singleton()->shader_connect(shader,p_src_id,p_src_slot,p_dst_id,p_dst_slot);
|
|
|
- version++;
|
|
|
+void ShaderGraph::scalar_op_node_set_op(ShaderType p_type,float p_id,ScalarOp p_op){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_SCALAR_OP);
|
|
|
+ n.param1=p_op;
|
|
|
+ _request_update();
|
|
|
+
|
|
|
}
|
|
|
-void ShaderGraph::disconnect(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) {
|
|
|
+ShaderGraph::ScalarOp ShaderGraph::scalar_op_node_get_op(ShaderType p_type,float p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,SCALAR_MAX_OP);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),SCALAR_MAX_OP);
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_SCALAR_OP,SCALAR_MAX_OP);
|
|
|
+ int op = n.param1;
|
|
|
+ return ScalarOp(op);
|
|
|
|
|
|
- VisualServer::get_singleton()->shader_disconnect(shader,p_src_id,p_src_slot,p_dst_id,p_dst_slot);
|
|
|
- version++;
|
|
|
}
|
|
|
|
|
|
-void ShaderGraph::get_connections(List<Connection> *p_connections) const {
|
|
|
|
|
|
- List<VS::ShaderGraphConnection> connections;
|
|
|
- VisualServer::get_singleton()->shader_get_connections(shader,&connections);
|
|
|
- for( List<VS::ShaderGraphConnection>::Element *E=connections.front();E;E=E->next()) {
|
|
|
+void ShaderGraph::vec_op_node_set_op(ShaderType p_type,float p_id,VecOp p_op){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_VEC_OP);
|
|
|
+ n.param1=p_op;
|
|
|
+ _request_update();
|
|
|
|
|
|
- Connection c;
|
|
|
- c.src_id=E->get().src_id;
|
|
|
- c.src_slot=E->get().src_slot;
|
|
|
- c.dst_id=E->get().dst_id;
|
|
|
- c.dst_slot=E->get().dst_slot;
|
|
|
- p_connections->push_back(c);
|
|
|
- }
|
|
|
}
|
|
|
+ShaderGraph::VecOp ShaderGraph::vec_op_node_get_op(ShaderType p_type,float p_id) const{
|
|
|
|
|
|
-void ShaderGraph::node_set_pos(int p_id,const Point2& p_pos) {
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,VEC_MAX_OP);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),VEC_MAX_OP);
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_VEC_OP,VEC_MAX_OP);
|
|
|
+ int op = n.param1;
|
|
|
+ return VecOp(op);
|
|
|
|
|
|
-#ifdef TOOLS_ENABLED
|
|
|
- ERR_FAIL_COND(!positions.has(p_id));
|
|
|
- positions[p_id]=p_pos;
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
-Point2 ShaderGraph::node_get_pos(int p_id) const {
|
|
|
-#ifdef TOOLS_ENABLED
|
|
|
- ERR_FAIL_COND_V(!positions.has(p_id),Point2());
|
|
|
- return positions[p_id];
|
|
|
-#endif
|
|
|
+
|
|
|
+void ShaderGraph::vec_scalar_op_node_set_op(ShaderType p_type,float p_id,VecScalarOp p_op){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_VEC_SCALAR_OP);
|
|
|
+ n.param1=p_op;
|
|
|
+ _request_update();
|
|
|
+
|
|
|
}
|
|
|
+ShaderGraph::VecScalarOp ShaderGraph::vec_scalar_op_node_get_op(ShaderType p_type,float p_id) const{
|
|
|
|
|
|
-void ShaderGraph::clear() {
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,VEC_SCALAR_MAX_OP);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),VEC_SCALAR_MAX_OP);
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_VEC_SCALAR_OP,VEC_SCALAR_MAX_OP);
|
|
|
+ int op = n.param1;
|
|
|
+ return VecScalarOp(op);
|
|
|
|
|
|
- VisualServer::get_singleton()->shader_clear(shader);
|
|
|
- version++;
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
-ShaderGraph::ShaderGraph() {
|
|
|
+void ShaderGraph::rgb_op_node_set_op(ShaderType p_type,float p_id,RGBOp p_op,float p_c){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_RGB_OP);
|
|
|
+ n.param1=p_op;
|
|
|
+ n.param2=p_c;
|
|
|
+ _request_update();
|
|
|
|
|
|
- //shader = VisualServer::get_singleton()->shader_create();
|
|
|
- version = 1;
|
|
|
}
|
|
|
+ShaderGraph::RGBOp ShaderGraph::rgb_op_node_get_op(ShaderType p_type,float p_id) const{
|
|
|
|
|
|
-ShaderGraph::~ShaderGraph() {
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,RGB_MAX_OP);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),RGB_MAX_OP);
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_RGB_OP,RGB_MAX_OP);
|
|
|
+ int op = n.param1;
|
|
|
+ return RGBOp(op);
|
|
|
|
|
|
- //VisualServer::get_singleton()->free(shader);
|
|
|
}
|
|
|
+float ShaderGraph::rgb_op_node_get_c(ShaderType p_type,float p_id) const{
|
|
|
|
|
|
-#if 0
|
|
|
-void ShaderGraph::shader_get_default_input_nodes(Mode p_type,List<PropertyInfo> *p_inputs) {
|
|
|
-
|
|
|
- switch(p_type) {
|
|
|
-
|
|
|
- case SHADER_VERTEX: {
|
|
|
-
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"vertex") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"normal") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"binormal") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"tangent") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"uv") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"color") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::REAL,"alpha") );
|
|
|
- } break;
|
|
|
- case SHADER_FRAGMENT: {
|
|
|
-
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"position") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"normal") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"binormal") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"tangent") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"uv") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"color") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::REAL,"alpha") );
|
|
|
-
|
|
|
- } break;
|
|
|
- case SHADER_POST_PROCESS: {
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::VECTOR3,"color") );
|
|
|
- p_inputs->push_back( PropertyInfo( Variant::REAL,"alpha") );
|
|
|
- } break;
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,0);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),0);
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_RGB_OP,0);
|
|
|
+ return n.param2;
|
|
|
|
|
|
- }
|
|
|
+}
|
|
|
+
|
|
|
+void ShaderGraph::xform_vec_mult_node_set_no_translation(ShaderType p_type,int p_id,bool p_no_translation){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_XFORM_VEC_MULT && n.type!=NODE_XFORM_VEC_INV_MULT);
|
|
|
+ n.param1=p_no_translation;
|
|
|
+ _request_update();
|
|
|
|
|
|
}
|
|
|
-void ShaderGraph::shader_get_default_output_nodes(ShaderGraphType p_type,List<PropertyInfo> *p_outputs) {
|
|
|
+bool ShaderGraph::xform_vec_mult_node_get_no_translation(ShaderType p_type,int p_id) const{
|
|
|
|
|
|
- switch(p_type) {
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,false);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),false);
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_XFORM_VEC_MULT && n.type!=NODE_XFORM_VEC_INV_MULT,false);
|
|
|
+ return n.param1;
|
|
|
|
|
|
- case SHADER_VERTEX: {
|
|
|
+}
|
|
|
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::VECTOR3,"vertex") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::VECTOR3,"normal") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::VECTOR3,"binormal") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::VECTOR3,"tangent") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::VECTOR3,"uv") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::VECTOR3,"color") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::REAL,"alpha") );
|
|
|
- } break;
|
|
|
- case SHADER_FRAGMENT: {
|
|
|
+void ShaderGraph::scalar_func_node_set_function(ShaderType p_type,int p_id,ScalarFunc p_func){
|
|
|
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::VECTOR3,"normal") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::VECTOR3,"diffuse") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::VECTOR3,"specular") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::REAL,"alpha") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::REAL,"emission") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::REAL,"spec_exp") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::REAL,"glow") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::REAL,"alpha_discard") );
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_SCALAR_FUNC);
|
|
|
+ n.param1=p_func;
|
|
|
+ _request_update();
|
|
|
|
|
|
- } break;
|
|
|
- case SHADER_POST_PROCESS: {
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::VECTOR3,"color") );
|
|
|
- p_outputs->push_back( PropertyInfo( Variant::REAL,"alpha") );
|
|
|
- } break;
|
|
|
+}
|
|
|
+ShaderGraph::ScalarFunc ShaderGraph::scalar_func_node_get_function(ShaderType p_type,int p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,SCALAR_MAX_FUNC);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),SCALAR_MAX_FUNC);
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_SCALAR_FUNC,SCALAR_MAX_FUNC);
|
|
|
+ int func = n.param1;
|
|
|
+ return ScalarFunc(func);
|
|
|
+}
|
|
|
|
|
|
- }
|
|
|
+void ShaderGraph::vec_func_node_set_function(ShaderType p_type,int p_id,VecFunc p_func){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_VEC_FUNC);
|
|
|
+ n.param1=p_func;
|
|
|
+
|
|
|
+ _request_update();
|
|
|
+
|
|
|
+}
|
|
|
+ShaderGraph::VecFunc ShaderGraph::vec_func_node_get_function(ShaderType p_type, int p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,VEC_MAX_FUNC);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),VEC_MAX_FUNC);
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_VEC_FUNC,VEC_MAX_FUNC);
|
|
|
+ int func = n.param1;
|
|
|
+ return VecFunc(func);
|
|
|
+}
|
|
|
+
|
|
|
+void ShaderGraph::input_node_set_name(ShaderType p_type,int p_id,const String& p_name){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ ERR_FAIL_COND(!p_name.is_valid_identifier());
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_SCALAR_INPUT && n.type!=NODE_VEC_INPUT && n.type==NODE_RGB_INPUT && n.type==NODE_XFORM_INPUT && n.type==NODE_TEXTURE_INPUT && n.type==NODE_CUBEMAP_INPUT);
|
|
|
+ n.param1="";
|
|
|
+ n.param1=_find_unique_name(p_type,p_name);
|
|
|
+ _request_update();
|
|
|
+
|
|
|
+}
|
|
|
+String ShaderGraph::input_node_get_name(ShaderType p_type,int p_id){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,String());
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),String());
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_SCALAR_INPUT && n.type!=NODE_VEC_INPUT && n.type==NODE_RGB_INPUT && n.type==NODE_XFORM_INPUT && n.type==NODE_TEXTURE_INPUT && n.type==NODE_CUBEMAP_INPUT,String());
|
|
|
+ return n.param1;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void ShaderGraph::scalar_input_node_set_value(ShaderType p_type,int p_id,float p_value) {
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_SCALAR_INPUT);
|
|
|
+ n.param2=p_value;
|
|
|
+ _request_update();
|
|
|
|
|
|
}
|
|
|
|
|
|
+float ShaderGraph::scalar_input_node_get_value(ShaderType p_type,int p_id) const{
|
|
|
|
|
|
-PropertyInfo ShaderGraph::shader_node_get_type_info(NodeType p_type) {
|
|
|
-
|
|
|
- switch(p_type) {
|
|
|
-
|
|
|
- case NODE_IN: return PropertyInfo(Variant::STRING,"in");
|
|
|
- case NODE_OUT: return PropertyInfo(Variant::STRING,"out");
|
|
|
- case NODE_CONSTANT: return PropertyInfo(Variant::REAL,"const");
|
|
|
- case NODE_PARAMETER: return PropertyInfo(Variant::STRING,"param");
|
|
|
- case NODE_ADD: return PropertyInfo(Variant::NIL,"add");
|
|
|
- case NODE_SUB: return PropertyInfo(Variant::NIL,"sub");
|
|
|
- case NODE_MUL: return PropertyInfo(Variant::NIL,"mul");
|
|
|
- case NODE_DIV: return PropertyInfo(Variant::NIL,"div");
|
|
|
- case NODE_MOD: return PropertyInfo(Variant::NIL,"rem");
|
|
|
- case NODE_SIN: return PropertyInfo(Variant::NIL,"sin");
|
|
|
- case NODE_COS: return PropertyInfo(Variant::NIL,"cos");
|
|
|
- case NODE_TAN: return PropertyInfo(Variant::NIL,"tan");
|
|
|
- case NODE_ARCSIN: return PropertyInfo(Variant::NIL,"arcsin");
|
|
|
- case NODE_ARCCOS: return PropertyInfo(Variant::NIL,"arccos");
|
|
|
- case NODE_ARCTAN: return PropertyInfo(Variant::NIL,"arctan");
|
|
|
- case NODE_POW: return PropertyInfo(Variant::NIL,"pow");
|
|
|
- case NODE_LOG: return PropertyInfo(Variant::NIL,"log");
|
|
|
- case NODE_MAX: return PropertyInfo(Variant::NIL,"max");
|
|
|
- case NODE_MIN: return PropertyInfo(Variant::NIL,"min");
|
|
|
- case NODE_COMPARE: return PropertyInfo(Variant::NIL,"cmp");
|
|
|
- case NODE_TEXTURE: return PropertyInfo(Variant::_RID,"texture1D",PROPERTY_HINT_RESOURCE_TYPE,"Texture");
|
|
|
- case NODE_TIME: return PropertyInfo(Variant::NIL,"time");
|
|
|
- case NODE_NOISE: return PropertyInfo(Variant::NIL,"noise");
|
|
|
- case NODE_PASS: return PropertyInfo(Variant::NIL,"pass");
|
|
|
- case NODE_VEC_IN: return PropertyInfo(Variant::STRING,"vin");
|
|
|
- case NODE_VEC_OUT: return PropertyInfo(Variant::STRING,"vout");
|
|
|
- case NODE_VEC_CONSTANT: return PropertyInfo(Variant::VECTOR3,"vconst");
|
|
|
- case NODE_VEC_PARAMETER: return PropertyInfo(Variant::STRING,"vparam");
|
|
|
- case NODE_VEC_ADD: return PropertyInfo(Variant::NIL,"vadd");
|
|
|
- case NODE_VEC_SUB: return PropertyInfo(Variant::NIL,"vsub");
|
|
|
- case NODE_VEC_MUL: return PropertyInfo(Variant::NIL,"vmul");
|
|
|
- case NODE_VEC_DIV: return PropertyInfo(Variant::NIL,"vdiv");
|
|
|
- case NODE_VEC_MOD: return PropertyInfo(Variant::NIL,"vrem");
|
|
|
- case NODE_VEC_CROSS: return PropertyInfo(Variant::NIL,"cross");
|
|
|
- case NODE_VEC_DOT: return PropertyInfo(Variant::NIL,"dot");
|
|
|
- case NODE_VEC_POW: return PropertyInfo(Variant::NIL,"vpow");
|
|
|
- case NODE_VEC_NORMALIZE: return PropertyInfo(Variant::NIL,"normalize");
|
|
|
- case NODE_VEC_INTERPOLATE: return PropertyInfo(Variant::NIL,"mix");
|
|
|
- case NODE_VEC_SCREEN_TO_UV: return PropertyInfo(Variant::NIL,"scrn2uv");
|
|
|
- case NODE_VEC_TRANSFORM3: return PropertyInfo(Variant::NIL,"xform3");
|
|
|
- case NODE_VEC_TRANSFORM4: return PropertyInfo(Variant::NIL,"xform4");
|
|
|
- case NODE_VEC_COMPARE: return PropertyInfo(Variant::_RID,"vcmp",PROPERTY_HINT_RESOURCE_TYPE,"Texture");
|
|
|
- case NODE_VEC_TEXTURE_2D: return PropertyInfo(Variant::_RID,"texture2D",PROPERTY_HINT_RESOURCE_TYPE,"Texture");
|
|
|
- case NODE_VEC_TEXTURE_CUBE: return PropertyInfo(Variant::NIL,"texcube");
|
|
|
- case NODE_VEC_NOISE: return PropertyInfo(Variant::NIL,"vec_noise");
|
|
|
- case NODE_VEC_0: return PropertyInfo(Variant::NIL,"vec_0");
|
|
|
- case NODE_VEC_1: return PropertyInfo(Variant::NIL,"vec_1");
|
|
|
- case NODE_VEC_2: return PropertyInfo(Variant::NIL,"vec_2");
|
|
|
- case NODE_VEC_BUILD: return PropertyInfo(Variant::NIL,"vbuild");
|
|
|
- case NODE_VEC_PASS: return PropertyInfo(Variant::NIL,"vpass");
|
|
|
- case NODE_COLOR_CONSTANT: return PropertyInfo(Variant::COLOR,"color_const");
|
|
|
- case NODE_COLOR_PARAMETER: return PropertyInfo(Variant::STRING,"color_param");
|
|
|
- case NODE_TEXTURE_PARAMETER: return PropertyInfo(Variant::STRING,"tex1D_param");
|
|
|
- case NODE_TEXTURE_2D_PARAMETER: return PropertyInfo(Variant::STRING,"tex2D_param");
|
|
|
- case NODE_TEXTURE_CUBE_PARAMETER: return PropertyInfo(Variant::STRING,"texcube_param");
|
|
|
- case NODE_TRANSFORM_CONSTANT: return PropertyInfo(Variant::TRANSFORM,"xform_const");
|
|
|
- case NODE_TRANSFORM_PARAMETER: return PropertyInfo(Variant::STRING,"xform_param");
|
|
|
- case NODE_LABEL: return PropertyInfo(Variant::STRING,"label");
|
|
|
-
|
|
|
- default: {}
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,0);
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),0);
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_SCALAR_INPUT,0);
|
|
|
+
|
|
|
+ return n.param2;
|
|
|
+}
|
|
|
+
|
|
|
+void ShaderGraph::vec_input_node_set_value(ShaderType p_type,int p_id,const Vector3& p_value){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_VEC_INPUT);
|
|
|
+
|
|
|
+ n.param2=p_value;
|
|
|
+ _request_update();
|
|
|
+
|
|
|
+}
|
|
|
+Vector3 ShaderGraph::vec_input_node_get_value(ShaderType p_type,int p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,Vector3());
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Vector3());
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_VEC_INPUT,Vector3());
|
|
|
+ return n.param2;
|
|
|
+}
|
|
|
+
|
|
|
+void ShaderGraph::rgb_input_node_set_value(ShaderType p_type,int p_id,const Color& p_value){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_RGB_INPUT);
|
|
|
+ n.param2=p_value;
|
|
|
+ _request_update();
|
|
|
+
|
|
|
+}
|
|
|
+Color ShaderGraph::rgb_input_node_get_value(ShaderType p_type,int p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,Color());
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Color());
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_RGB_INPUT,Color());
|
|
|
+ return n.param2;
|
|
|
+}
|
|
|
+
|
|
|
+void ShaderGraph::xform_input_node_set_value(ShaderType p_type,int p_id,const Transform& p_value){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_XFORM_INPUT);
|
|
|
+ n.param2=p_value;
|
|
|
+ _request_update();
|
|
|
+
|
|
|
+}
|
|
|
+Transform ShaderGraph::xform_input_node_get_value(ShaderType p_type,int p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,Transform());
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Transform());
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_XFORM_INPUT,Transform());
|
|
|
+ return n.param2;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void ShaderGraph::texture_input_node_set_value(ShaderType p_type,int p_id,const Ref<Texture>& p_texture) {
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_TEXTURE_INPUT);
|
|
|
+ n.param2=p_texture;
|
|
|
+ _request_update();
|
|
|
+
|
|
|
+}
|
|
|
|
|
|
+Ref<Texture> ShaderGraph::texture_input_node_get_value(ShaderType p_type,int p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,Ref<Texture>());
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Ref<Texture>());
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_TEXTURE_INPUT,Ref<Texture>());
|
|
|
+ return n.param2;
|
|
|
+}
|
|
|
+
|
|
|
+void ShaderGraph::cubemap_input_node_set_value(ShaderType p_type,int p_id,const Ref<CubeMap>& p_cubemap){
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_CUBEMAP_INPUT);
|
|
|
+ n.param2=p_cubemap;
|
|
|
+ _request_update();
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+Ref<CubeMap> ShaderGraph::cubemap_input_node_get_value(ShaderType p_type,int p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,Ref<CubeMap>());
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Ref<CubeMap>());
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_CUBEMAP_INPUT,Ref<CubeMap>());
|
|
|
+ return n.param2;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void ShaderGraph::comment_node_set_text(ShaderType p_type,int p_id,const String& p_comment) {
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND(n.type!=NODE_COMMENT);
|
|
|
+ n.param1=p_comment;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+String ShaderGraph::comment_node_get_text(ShaderType p_type,int p_id) const{
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,String());
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),String());
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ ERR_FAIL_COND_V(n.type!=NODE_COMMENT,String());
|
|
|
+ return n.param1;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void ShaderGraph::_request_update() {
|
|
|
+
|
|
|
+ if (_pending_update_shader)
|
|
|
+ return;
|
|
|
+
|
|
|
+ _pending_update_shader=true;
|
|
|
+ call_deferred("_update_shader");
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+Variant ShaderGraph::node_get_state(ShaderType p_type,int p_id) const {
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX_V(p_type,3,Variant());
|
|
|
+ ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Variant());
|
|
|
+ const Node& n = shader[p_type].node_map[p_id];
|
|
|
+ Dictionary s;
|
|
|
+ s["pos"]=n.pos;
|
|
|
+ s["param1"]=n.param1;
|
|
|
+ s["param2"]=n.param2;
|
|
|
+ return s;
|
|
|
+
|
|
|
+}
|
|
|
+void ShaderGraph::node_set_state(ShaderType p_type,int p_id,const Variant& p_state) {
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_type,3);
|
|
|
+ ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
|
|
|
+ Node& n = shader[p_type].node_map[p_id];
|
|
|
+ Dictionary d = p_state;
|
|
|
+ ERR_FAIL_COND(!d.has("pos"));
|
|
|
+ ERR_FAIL_COND(!d.has("param1"));
|
|
|
+ ERR_FAIL_COND(!d.has("param2"));
|
|
|
+ n.pos=d["pos"];
|
|
|
+ n.param1=d["param1"];
|
|
|
+ n.param2=d["param2"];
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+ShaderGraph::ShaderGraph(Mode p_mode) : Shader(p_mode) {
|
|
|
+
|
|
|
+ //shader = VisualServer::get_singleton()->shader_create();
|
|
|
+ _pending_update_shader=false;
|
|
|
+ Node out;
|
|
|
+ out.id=0;
|
|
|
+ out.pos=Vector2(250,20);
|
|
|
+ out.type=NODE_OUTPUT;
|
|
|
+ for(int i=0;i<3;i++) {
|
|
|
+
|
|
|
+ shader[i].node_map.insert(0,out);
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- ERR_FAIL_V( PropertyInfo(Variant::NIL,"error") );
|
|
|
-}
|
|
|
-int ShaderGraph::shader_get_input_count(NodeType p_type) {
|
|
|
-
|
|
|
- switch(p_type) {
|
|
|
- case NODE_IN: return 0;
|
|
|
- case NODE_OUT: return 1;
|
|
|
- case NODE_CONSTANT: return 0;
|
|
|
- case NODE_PARAMETER: return 0;
|
|
|
- case NODE_ADD: return 2;
|
|
|
- case NODE_SUB: return 2;
|
|
|
- case NODE_MUL: return 2;
|
|
|
- case NODE_DIV: return 2;
|
|
|
- case NODE_MOD: return 2;
|
|
|
- case NODE_SIN: return 1;
|
|
|
- case NODE_COS: return 1;
|
|
|
- case NODE_TAN: return 1;
|
|
|
- case NODE_ARCSIN: return 1;
|
|
|
- case NODE_ARCCOS: return 1;
|
|
|
- case NODE_ARCTAN: return 1;
|
|
|
- case NODE_POW: return 2;
|
|
|
- case NODE_LOG: return 1;
|
|
|
- case NODE_MAX: return 2;
|
|
|
- case NODE_MIN: return 2;
|
|
|
- case NODE_COMPARE: return 4;
|
|
|
- case NODE_TEXTURE: return 1; ///< param 0: texture
|
|
|
- case NODE_TIME: return 1; ///< param 0: interval length
|
|
|
- case NODE_NOISE: return 0;
|
|
|
- case NODE_PASS: return 1;
|
|
|
- case NODE_VEC_IN: return 0; ///< param 0: name
|
|
|
- case NODE_VEC_OUT: return 1; ///< param 0: name
|
|
|
- case NODE_VEC_CONSTANT: return 0; ///< param 0: value
|
|
|
- case NODE_VEC_PARAMETER: return 0; ///< param 0: name
|
|
|
- case NODE_VEC_ADD: return 2;
|
|
|
- case NODE_VEC_SUB: return 2;
|
|
|
- case NODE_VEC_MUL: return 2;
|
|
|
- case NODE_VEC_DIV: return 2;
|
|
|
- case NODE_VEC_MOD: return 2;
|
|
|
- case NODE_VEC_CROSS: return 2;
|
|
|
- case NODE_VEC_DOT: return 2;
|
|
|
- case NODE_VEC_POW: return 2;
|
|
|
- case NODE_VEC_NORMALIZE: return 1;
|
|
|
- case NODE_VEC_INTERPOLATE: return 3;
|
|
|
- case NODE_VEC_SCREEN_TO_UV: return 1;
|
|
|
- case NODE_VEC_TRANSFORM3: return 4;
|
|
|
- case NODE_VEC_TRANSFORM4: return 5;
|
|
|
- case NODE_VEC_COMPARE: return 4;
|
|
|
- case NODE_VEC_TEXTURE_2D: return 1;
|
|
|
- case NODE_VEC_TEXTURE_CUBE: return 1;
|
|
|
- case NODE_VEC_NOISE: return 0;
|
|
|
- case NODE_VEC_0: return 1;
|
|
|
- case NODE_VEC_1: return 1;
|
|
|
- case NODE_VEC_2: return 1;
|
|
|
- case NODE_VEC_BUILD: return 3;
|
|
|
- case NODE_VEC_PASS: return 1;
|
|
|
- case NODE_COLOR_CONSTANT: return 0;
|
|
|
- case NODE_COLOR_PARAMETER: return 0;
|
|
|
- case NODE_TEXTURE_PARAMETER: return 1;
|
|
|
- case NODE_TEXTURE_2D_PARAMETER: return 1;
|
|
|
- case NODE_TEXTURE_CUBE_PARAMETER: return 1;
|
|
|
- case NODE_TRANSFORM_CONSTANT: return 1;
|
|
|
- case NODE_TRANSFORM_PARAMETER: return 1;
|
|
|
- case NODE_LABEL: return 0;
|
|
|
- default: {}
|
|
|
+ShaderGraph::~ShaderGraph() {
|
|
|
+
|
|
|
+ //VisualServer::get_singleton()->free(shader);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+const ShaderGraph::InOutParamInfo ShaderGraph::inout_param_info[]={
|
|
|
+ //material vertex in
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Vertex","SRC_VERTEX",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Normal","SRC_NORMAL",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Tangent","SRC_TANGENT",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"BinormalF","SRC_BINORMALF",SLOT_TYPE_SCALAR,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"WorldMatrix","WORLD_MATRIX",SLOT_TYPE_XFORM,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"InvCameraMatrix","INV_CAMERA_MATRIX",SLOT_TYPE_XFORM,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"ProjectionMatrix","PROJECTION_MATRIX",SLOT_TYPE_XFORM,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"ModelviewMatrix","MODELVIEW_MATRIX",SLOT_TYPE_XFORM,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"InstanceID","INSTANCE_ID",SLOT_TYPE_SCALAR,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Time","TIME",SLOT_TYPE_SCALAR,SLOT_IN},
|
|
|
+ //material vertex out
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Vertex","VERTEX",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Normal","NORMAL",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Tangent","TANGENT",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Binormal","BINORMAL",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"UV","UV",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"UV2","UV2",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Color","COLOR.rgb",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Alpha","COLOR.a",SLOT_TYPE_SCALAR,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Var1","VAR1.rgb",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Var2","VAR2.rgb",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"SpecExp","SPEC_EXP",SLOT_TYPE_SCALAR,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_VERTEX,"PointSize","POINT_SIZE",SLOT_TYPE_SCALAR,SLOT_OUT},
|
|
|
+ //pixel vertex in
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Vertex","VERTEX",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Position","POSITION",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Normal","IN_NORMAL",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Tangent","TANGENT",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Binormal","BINORMAL",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"UV","UV",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"UV2","UV2",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"UVScreen","SCREEN_UV",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"PointCoord","POINT_COORD",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Color","COLOR.rgb",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Alpha","COLOR.a",SLOT_TYPE_SCALAR,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"InvCameraMatrix","INV_CAMERA_MATRIX",SLOT_TYPE_XFORM,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Time","TIME",SLOT_TYPE_SCALAR,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Var1","VAR1.rgb",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Var2","VAR2.rgb",SLOT_TYPE_VEC,SLOT_IN},
|
|
|
+ //pixel vertex out
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Diffuse","DIFFUSE_OUT",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"DiffuseAlpha","ALPHA_OUT",SLOT_TYPE_SCALAR,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Specular","SPECULAR",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"SpecularExp","SPECULAR",SLOT_TYPE_SCALAR,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Emission","EMISSION",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Glow","GLOW",SLOT_TYPE_SCALAR,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"ShadeParam","SHADE_PARAM",SLOT_TYPE_SCALAR,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Normal","NORMAL",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"NormalMap","NORMALMAP",SLOT_TYPE_VEC,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"NormalMapDepth","NORMALMAP_DEPTH",SLOT_TYPE_SCALAR,SLOT_OUT},
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Discard","DISCARD",SLOT_TYPE_SCALAR,SLOT_OUT},
|
|
|
+ //end
|
|
|
+ {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,NULL,NULL,SLOT_TYPE_SCALAR,SLOT_OUT},
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+void ShaderGraph::get_input_output_node_slot_info(Mode p_mode, ShaderType p_type, List<SlotInfo> *r_slots) {
|
|
|
+
|
|
|
+ const InOutParamInfo* iop = &inout_param_info[0];
|
|
|
+ while(iop->name) {
|
|
|
+ if (p_mode==iop->shader_mode && p_type==iop->shader_type) {
|
|
|
+
|
|
|
+ SlotInfo si;
|
|
|
+ si.dir=iop->dir;
|
|
|
+ si.name=iop->name;
|
|
|
+ si.type=iop->slot_type;
|
|
|
+ r_slots->push_back(si);
|
|
|
+ }
|
|
|
+ iop++;
|
|
|
}
|
|
|
- ERR_FAIL_V( 0 );
|
|
|
-}
|
|
|
-int ShaderGraph::shader_get_output_count(NodeType p_type) {
|
|
|
-
|
|
|
- switch(p_type) {
|
|
|
- case NODE_IN: return 1;
|
|
|
- case NODE_OUT: return 0;
|
|
|
- case NODE_CONSTANT: return 1;
|
|
|
- case NODE_PARAMETER: return 1;
|
|
|
- case NODE_ADD: return 1;
|
|
|
- case NODE_SUB: return 1;
|
|
|
- case NODE_MUL: return 1;
|
|
|
- case NODE_DIV: return 1;
|
|
|
- case NODE_MOD: return 1;
|
|
|
- case NODE_SIN: return 1;
|
|
|
- case NODE_COS: return 1;
|
|
|
- case NODE_TAN: return 1;
|
|
|
- case NODE_ARCSIN: return 1;
|
|
|
- case NODE_ARCCOS: return 1;
|
|
|
- case NODE_ARCTAN: return 1;
|
|
|
- case NODE_POW: return 1;
|
|
|
- case NODE_LOG: return 1;
|
|
|
- case NODE_MAX: return 1;
|
|
|
- case NODE_MIN: return 1;
|
|
|
- case NODE_COMPARE: return 2;
|
|
|
- case NODE_TEXTURE: return 3; ///< param 0: texture
|
|
|
- case NODE_TIME: return 1; ///< param 0: interval length
|
|
|
- case NODE_NOISE: return 1;
|
|
|
- case NODE_PASS: return 1;
|
|
|
- case NODE_VEC_IN: return 1; ///< param 0: name
|
|
|
- case NODE_VEC_OUT: return 0; ///< param 0: name
|
|
|
- case NODE_VEC_CONSTANT: return 1; ///< param 0: value
|
|
|
- case NODE_VEC_PARAMETER: return 1; ///< param 0: name
|
|
|
- case NODE_VEC_ADD: return 1;
|
|
|
- case NODE_VEC_SUB: return 1;
|
|
|
- case NODE_VEC_MUL: return 1;
|
|
|
- case NODE_VEC_DIV: return 1;
|
|
|
- case NODE_VEC_MOD: return 1;
|
|
|
- case NODE_VEC_CROSS: return 1;
|
|
|
- case NODE_VEC_DOT: return 1;
|
|
|
- case NODE_VEC_POW: return 1;
|
|
|
- case NODE_VEC_NORMALIZE: return 1;
|
|
|
- case NODE_VEC_INTERPOLATE: return 1;
|
|
|
- case NODE_VEC_SCREEN_TO_UV: return 1;
|
|
|
- case NODE_VEC_TRANSFORM3: return 1;
|
|
|
- case NODE_VEC_TRANSFORM4: return 1;
|
|
|
- case NODE_VEC_COMPARE: return 2;
|
|
|
- case NODE_VEC_TEXTURE_2D: return 3;
|
|
|
- case NODE_VEC_TEXTURE_CUBE: return 3;
|
|
|
- case NODE_VEC_NOISE: return 1;
|
|
|
- case NODE_VEC_0: return 1;
|
|
|
- case NODE_VEC_1: return 1;
|
|
|
- case NODE_VEC_2: return 1;
|
|
|
- case NODE_VEC_BUILD: return 1;
|
|
|
- case NODE_VEC_PASS: return 1;
|
|
|
- case NODE_COLOR_CONSTANT: return 2;
|
|
|
- case NODE_COLOR_PARAMETER: return 2;
|
|
|
- case NODE_TEXTURE_PARAMETER: return 3;
|
|
|
- case NODE_TEXTURE_2D_PARAMETER: return 3;
|
|
|
- case NODE_TEXTURE_CUBE_PARAMETER: return 3;
|
|
|
- case NODE_TRANSFORM_CONSTANT: return 1;
|
|
|
- case NODE_TRANSFORM_PARAMETER: return 1;
|
|
|
- case NODE_LABEL: return 0;
|
|
|
-
|
|
|
- default: {}
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+const ShaderGraph::NodeSlotInfo ShaderGraph::node_slot_info[]= {
|
|
|
+
|
|
|
+ {NODE_SCALAR_CONST,{SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, //scalar constant
|
|
|
+ {NODE_VEC_CONST,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, //vec3 constant
|
|
|
+ {NODE_RGB_CONST,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, //rgb constant (shows a color picker instead)
|
|
|
+ {NODE_XFORM_CONST,{SLOT_MAX},{SLOT_TYPE_XFORM,SLOT_MAX}}, // 4x4 matrix constant
|
|
|
+ {NODE_TIME,{SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // time in seconds
|
|
|
+ {NODE_SCREEN_TEX,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // screen texture sampler (takes UV) (only usable in fragment shader)
|
|
|
+ {NODE_SCALAR_OP,{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc)
|
|
|
+ {NODE_VEC_OP,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // scalar vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc)
|
|
|
+ {NODE_VEC_SCALAR_OP,{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc)
|
|
|
+ {NODE_RGB_OP,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_TYPE_SCALAR},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc)
|
|
|
+ {NODE_XFORM_MULT,{SLOT_TYPE_XFORM,SLOT_TYPE_XFORM,SLOT_MAX},{SLOT_TYPE_XFORM,SLOT_MAX}}, // mat4 x mat4
|
|
|
+ {NODE_XFORM_VEC_MULT,{SLOT_TYPE_XFORM,SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // mat4 x vec3 mult (with no-translation option)
|
|
|
+ {NODE_XFORM_VEC_INV_MULT,{SLOT_TYPE_XFORM,SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // mat4 x vec3 inverse mult (with no-translation option)
|
|
|
+ {NODE_SCALAR_FUNC,{SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar function (sin,{SLOT_MAX},{SLOT_MAX}}, cos,{SLOT_MAX},{SLOT_MAX}}, etc)
|
|
|
+ {NODE_VEC_FUNC,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vector function (normalize,{SLOT_MAX},{SLOT_MAX}}, negate,{SLOT_MAX},{SLOT_MAX}}, reciprocal,{SLOT_MAX},{SLOT_MAX}}, rgb2hsv,{SLOT_MAX},{SLOT_MAX}}, hsv2rgb,{SLOT_MAX},{SLOT_MAX}}, etc,{SLOT_MAX},{SLOT_MAX}}, etc)
|
|
|
+ {NODE_VEC_LEN,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // vec3 length
|
|
|
+ {NODE_DOT_PROD,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // vec3 . vec3 (dot product -> scalar output)
|
|
|
+ {NODE_VEC_TO_SCALAR,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR}}, // 1 vec3 input,{SLOT_MAX},{SLOT_MAX}}, 3 scalar outputs
|
|
|
+ {NODE_SCALAR_TO_VEC,{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR},{SLOT_TYPE_VEC,SLOT_MAX}}, // 3 scalar input,{SLOT_MAX},{SLOT_MAX}}, 1 vec3 output
|
|
|
+ {NODE_SCALAR_INTERP,{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar interpolation (with optional curve)
|
|
|
+ {NODE_VEC_INTERP,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_TYPE_SCALAR},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 interpolation (with optional curve)
|
|
|
+ {NODE_SCALAR_INPUT,{SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar uniform (assignable in material)
|
|
|
+ {NODE_VEC_INPUT,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 uniform (assignable in material)
|
|
|
+ {NODE_RGB_INPUT,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // color uniform (assignable in material)
|
|
|
+ {NODE_XFORM_INPUT,{SLOT_MAX},{SLOT_TYPE_XFORM,SLOT_MAX}}, // mat4 uniform (assignable in material)
|
|
|
+ {NODE_TEXTURE_INPUT,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX}}, // texture input (assignable in material)
|
|
|
+ {NODE_CUBEMAP_INPUT,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX}}, // cubemap input (assignable in material)
|
|
|
+ {NODE_COMMENT,{SLOT_MAX},{SLOT_MAX}}, // comment
|
|
|
+ {NODE_TYPE_MAX,{SLOT_MAX},{SLOT_MAX}}
|
|
|
+};
|
|
|
+
|
|
|
+int ShaderGraph::get_node_input_slot_count(Mode p_mode, ShaderType p_shader_type,NodeType p_type) {
|
|
|
+
|
|
|
+ if (p_type==NODE_INPUT || p_type==NODE_OUTPUT) {
|
|
|
+
|
|
|
+ const InOutParamInfo* iop = &inout_param_info[0];
|
|
|
+ int pc=0;
|
|
|
+ while(iop->name) {
|
|
|
+ if (p_mode==iop->shader_mode && p_shader_type==iop->shader_type) {
|
|
|
+
|
|
|
+ if (iop->dir==SLOT_OUT)
|
|
|
+ pc++;
|
|
|
+ }
|
|
|
+ iop++;
|
|
|
+ }
|
|
|
+ return pc;
|
|
|
+ } else if (p_type==NODE_VEC_TO_XFORM){
|
|
|
+ return 4;
|
|
|
+ } else if (p_type==NODE_XFORM_TO_VEC){
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+
|
|
|
+ const NodeSlotInfo*nsi=&node_slot_info[0];
|
|
|
+ while(nsi->type!=NODE_TYPE_MAX) {
|
|
|
+
|
|
|
+ if (nsi->type==p_type) {
|
|
|
+ int pc=0;
|
|
|
+ for(int i=0;i<NodeSlotInfo::MAX_INS;i++) {
|
|
|
+ if (nsi->ins[i]==SLOT_MAX)
|
|
|
+ break;
|
|
|
+ pc++;
|
|
|
+ }
|
|
|
+ return pc;
|
|
|
+ }
|
|
|
+
|
|
|
+ nsi++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int ShaderGraph::get_node_output_slot_count(Mode p_mode, ShaderType p_shader_type,NodeType p_type){
|
|
|
+
|
|
|
+ if (p_type==NODE_INPUT || p_type==NODE_OUTPUT) {
|
|
|
+
|
|
|
+ const InOutParamInfo* iop = &inout_param_info[0];
|
|
|
+ int pc=0;
|
|
|
+ while(iop->name) {
|
|
|
+ if (p_mode==iop->shader_mode && p_shader_type==iop->shader_type) {
|
|
|
+
|
|
|
+ if (iop->dir==SLOT_IN)
|
|
|
+ pc++;
|
|
|
+ }
|
|
|
+ iop++;
|
|
|
+ }
|
|
|
+ return pc;
|
|
|
+ } else if (p_type==NODE_VEC_TO_XFORM){
|
|
|
+ return 1;
|
|
|
+ } else if (p_type==NODE_XFORM_TO_VEC){
|
|
|
+ return 4;
|
|
|
+ } else {
|
|
|
+
|
|
|
+ const NodeSlotInfo*nsi=&node_slot_info[0];
|
|
|
+ while(nsi->type!=NODE_TYPE_MAX) {
|
|
|
+
|
|
|
+ if (nsi->type==p_type) {
|
|
|
+ int pc=0;
|
|
|
+ for(int i=0;i<NodeSlotInfo::MAX_OUTS;i++) {
|
|
|
+ if (nsi->outs[i]==SLOT_MAX)
|
|
|
+ break;
|
|
|
+ pc++;
|
|
|
+ }
|
|
|
+ return pc;
|
|
|
+ }
|
|
|
+
|
|
|
+ nsi++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
}
|
|
|
- ERR_FAIL_V( 0 );
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-#define RET2(m_a,m_b) if (p_idx==0) return m_a; else if (p_idx==1) return m_b; else return "";
|
|
|
-#define RET3(m_a,m_b,m_c) if (p_idx==0) return m_a; else if (p_idx==1) return m_b; else if (p_idx==2) return m_c; else return "";
|
|
|
-#define RET4(m_a,m_b,m_c,m_d) if (p_idx==0) return m_a; else if (p_idx==1) return m_b; else if (p_idx==2) return m_c; else if (p_idx==3) return m_d; else return "";
|
|
|
-
|
|
|
-#define RET5(m_a,m_b,m_c,m_d,m_e) if (p_idx==0) return m_a; else if (p_idx==1) return m_b; else if (p_idx==2) return m_c; else if (p_idx==3) return m_d; else if (p_idx==4) return m_e; else return "";
|
|
|
-
|
|
|
-String ShaderGraph::shader_get_input_name(NodeType p_type,int p_idx) {
|
|
|
-
|
|
|
- switch(p_type) {
|
|
|
-
|
|
|
- case NODE_IN: return "";
|
|
|
- case NODE_OUT: return "out";
|
|
|
- case NODE_CONSTANT: return "";
|
|
|
- case NODE_PARAMETER: return "";
|
|
|
- case NODE_ADD: RET2("a","b");
|
|
|
- case NODE_SUB: RET2("a","b");
|
|
|
- case NODE_MUL: RET2("a","b");
|
|
|
- case NODE_DIV: RET2("a","b");
|
|
|
- case NODE_MOD: RET2("a","b");
|
|
|
- case NODE_SIN: return "rad";
|
|
|
- case NODE_COS: return "rad";
|
|
|
- case NODE_TAN: return "rad";
|
|
|
- case NODE_ARCSIN: return "in";
|
|
|
- case NODE_ARCCOS: return "in";
|
|
|
- case NODE_ARCTAN: return "in";
|
|
|
- case NODE_POW: RET2("in","exp");
|
|
|
- case NODE_LOG: return "in";
|
|
|
- case NODE_MAX: return "in";
|
|
|
- case NODE_MIN: return "in";
|
|
|
- case NODE_COMPARE: RET4("a","b","ret1","ret2");
|
|
|
- case NODE_TEXTURE: return "u";
|
|
|
- case NODE_TIME: return "";
|
|
|
- case NODE_NOISE: return "";
|
|
|
- case NODE_PASS: return "in";
|
|
|
- case NODE_VEC_IN: return "";
|
|
|
- case NODE_VEC_OUT: return "out";
|
|
|
- case NODE_VEC_CONSTANT: return "";
|
|
|
- case NODE_VEC_PARAMETER: return "";
|
|
|
- case NODE_VEC_ADD: RET2("a","b");
|
|
|
- case NODE_VEC_SUB: RET2("a","b");
|
|
|
- case NODE_VEC_MUL: RET2("a","b");
|
|
|
- case NODE_VEC_DIV: RET2("a","b");
|
|
|
- case NODE_VEC_MOD: RET2("a","b");
|
|
|
- case NODE_VEC_CROSS: RET2("a","b");
|
|
|
- case NODE_VEC_DOT: RET2("a","b");
|
|
|
- case NODE_VEC_POW: RET2("a","b");
|
|
|
- case NODE_VEC_NORMALIZE: return "vec";
|
|
|
- case NODE_VEC_INTERPOLATE: RET3("a","b","c");
|
|
|
- case NODE_VEC_SCREEN_TO_UV: return "scr";
|
|
|
- case NODE_VEC_TRANSFORM3: RET4("in","col0","col1","col2");
|
|
|
- case NODE_VEC_TRANSFORM4: RET5("in","col0","col1","col2","col3");
|
|
|
- case NODE_VEC_COMPARE: RET4("a","b","ret1","ret2");
|
|
|
- case NODE_VEC_TEXTURE_2D: return "uv";
|
|
|
- case NODE_VEC_TEXTURE_CUBE: return "uvw";
|
|
|
- case NODE_VEC_NOISE: return "";
|
|
|
- case NODE_VEC_0: return "vec";
|
|
|
- case NODE_VEC_1: return "vec";
|
|
|
- case NODE_VEC_2: return "vec";
|
|
|
- case NODE_VEC_BUILD: RET3("x/r","y/g","z/b");
|
|
|
- case NODE_VEC_PASS: return "in";
|
|
|
- case NODE_COLOR_CONSTANT: return "";
|
|
|
- case NODE_COLOR_PARAMETER: return "";
|
|
|
- case NODE_TEXTURE_PARAMETER: return "u";
|
|
|
- case NODE_TEXTURE_2D_PARAMETER: return "uv";
|
|
|
- case NODE_TEXTURE_CUBE_PARAMETER: return "uvw";
|
|
|
- case NODE_TRANSFORM_CONSTANT: return "in";
|
|
|
- case NODE_TRANSFORM_PARAMETER: return "in";
|
|
|
- case NODE_LABEL: return "";
|
|
|
-
|
|
|
- default: {}
|
|
|
+}
|
|
|
+ShaderGraph::SlotType ShaderGraph::get_node_input_slot_type(Mode p_mode, ShaderType p_shader_type,NodeType p_type,int p_idx){
|
|
|
+
|
|
|
+ if (p_type==NODE_INPUT || p_type==NODE_OUTPUT) {
|
|
|
+
|
|
|
+ const InOutParamInfo* iop = &inout_param_info[0];
|
|
|
+ int pc=0;
|
|
|
+ while(iop->name) {
|
|
|
+ if (p_mode==iop->shader_mode && p_shader_type==iop->shader_type) {
|
|
|
+
|
|
|
+ if (iop->dir==SLOT_OUT) {
|
|
|
+ if (pc==p_idx)
|
|
|
+ return iop->slot_type;
|
|
|
+ pc++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ iop++;
|
|
|
+ }
|
|
|
+ ERR_FAIL_V(SLOT_MAX);
|
|
|
+ } else if (p_type==NODE_VEC_TO_XFORM){
|
|
|
+ return SLOT_TYPE_VEC;
|
|
|
+ } else if (p_type==NODE_XFORM_TO_VEC){
|
|
|
+ return SLOT_TYPE_XFORM;
|
|
|
+ } else {
|
|
|
+
|
|
|
+ const NodeSlotInfo*nsi=&node_slot_info[0];
|
|
|
+ while(nsi->type!=NODE_TYPE_MAX) {
|
|
|
+
|
|
|
+ if (nsi->type==p_type) {
|
|
|
+ for(int i=0;i<NodeSlotInfo::MAX_INS;i++) {
|
|
|
+ if (nsi->ins[i]==SLOT_MAX)
|
|
|
+ break;
|
|
|
+ if (i==p_idx)
|
|
|
+ return nsi->ins[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ nsi++;
|
|
|
+ }
|
|
|
+
|
|
|
+ ERR_FAIL_V(SLOT_MAX);
|
|
|
+
|
|
|
}
|
|
|
+}
|
|
|
+ShaderGraph::SlotType ShaderGraph::get_node_output_slot_type(Mode p_mode, ShaderType p_shader_type,NodeType p_type,int p_idx){
|
|
|
+
|
|
|
+ if (p_type==NODE_INPUT || p_type==NODE_OUTPUT) {
|
|
|
+
|
|
|
+ const InOutParamInfo* iop = &inout_param_info[0];
|
|
|
+ int pc=0;
|
|
|
+ while(iop->name) {
|
|
|
+ if (p_mode==iop->shader_mode && p_shader_type==iop->shader_type) {
|
|
|
+
|
|
|
+ if (iop->dir==SLOT_IN) {
|
|
|
+ if (pc==p_idx)
|
|
|
+ return iop->slot_type;
|
|
|
+ pc++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ iop++;
|
|
|
+ }
|
|
|
+ ERR_FAIL_V(SLOT_MAX);
|
|
|
+ } else if (p_type==NODE_VEC_TO_XFORM){
|
|
|
+ return SLOT_TYPE_XFORM;
|
|
|
+ } else if (p_type==NODE_XFORM_TO_VEC){
|
|
|
+ return SLOT_TYPE_VEC;
|
|
|
+ } else {
|
|
|
+
|
|
|
+ const NodeSlotInfo*nsi=&node_slot_info[0];
|
|
|
+ while(nsi->type!=NODE_TYPE_MAX) {
|
|
|
+
|
|
|
+ if (nsi->type==p_type) {
|
|
|
+ for(int i=0;i<NodeSlotInfo::MAX_OUTS;i++) {
|
|
|
+ if (nsi->outs[i]==SLOT_MAX)
|
|
|
+ break;
|
|
|
+ if (i==p_idx)
|
|
|
+ return nsi->outs[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ nsi++;
|
|
|
+ }
|
|
|
|
|
|
- ERR_FAIL_V("");
|
|
|
-}
|
|
|
-String ShaderGraph::shader_get_output_name(NodeType p_type,int p_idx) {
|
|
|
-
|
|
|
- switch(p_type) {
|
|
|
-
|
|
|
- case NODE_IN: return "in";
|
|
|
- case NODE_OUT: return "";
|
|
|
- case NODE_CONSTANT: return "out";
|
|
|
- case NODE_PARAMETER: return "out";
|
|
|
- case NODE_ADD: return "sum";
|
|
|
- case NODE_SUB: return "dif";
|
|
|
- case NODE_MUL: return "prod";
|
|
|
- case NODE_DIV: return "quot";
|
|
|
- case NODE_MOD: return "rem";
|
|
|
- case NODE_SIN: return "out";
|
|
|
- case NODE_COS: return "out";
|
|
|
- case NODE_TAN: return "out";
|
|
|
- case NODE_ARCSIN: return "rad";
|
|
|
- case NODE_ARCCOS: return "rad";
|
|
|
- case NODE_ARCTAN: return "rad";
|
|
|
- case NODE_POW: RET2("in","exp");
|
|
|
- case NODE_LOG: return "out";
|
|
|
- case NODE_MAX: return "out";
|
|
|
- case NODE_MIN: return "out";
|
|
|
- case NODE_COMPARE: RET2("a/b","a/b");
|
|
|
- case NODE_TEXTURE: RET3("rgb","a","v");
|
|
|
- case NODE_TIME: return "out";
|
|
|
- case NODE_NOISE: return "out";
|
|
|
- case NODE_PASS: return "out";
|
|
|
- case NODE_VEC_IN: return "in";
|
|
|
- case NODE_VEC_OUT: return "";
|
|
|
- case NODE_VEC_CONSTANT: return "out";
|
|
|
- case NODE_VEC_PARAMETER: return "out";
|
|
|
- case NODE_VEC_ADD: return "sum";
|
|
|
- case NODE_VEC_SUB: return "sub";
|
|
|
- case NODE_VEC_MUL: return "mul";
|
|
|
- case NODE_VEC_DIV: return "div";
|
|
|
- case NODE_VEC_MOD: return "rem";
|
|
|
- case NODE_VEC_CROSS: return "crs";
|
|
|
- case NODE_VEC_DOT: return "prod";
|
|
|
- case NODE_VEC_POW: return "out";
|
|
|
- case NODE_VEC_NORMALIZE: return "norm";
|
|
|
- case NODE_VEC_INTERPOLATE: return "out";
|
|
|
- case NODE_VEC_SCREEN_TO_UV: return "uv";
|
|
|
- case NODE_VEC_TRANSFORM3: return "prod";
|
|
|
- case NODE_VEC_TRANSFORM4: return "prod";
|
|
|
- case NODE_VEC_COMPARE: RET2("a/b","a/b");
|
|
|
- case NODE_VEC_TEXTURE_2D: RET3("rgb","a","v");
|
|
|
- case NODE_VEC_TEXTURE_CUBE: RET3("rgb","a","v");
|
|
|
- case NODE_VEC_NOISE: return "out";
|
|
|
- case NODE_VEC_0: return "x/r";
|
|
|
- case NODE_VEC_1: return "y/g";
|
|
|
- case NODE_VEC_2: return "z/b";
|
|
|
- case NODE_VEC_BUILD: return "vec";
|
|
|
- case NODE_VEC_PASS: return "out";
|
|
|
- case NODE_COLOR_CONSTANT: RET2("rgb","a");
|
|
|
- case NODE_COLOR_PARAMETER: RET2("rgb","a");
|
|
|
- case NODE_TEXTURE_PARAMETER: RET3("rgb","a","v");
|
|
|
- case NODE_TEXTURE_2D_PARAMETER: RET3("rgb","a","v");
|
|
|
- case NODE_TEXTURE_CUBE_PARAMETER: RET3("rgb","a","v");
|
|
|
- case NODE_TRANSFORM_CONSTANT: return "out";
|
|
|
- case NODE_TRANSFORM_PARAMETER: return "out";
|
|
|
- case NODE_LABEL: return "";
|
|
|
-
|
|
|
- default: {}
|
|
|
+ ERR_FAIL_V(SLOT_MAX);
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
- ERR_FAIL_V("");
|
|
|
-}
|
|
|
-bool ShaderGraph::shader_is_input_vector(NodeType p_type,int p_input) {
|
|
|
-
|
|
|
- switch(p_type) {
|
|
|
-
|
|
|
- case NODE_IN: return false;
|
|
|
- case NODE_OUT: return false;
|
|
|
- case NODE_CONSTANT: return false;
|
|
|
- case NODE_PARAMETER: return false;
|
|
|
- case NODE_ADD: return false;
|
|
|
- case NODE_SUB: return false;
|
|
|
- case NODE_MUL: return false;
|
|
|
- case NODE_DIV: return false;
|
|
|
- case NODE_MOD: return false;
|
|
|
- case NODE_SIN: return false;
|
|
|
- case NODE_COS: return false;
|
|
|
- case NODE_TAN: return false;
|
|
|
- case NODE_ARCSIN: return false;
|
|
|
- case NODE_ARCCOS: return false;
|
|
|
- case NODE_ARCTAN: return false;
|
|
|
- case NODE_POW: return false;
|
|
|
- case NODE_LOG: return false;
|
|
|
- case NODE_MAX: return false;
|
|
|
- case NODE_MIN: return false;
|
|
|
- case NODE_COMPARE: return false;
|
|
|
- case NODE_TEXTURE: return false;
|
|
|
- case NODE_TIME: return false;
|
|
|
- case NODE_NOISE: return false;
|
|
|
- case NODE_PASS: return false;
|
|
|
- case NODE_VEC_IN: return false;
|
|
|
- case NODE_VEC_OUT: return true;
|
|
|
- case NODE_VEC_CONSTANT: return false;
|
|
|
- case NODE_VEC_PARAMETER: return false;
|
|
|
- case NODE_VEC_ADD: return true;
|
|
|
- case NODE_VEC_SUB: return true;
|
|
|
- case NODE_VEC_MUL: return true;
|
|
|
- case NODE_VEC_DIV: return true;
|
|
|
- case NODE_VEC_MOD: return true;
|
|
|
- case NODE_VEC_CROSS: return true;
|
|
|
- case NODE_VEC_DOT: return true;
|
|
|
- case NODE_VEC_POW: return (p_input==0)?true:false;
|
|
|
- case NODE_VEC_NORMALIZE: return true;
|
|
|
- case NODE_VEC_INTERPOLATE: return (p_input<2)?true:false;
|
|
|
- case NODE_VEC_SCREEN_TO_UV: return true;
|
|
|
- case NODE_VEC_TRANSFORM3: return true;
|
|
|
- case NODE_VEC_TRANSFORM4: return true;
|
|
|
- case NODE_VEC_COMPARE: return (p_input<2)?false:true;
|
|
|
- case NODE_VEC_TEXTURE_2D: return true;
|
|
|
- case NODE_VEC_TEXTURE_CUBE: return true;
|
|
|
- case NODE_VEC_NOISE: return false;
|
|
|
- case NODE_VEC_0: return true;
|
|
|
- case NODE_VEC_1: return true;
|
|
|
- case NODE_VEC_2: return true;
|
|
|
- case NODE_VEC_BUILD: return false;
|
|
|
- case NODE_VEC_PASS: return true;
|
|
|
- case NODE_COLOR_CONSTANT: return false;
|
|
|
- case NODE_COLOR_PARAMETER: return false;
|
|
|
- case NODE_TEXTURE_PARAMETER: return false;
|
|
|
- case NODE_TEXTURE_2D_PARAMETER: return true;
|
|
|
- case NODE_TEXTURE_CUBE_PARAMETER: return true;
|
|
|
- case NODE_TRANSFORM_CONSTANT: return true;
|
|
|
- case NODE_TRANSFORM_PARAMETER: return true;
|
|
|
- case NODE_LABEL: return false;
|
|
|
-
|
|
|
- default: {}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+void ShaderGraph::_update_shader() {
|
|
|
+
|
|
|
+
|
|
|
+ String code[3];
|
|
|
+
|
|
|
+ for(int i=0;i<3;i++) {
|
|
|
+
|
|
|
+ int idx=0;
|
|
|
+ for (Map<int,Node>::Element *E=shader[i].node_map.front();E;E=E->next()) {
|
|
|
+
|
|
|
+ E->get().sort_order=idx++;
|
|
|
+ }
|
|
|
+ //simple method for graph solving using bubblesort derived algorithm
|
|
|
+ int iters=0;
|
|
|
+ int iter_max=shader[i].node_map.size()*shader[i].node_map.size();
|
|
|
+
|
|
|
+ while(true) {
|
|
|
+ if (iters>iter_max)
|
|
|
+ break;
|
|
|
+
|
|
|
+ int swaps=0;
|
|
|
+ for (Map<int,Node>::Element *E=shader[i].node_map.front();E;E=E->next()) {
|
|
|
+
|
|
|
+ for(Map<int,SourceSlot>::Element *F=E->get().connections.front();F;F=F->next()) {
|
|
|
+
|
|
|
+ //this is kinda slow, could be sped up
|
|
|
+ Map<int,Node>::Element *G = shader[i].node_map.find(F->get().id);
|
|
|
+ ERR_FAIL_COND(!G);
|
|
|
+ if (G->get().sort_order > E->get().sort_order) {
|
|
|
+
|
|
|
+ SWAP(G->get().sort_order,E->get().sort_order);
|
|
|
+ swaps++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ iters++;
|
|
|
+ if (swaps==0) {
|
|
|
+ iters=0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (iters>0) {
|
|
|
+
|
|
|
+ shader[i].error=GRAPH_ERROR_CYCLIC;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ Vector<Node*> order;
|
|
|
+ order.resize(shader[i].node_map.size());
|
|
|
+
|
|
|
+ for (Map<int,Node>::Element *E=shader[i].node_map.front();E;E=E->next()) {
|
|
|
+
|
|
|
+ order[E->get().sort_order]=&E->get();
|
|
|
+ }
|
|
|
+
|
|
|
+ //generate code for the ordered graph
|
|
|
+ bool failed=false;
|
|
|
+
|
|
|
+ if (i==SHADER_TYPE_FRAGMENT && get_mode()==MODE_MATERIAL) {
|
|
|
+ code[i]+="vec3 DIFFUSE_OUT=vec3(0,0,0);";
|
|
|
+ code[i]+="float ALPHA_OUT=0;";
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String,String> inputs_xlate;
|
|
|
+ Set<String> inputs_used;
|
|
|
+
|
|
|
+ for(int j=0;j<order.size();j++) {
|
|
|
+
|
|
|
+ Node *n=order[j];
|
|
|
+ if (n->type==NODE_INPUT) {
|
|
|
+
|
|
|
+ const InOutParamInfo* iop = &inout_param_info[0];
|
|
|
+ int idx=0;
|
|
|
+ while(iop->name) {
|
|
|
+ if (get_mode()==iop->shader_mode && i==iop->shader_type && SLOT_IN==iop->dir) {
|
|
|
+
|
|
|
+ const char *typestr[4]={"float","vec3","mat4","texture"};
|
|
|
+
|
|
|
+ String vname=("nd"+itos(n->id)+"sl"+itos(idx));
|
|
|
+ inputs_xlate[vname]=String(typestr[iop->slot_type])+" "+vname+"="+iop->variable+";\n";
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
+ iop++;
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (n->type==NODE_OUTPUT) {
|
|
|
+
|
|
|
+
|
|
|
+ bool use_alpha=false;
|
|
|
+ const InOutParamInfo* iop = &inout_param_info[0];
|
|
|
+ int idx=0;
|
|
|
+ while(iop->name) {
|
|
|
+ if (get_mode()==iop->shader_mode && i==iop->shader_type && SLOT_OUT==iop->dir) {
|
|
|
+
|
|
|
+ if (n->connections.has(idx)) {
|
|
|
+ String iname=("nd"+itos(n->connections[idx].id)+"sl"+itos(n->connections[idx].slot));
|
|
|
+ if (node_get_type(ShaderType(i),n->connections[idx].id)==NODE_INPUT)
|
|
|
+ inputs_used.insert(iname);
|
|
|
+ code[i]+=String(iop->variable)+"="+iname+";\n";
|
|
|
+ if (i==SHADER_TYPE_FRAGMENT && get_mode()==MODE_MATERIAL && String(iop->name)=="DiffuseAlpha")
|
|
|
+ use_alpha=true;
|
|
|
+ }
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
+ iop++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (i==SHADER_TYPE_FRAGMENT && get_mode()==MODE_MATERIAL) {
|
|
|
+
|
|
|
+ if (use_alpha) {
|
|
|
+ code[i]+="DIFFUSE_ALPHA.rgb=DIFFUSE_OUT;\n";
|
|
|
+ code[i]+="DIFFUSE_ALPHA.a=ALPHA_OUT;\n";
|
|
|
+ } else {
|
|
|
+ code[i]+="DIFFUSE=DIFFUSE_OUT;\n";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ Vector<String> inputs;
|
|
|
+ int max = get_node_input_slot_count(get_mode(),ShaderType(i),n->type);
|
|
|
+ for(int k=0;k<max;k++) {
|
|
|
+ if (!n->connections.has(k)) {
|
|
|
+ shader[i].error=GRAPH_ERROR_MISSING_CONNECTIONS;
|
|
|
+ failed=true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ String iname="nd"+itos(n->connections[k].id)+"sl"+itos(n->connections[k].slot);
|
|
|
+ inputs.push_back(iname);
|
|
|
+ if (node_get_type(ShaderType(i),n->connections[k].id)==NODE_INPUT)
|
|
|
+ inputs_used.insert(iname);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if (failed)
|
|
|
+ break;
|
|
|
+ _add_node_code(ShaderType(i),n,inputs,code[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if (failed)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ for(Set<String>::Element *E=inputs_used.front();E;E=E->next()) {
|
|
|
+
|
|
|
+ ERR_CONTINUE( !inputs_xlate.has(E->get()));
|
|
|
+ code[i]=inputs_xlate[E->get()]+code[i];
|
|
|
+ }
|
|
|
+ shader[i].error=GRAPH_OK;
|
|
|
+ print_line("ShADER: "+code[i]);
|
|
|
}
|
|
|
|
|
|
- ERR_FAIL_V(false);
|
|
|
-}
|
|
|
-bool ShaderGraph::shader_is_output_vector(NodeType p_type,int p_input) {
|
|
|
-
|
|
|
- switch(p_type) {
|
|
|
-
|
|
|
- case NODE_IN: return false;
|
|
|
- case NODE_OUT: return false ;
|
|
|
- case NODE_CONSTANT: return false;
|
|
|
- case NODE_PARAMETER: return false;
|
|
|
- case NODE_ADD: return false;
|
|
|
- case NODE_SUB: return false;
|
|
|
- case NODE_MUL: return false;
|
|
|
- case NODE_DIV: return false;
|
|
|
- case NODE_MOD: return false;
|
|
|
- case NODE_SIN: return false;
|
|
|
- case NODE_COS: return false;
|
|
|
- case NODE_TAN: return false;
|
|
|
- case NODE_ARCSIN: return false;
|
|
|
- case NODE_ARCCOS: return false;
|
|
|
- case NODE_ARCTAN: return false;
|
|
|
- case NODE_POW: return false;
|
|
|
- case NODE_LOG: return false;
|
|
|
- case NODE_MAX: return false;
|
|
|
- case NODE_MIN: return false;
|
|
|
- case NODE_COMPARE: return false;
|
|
|
- case NODE_TEXTURE: return false;
|
|
|
- case NODE_TIME: return false;
|
|
|
- case NODE_NOISE: return false;
|
|
|
- case NODE_PASS: return false;
|
|
|
- case NODE_VEC_IN: return true;
|
|
|
- case NODE_VEC_OUT: return false;
|
|
|
- case NODE_VEC_CONSTANT: return true;
|
|
|
- case NODE_VEC_PARAMETER: return true;
|
|
|
- case NODE_VEC_ADD: return true;
|
|
|
- case NODE_VEC_SUB: return true;
|
|
|
- case NODE_VEC_MUL: return true;
|
|
|
- case NODE_VEC_DIV: return true;
|
|
|
- case NODE_VEC_MOD: return true;
|
|
|
- case NODE_VEC_CROSS: return true;
|
|
|
- case NODE_VEC_DOT: return false;
|
|
|
- case NODE_VEC_POW: return true;
|
|
|
- case NODE_VEC_NORMALIZE: return true;
|
|
|
- case NODE_VEC_INTERPOLATE: return true;
|
|
|
- case NODE_VEC_SCREEN_TO_UV: return true;
|
|
|
- case NODE_VEC_TRANSFORM3: return true;
|
|
|
- case NODE_VEC_TRANSFORM4: return true;
|
|
|
- case NODE_VEC_COMPARE: return true;
|
|
|
- case NODE_VEC_TEXTURE_2D: return (p_input==0)?true:false;
|
|
|
- case NODE_VEC_TEXTURE_CUBE: return (p_input==0)?true:false;
|
|
|
- case NODE_VEC_NOISE: return true;
|
|
|
- case NODE_VEC_0: return false;
|
|
|
- case NODE_VEC_1: return false;
|
|
|
- case NODE_VEC_2: return false;
|
|
|
- case NODE_VEC_BUILD: return true;
|
|
|
- case NODE_VEC_PASS: return true;
|
|
|
- case NODE_COLOR_CONSTANT: return (p_input==0)?true:false;
|
|
|
- case NODE_COLOR_PARAMETER: return (p_input==0)?true:false;
|
|
|
- case NODE_TEXTURE_PARAMETER: return (p_input==0)?true:false;
|
|
|
- case NODE_TEXTURE_2D_PARAMETER: return (p_input==0)?true:false;
|
|
|
- case NODE_TEXTURE_CUBE_PARAMETER: return (p_input==0)?true:false;
|
|
|
- case NODE_TRANSFORM_CONSTANT: return true;
|
|
|
- case NODE_TRANSFORM_PARAMETER: return true;
|
|
|
- case NODE_LABEL: return false;
|
|
|
-
|
|
|
- default: {}
|
|
|
+ bool all_ok=true;
|
|
|
+ for(int i=0;i<3;i++) {
|
|
|
+ if (shader[i].error!=GRAPH_OK)
|
|
|
+ all_ok=false;
|
|
|
}
|
|
|
|
|
|
- ERR_FAIL_V("");
|
|
|
+ if (all_ok) {
|
|
|
+ set_code(code[0],code[1],code[2]);
|
|
|
+ }
|
|
|
+ //do shader here
|
|
|
+ print_line("UPDATING SHADER");
|
|
|
+ _pending_update_shader=false;
|
|
|
}
|
|
|
|
|
|
-#endif
|
|
|
-#endif
|
|
|
+void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<String>& p_inputs,String& code) {
|
|
|
+
|
|
|
+
|
|
|
+ const char *typestr[4]={"float","vec3","mat4","texture"};
|
|
|
+#define OUTNAME(id,slot) (String(typestr[get_node_output_slot_type(get_mode(),p_type,p_node->type,slot)])+" "+("nd"+itos(id)+"sl"+itos(slot)))
|
|
|
+
|
|
|
+ switch(p_node->type) {
|
|
|
+
|
|
|
+ case NODE_INPUT: {
|
|
|
+
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_SCALAR_CONST: {
|
|
|
+
|
|
|
+ double scalar = p_node->param1;
|
|
|
+ code+=OUTNAME(p_node->id,0)+"="+rtos(scalar)+";\n";
|
|
|
+ }break;
|
|
|
+ case NODE_VEC_CONST: {
|
|
|
+ Vector3 vec = p_node->param1;
|
|
|
+ code+=OUTNAME(p_node->id,0)+"=vec3("+rtos(vec.x)+","+rtos(vec.y)+","+rtos(vec.z)+");\n";
|
|
|
+ }break;
|
|
|
+ case NODE_RGB_CONST: {
|
|
|
+ Color col = p_node->param1;
|
|
|
+ code+=OUTNAME(p_node->id,0)+"=vec3("+rtos(col.r)+","+rtos(col.g)+","+rtos(col.b)+");\n";
|
|
|
+ }break;
|
|
|
+ case NODE_XFORM_CONST: {
|
|
|
+
|
|
|
+ Transform xf = p_node->param1;
|
|
|
+ code+=OUTNAME(p_node->id,0)+"=mat4(\n";
|
|
|
+ code+="\tvec4(vec3("+rtos(xf.basis.get_axis(0).x)+","+rtos(xf.basis.get_axis(0).y)+","+rtos(xf.basis.get_axis(0).z)+"),0),\n";
|
|
|
+ code+="\tvec4(vec3("+rtos(xf.basis.get_axis(1).x)+","+rtos(xf.basis.get_axis(1).y)+","+rtos(xf.basis.get_axis(1).z)+"),0),\n";
|
|
|
+ code+="\tvec4(vec3("+rtos(xf.basis.get_axis(2).x)+","+rtos(xf.basis.get_axis(2).y)+","+rtos(xf.basis.get_axis(2).z)+"),0),\n";
|
|
|
+ code+="\tvec4(vec3("+rtos(xf.origin.x)+","+rtos(xf.origin.y)+","+rtos(xf.origin.z)+"),1)\n";
|
|
|
+ code+=");";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_TIME: {
|
|
|
+ code+=OUTNAME(p_node->id,0)+"=TIME;\n";
|
|
|
+ }break;
|
|
|
+ case NODE_SCREEN_TEX: {
|
|
|
+ code+=OUTNAME(p_node->id,0)+"=texscreen("+p_inputs[0]+");\n";
|
|
|
+ }break;
|
|
|
+ case NODE_SCALAR_OP: {
|
|
|
+ int op = p_node->param1;
|
|
|
+ String optxt;
|
|
|
+ switch(op) {
|
|
|
+
|
|
|
+ case SCALAR_OP_ADD: optxt = p_inputs[0]+"+"+p_inputs[1]+";"; break;
|
|
|
+ case SCALAR_OP_SUB: optxt = p_inputs[0]+"-"+p_inputs[1]+";"; break;
|
|
|
+ case SCALAR_OP_MUL: optxt = p_inputs[0]+"*"+p_inputs[1]+";"; break;
|
|
|
+ case SCALAR_OP_DIV: optxt = p_inputs[0]+"/"+p_inputs[1]+";"; break;
|
|
|
+ case SCALAR_OP_MOD: optxt = "mod("+p_inputs[0]+","+p_inputs[1]+");"; break;
|
|
|
+ case SCALAR_OP_POW: optxt = "pow("+p_inputs[0]+","+p_inputs[1]+");"; break;
|
|
|
+ case SCALAR_OP_MAX: optxt = "max("+p_inputs[0]+","+p_inputs[1]+");"; break;
|
|
|
+ case SCALAR_OP_MIN: optxt = "min("+p_inputs[0]+","+p_inputs[1]+");"; break;
|
|
|
+ case SCALAR_OP_ATAN2: optxt = "atan2("+p_inputs[0]+","+p_inputs[1]+");"; break;
|
|
|
+
|
|
|
+ }
|
|
|
+ code+=OUTNAME(p_node->id,0)+"="+optxt+"\n";;
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_VEC_OP: {
|
|
|
+ int op = p_node->param1;
|
|
|
+ String optxt;
|
|
|
+ switch(op) {
|
|
|
+ case VEC_OP_ADD: optxt = p_inputs[0]+"+"+p_inputs[1]+";"; break;
|
|
|
+ case VEC_OP_SUB: optxt = p_inputs[0]+"-"+p_inputs[1]+";"; break;
|
|
|
+ case VEC_OP_MUL: optxt = p_inputs[0]+"*"+p_inputs[1]+";"; break;
|
|
|
+ case VEC_OP_DIV: optxt = p_inputs[0]+"/"+p_inputs[1]+";"; break;
|
|
|
+ case VEC_OP_MOD: optxt = "mod("+p_inputs[0]+","+p_inputs[1]+");"; break;
|
|
|
+ case VEC_OP_POW: optxt = "pow("+p_inputs[0]+","+p_inputs[1]+");"; break;
|
|
|
+ case VEC_OP_MAX: optxt = "max("+p_inputs[0]+","+p_inputs[1]+");"; break;
|
|
|
+ case VEC_OP_MIN: optxt = "min("+p_inputs[0]+","+p_inputs[1]+");"; break;
|
|
|
+ case VEC_OP_CROSS: optxt = "cross("+p_inputs[0]+","+p_inputs[1]+");"; break;
|
|
|
+ }
|
|
|
+ code+=OUTNAME(p_node->id,0)+"="+optxt+"\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_VEC_SCALAR_OP: {
|
|
|
+ int op = p_node->param1;
|
|
|
+ String optxt;
|
|
|
+ switch(op) {
|
|
|
+ case VEC_OP_MUL: optxt = p_inputs[0]+"*"+p_inputs[1]+";"; break;
|
|
|
+ case VEC_OP_DIV: optxt = p_inputs[0]+"/"+p_inputs[1]+";"; break;
|
|
|
+ case VEC_OP_POW: optxt = "pow("+p_inputs[0]+","+p_inputs[1]+");"; break;
|
|
|
+ }
|
|
|
+ code+=OUTNAME(p_node->id,0)+"="+optxt+"\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_RGB_OP: {
|
|
|
+
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_XFORM_MULT: {
|
|
|
+
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+"*"+p_inputs[1]+";\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_XFORM_VEC_MULT: {
|
|
|
+
|
|
|
+ bool no_translation = p_node->param1;
|
|
|
+ if (no_translation) {
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+"*vec4("+p_inputs[1]+",0);\n";
|
|
|
+ } else {
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+"*vec4("+p_inputs[1]+",1);\n";
|
|
|
+ }
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_XFORM_VEC_INV_MULT: {
|
|
|
+ bool no_translation = p_node->param1;
|
|
|
+ if (no_translation) {
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+p_inputs[1]+"*vec4("+p_inputs[0]+",0);\n";
|
|
|
+ } else {
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+p_inputs[1]+"*vec4("+p_inputs[0]+",1);\n";
|
|
|
+ }
|
|
|
+ }break;
|
|
|
+ case NODE_SCALAR_FUNC: {
|
|
|
+
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_VEC_FUNC: {
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_VEC_LEN: {
|
|
|
+
|
|
|
+ code += OUTNAME(p_node->id,0)+"=length("+p_inputs[1]+");\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_DOT_PROD: {
|
|
|
+ code += OUTNAME(p_node->id,0)+"=dot("+p_inputs[1]+","+p_inputs[0]+");\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_VEC_TO_SCALAR: {
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+".x;\n";
|
|
|
+ code += OUTNAME(p_node->id,1)+"="+p_inputs[0]+".y;\n";
|
|
|
+ code += OUTNAME(p_node->id,2)+"="+p_inputs[0]+".z;\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_SCALAR_TO_VEC: {
|
|
|
+ code += OUTNAME(p_node->id,0)+"=vec3("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+""+");\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_VEC_TO_XFORM: {
|
|
|
+ code += OUTNAME(p_node->id,0)+"=xform("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+","+","+p_inputs[3]+");\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_XFORM_TO_VEC: {
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+".x;\n";
|
|
|
+ code += OUTNAME(p_node->id,1)+"="+p_inputs[0]+".y;\n";
|
|
|
+ code += OUTNAME(p_node->id,2)+"="+p_inputs[0]+".z;\n";
|
|
|
+ code += OUTNAME(p_node->id,3)+"="+p_inputs[0]+".o;\n";
|
|
|
+ }break;
|
|
|
+ case NODE_SCALAR_INTERP: {
|
|
|
+
|
|
|
+ code += OUTNAME(p_node->id,0)+"=mix("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+");\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_VEC_INTERP: {
|
|
|
+ code += OUTNAME(p_node->id,0)+"=mix("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+");\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_SCALAR_INPUT: {
|
|
|
+ String name = p_node->param1;
|
|
|
+ float dv=p_node->param2;
|
|
|
+ code +="uniform float "+name+"="+rtos(dv)+";\n";
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+name+";\n";
|
|
|
+ }break;
|
|
|
+ case NODE_VEC_INPUT: {
|
|
|
+
|
|
|
+ String name = p_node->param1;
|
|
|
+ Vector3 dv=p_node->param2;
|
|
|
+ code +="uniform float "+name+"=vec3("+rtos(dv.x)+","+rtos(dv.y)+","+rtos(dv.z)+");\n";
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+name+";\n";
|
|
|
+ }break;
|
|
|
+ case NODE_RGB_INPUT: {
|
|
|
+
|
|
|
+ String name = p_node->param1;
|
|
|
+ Color dv= p_node->param2;
|
|
|
+
|
|
|
+ code +="uniform color "+name+"=vec4("+rtos(dv.r)+","+rtos(dv.g)+","+rtos(dv.g)+","+rtos(dv.a)+");\n";
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+name+".rgb;\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_XFORM_INPUT: {
|
|
|
+
|
|
|
+ String name = p_node->param1;
|
|
|
+ Transform dv= p_node->param2;
|
|
|
+
|
|
|
+ code +="uniform mat4 "+name+"=mat4(\n";
|
|
|
+ code+="\tvec4(vec3("+rtos(dv.basis.get_axis(0).x)+","+rtos(dv.basis.get_axis(0).y)+","+rtos(dv.basis.get_axis(0).z)+"),0),\n";
|
|
|
+ code+="\tvec4(vec3("+rtos(dv.basis.get_axis(1).x)+","+rtos(dv.basis.get_axis(1).y)+","+rtos(dv.basis.get_axis(1).z)+"),0),\n";
|
|
|
+ code+="\tvec4(vec3("+rtos(dv.basis.get_axis(2).x)+","+rtos(dv.basis.get_axis(2).y)+","+rtos(dv.basis.get_axis(2).z)+"),0),\n";
|
|
|
+ code+="\tvec4(vec3("+rtos(dv.origin.x)+","+rtos(dv.origin.y)+","+rtos(dv.origin.z)+"),1)\n";
|
|
|
+ code+=");";
|
|
|
+
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+name+";\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_TEXTURE_INPUT: {
|
|
|
+ String name = p_node->param1;
|
|
|
+ String rname="_read_tex"+itos(p_node->id);
|
|
|
+ code +="uniform texture "+name+";";
|
|
|
+ code +="vec4 "+rname+"=tex("+name+","+p_inputs[0]+".xy);\n";
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+rname+".rgb;\n";
|
|
|
+ code += OUTNAME(p_node->id,1)+"="+rname+".a;\n";
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_CUBEMAP_INPUT: {
|
|
|
+
|
|
|
+ String name = p_node->param1;
|
|
|
+ code +="uniform cubemap "+name+";";
|
|
|
+ String rname="_read_tex"+itos(p_node->id);
|
|
|
+ code +="vec4 "+rname+"=texcube("+name+","+p_inputs[0]+".xy);\n";
|
|
|
+ code += OUTNAME(p_node->id,0)+"="+rname+".rgb;\n";
|
|
|
+ code += OUTNAME(p_node->id,1)+"="+rname+".a;\n";
|
|
|
+ }break;
|
|
|
+ case NODE_OUTPUT: {
|
|
|
+
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_COMMENT: {
|
|
|
+
|
|
|
+ }break;
|
|
|
+ case NODE_TYPE_MAX: {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|