From 12c923cb8b19ca9dc49c45601e8e20630cbd8497 Mon Sep 17 00:00:00 2001 From: kleonc <9283098+kleonc@users.noreply.github.com> Date: Wed, 3 May 2023 18:16:22 +0200 Subject: [PATCH] Fix rendering tiles using nested AtlasTextures --- scene/2d/tile_map.cpp | 17 +++++++++-------- scene/resources/texture.cpp | 32 +++++++++++++++++++++----------- scene/resources/texture.h | 3 ++- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 13a923de593..8eb30f8e408 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -564,18 +564,19 @@ void TileMap::update_dirty_quadrants() { } Ref normal_map = tile_set->tile_get_normal_map(c.id); - Color modulate = tile_set->tile_get_modulate(c.id); - Color self_modulate = get_self_modulate(); - modulate = Color(modulate.r * self_modulate.r, modulate.g * self_modulate.g, - modulate.b * self_modulate.b, modulate.a * self_modulate.a); + Color modulate = tile_set->tile_get_modulate(c.id) * get_self_modulate(); if (r == Rect2()) { tex->draw_rect(canvas_item, rect, false, modulate, c.transpose, normal_map); } else { - if (!multirect_started) { - multirect_started = true; - VisualServerCanvasHelper::tilemap_begin(); + Rect2 dst_rect; + Rect2 src_rect; + if (tex->get_combined_rect_region(rect, r, dst_rect, src_rect)) { + if (!multirect_started) { + multirect_started = true; + VisualServerCanvasHelper::tilemap_begin(); + } + VisualServerCanvasHelper::tilemap_add_rect(canvas_item, dst_rect, tex->get_rid(), src_rect, modulate, c.transpose, normal_map.is_valid() ? normal_map->get_rid() : RID(), clip_uv); } - VisualServerCanvasHelper::tilemap_add_rect(canvas_item, rect, tex->get_rid(), r, modulate, c.transpose, normal_map.is_valid() ? normal_map->get_rid() : RID(), clip_uv); } Vector shapes = tile_set->tile_get_shapes(c.id); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 67e77c6c3e2..b9d8939a287 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -66,6 +66,10 @@ bool Texture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect return true; } +bool Texture::get_combined_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_combined_rect, Rect2 &r_combined_src_rect) const { + return get_rect_region(p_rect, p_src_rect, r_combined_rect, r_combined_src_rect); +} + void Texture::_bind_methods() { ClassDB::bind_method(D_METHOD("get_width"), &Texture::get_width); ClassDB::bind_method(D_METHOD("get_height"), &Texture::get_height); @@ -1029,16 +1033,15 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile atlas->draw_rect_region(p_canvas_item, dr, rc, p_modulate, p_transpose, p_normal_map); } void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map, bool p_clip_uv) const { - //this might not necessarily work well if using a rect, needs to be fixed properly if (!atlas.is_valid()) { return; } - Rect2 dr; - Rect2 src_c; - get_rect_region(p_rect, p_src_rect, dr, src_c); - - atlas->draw_rect_region(p_canvas_item, dr, src_c, p_modulate, p_transpose, p_normal_map); + Rect2 dst; + Rect2 src; + if (get_rect_region(p_rect, p_src_rect, dst, src)) { + atlas->draw_rect_region(p_canvas_item, dst, src, p_modulate, p_transpose, p_normal_map); + } } bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { @@ -1071,6 +1074,18 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, return true; } +bool AtlasTexture::get_combined_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_combined_rect, Rect2 &r_combined_src_rect) const { + if (!atlas.is_valid()) { + return false; + } + Rect2 dst; + Rect2 src; + if (get_rect_region(p_rect, p_src_rect, dst, src)) { + return atlas->get_combined_rect_region(dst, src, r_combined_rect, r_combined_src_rect); + } + return false; +} + bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const { if (!atlas.is_valid()) { return true; @@ -1197,11 +1212,6 @@ void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid); } -bool MeshTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { - r_rect = p_rect; - r_src_rect = p_src_rect; - return true; -} bool MeshTexture::is_pixel_opaque(int p_x, int p_y) const { return true; diff --git a/scene/resources/texture.h b/scene/resources/texture.h index cde6ea92795..82bab6f30c6 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -77,6 +77,7 @@ public: virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref(), bool p_clip_uv = true) const; virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const; + virtual bool get_combined_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_combined_rect, Rect2 &r_combined_src_rect) const; virtual Ref get_data() const { return Ref(); } @@ -276,6 +277,7 @@ public: virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref(), bool p_clip_uv = true) const; virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const; + virtual bool get_combined_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_combined_rect, Rect2 &r_combined_src_rect) const; bool is_pixel_opaque(int p_x, int p_y) const; @@ -317,7 +319,6 @@ public: virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref(), bool p_clip_uv = true) const; - virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const; bool is_pixel_opaque(int p_x, int p_y) const;