From 1f3d6824c8db30cd5636aaa3978a953bedff4ed8 Mon Sep 17 00:00:00 2001 From: MarianoGNU Date: Sun, 20 Dec 2015 18:21:53 -0300 Subject: [PATCH] Move shaders to default theme and add shader_override related methods to Control class --- scene/gui/color_picker.cpp | 49 ++-------- scene/gui/control.cpp | 94 ++++++++++++++++++- scene/gui/control.h | 6 +- .../resources/default_theme/default_theme.cpp | 11 ++- .../{make_png_header.py => make_header.py} | 57 ++++++++--- scene/resources/default_theme/theme_data.h | 39 ++++++++ scene/resources/default_theme/uv_editor.gsl | 19 ++++ scene/resources/default_theme/w_editor.gsl | 11 +++ scene/resources/theme.cpp | 45 +++++++++ scene/resources/theme.h | 10 +- 10 files changed, 282 insertions(+), 59 deletions(-) rename scene/resources/default_theme/{make_png_header.py => make_header.py} (53%) create mode 100644 scene/resources/default_theme/uv_editor.gsl create mode 100644 scene/resources/default_theme/w_editor.gsl diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 1bdb6c458f1..2acb7b4bfd0 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -38,6 +38,10 @@ void ColorPicker::_notification(int p_what) { switch(p_what) { case NOTIFICATION_THEME_CHANGED: { + uv_material->set_shader(get_shader("uv_editor")); + uv_material->set_shader_param("H", h); + + w_material->set_shader(get_shader("w_editor")); _update_controls(); } break; @@ -337,55 +341,16 @@ ColorPicker::ColorPicker() : _update_color(); updating=false; - const char *uv_shader_code= - "vec3 nd1sl2=vec3(UV,0);\n" - "uniform float H=0;\n" - "float nd4sl0=H;\n" - "float nd7sl0=nd1sl2.x;\n" - "float nd7sl1=nd1sl2.y;\n" - "float nd7sl2=nd1sl2.z;\n" - "float nd2sl1def=-1;\n" - "float nd2sl0=nd7sl1*nd2sl1def;\n" - "float nd6sl1def=1;\n" - "float nd6sl0=nd2sl0+nd6sl1def;\n" - "vec3 nd3sl0=vec3(nd4sl0,nd7sl0,nd6sl0);\n" - "vec3 nd5sl0;\n" - "{\n" - " vec3 c = nd3sl0;\n" - " vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n" - " vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n" - " nd5sl0=c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n" - "}\n" - "COLOR.rgb=nd5sl0;"; - - const char *w_shader_code= - "vec3 nd1sl2=vec3(UV,0);\n" - "float nd2sl0=nd1sl2.x;\n" - "float nd2sl1=nd1sl2.y;\n" - "float nd2sl2=nd1sl2.z;\n" - "float nd3sl1def=1;\n" - "float nd3sl2def=1;\n" - "vec3 nd3sl0=vec3(nd2sl1,nd3sl1def,nd3sl2def);\n" - "vec3 nd6sl0;\n" - "{\n" - " vec3 c = nd3sl0;\n" - " vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n" - " vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n" - " nd6sl0=c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n" - "}\n" - "COLOR.rgb=nd6sl0;"; - set_color(Color(1,1,1)); uv_material.instance(); - Ref s_uv = memnew( Shader(Shader::MODE_CANVAS_ITEM) ); - s_uv->set_code("", uv_shader_code, ""); + Ref s_uv = get_shader("uv_editor"); uv_material->set_shader(s_uv); uv_material->set_shader_param("H", h); w_material.instance(); - Ref s_w = (memnew( Shader(Shader::MODE_CANVAS_ITEM) )); - s_w->set_code("", w_shader_code, ""); + + Ref s_w = get_shader("w_editor"); w_material->set_shader(s_w); uv_edit->set_material(uv_material); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 5a8ecfeffee..e93b2529799 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -140,6 +140,11 @@ bool Control::_set(const StringName& p_name, const Variant& p_value) { data.icon_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); update(); + } else if (name.begins_with("custom_shaders/")) { + String dname = name.get_slicec('/',1); + data.shader_override.erase(dname); + notification(NOTIFICATION_THEME_CHANGED); + update(); } else if (name.begins_with("custom_styles/")) { String dname = name.get_slicec('/',1); data.style_override.erase(dname); @@ -168,6 +173,10 @@ bool Control::_set(const StringName& p_name, const Variant& p_value) { String dname = name.get_slicec('/',1); notification(NOTIFICATION_THEME_CHANGED); add_icon_override(dname,p_value); + } else if (name.begins_with("custom_shaders/")) { + String dname = name.get_slicec('/',1); + add_shader_override(dname,p_value); + notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("custom_styles/")) { String dname = name.get_slicec('/',1); add_style_override(dname,p_value); @@ -220,6 +229,10 @@ bool Control::_get(const StringName& p_name,Variant &r_ret) const { String name = sname.get_slicec('/',1); r_ret= data.icon_override.has(name)?Variant(data.icon_override[name]):Variant(); + } else if (sname.begins_with("custom_shaders/")) { + String name = sname.get_slicec('/',1); + + r_ret= data.shader_override.has(name)?Variant(data.shader_override[name]):Variant(); } else if (sname.begins_with("custom_styles/")) { String name = sname.get_slicec('/',1); @@ -267,6 +280,18 @@ void Control::_get_property_list( List *p_list) const { p_list->push_back( PropertyInfo(Variant::OBJECT,"custom_icons/"+E->get(),PROPERTY_HINT_RESOURCE_TYPE, "Texture",hint) ); } } + { + List names; + theme->get_shader_list(get_type_name(),&names); + for(List::Element *E=names.front();E;E=E->next()) { + + uint32_t hint= PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_CHECKABLE; + if (data.shader_override.has(E->get())) + hint|=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_CHECKED; + + p_list->push_back( PropertyInfo(Variant::OBJECT,"custom_shaders/"+E->get(),PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemShader,CanvasItemShaderGraph",hint) ); + } + } { List names; theme->get_stylebox_list(get_type_name(),&names); @@ -1384,6 +1409,35 @@ Ref Control::get_icon(const StringName& p_name,const StringName& p_type } +Ref Control::get_shader(const StringName& p_name,const StringName& p_type) const { + if (p_type==StringName()) { + + const Ref* sdr = data.shader_override.getptr(p_name); + if (sdr) + return *sdr; + } + + StringName type = p_type?p_type:get_type_name(); + + // try with custom themes + Control *theme_owner = data.theme_owner; + + while(theme_owner) { + + if (theme_owner->data.theme->has_shader(p_name, type)) + return data.theme_owner->data.theme->get_shader(p_name, type ); + Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to():NULL; + + if (parent) + theme_owner=parent->data.theme_owner; + else + theme_owner=NULL; + + } + + return Theme::get_default()->get_shader( p_name, type ); +} + Ref Control::get_stylebox(const StringName& p_name,const StringName& p_type) const { if (p_type==StringName()) { @@ -1530,7 +1584,37 @@ bool Control::has_icon(const StringName& p_name,const StringName& p_type) const } return Theme::get_default()->has_icon( p_name, type ); + +} +bool Control::has_shader(const StringName &p_name, const StringName &p_type) const +{ + if (p_type==StringName()) { + const Ref* sdr = data.shader_override.getptr(p_name); + if (sdr) + return true; + } + + StringName type = p_type?p_type:get_type_name(); + + // try with custom themes + Control *theme_owner = data.theme_owner; + + while(theme_owner) { + + if (theme_owner->data.theme->has_shader(p_name, type)) + return true; + Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to():NULL; + + if (parent) + theme_owner=parent->data.theme_owner; + else + theme_owner=NULL; + + } + + return Theme::get_default()->has_shader( p_name, type ); + } bool Control::has_stylebox(const StringName& p_name,const StringName& p_type) const { @@ -1996,7 +2080,14 @@ void Control::add_icon_override(const StringName& p_name, const Ref& p_ data.icon_override[p_name]=p_icon; notification(NOTIFICATION_THEME_CHANGED); update(); + +} +void Control::add_shader_override(const StringName &p_name, const Ref &p_shader) { + ERR_FAIL_COND(p_shader.is_null()); + data.shader_override[p_name]=p_shader; + notification(NOTIFICATION_THEME_CHANGED); + update(); } void Control::add_style_override(const StringName& p_name, const Ref& p_style) { @@ -2837,8 +2928,9 @@ void Control::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_theme","theme:Theme"),&Control::set_theme); ObjectTypeDB::bind_method(_MD("get_theme:Theme"),&Control::get_theme); - + ObjectTypeDB::bind_method(_MD("add_icon_override","name","texture:Texture"),&Control::add_icon_override); + ObjectTypeDB::bind_method(_MD("add_shader_override","name","shader:Shader"),&Control::add_shader_override); ObjectTypeDB::bind_method(_MD("add_style_override","name","stylebox:StyleBox"),&Control::add_style_override); ObjectTypeDB::bind_method(_MD("add_font_override","name","font:Font"),&Control::add_font_override); ObjectTypeDB::bind_method(_MD("add_color_override","name","color"),&Control::add_color_override); diff --git a/scene/gui/control.h b/scene/gui/control.h index 0ead632aaba..4908b07295e 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -144,6 +144,7 @@ private: NodePath focus_neighbour[4]; HashMap, StringNameHasher > icon_override; + HashMap, StringNameHasher > shader_override; HashMap, StringNameHasher > style_override; HashMap, StringNameHasher > font_override; HashMap color_override; @@ -357,18 +358,21 @@ public: /* SKINNING */ void add_icon_override(const StringName& p_name, const Ref& p_icon); + void add_shader_override(const StringName& p_name, const Ref& p_shader); void add_style_override(const StringName& p_name, const Ref& p_style); void add_font_override(const StringName& p_name, const Ref& p_font); void add_color_override(const StringName& p_name, const Color& p_color); void add_constant_override(const StringName& p_name, int p_constant); Ref get_icon(const StringName& p_name,const StringName& p_type=StringName()) const; + Ref get_shader(const StringName &p_name, const StringName &p_type=StringName()) const; Ref get_stylebox(const StringName& p_name,const StringName& p_type=StringName()) const; Ref get_font(const StringName& p_name,const StringName& p_type=StringName()) const; Color get_color(const StringName& p_name,const StringName& p_type=StringName()) const; int get_constant(const StringName& p_name,const StringName& p_type=StringName()) const; bool has_icon(const StringName& p_name,const StringName& p_type=StringName()) const; + bool has_shader(const StringName& p_name,const StringName& p_type=StringName()) const; bool has_stylebox(const StringName& p_name,const StringName& p_type=StringName()) const; bool has_font(const StringName& p_name,const StringName& p_type=StringName()) const; bool has_color(const StringName& p_name,const StringName& p_type=StringName()) const; @@ -400,7 +404,7 @@ public: Control(); ~Control(); - + }; VARIANT_ENUM_CAST(Control::AnchorType); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 842dbb154b2..2d6039ca4d4 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -80,6 +80,13 @@ static Ref make_icon(T p_src) { return texture; } +static Ref make_shader(const char*vertex_code,const char*fragment_code,const char*lighting_code) { + Ref shader = (memnew( Shader(Shader::MODE_CANVAS_ITEM) )); + shader->set_code(vertex_code, fragment_code, lighting_code); + + return shader; +} + static Ref make_font(int p_height,int p_ascent, int p_valign, int p_charcount, const int *p_chars,const Ref &p_texture) { @@ -768,7 +775,9 @@ void make_default_theme() { t->set_constant("hseparator","ColorPicker", 4); t->set_icon("screen_picker","ColorPicker", make_icon( icon_color_pick_png ) ); - + + t->set_shader("uv_editor", "ColorPicker", make_shader("", uv_editor_shader_code, "")); + t->set_shader("w_editor", "ColorPicker", make_shader("", w_editor_shader_code, "")); // TooltipPanel diff --git a/scene/resources/default_theme/make_png_header.py b/scene/resources/default_theme/make_header.py similarity index 53% rename from scene/resources/default_theme/make_png_header.py rename to scene/resources/default_theme/make_header.py index 0f0ce1808f3..2d3f989e015 100644 --- a/scene/resources/default_theme/make_png_header.py +++ b/scene/resources/default_theme/make_header.py @@ -3,9 +3,6 @@ import os; import glob; import string; -pixmaps = glob.glob("*.png"); - -pixmaps.sort(); #Generate include files @@ -15,27 +12,61 @@ f.write("// THIS FILE HAS BEEN AUTOGENERATED, DONT EDIT!!\n"); f.write("\n\n"); -f.write("\n\n\n"); - +#Generate png image block + +pixmaps = glob.glob("*.png"); + +pixmaps.sort(); + +f.write("\n\n\n"); - for x in pixmaps: - + var_str=x[:-4]+"_png"; - + f.write("static const unsigned char "+ var_str +"[]={\n"); - + pngf=open(x,"rb"); - + b=pngf.read(1); while(len(b)==1): f.write(hex(ord(b))) b=pngf.read(1); if (len(b)==1): f.write(",") - + f.write("\n};\n\n\n"); pngf.close(); - -f.close(); +#Generate shaders block + +shaders = glob.glob("*.gsl") + +shaders.sort(); + +f.write("\n\n\n"); + +for x in shaders: + + var_str=x[:-4]+"_shader_code"; + + f.write("static const char *"+ var_str +"=\n"); + + sf=open(x,"rb"); + + + b=sf.readline(); + while(b!=""): + if (b.endswith("\r\n")): + b=b[:-2] + if (b.endswith("\n")): + b=b[:-1] + f.write(" \""+b) + b=sf.readline(); + if (b!=""): + f.write("\"\n") + + f.write("\";\n\n\n"); + sf.close(); + +f.close(); diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index dc69cf4b0b6..004b3e4ce88 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -524,3 +524,42 @@ static const unsigned char vsplitter_png[]={ }; + + + +static const char *uv_editor_shader_code= + "vec3 nd1sl2=vec3(UV,0);" + "uniform float H=0;" + "float nd4sl0=H;" + "float nd7sl0=nd1sl2.x;" + "float nd7sl1=nd1sl2.y;" + "float nd7sl2=nd1sl2.z;" + "float nd2sl1def=-1;" + "float nd2sl0=nd7sl1*nd2sl1def;" + "float nd6sl1def=1;" + "float nd6sl0=nd2sl0+nd6sl1def;" + "vec3 nd3sl0=vec3(nd4sl0,nd7sl0,nd6sl0);" + "vec3 nd5sl0;" + "{" + " vec3 c = nd3sl0;" + " vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);" + " vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);" + " nd5sl0=c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);" + "}" + "COLOR.rgb=nd5sl0;"; + + +static const char *w_editor_shader_code= + "vec3 nd1sl2=vec3(UV,0);" + "float nd2sl1=1-nd1sl2.y;" + "vec3 nd3sl0=vec3(nd2sl1,1,1);" + "vec3 nd6sl0;" + "{" + " vec3 c = nd3sl0;" + " vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);" + " vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);" + " nd6sl0=c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);" + "}" + "COLOR.rgb=nd6sl0;"; + + diff --git a/scene/resources/default_theme/uv_editor.gsl b/scene/resources/default_theme/uv_editor.gsl new file mode 100644 index 00000000000..8c24e76dd5c --- /dev/null +++ b/scene/resources/default_theme/uv_editor.gsl @@ -0,0 +1,19 @@ +vec3 nd1sl2=vec3(UV,0); +uniform float H=0; +float nd4sl0=H; +float nd7sl0=nd1sl2.x; +float nd7sl1=nd1sl2.y; +float nd7sl2=nd1sl2.z; +float nd2sl1def=-1; +float nd2sl0=nd7sl1*nd2sl1def; +float nd6sl1def=1; +float nd6sl0=nd2sl0+nd6sl1def; +vec3 nd3sl0=vec3(nd4sl0,nd7sl0,nd6sl0); +vec3 nd5sl0; +{ + vec3 c = nd3sl0; + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + nd5sl0=c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} +COLOR.rgb=nd5sl0; \ No newline at end of file diff --git a/scene/resources/default_theme/w_editor.gsl b/scene/resources/default_theme/w_editor.gsl new file mode 100644 index 00000000000..6d2dd9a0bba --- /dev/null +++ b/scene/resources/default_theme/w_editor.gsl @@ -0,0 +1,11 @@ +vec3 nd1sl2=vec3(UV,0); +float nd2sl1=1-nd1sl2.y; +vec3 nd3sl0=vec3(nd2sl1,1,1); +vec3 nd6sl0; +{ + vec3 c = nd3sl0; + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + nd6sl0=c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} +COLOR.rgb=nd6sl0; \ No newline at end of file diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index e2413f7d84f..685b2e07e1b 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -266,7 +266,52 @@ void Theme::get_icon_list(StringName p_type, List *p_list) const { p_list->push_back(*key); } + +} +void Theme::set_shader(const StringName &p_name,const StringName &p_type,const Ref& p_shader) { + bool new_value=!shader_map.has(p_type) || !shader_map[p_type].has(p_name); + + shader_map[p_type][p_name]=p_shader; + + if (new_value) { + _change_notify(); + emit_changed();; + } +} + +Ref Theme::get_shader(const StringName &p_name, const StringName &p_type) const { + if (shader_map.has(p_type) && shader_map[p_type].has(p_name) && shader_map[p_type][p_name].is_valid()) { + return shader_map[p_type][p_name]; + } else { + return NULL; + } +} + +bool Theme::has_shader(const StringName &p_name, const StringName &p_type) const { + return (shader_map.has(p_type) && shader_map[p_type].has(p_name) && shader_map[p_type][p_name].is_valid()); +} + +void Theme::clear_shader(const StringName &p_name, const StringName &p_type) { + ERR_FAIL_COND(!shader_map.has(p_type)); + ERR_FAIL_COND(!shader_map[p_type].has(p_name)); + + shader_map[p_type].erase(p_name); + _change_notify(); + emit_changed();; +} + +void Theme::get_shader_list(const StringName &p_type, List *p_list) const { + if (!shader_map.has(p_type)) + return; + + const StringName *key=NULL; + + while((key=shader_map[p_type].next(key))) { + + p_list->push_back(*key); + } + } diff --git a/scene/resources/theme.h b/scene/resources/theme.h index f0747fb3c47..180f55381d6 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -33,6 +33,7 @@ #include "scene/resources/font.h" #include "scene/resources/style_box.h" #include "scene/resources/texture.h" +#include "scene/resources/shader.h" #include "io/resource_loader.h" /** @@ -48,6 +49,7 @@ class Theme : public Resource { HashMap,StringNameHasher >, StringNameHasher > icon_map; HashMap,StringNameHasher >,StringNameHasher > style_map; HashMap,StringNameHasher >,StringNameHasher > font_map; + HashMap,StringNameHasher >, StringNameHasher > shader_map; HashMap,StringNameHasher > color_map; HashMap,StringNameHasher > constant_map; protected: @@ -86,7 +88,13 @@ public: bool has_icon(const StringName& p_name,const StringName& p_type) const; void clear_icon(const StringName& p_name,const StringName& p_type); void get_icon_list(StringName p_type, List *p_list) const; - + + void set_shader(const StringName& p_name,const StringName& p_type,const Ref& p_shader); + Ref get_shader(const StringName& p_name,const StringName& p_type) const; + bool has_shader(const StringName& p_name,const StringName& p_type) const; + void clear_shader(const StringName& p_name,const StringName& p_type); + void get_shader_list(const StringName& p_name, List *p_list) const; + void set_stylebox(const StringName& p_name,const StringName& p_type,const Ref& p_style); Ref get_stylebox(const StringName& p_name,const StringName& p_type) const; bool has_stylebox(const StringName& p_name,const StringName& p_type) const;