From d0d0896c59aa71c6eaea566140d1c0c1f779d44f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Tue, 15 Aug 2017 23:46:17 +0200 Subject: [PATCH] Let TileMap apply its material So when a material is set, every tile will be rendered with that. Quadrants will not be recreated, so a `CanvasItem` will exist per material per quadrant regardless a global material is set. This makes also __Use parent material__ work for `TileMap`s. Based on 3bb5abbc35b6690768f32db7becf874febc25713 --- scene/2d/canvas_item.h | 4 ++-- scene/2d/tile_map.cpp | 30 ++++++++++++++++++++++++++++++ scene/2d/tile_map.h | 7 +++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 2e53e7092f..1e58c7033e 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -253,10 +253,10 @@ public: RID get_canvas() const; Ref get_world_2d() const; - void set_material(const Ref &p_material); + virtual void set_material(const Ref &p_material); Ref get_material() const; - void set_use_parent_material(bool p_use_parent_material); + virtual void set_use_parent_material(bool p_use_parent_material); bool get_use_parent_material() const; InputEvent make_input_local(const InputEvent &pevent) const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index acc1640ce6..75fe24e0a9 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -356,6 +356,7 @@ void TileMap::_update_dirty_quadrants() { if (mat.is_valid()) vs->canvas_item_set_material(canvas_item, mat->get_rid()); vs->canvas_item_set_parent(canvas_item, get_canvas_item()); + _update_item_material_state(canvas_item); Matrix32 xform; xform.set_origin(q.pos); vs->canvas_item_set_transform(canvas_item, xform); @@ -839,6 +840,35 @@ void TileMap::_clear_quadrants() { } } +void TileMap::set_material(const Ref &p_material) { + + CanvasItem::set_material(p_material); + _update_all_items_material_state(); +} + +void TileMap::set_use_parent_material(bool p_use_parent_material) { + + CanvasItem::set_use_parent_material(p_use_parent_material); + _update_all_items_material_state(); +} + +void TileMap::_update_all_items_material_state() { + + for (Map::Element *E = quadrant_map.front(); E; E = E->next()) { + + Quadrant &q = E->get(); + for (List::Element *E = q.canvas_items.front(); E; E = E->next()) { + + _update_item_material_state(E->get()); + } + } +} + +void TileMap::_update_item_material_state(const RID &p_canvas_item) { + + VS::get_singleton()->canvas_item_set_use_parent_material(p_canvas_item, get_use_parent_material() || get_material().is_valid()); +} + void TileMap::clear() { _clear_quadrants(); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 3609058258..b8634fcebb 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -183,6 +183,9 @@ private: void _update_quadrant_transform(); void _recompute_rect_cache(); + void _update_all_items_material_state(); + _FORCE_INLINE_ void _update_item_material_state(const RID &p_canvas_item); + _FORCE_INLINE_ int _get_quadrant_size() const; void _set_tile_data(const DVector &p_data); @@ -278,6 +281,10 @@ public: virtual void set_light_mask(int p_light_mask); + virtual void set_material(const Ref &p_material); + + virtual void set_use_parent_material(bool p_use_parent_material); + void clear(); TileMap();