Browse Source

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.

Closes #9996.
Pedro J. Estébanez 8 năm trước cách đây
mục cha
commit
3bb5abbc35
3 tập tin đã thay đổi với 39 bổ sung2 xóa
  1. 2 2
      scene/2d/canvas_item.h
  2. 30 0
      scene/2d/tile_map.cpp
  3. 7 0
      scene/2d/tile_map.h

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

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

+ 30 - 0
scene/2d/tile_map.cpp

@@ -336,6 +336,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);
 				Transform2D xform;
 				xform.set_origin(q.pos);
 				vs->canvas_item_set_transform(canvas_item, xform);
@@ -782,6 +783,35 @@ void TileMap::_clear_quadrants() {
 	}
 }
 
+void TileMap::set_material(const Ref<Material> &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 PoolVector<int> &p_data);
@@ -278,6 +281,10 @@ public:
 
 	virtual void set_light_mask(int p_light_mask);
 
+	virtual void set_material(const Ref<Material> &p_material);
+
+	virtual void set_use_parent_material(bool p_use_parent_material);
+
 	void clear();
 
 	TileMap();