2
0
Эх сурвалжийг харах

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
Pedro J. Estébanez 8 жил өмнө
parent
commit
d0d0896c59

+ 2 - 2
scene/2d/canvas_item.h

@@ -253,10 +253,10 @@ public:
 	RID get_canvas() const;
 	Ref<World2D> get_world_2d() const;
 
-	void set_material(const Ref<CanvasItemMaterial> &p_material);
+	virtual void set_material(const Ref<CanvasItemMaterial> &p_material);
 	Ref<CanvasItemMaterial> 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;

+ 30 - 0
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<CanvasItemMaterial> &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<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
+
+		Quadrant &q = E->get();
+		for (List<RID>::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();

+ 7 - 0
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<int> &p_data);
@@ -278,6 +281,10 @@ public:
 
 	virtual void set_light_mask(int p_light_mask);
 
+	virtual void set_material(const Ref<CanvasItemMaterial> &p_material);
+
+	virtual void set_use_parent_material(bool p_use_parent_material);
+
 	void clear();
 
 	TileMap();