diff options
Diffstat (limited to 'scene/2d/canvas_item.cpp')
-rw-r--r-- | scene/2d/canvas_item.cpp | 366 |
1 files changed, 274 insertions, 92 deletions
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 44a7e25725..c3ff03d8f4 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -36,6 +36,191 @@ #include "scene/resources/texture.h" #include "scene/resources/style_box.h" + +bool CanvasItemMaterial::_set(const StringName& p_name, const Variant& p_value) { + + if (p_name==SceneStringNames::get_singleton()->shader_shader) { + set_shader(p_value); + return true; + } else if (p_name==SceneStringNames::get_singleton()->shader_unshaded) { + set_unshaded(p_value); + return true; + } else { + + if (shader.is_valid()) { + + + StringName pr = shader->remap_param(p_name); + if (!pr) { + String n = p_name; + if (n.find("param/")==0) { //backwards compatibility + pr = n.substr(6,n.length()); + } + } + if (pr) { + VisualServer::get_singleton()->canvas_item_material_set_shader_param(material,pr,p_value); + return true; + } + } + } + + return false; +} + +bool CanvasItemMaterial::_get(const StringName& p_name,Variant &r_ret) const { + + + if (p_name==SceneStringNames::get_singleton()->shader_shader) { + + r_ret=get_shader(); + return true; + } else if (p_name==SceneStringNames::get_singleton()->shader_unshaded) { + + + r_ret=unshaded; + return true; + } else { + + if (shader.is_valid()) { + + StringName pr = shader->remap_param(p_name); + if (pr) { + r_ret=VisualServer::get_singleton()->canvas_item_material_get_shader_param(material,pr); + return true; + } + } + + } + + + return false; +} + + +void CanvasItemMaterial::_get_property_list( List<PropertyInfo> *p_list) const { + + p_list->push_back( PropertyInfo( Variant::OBJECT, "shader/shader", PROPERTY_HINT_RESOURCE_TYPE,"CanvasItemShader,CanvasItemShaderGraph" ) ); + p_list->push_back( PropertyInfo( Variant::BOOL, "shader/unshaded") ); + + if (!shader.is_null()) { + + shader->get_param_list(p_list); + } + +} + +void CanvasItemMaterial::set_shader(const Ref<Shader>& p_shader) { + + ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode()!=Shader::MODE_CANVAS_ITEM); +#ifdef TOOLS_ENABLED + + if (shader.is_valid()) { + shader->disconnect("changed",this,"_shader_changed"); + } +#endif + shader=p_shader; + +#ifdef TOOLS_ENABLED + + if (shader.is_valid()) { + shader->connect("changed",this,"_shader_changed"); + } +#endif + + RID rid; + if (shader.is_valid()) + rid=shader->get_rid(); + + VS::get_singleton()->canvas_item_material_set_shader(material,rid); + _change_notify(); //properties for shader exposed + emit_changed(); +} + +Ref<Shader> CanvasItemMaterial::get_shader() const{ + + return shader; +} + +void CanvasItemMaterial::set_shader_param(const StringName& p_param,const Variant& p_value){ + + VS::get_singleton()->canvas_item_material_set_shader_param(material,p_param,p_value); +} + +Variant CanvasItemMaterial::get_shader_param(const StringName& p_param) const{ + + return VS::get_singleton()->canvas_item_material_get_shader_param(material,p_param); +} + +void CanvasItemMaterial::_shader_changed() { + + +} + +RID CanvasItemMaterial::get_rid() const { + + return material; +} + +void CanvasItemMaterial::set_unshaded(bool p_unshaded) { + + unshaded=p_unshaded; + VS::get_singleton()->canvas_item_material_set_unshaded(material,p_unshaded); +} + +bool CanvasItemMaterial::is_unshaded() const{ + + return unshaded; +} + +void CanvasItemMaterial::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_shader","shader:Shader"),&CanvasItemMaterial::set_shader); + ObjectTypeDB::bind_method(_MD("get_shader:Shader"),&CanvasItemMaterial::get_shader); + ObjectTypeDB::bind_method(_MD("set_shader_param","param","value"),&CanvasItemMaterial::set_shader_param); + ObjectTypeDB::bind_method(_MD("get_shader_param","param"),&CanvasItemMaterial::get_shader_param); + ObjectTypeDB::bind_method(_MD("set_unshaded","unshaded"),&CanvasItemMaterial::set_unshaded); + ObjectTypeDB::bind_method(_MD("is_unshaded"),&CanvasItemMaterial::is_unshaded); + +} + +void CanvasItemMaterial::get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const { + + String f = p_function.operator String(); + if ((f=="get_shader_param" || f=="set_shader_param") && p_idx==0) { + + if (shader.is_valid()) { + List<PropertyInfo> pl; + shader->get_param_list(&pl); + for (List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { + r_options->push_back("\""+E->get().name.replace_first("shader_param/","")+"\""); + } + } + } + Resource::get_argument_options(p_function,p_idx,r_options); +} + +CanvasItemMaterial::CanvasItemMaterial() { + + material=VS::get_singleton()->canvas_item_material_create(); + unshaded=false; +} + +CanvasItemMaterial::~CanvasItemMaterial(){ + + VS::get_singleton()->free(material); +} + + + + + + + + +/////////////////////////////////////////////////////////////////// + + + bool CanvasItem::is_visible() const { if (!is_inside_tree()) @@ -458,6 +643,16 @@ CanvasItem::BlendMode CanvasItem::get_blend_mode() const { return blend_mode; } +void CanvasItem::set_light_mask(int p_light_mask) { + + light_mask=p_light_mask; + VS::get_singleton()->canvas_item_set_light_mask(canvas_item,p_light_mask); +} + +int CanvasItem::get_light_mask() const{ + + return light_mask; +} void CanvasItem::item_rect_changed() { @@ -511,7 +706,7 @@ void CanvasItem::draw_texture(const Ref<Texture>& p_texture,const Point2& p_pos) p_texture->draw(canvas_item,p_pos); } -void CanvasItem::draw_texture_rect(const Ref<Texture>& p_texture,const Rect2& p_rect, bool p_tile,const Color& p_modulate) { +void CanvasItem::draw_texture_rect(const Ref<Texture>& p_texture,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -519,17 +714,17 @@ void CanvasItem::draw_texture_rect(const Ref<Texture>& p_texture,const Rect2& p_ } ERR_FAIL_COND(p_texture.is_null()); - p_texture->draw_rect(canvas_item,p_rect,p_tile,p_modulate); + p_texture->draw_rect(canvas_item,p_rect,p_tile,p_modulate,p_transpose); } -void CanvasItem::draw_texture_rect_region(const Ref<Texture>& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) { +void CanvasItem::draw_texture_rect_region(const Ref<Texture>& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL(); } ERR_FAIL_COND(p_texture.is_null()); - p_texture->draw_rect_region(canvas_item,p_rect,p_src_rect,p_modulate); + p_texture->draw_rect_region(canvas_item,p_rect,p_src_rect,p_modulate,p_transpose); } void CanvasItem::draw_style_box(const Ref<StyleBox>& p_style_box,const Rect2& p_rect) { @@ -720,110 +915,94 @@ bool CanvasItem::is_draw_behind_parent_enabled() const{ return behind; } -void CanvasItem::set_shader(const Ref<Shader>& p_shader) { - - ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode()!=Shader::MODE_CANVAS_ITEM); - -#ifdef TOOLS_ENABLED +void CanvasItem::set_material(const Ref<CanvasItemMaterial>& p_material) { - if (shader.is_valid()) { - shader->disconnect("changed",this,"_shader_changed"); - } -#endif - shader=p_shader; - -#ifdef TOOLS_ENABLED - - if (shader.is_valid()) { - shader->connect("changed",this,"_shader_changed"); - } -#endif + material=p_material; RID rid; - if (shader.is_valid()) - rid=shader->get_rid(); - VS::get_singleton()->canvas_item_set_shader(canvas_item,rid); - _change_notify(); //properties for shader exposed + if (material.is_valid()) + rid=material->get_rid(); + VS::get_singleton()->canvas_item_set_material(canvas_item,rid); + _change_notify(); //properties for material exposed } -void CanvasItem::set_use_parent_shader(bool p_use_parent_shader) { +void CanvasItem::set_use_parent_material(bool p_use_parent_material) { - use_parent_shader=p_use_parent_shader; - VS::get_singleton()->canvas_item_set_use_parent_shader(canvas_item,p_use_parent_shader); + use_parent_material=p_use_parent_material; + VS::get_singleton()->canvas_item_set_use_parent_material(canvas_item,p_use_parent_material); } -bool CanvasItem::get_use_parent_shader() const{ +bool CanvasItem::get_use_parent_material() const{ - return use_parent_shader; + return use_parent_material; } -Ref<Shader> CanvasItem::get_shader() const{ +Ref<CanvasItemMaterial> CanvasItem::get_material() const{ - return shader; + return material; } -void CanvasItem::set_shader_param(const StringName& p_param,const Variant& p_value) { - VS::get_singleton()->canvas_item_set_shader_param(canvas_item,p_param,p_value); -} - -Variant CanvasItem::get_shader_param(const StringName& p_param) const { - - return VS::get_singleton()->canvas_item_get_shader_param(canvas_item,p_param); -} - -bool CanvasItem::_set(const StringName& p_name, const Variant& p_value) { +InputEvent CanvasItem::make_input_local(const InputEvent& p_event) const { - if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); - if (pr) { - set_shader_param(pr,p_value); - return true; - } - } - return false; -} + ERR_FAIL_COND_V(!is_inside_tree(),p_event); -bool CanvasItem::_get(const StringName& p_name,Variant &r_ret) const{ + InputEvent ev = p_event; - if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); - if (pr) { - r_ret=get_shader_param(pr); - return true; - } - } - return false; + Matrix32 local_matrix = (get_canvas_transform() * get_global_transform()).affine_inverse(); -} -void CanvasItem::_get_property_list( List<PropertyInfo> *p_list) const{ + switch(ev.type) { - if (shader.is_valid()) { - shader->get_param_list(p_list); - } -} + case InputEvent::MOUSE_BUTTON: { -#ifdef TOOLS_ENABLED -void CanvasItem::_shader_changed() { + Vector2 g = local_matrix.xform(Vector2(ev.mouse_button.global_x,ev.mouse_button.global_y)); + Vector2 l = local_matrix.xform(Vector2(ev.mouse_button.x,ev.mouse_button.y)); + ev.mouse_button.x=l.x; + ev.mouse_button.y=l.y; + ev.mouse_button.global_x=g.x; + ev.mouse_button.global_y=g.y; - _change_notify(); -} -#endif + } break; + case InputEvent::MOUSE_MOTION: { + + Vector2 g = local_matrix.xform(Vector2(ev.mouse_motion.global_x,ev.mouse_motion.global_y)); + Vector2 l = local_matrix.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y)); + Vector2 r = local_matrix.basis_xform(Vector2(ev.mouse_motion.relative_x,ev.mouse_motion.relative_y)); + Vector2 s = local_matrix.basis_xform(Vector2(ev.mouse_motion.speed_x,ev.mouse_motion.speed_y)); + ev.mouse_motion.x=l.x; + ev.mouse_motion.y=l.y; + ev.mouse_motion.global_x=g.x; + ev.mouse_motion.global_y=g.y; + ev.mouse_motion.relative_x=r.x; + ev.mouse_motion.relative_y=r.y; + ev.mouse_motion.speed_x=s.x; + ev.mouse_motion.speed_y=s.y; -void CanvasItem::get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const { + } break; + case InputEvent::SCREEN_TOUCH: { - if (p_idx==0 && shader.is_valid() && (p_function.operator String()=="get_shader_param" || p_function.operator String()=="set_shader_param")) { - List<PropertyInfo> pl; - shader->get_param_list(&pl); - for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { - r_options->push_back("\""+E->get().name.replace_first("shader_param/","")+"\""); - } + Vector2 t = local_matrix.xform(Vector2(ev.screen_touch.x,ev.screen_touch.y)); + ev.screen_touch.x=t.x; + ev.screen_touch.y=t.y; - return; + } break; + case InputEvent::SCREEN_DRAG: { + + + Vector2 t = local_matrix.xform(Vector2(ev.screen_drag.x,ev.screen_drag.y)); + Vector2 r = local_matrix.basis_xform(Vector2(ev.screen_drag.relative_x,ev.screen_drag.relative_y)); + Vector2 s = local_matrix.basis_xform(Vector2(ev.screen_drag.speed_x,ev.screen_drag.speed_y)); + ev.screen_drag.x=t.x; + ev.screen_drag.y=t.y; + ev.screen_drag.relative_x=r.x; + ev.screen_drag.relative_y=r.y; + ev.screen_drag.speed_x=s.x; + ev.screen_drag.speed_y=s.y; + } break; } - Node::get_argument_options(p_function,p_idx,r_options); + return ev; } @@ -857,6 +1036,9 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_blend_mode","blend_mode"),&CanvasItem::set_blend_mode); ObjectTypeDB::bind_method(_MD("get_blend_mode"),&CanvasItem::get_blend_mode); + ObjectTypeDB::bind_method(_MD("set_light_mask","light_mask"),&CanvasItem::set_light_mask); + ObjectTypeDB::bind_method(_MD("get_light_mask"),&CanvasItem::get_light_mask); + ObjectTypeDB::bind_method(_MD("set_opacity","opacity"),&CanvasItem::set_opacity); ObjectTypeDB::bind_method(_MD("get_opacity"),&CanvasItem::get_opacity); ObjectTypeDB::bind_method(_MD("set_self_opacity","self_opacity"),&CanvasItem::set_self_opacity); @@ -867,9 +1049,6 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("_set_on_top","on_top"),&CanvasItem::_set_on_top); ObjectTypeDB::bind_method(_MD("_is_on_top"),&CanvasItem::_is_on_top); -#ifdef TOOLS_ENABLED - ObjectTypeDB::bind_method(_MD("_shader_changed"),&CanvasItem::_shader_changed); -#endif //ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform); ObjectTypeDB::bind_method(_MD("draw_line","from","to","color","width"),&CanvasItem::draw_line,DEFVAL(1.0)); @@ -888,20 +1067,21 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("draw_set_transform","pos","rot","scale"),&CanvasItem::draw_set_transform); ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform); ObjectTypeDB::bind_method(_MD("get_global_transform"),&CanvasItem::get_global_transform); + ObjectTypeDB::bind_method(_MD("get_global_transform_with_canvas"),&CanvasItem::get_global_transform_with_canvas); ObjectTypeDB::bind_method(_MD("get_viewport_transform"),&CanvasItem::get_viewport_transform); ObjectTypeDB::bind_method(_MD("get_viewport_rect"),&CanvasItem::get_viewport_rect); + ObjectTypeDB::bind_method(_MD("get_canvas_transform"),&CanvasItem::get_canvas_transform); ObjectTypeDB::bind_method(_MD("get_canvas"),&CanvasItem::get_canvas); ObjectTypeDB::bind_method(_MD("get_world_2d"),&CanvasItem::get_world_2d); //ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasItem::get_viewport); - ObjectTypeDB::bind_method(_MD("set_shader","shader"),&CanvasItem::set_shader); - ObjectTypeDB::bind_method(_MD("get_shader"),&CanvasItem::get_shader); - ObjectTypeDB::bind_method(_MD("set_use_parent_shader","enable"),&CanvasItem::set_use_parent_shader); - ObjectTypeDB::bind_method(_MD("get_use_parent_shader"),&CanvasItem::get_use_parent_shader); + ObjectTypeDB::bind_method(_MD("set_material","material:CanvasItemMaterial"),&CanvasItem::set_material); + ObjectTypeDB::bind_method(_MD("get_material:CanvasItemMaterial"),&CanvasItem::get_material); - ObjectTypeDB::bind_method(_MD("set_shader_param","param","value"),&CanvasItem::set_shader_param); - ObjectTypeDB::bind_method(_MD("get_shader_param","param"),&CanvasItem::get_shader_param); + ObjectTypeDB::bind_method(_MD("set_use_parent_material","enable"),&CanvasItem::set_use_parent_material); + ObjectTypeDB::bind_method(_MD("get_use_parent_material"),&CanvasItem::get_use_parent_material); + ObjectTypeDB::bind_method(_MD("make_input_local","event"),&CanvasItem::make_input_local); BIND_VMETHOD(MethodInfo("_draw")); @@ -912,8 +1092,9 @@ void CanvasItem::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top",PROPERTY_HINT_NONE,"",0), _SCS("_set_on_top"),_SCS("_is_on_top") ); //compatibility ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"),_SCS("get_blend_mode") ); - ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"shader/shader",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemShader,CanvasItemShaderGraph"), _SCS("set_shader"),_SCS("get_shader") ); - ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"shader/use_parent"), _SCS("set_use_parent_shader"),_SCS("get_use_parent_shader") ); + ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/light_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_light_mask"),_SCS("get_light_mask") ); + ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"material/material",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial"), _SCS("set_material"),_SCS("get_material") ); + ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"material/use_parent"), _SCS("set_use_parent_material"),_SCS("get_use_parent_material") ); //exporting these two things doesn't really make much sense i think //ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transform/toplevel"), _SCS("set_as_toplevel"),_SCS("is_set_as_toplevel") ); //ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),_SCS("set_transform_notify"),_SCS("is_transform_notify_enabled")); @@ -990,8 +1171,9 @@ CanvasItem::CanvasItem() : xform_change(this) { block_transform_notify=false; // viewport=NULL; canvas_layer=NULL; - use_parent_shader=false; + use_parent_material=false; global_invalid=true; + light_mask=1; C=NULL; |