浏览代码

Fix rendering tiles using nested AtlasTextures

kleonc 2 年之前
父节点
当前提交
12c923cb8b
共有 3 个文件被更改,包括 32 次插入20 次删除
  1. 9 8
      scene/2d/tile_map.cpp
  2. 21 11
      scene/resources/texture.cpp
  3. 2 1
      scene/resources/texture.h

+ 9 - 8
scene/2d/tile_map.cpp

@@ -564,18 +564,19 @@ void TileMap::update_dirty_quadrants() {
 			}
 
 			Ref<Texture> 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<TileSet::ShapeData> shapes = tile_set->tile_get_shapes(c.id);

+ 21 - 11
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<Texture> &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;

+ 2 - 1
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<Texture> &p_normal_map = Ref<Texture>()) 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<Texture> &p_normal_map = Ref<Texture>(), 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<Image> get_data() const { return Ref<Image>(); }
 
@@ -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<Texture> &p_normal_map = Ref<Texture>()) 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<Texture> &p_normal_map = Ref<Texture>(), 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<Texture> &p_normal_map = Ref<Texture>()) 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<Texture> &p_normal_map = Ref<Texture>()) 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<Texture> &p_normal_map = Ref<Texture>(), 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;