Browse Source

Draw materials in tile atlas view

(cherry picked from commit 16ac217aa0a5a45881639a5446158ab4bd895bbc)
kobewi 2 years ago
parent
commit
9acd4cfdfc
2 changed files with 46 additions and 2 deletions
  1. 41 2
      editor/plugins/tiles/tile_atlas_view.cpp
  2. 5 0
      editor/plugins/tiles/tile_atlas_view.h

+ 41 - 2
editor/plugins/tiles/tile_atlas_view.cpp

@@ -244,13 +244,16 @@ void TileAtlasView::_draw_base_tiles() {
 		for (int i = 0; i < tile_set_atlas_source->get_tiles_count(); i++) {
 			Vector2i atlas_coords = tile_set_atlas_source->get_tile_id(i);
 
+			// Different materials need to be drawn with different CanvasItems.
+			RID ci_rid = _get_canvas_item_to_draw(tile_set_atlas_source->get_tile_data(atlas_coords, 0), base_tiles_draw, material_tiles_draw);
+
 			for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(atlas_coords); frame++) {
 				// Update the y to max value.
 				Rect2i base_frame_rect = tile_set_atlas_source->get_tile_texture_region(atlas_coords, frame);
 				Vector2 offset_pos = Rect2(base_frame_rect).get_center() + Vector2(tile_set_atlas_source->get_tile_data(atlas_coords, 0)->get_texture_origin());
 
 				// Draw the tile.
-				TileMap::draw_tile(base_tiles_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, 0, frame);
+				TileMap::draw_tile(ci_rid, offset_pos, tile_set, source_id, atlas_coords, 0, frame);
 			}
 		}
 
@@ -286,6 +289,33 @@ void TileAtlasView::_draw_base_tiles() {
 	}
 }
 
+RID TileAtlasView::_get_canvas_item_to_draw(const TileData *p_for_data, const CanvasItem *p_base_item, HashMap<Ref<Material>, RID> &p_material_map) {
+	Ref<Material> mat = p_for_data->get_material();
+	if (mat.is_null()) {
+		return p_base_item->get_canvas_item();
+	} else if (p_material_map.has(mat)) {
+		return p_material_map[mat];
+	} else {
+		RID ci_rid = RS::get_singleton()->canvas_item_create();
+		RS::get_singleton()->canvas_item_set_parent(ci_rid, p_base_item->get_canvas_item());
+		RS::get_singleton()->canvas_item_set_material(ci_rid, mat->get_rid());
+		p_material_map[mat] = ci_rid;
+		return ci_rid;
+	}
+}
+
+void TileAtlasView::_clear_material_canvas_items() {
+	for (KeyValue<Ref<Material>, RID> kv : material_tiles_draw) {
+		RS::get_singleton()->free(kv.value);
+	}
+	material_tiles_draw.clear();
+
+	for (KeyValue<Ref<Material>, RID> kv : material_alternatives_draw) {
+		RS::get_singleton()->free(kv.value);
+	}
+	material_alternatives_draw.clear();
+}
+
 void TileAtlasView::_draw_base_tiles_texture_grid() {
 	Ref<Texture2D> texture = tile_set_atlas_source->get_texture();
 	if (texture.is_valid()) {
@@ -370,6 +400,9 @@ void TileAtlasView::_draw_alternatives() {
 				TileData *tile_data = tile_set_atlas_source->get_tile_data(atlas_coords, alternative_id);
 				bool transposed = tile_data->get_transpose();
 
+				// Different materials need to be drawn with different CanvasItems.
+				RID ci_rid = _get_canvas_item_to_draw(tile_data, alternatives_draw, material_alternatives_draw);
+
 				// Update the y to max value.
 				Vector2i offset_pos;
 				if (transposed) {
@@ -381,7 +414,7 @@ void TileAtlasView::_draw_alternatives() {
 				}
 
 				// Draw the tile.
-				TileMap::draw_tile(alternatives_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, alternative_id);
+				TileMap::draw_tile(ci_rid, offset_pos, tile_set, source_id, atlas_coords, alternative_id);
 
 				// Increment the x position.
 				current_pos.x += transposed ? texture_region_size.y : texture_region_size.x;
@@ -407,6 +440,8 @@ void TileAtlasView::set_atlas_source(TileSet *p_tile_set, TileSetAtlasSource *p_
 	tile_set = p_tile_set;
 	tile_set_atlas_source = p_tile_set_atlas_source;
 
+	_clear_material_canvas_items();
+
 	if (!tile_set) {
 		return;
 	}
@@ -690,3 +725,7 @@ TileAtlasView::TileAtlasView() {
 	alternatives_draw->connect("draw", callable_mp(this, &TileAtlasView::_draw_alternatives));
 	alternative_tiles_drawing_root->add_child(alternatives_draw);
 }
+
+TileAtlasView::~TileAtlasView() {
+	_clear_material_canvas_items();
+}

+ 5 - 0
editor/plugins/tiles/tile_atlas_view.h

@@ -89,7 +89,11 @@ private:
 	Control *base_tiles_drawing_root = nullptr;
 
 	Control *base_tiles_draw = nullptr;
+	HashMap<Ref<Material>, RID> material_tiles_draw;
+	HashMap<Ref<Material>, RID> material_alternatives_draw;
 	void _draw_base_tiles();
+	RID _get_canvas_item_to_draw(const TileData *p_for_data, const CanvasItem *p_base_item, HashMap<Ref<Material>, RID> &p_material_map);
+	void _clear_material_canvas_items();
 
 	Control *base_tiles_texture_grid = nullptr;
 	void _draw_base_tiles_texture_grid();
@@ -157,6 +161,7 @@ public:
 	void queue_redraw();
 
 	TileAtlasView();
+	~TileAtlasView();
 };
 
 #endif // TILE_ATLAS_VIEW_H