diff options
author | Maximillian <maximillian.pol@gmail.com> | 2015-01-08 09:30:13 -0700 |
---|---|---|
committer | Maximillian <maximillian.pol@gmail.com> | 2015-01-08 09:30:13 -0700 |
commit | 41b3a1fea3e1c948520514d34dafe5a48728f1f8 (patch) | |
tree | f6d08c5ee598edf1da2497ea9e4f6c99bb37e468 | |
parent | 5c5519e2c896200652102d34cafde1315b3b9146 (diff) | |
parent | 78f4b937034c8bc24c2a871b1fc08ecbe39d0e5e (diff) |
Merge branch 'master' of https://github.com/okamstudio/godot
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.cpp | 3 | ||||
-rw-r--r-- | scene/gui/graph_edit.cpp | 29 | ||||
-rw-r--r-- | scene/gui/graph_edit.h | 5 | ||||
-rw-r--r-- | scene/gui/graph_node.cpp | 31 | ||||
-rw-r--r-- | scene/resources/shader_graph.cpp | 212 | ||||
-rw-r--r-- | scene/resources/shader_graph.h | 6 | ||||
-rw-r--r-- | scene/scene_string_names.cpp | 1 | ||||
-rw-r--r-- | scene/scene_string_names.h | 1 | ||||
-rw-r--r-- | servers/visual/shader_language.cpp | 31 | ||||
-rw-r--r-- | tools/editor/plugins/shader_graph_editor_plugin.cpp | 80 | ||||
-rw-r--r-- | tools/editor/plugins/shader_graph_editor_plugin.h | 3 |
11 files changed, 336 insertions, 66 deletions
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 50b63e1aa0..8eed423b8a 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -131,6 +131,7 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a SL::BlockNode *bnode=(SL::BlockNode*)p_node; //variables + code+="{"ENDL; for(Map<StringName,SL::DataType>::Element *E=bnode->variables.front();E;E=E->next()) { code+=_mktab(p_level)+_typestr(E->value())+" "+replace_string(E->key())+";"ENDL; @@ -141,6 +142,7 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a code+=_mktab(p_level)+dump_node_code(bnode->statements[i],p_level)+";"ENDL; } + code+="}"ENDL; } break; case SL::Node::TYPE_VARIABLE: { @@ -676,6 +678,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { //mode_replace_table[1]["POSITION"]="IN_POSITION"; mode_replace_table[1]["NORMAL"]="normal"; mode_replace_table[1]["TANGENT"]="tangent"; + mode_replace_table[1]["POSITION"]="gl_Position"; mode_replace_table[1]["BINORMAL"]="binormal"; mode_replace_table[1]["NORMALMAP"]="normalmap"; mode_replace_table[1]["NORMALMAP_DEPTH"]="normaldepth"; diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 5f38d541b7..3cd0dd3d16 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -1,5 +1,6 @@ #include "graph_edit.h" - +#include "os/input.h" +#include "os/keyboard.h" bool GraphEditFilter::has_point(const Point2& p_point) const { return ge->_filter_input(p_point); @@ -53,7 +54,7 @@ void GraphEdit::disconnect_node(const StringName& p_from, int p_from_port,const } } -void GraphEdit::get_connection_list(List<Connection> *r_connections) { +void GraphEdit::get_connection_list(List<Connection> *r_connections) const { *r_connections=connections; } @@ -88,7 +89,6 @@ void GraphEdit::_update_scroll() { updating=true; Rect2 screen; - screen.size=get_size(); for(int i=0;i<get_child_count();i++) { GraphNode *gn=get_child(i)->cast_to<GraphNode>(); @@ -101,6 +101,10 @@ void GraphEdit::_update_scroll() { screen = screen.merge(r); } + screen.pos-=get_size(); + screen.size+=get_size()*2.0; + + h_scroll->set_min(screen.pos.x); h_scroll->set_max(screen.pos.x+screen.size.x); h_scroll->set_page(get_size().x); @@ -492,7 +496,7 @@ void GraphEdit::_top_layer_draw() { void GraphEdit::_input_event(const InputEvent& p_ev) { - if (p_ev.type==InputEvent::MOUSE_MOTION && p_ev.mouse_motion.button_mask&BUTTON_MASK_MIDDLE) { + if (p_ev.type==InputEvent::MOUSE_MOTION && (p_ev.mouse_motion.button_mask&BUTTON_MASK_MIDDLE || (p_ev.mouse_motion.button_mask&BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { h_scroll->set_val( h_scroll->get_val() - p_ev.mouse_motion.relative_x ); v_scroll->set_val( v_scroll->get_val() - p_ev.mouse_motion.relative_y ); } @@ -515,12 +519,27 @@ bool GraphEdit::is_right_disconnects_enabled() const{ return right_disconnects; } - +Array GraphEdit::_get_connection_list() const { + + List<Connection> conns; + get_connection_list(&conns); + Array arr; + for(List<Connection>::Element *E=conns.front();E;E=E->next()) { + Dictionary d; + d["from"]=E->get().from; + d["from_port"]=E->get().from_port; + d["to"]=E->get().to; + d["to_port"]=E->get().to_port; + arr.push_back(d); + } + return arr; +} void GraphEdit::_bind_methods() { ObjectTypeDB::bind_method(_MD("connect_node:Error","from","from_port","to","to_port"),&GraphEdit::connect_node); ObjectTypeDB::bind_method(_MD("is_node_connected","from","from_port","to","to_port"),&GraphEdit::is_node_connected); ObjectTypeDB::bind_method(_MD("disconnect_node","from","from_port","to","to_port"),&GraphEdit::disconnect_node); + ObjectTypeDB::bind_method(_MD("get_connection_list"),&GraphEdit::_get_connection_list); ObjectTypeDB::bind_method(_MD("set_right_disconnects","enable"),&GraphEdit::set_right_disconnects); ObjectTypeDB::bind_method(_MD("is_right_disconnects_enabled"),&GraphEdit::is_right_disconnects_enabled); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 1df2776cef..0a9da73ab6 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -69,6 +69,8 @@ private: void _top_layer_draw(); void _update_scroll_offset(); + Array _get_connection_list() const; + friend class GraphEditFilter; bool _filter_input(const Point2& p_point); protected: @@ -85,7 +87,8 @@ public: void disconnect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); void clear_connections(); - void get_connection_list(List<Connection> *r_connections); + GraphEditFilter *get_top_layer() const { return top_layer; } + void get_connection_list(List<Connection> *r_connections) const; void set_right_disconnects(bool p_enable); bool is_right_disconnects_enabled() const; diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 50ee9abcf8..444b37855f 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -1,4 +1,5 @@ #include "graph_node.h" +#include "method_bind_ext.inc" bool GraphNode::_set(const StringName& p_name, const Variant& p_value) { @@ -38,9 +39,8 @@ bool GraphNode::_set(const StringName& p_name, const Variant& p_value) { bool GraphNode::_get(const StringName& p_name,Variant &r_ret) const{ - print_line("get "+p_name.operator String()); - if (!p_name.operator String().begins_with("slot/")) { - print_line("no begins"); + + if (!p_name.operator String().begins_with("slot/")) { return false; } @@ -68,7 +68,6 @@ bool GraphNode::_get(const StringName& p_name,Variant &r_ret) const{ else return false; - print_line("ask for: "+p_name.operator String()+" get: "+String(r_ret)); return true; } void GraphNode::_get_property_list( List<PropertyInfo> *p_list) const{ @@ -540,6 +539,30 @@ void GraphNode::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_title"),&GraphNode::get_title); ObjectTypeDB::bind_method(_MD("_input_event"),&GraphNode::_input_event); + ObjectTypeDB::bind_method(_MD("set_slot","idx","enable_left","type_left","color_left","enable_right","type_right","color_right"),&GraphNode::set_slot); + ObjectTypeDB::bind_method(_MD("clear_slot","idx"),&GraphNode::clear_slot); + ObjectTypeDB::bind_method(_MD("clear_all_slots","idx"),&GraphNode::clear_all_slots); + ObjectTypeDB::bind_method(_MD("is_slot_enabled_left","idx"),&GraphNode::is_slot_enabled_left); + ObjectTypeDB::bind_method(_MD("get_slot_type_left","idx"),&GraphNode::get_slot_type_left); + ObjectTypeDB::bind_method(_MD("get_slot_color_left","idx"),&GraphNode::get_slot_color_left); + ObjectTypeDB::bind_method(_MD("is_slot_enabled_right","idx"),&GraphNode::is_slot_enabled_right); + ObjectTypeDB::bind_method(_MD("get_slot_type_right","idx"),&GraphNode::get_slot_type_right); + ObjectTypeDB::bind_method(_MD("get_slot_color_right","idx"),&GraphNode::get_slot_color_right); + + ObjectTypeDB::bind_method(_MD("set_offset","offset"),&GraphNode::set_offset); + ObjectTypeDB::bind_method(_MD("get_offset"),&GraphNode::get_offset); + + ObjectTypeDB::bind_method(_MD("get_connection_output_count"),&GraphNode::get_connection_output_count); + ObjectTypeDB::bind_method(_MD("get_connection_input_count"),&GraphNode::get_connection_input_count); + + ObjectTypeDB::bind_method(_MD("get_connection_output_pos","idx"),&GraphNode::get_connection_output_pos); + ObjectTypeDB::bind_method(_MD("get_connection_output_type","idx"),&GraphNode::get_connection_output_type); + ObjectTypeDB::bind_method(_MD("get_connection_output_color","idx"),&GraphNode::get_connection_output_color); + ObjectTypeDB::bind_method(_MD("get_connection_input_pos","idx"),&GraphNode::get_connection_input_pos); + ObjectTypeDB::bind_method(_MD("get_connection_input_type","idx"),&GraphNode::get_connection_input_type); + ObjectTypeDB::bind_method(_MD("get_connection_input_color","idx"),&GraphNode::get_connection_input_color); + + ObjectTypeDB::bind_method(_MD("set_show_close_button","show"),&GraphNode::set_show_close_button); ObjectTypeDB::bind_method(_MD("is_close_button_visible"),&GraphNode::is_close_button_visible); diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp index 4c81724841..8b2f318ec0 100644 --- a/scene/resources/shader_graph.cpp +++ b/scene/resources/shader_graph.cpp @@ -27,8 +27,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "shader_graph.h" - - +#include "scene/scene_string_names.h" +//todo +//-RGB ops +//-mostrar error de conexion Array ShaderGraph::_get_node_list(ShaderType p_type) const { @@ -135,6 +137,13 @@ Dictionary ShaderGraph::_get_data() const { } + +ShaderGraph::GraphError ShaderGraph::get_graph_error(ShaderType p_type) const { + + ERR_FAIL_INDEX_V(p_type,3,GRAPH_OK); + return shader[p_type].error; +} + void ShaderGraph::_bind_methods() { ObjectTypeDB::bind_method(_MD("_update_shader"),&ShaderGraph::_update_shader); @@ -178,9 +187,9 @@ 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_set_op","shader_type","id","op"),&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); @@ -354,6 +363,8 @@ void ShaderGraph::_bind_methods() { BIND_CONSTANT( VEC_FUNC_HSV2RGB ); BIND_CONSTANT( VEC_MAX_FUNC ); + ADD_SIGNAL(MethodInfo("updated")); + #if 0 ObjectTypeDB::bind_method(_MD("node_add"),&ShaderGraph::node_add ); @@ -566,7 +577,7 @@ void ShaderGraph::node_remove(ShaderType p_type,int p_id) { } shader[p_type].node_map.erase(p_id); - print_line("erased node, amount left: "+itos(shader[p_type].node_map.size())); + _request_update(); } @@ -632,7 +643,6 @@ bool ShaderGraph::is_node_connected(ShaderType p_type,int p_src_id,int p_src_slo 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); - print_line("** dsisconnect"); SourceSlot ts; ts.id=p_src_id; ts.slot=p_src_slot; @@ -869,14 +879,14 @@ ShaderGraph::VecScalarOp ShaderGraph::vec_scalar_op_node_get_op(ShaderType p_typ } -void ShaderGraph::rgb_op_node_set_op(ShaderType p_type,float p_id,RGBOp p_op,float p_c){ +void ShaderGraph::rgb_op_node_set_op(ShaderType p_type,float p_id,RGBOp 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_RGB_OP); n.param1=p_op; - n.param2=p_c; + _request_update(); } @@ -890,15 +900,7 @@ ShaderGraph::RGBOp ShaderGraph::rgb_op_node_get_op(ShaderType p_type,float p_id) return RGBOp(op); } -float ShaderGraph::rgb_op_node_get_c(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_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){ @@ -926,7 +928,9 @@ void ShaderGraph::scalar_func_node_set_function(ShaderType p_type,int p_id,Scala 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; + int func = p_func; + ERR_FAIL_INDEX(func,SCALAR_MAX_FUNC); + n.param1=func; _request_update(); } @@ -946,7 +950,9 @@ void ShaderGraph::vec_func_node_set_function(ShaderType p_type,int p_id,VecFunc 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; + int func = p_func; + ERR_FAIL_INDEX(func,VEC_MAX_FUNC); + n.param1=func; _request_update(); @@ -1214,7 +1220,7 @@ const ShaderGraph::InOutParamInfo ShaderGraph::inout_param_info[]={ {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,"Position","POSITION.xyz","",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}, @@ -1284,10 +1290,10 @@ const ShaderGraph::NodeSlotInfo ShaderGraph::node_slot_info[]= { {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_RGB_OP,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,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_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_XFORM_VEC_INV_MULT,{SLOT_TYPE_VEC,SLOT_TYPE_XFORM,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 @@ -1418,6 +1424,7 @@ ShaderGraph::SlotType ShaderGraph::get_node_input_slot_type(Mode p_mode, ShaderT 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) @@ -1666,7 +1673,7 @@ void ShaderGraph::_update_shader() { shader[i].error=GRAPH_OK; - print_line("ShADER: "+code[i]); + } bool all_ok=true; @@ -1679,8 +1686,9 @@ void ShaderGraph::_update_shader() { set_code(code[0],code[1],code[2]); } //do shader here - print_line("UPDATING SHADER"); + _pending_update_shader=false; + emit_signal(SceneStringNames::get_singleton()->updated); } void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<String>& p_inputs,String& code) { @@ -1688,6 +1696,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str 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))) +#define OUTVAR(id,slot) ("nd"+itos(id)+"sl"+itos(slot)) switch(p_node->type) { @@ -1766,16 +1775,94 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str 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; + case VEC_SCALAR_OP_MUL: optxt = p_inputs[0]+"*"+p_inputs[1]+";"; break; + case VEC_SCALAR_OP_DIV: optxt = p_inputs[0]+"/"+p_inputs[1]+";"; break; + case VEC_SCALAR_OP_POW: optxt = "pow("+p_inputs[0]+","+p_inputs[1]+");"; break; } code+=OUTNAME(p_node->id,0)+"="+optxt+"\n"; }break; case NODE_RGB_OP: { + int op = p_node->param1; + static const char*axisn[3]={"x","y","z"}; + switch(op) { + case RGB_OP_SCREEN: { + + code += OUTNAME(p_node->id,0)+"=vec3(1.0)-(vec3(1.0)-"+p_inputs[0]+")*(vec3(1.0)-"+p_inputs[1]+");\n"; + } break; + case RGB_OP_DIFFERENCE: { + + code += OUTNAME(p_node->id,0)+"=abs("+p_inputs[0]+"-"+p_inputs[1]+");\n"; + + } break; + case RGB_OP_DARKEN: { + + code += OUTNAME(p_node->id,0)+"=min("+p_inputs[0]+","+p_inputs[1]+");\n"; + } break; + case RGB_OP_LIGHTEN: { + + code += OUTNAME(p_node->id,0)+"=max("+p_inputs[0]+","+p_inputs[1]+");\n"; + + } break; + case RGB_OP_OVERLAY: { + + code += OUTNAME(p_node->id,0)+";\n"; + for(int i=0;i<3;i++) { + code += "{\n"; + code += "\tfloat base="+p_inputs[0]+"."+axisn[i]+";\n"; + code += "\tfloat blend="+p_inputs[1]+"."+axisn[i]+";\n"; + code += "\tif (base < 0.5) {\n"; + code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = 2.0 * base * blend;\n"; + code += "\t} else {\n"; + code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = 1.0 - 2.0 * (1.0 - blend) * (1.0 - base);\n"; + code += "\t}\n"; + code += "}\n"; + } + } break; + case RGB_OP_DODGE: { + + code += OUTNAME(p_node->id,0)+"=("+p_inputs[0]+")/(vec3(1.0)-"+p_inputs[1]+");\n"; + + } break; + case RGB_OP_BURN: { + + code += OUTNAME(p_node->id,0)+"=vec3(1.0)-(vec3(1.0)-"+p_inputs[0]+")/("+p_inputs[1]+");\n"; + } break; + case RGB_OP_SOFT_LIGHT: { + + code += OUTNAME(p_node->id,0)+";\n"; + for(int i=0;i<3;i++) { + code += "{\n"; + code += "\tfloat base="+p_inputs[0]+"."+axisn[i]+";\n"; + code += "\tfloat blend="+p_inputs[1]+"."+axisn[i]+";\n"; + code += "\tif (base < 0.5) {\n"; + code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = (base * (blend+0.5));\n"; + code += "\t} else {\n"; + code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = (1 - (1-base) * (1-(blend-0.5)));\n"; + code += "\t}\n"; + code += "}\n"; + } + + } break; + case RGB_OP_HARD_LIGHT: { + + code += OUTNAME(p_node->id,0)+";\n"; + for(int i=0;i<3;i++) { + code += "{\n"; + code += "\tfloat base="+p_inputs[0]+"."+axisn[i]+";\n"; + code += "\tfloat blend="+p_inputs[1]+"."+axisn[i]+";\n"; + code += "\tif (base < 0.5) {\n"; + code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = (base * (2*blend));\n"; + code += "\t} else {\n"; + code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = (1 - (1-base) * (1-2*(blend-0.5)));\n"; + code += "\t}\n"; + code += "}\n"; + } + + } break; + } }break; case NODE_XFORM_MULT: { @@ -1786,26 +1873,85 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str bool no_translation = p_node->param1; if (no_translation) { - code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+"*vec4("+p_inputs[1]+",0);\n"; + code += OUTNAME(p_node->id,0)+"=("+p_inputs[0]+"*vec4("+p_inputs[1]+",0)).xyz;\n"; } else { - code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+"*vec4("+p_inputs[1]+",1);\n"; + code += OUTNAME(p_node->id,0)+"=("+p_inputs[0]+"*vec4("+p_inputs[1]+",1)).xyz;\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"; + code += OUTNAME(p_node->id,0)+"=("+p_inputs[1]+"*vec4("+p_inputs[0]+",0)).xyz;\n"; } else { - code += OUTNAME(p_node->id,0)+"="+p_inputs[1]+"*vec4("+p_inputs[0]+",1);\n"; + code += OUTNAME(p_node->id,0)+"=("+p_inputs[1]+"*vec4("+p_inputs[0]+",1)).xyz;\n"; } }break; case NODE_SCALAR_FUNC: { - - - }break; + static const char*scalar_func_id[SCALAR_MAX_FUNC]={ + "sin($)", + "cos($)", + "tan($)", + "asin($)", + "acos($)", + "atan($)", + "sinh($)", + "cosh($)", + "tanh($)", + "log($)", + "exp($)", + "sqrt($)", + "abs($)", + "sign($)", + "floor($)", + "round($)", + "ceil($)", + "frac($)", + "min(max($,0),1)", + "-($)", + }; + + int func = p_node->param1; + ERR_FAIL_INDEX(func,SCALAR_MAX_FUNC); + code += OUTNAME(p_node->id,0)+"="+String(scalar_func_id[func]).replace("$",p_inputs[0])+";\n"; + + } break; case NODE_VEC_FUNC: { + static const char*vec_func_id[VEC_MAX_FUNC]={ + "normalize($)", + "max(min($,vec3(1,1,1)),vec3(0,0,0))", + "-($)", + "1.0/($)", + "", + "", + }; + + + int func = p_node->param1; + ERR_FAIL_INDEX(func,VEC_MAX_FUNC); + if (func==VEC_FUNC_RGB2HSV) { + code += OUTNAME(p_node->id,0)+";\n"; + code+="{\n"; + code+="\tvec3 c = "+p_inputs[0]+";\n"; + code+="\tvec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n"; + code+="\tvec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n"; + code+="\tvec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n"; + code+="\tfloat d = q.x - min(q.w, q.y);\n"; + code+="\tfloat e = 1.0e-10;\n"; + code+="\t"+OUTVAR(p_node->id,0)+"=vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n"; + code+="}\n"; + } else if (func==VEC_FUNC_HSV2RGB) { + code += OUTNAME(p_node->id,0)+";\n";; + code+="{\n"; + code+="\tvec3 c = "+p_inputs[0]+";\n"; + code+="\tvec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n"; + code+="\tvec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n"; + code+="\t"+OUTVAR(p_node->id,0)+"=c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n"; + code+="}\n"; + } else { + code += OUTNAME(p_node->id,0)+"="+String(vec_func_id[func]).replace("$",p_inputs[0])+";\n"; + } }break; case NODE_VEC_LEN: { diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h index 984164b449..55d09b4c38 100644 --- a/scene/resources/shader_graph.h +++ b/scene/resources/shader_graph.h @@ -267,9 +267,8 @@ public: RGB_MAX_OP }; - void rgb_op_node_set_op(ShaderType p_which,float p_id,RGBOp p_op,float p_c); + void rgb_op_node_set_op(ShaderType p_which,float p_id,RGBOp p_op); RGBOp rgb_op_node_get_op(ShaderType p_which,float p_id) const; - float rgb_op_node_get_c(ShaderType p_which,float p_id) const; void xform_vec_mult_node_set_no_translation(ShaderType p_which,int p_id,bool p_no_translation); bool xform_vec_mult_node_get_no_translation(ShaderType p_which,int p_id) const; @@ -349,6 +348,8 @@ public: Variant node_get_state(ShaderType p_type, int p_node) const; void node_set_state(ShaderType p_type, int p_id, const Variant& p_state); + GraphError get_graph_error(ShaderType p_type) const; + static int get_type_input_count(NodeType p_type); static int get_type_output_count(NodeType p_type); static SlotType get_type_input_type(NodeType p_type,int p_idx); @@ -388,6 +389,7 @@ VARIANT_ENUM_CAST( ShaderGraph::VecScalarOp ); VARIANT_ENUM_CAST( ShaderGraph::RGBOp ); VARIANT_ENUM_CAST( ShaderGraph::ScalarFunc ); VARIANT_ENUM_CAST( ShaderGraph::VecFunc ); +VARIANT_ENUM_CAST( ShaderGraph::GraphError ); class MaterialShaderGraph : public ShaderGraph { diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 0d66257eda..af5e6d4165 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -67,6 +67,7 @@ SceneStringNames::SceneStringNames() { idle=StaticCString::create("idle"); iteration=StaticCString::create("iteration"); update=StaticCString::create("update"); + updated=StaticCString::create("updated"); _get_gizmo_geometry=StaticCString::create("_get_gizmo_geometry"); _can_gizmo_scale=StaticCString::create("_can_gizmo_scale"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index b0628c86b6..14e5e83b8d 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -63,6 +63,7 @@ public: StringName idle; StringName iteration; StringName update; + StringName updated; StringName line_separation; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 40e36d2a89..f2348bf59f 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -768,16 +768,20 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={ //constructors {"bool",TYPE_BOOL,{TYPE_BOOL,TYPE_VOID}}, {"float",TYPE_FLOAT,{TYPE_FLOAT,TYPE_VOID}}, + {"vec2",TYPE_VEC2,{TYPE_FLOAT,TYPE_VOID}}, {"vec2",TYPE_VEC2,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}}, + {"vec3",TYPE_VEC3,{TYPE_FLOAT,TYPE_VOID}}, {"vec3",TYPE_VEC3,{TYPE_FLOAT,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}}, {"vec3",TYPE_VEC3,{TYPE_VEC2,TYPE_FLOAT,TYPE_VOID}}, {"vec3",TYPE_VEC3,{TYPE_FLOAT,TYPE_VEC2,TYPE_VOID}}, + {"vec4",TYPE_VEC4,{TYPE_FLOAT,TYPE_VOID}}, {"vec4",TYPE_VEC4,{TYPE_FLOAT,TYPE_FLOAT,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}}, {"vec4",TYPE_VEC4,{TYPE_FLOAT,TYPE_VEC2,TYPE_FLOAT,TYPE_VOID}}, {"vec4",TYPE_VEC4,{TYPE_VEC2,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}}, {"vec4",TYPE_VEC4,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VEC2,TYPE_VOID}}, {"vec4",TYPE_VEC4,{TYPE_FLOAT,TYPE_VEC3,TYPE_VOID}}, {"vec4",TYPE_VEC4,{TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}}, + {"vec4",TYPE_VEC4,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}}, {"mat3",TYPE_MAT3,{TYPE_VEC3,TYPE_VEC3,TYPE_VEC3,TYPE_VOID}}, {"mat4",TYPE_MAT4,{TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VOID}}, //intrinsics - trigonometry @@ -856,6 +860,9 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={ {"clamp",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VEC2,TYPE_VOID}}, {"clamp",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VEC3,TYPE_VOID}}, {"clamp",TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VOID}}, + {"clamp",TYPE_VEC2,{TYPE_VEC2,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}}, + {"clamp",TYPE_VEC3,{TYPE_VEC3,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}}, + {"clamp",TYPE_VEC4,{TYPE_VEC4,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}}, {"mix",TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}}, {"mix",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_FLOAT,TYPE_VOID}}, {"mix",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VEC2,TYPE_VOID}}, @@ -1047,7 +1054,7 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::vertex_builtins_defs[]={ const ShaderLanguage::BuiltinsDef ShaderLanguage::fragment_builtins_defs[]={ { "VERTEX", TYPE_VEC3}, - { "POSITION", TYPE_VEC3}, + { "POSITION", TYPE_VEC4}, { "NORMAL", TYPE_VEC3}, { "TANGENT", TYPE_VEC3}, { "BINORMAL", TYPE_VEC3}, @@ -1210,9 +1217,25 @@ ShaderLanguage::Node* ShaderLanguage::validate_function_call(Parser&parser, Oper Variant data; switch(p_func->return_cache) { case TYPE_FLOAT: data = cdata[0]; break; - case TYPE_VEC2: data = Vector2(cdata[0],cdata[1]); break; - case TYPE_VEC3: data = Vector3(cdata[0],cdata[1],cdata[2]); break; - case TYPE_VEC4: data = Plane(cdata[0],cdata[1],cdata[2],cdata[3]); break; + case TYPE_VEC2: + if (cdata.size()==1) + data = Vector2(cdata[0],cdata[0]); + else + data = Vector2(cdata[0],cdata[1]); + + break; + case TYPE_VEC3: + if (cdata.size()==1) + data = Vector3(cdata[0],cdata[0],cdata[0]); + else + data = Vector3(cdata[0],cdata[1],cdata[2]); + break; + case TYPE_VEC4: + if (cdata.size()==1) + data = Plane(cdata[0],cdata[0],cdata[0],cdata[0]); + else + data = Plane(cdata[0],cdata[1],cdata[2],cdata[3]); + break; } cn->datatype=p_func->return_cache; diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index 54e8268574..0a206c4a45 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -200,7 +200,7 @@ void ShaderGraphView::_vec_input_changed(double p_value, int p_id,Array p_arr){ } void ShaderGraphView::_xform_input_changed(int p_id, Node *p_button){ - print_line("XFIC"); + ToolButton *tb = p_button->cast_to<ToolButton>(); ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); ped_popup->set_size(tb->get_size()); @@ -445,7 +445,7 @@ void ShaderGraphView::_node_removed(int p_id) { void ShaderGraphView::_node_moved(const Vector2& p_from, const Vector2& p_to,int p_id) { - print_line("moved from "+p_from+" to "+p_to); + ERR_FAIL_COND(!node_map.has(p_id)); UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); ur->create_action("Move Shader Graph Node"); @@ -745,14 +745,9 @@ void ShaderGraphView::_create_node(int p_id) { } break; // mat4 x mat4 - case ShaderGraph::NODE_XFORM_VEC_MULT: - case ShaderGraph::NODE_XFORM_VEC_INV_MULT: { - - if (graph->node_get_type(type,p_id)==ShaderGraph::NODE_XFORM_VEC_INV_MULT) - gn->set_title("XFVecMult"); - else - gn->set_title("XFVecInvMult"); + case ShaderGraph::NODE_XFORM_VEC_MULT: { + gn->set_title("XFVecMult"); Button *button = memnew( Button("RotOnly")); button->set_toggle_mode(true); @@ -774,6 +769,32 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + } break; + case ShaderGraph::NODE_XFORM_VEC_INV_MULT: { + + gn->set_title("XFVecInvMult"); + + + Button *button = memnew( Button("RotOnly")); + button->set_toggle_mode(true); + button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); + button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); + + gn->add_child(button); + + gn->add_child( memnew(Label("vec"))); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("xf"))); + hbc->add_spacer(); + Label *l = memnew(Label("out")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + } break; // mat4 x vec3 inverse mult (with no-translation option) case ShaderGraph::NODE_SCALAR_FUNC: { @@ -1002,7 +1023,7 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); } break; // vec3 interpolation (with optional curve) case ShaderGraph::NODE_SCALAR_INPUT: { @@ -1192,7 +1213,7 @@ void ShaderGraphView::_create_node(int p_id) { graph_edit->add_child(gn); node_map[p_id]=gn; gn->set_offset(graph->node_get_pos(type,p_id)); - print_line("NODE "+itos(p_id)+" OFS "+gn->get_offset()); + } @@ -1215,7 +1236,7 @@ void ShaderGraphView::_update_graph() { List<int> nl; graph->get_node_list(type,&nl); - print_line("graph nodes: "+itos(nl.size())); + for(List<int>::Element *E=nl.front();E;E=E->next()) { _create_node(E->get()); @@ -1234,11 +1255,29 @@ void ShaderGraphView::_update_graph() { } +void ShaderGraphView::_sg_updated() { + + if (!graph.is_valid()) + return; + switch(graph->get_graph_error(type)) { + case ShaderGraph::GRAPH_OK: status->set_text(""); break; + case ShaderGraph::GRAPH_ERROR_CYCLIC: status->set_text("Error: Cyclic Connection Link"); break; + case ShaderGraph::GRAPH_ERROR_MISSING_CONNECTIONS: status->set_text("Error: Missing Input Connections"); break; + } +} + void ShaderGraphView::set_graph(Ref<ShaderGraph> p_graph){ - print_line("GRAPH EDIT: "+itos(p_graph.is_valid())); + + if (graph.is_valid()) { + graph->disconnect("updated",this,"_sg_updated"); + } graph=p_graph; + if (graph.is_valid()) { + graph->connect("updated",this,"_sg_updated"); + } _update_graph(); + _sg_updated(); } @@ -1322,6 +1361,7 @@ void ShaderGraphView::_bind_methods() { ObjectTypeDB::bind_method("_cube_edited",&ShaderGraphView::_cube_edited); ObjectTypeDB::bind_method("_comment_edited",&ShaderGraphView::_comment_edited); + ObjectTypeDB::bind_method("_sg_updated",&ShaderGraphView::_sg_updated); } ShaderGraphView::ShaderGraphView(ShaderGraph::ShaderType p_type) { @@ -1331,8 +1371,15 @@ ShaderGraphView::ShaderGraphView(ShaderGraph::ShaderType p_type) { block_update=false; ped_popup = memnew( CustomPropertyEditor ); graph_edit->add_child(ped_popup); - - + status = memnew( Label ); + graph_edit->get_top_layer()->add_child(status); + status->set_pos(Vector2(5,5)); + status->add_color_override("font_color_shadow",Color(0,0,0)); + status->add_color_override("font_color",Color(1,0.4,0.3)); + status->add_constant_override("shadow_as_outline",1); + status->add_constant_override("shadow_offset_x",2); + status->add_constant_override("shadow_offset_y",2); + status->set_text(""); } @@ -1423,7 +1470,7 @@ ShaderGraphEditor::ShaderGraphEditor() { HBoxContainer *hbc = memnew( HBoxContainer ); menu = memnew( MenuButton ); - menu->set_text("Add.."); + menu->set_text("Add Node.."); hbc->add_child(menu); add_child(hbc); @@ -1445,6 +1492,7 @@ ShaderGraphEditor::ShaderGraphEditor() { graph_edits[i]->get_graph_edit()->connect("connection_request",graph_edits[i],"_connection_request"); graph_edits[i]->get_graph_edit()->connect("disconnection_request",graph_edits[i],"_disconnection_request"); graph_edits[i]->get_graph_edit()->set_right_disconnects(true); + } tabs->set_current_tab(1); diff --git a/tools/editor/plugins/shader_graph_editor_plugin.h b/tools/editor/plugins/shader_graph_editor_plugin.h index 8be3b3293e..bd983c59be 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.h +++ b/tools/editor/plugins/shader_graph_editor_plugin.h @@ -54,6 +54,7 @@ class ShaderGraphView : public Node { CustomPropertyEditor *ped_popup; bool block_update; + Label *status; GraphEdit *graph_edit; Ref<ShaderGraph> graph; int edited_id; @@ -95,7 +96,7 @@ class ShaderGraphView : public Node { void _variant_edited(); void _comment_edited(int p_id,Node* p_button); - + void _sg_updated(); Map<int,GraphNode*> node_map; protected: void _notification(int p_what); |