diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index b1118384a308..965a6ebbf78c 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/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, RID> &p_material_map) { + Ref 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, RID> kv : material_tiles_draw) { + RS::get_singleton()->free(kv.value); + } + material_tiles_draw.clear(); + + for (KeyValue, RID> kv : material_alternatives_draw) { + RS::get_singleton()->free(kv.value); + } + material_alternatives_draw.clear(); +} + void TileAtlasView::_draw_base_tiles_texture_grid() { Ref 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; @@ -405,6 +438,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; } @@ -695,3 +730,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(); +} diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h index 0e2ae49f0a0a..e5b088af6138 100644 --- a/editor/plugins/tiles/tile_atlas_view.h +++ b/editor/plugins/tiles/tile_atlas_view.h @@ -89,7 +89,11 @@ class TileAtlasView : public Control { Control *base_tiles_drawing_root = nullptr; Control *base_tiles_draw = nullptr; + HashMap, RID> material_tiles_draw; + HashMap, 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, RID> &p_material_map); + void _clear_material_canvas_items(); Control *base_tiles_texture_grid = nullptr; void _draw_base_tiles_texture_grid(); @@ -164,6 +168,7 @@ class TileAtlasView : public Control { void queue_redraw(); TileAtlasView(); + ~TileAtlasView(); }; #endif // TILE_ATLAS_VIEW_H