mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 13:41:03 +00:00 
			
		
		
		
	Fixes a canvas item set to clip children being drawn as black if no children are visible
This commit is contained in:
		
							parent
							
								
									d857005f5f
								
							
						
					
					
						commit
						f25508befb
					
				
					 3 changed files with 37 additions and 20 deletions
				
			
		|  | @ -396,6 +396,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ | |||
| 
 | ||||
| 	Item *ci = p_item_list; | ||||
| 	Item *canvas_group_owner = nullptr; | ||||
| 	bool skip_item = false; | ||||
| 
 | ||||
| 	state.last_item_index = 0; | ||||
| 
 | ||||
|  | @ -464,6 +465,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ | |||
| 					Rect2i group_rect = ci->canvas_group_owner->global_rect_cache; | ||||
| 					texture_storage->render_target_copy_to_back_buffer(p_to_render_target, group_rect, false); | ||||
| 					if (ci->canvas_group_owner->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) { | ||||
| 						ci->canvas_group_owner->use_canvas_group = false; | ||||
| 						items[item_count++] = ci->canvas_group_owner; | ||||
| 					} | ||||
| 				} else if (!backbuffer_cleared) { | ||||
|  | @ -478,9 +480,8 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ | |||
| 			ci->canvas_group_owner = nullptr; //must be cleared
 | ||||
| 		} | ||||
| 
 | ||||
| 		if (!backbuffer_cleared && canvas_group_owner == nullptr && ci->canvas_group != nullptr && !backbuffer_copy) { | ||||
| 			texture_storage->render_target_clear_back_buffer(p_to_render_target, Rect2i(), Color(0, 0, 0, 0)); | ||||
| 			backbuffer_cleared = true; | ||||
| 		if (canvas_group_owner == nullptr && ci->canvas_group != nullptr && ci->canvas_group->mode != RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) { | ||||
| 			skip_item = true; | ||||
| 		} | ||||
| 
 | ||||
| 		if (ci == canvas_group_owner) { | ||||
|  | @ -498,6 +499,11 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ | |||
| 			canvas_group_owner = nullptr; | ||||
| 			// Backbuffer is dirty now and needs to be re-cleared if another CanvasGroup needs it.
 | ||||
| 			backbuffer_cleared = false; | ||||
| 
 | ||||
| 			// Tell the renderer to paint this as a canvas group
 | ||||
| 			ci->use_canvas_group = true; | ||||
| 		} else { | ||||
| 			ci->use_canvas_group = false; | ||||
| 		} | ||||
| 
 | ||||
| 		if (backbuffer_copy) { | ||||
|  | @ -513,9 +519,9 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ | |||
| 			texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps); | ||||
| 
 | ||||
| 			backbuffer_copy = false; | ||||
| 			backbuffer_gen_mipmaps = false; | ||||
| 			material_screen_texture_cached = true; // After a backbuffer copy, screen texture makes no further copies.
 | ||||
| 			material_screen_texture_mipmaps_cached = backbuffer_gen_mipmaps; | ||||
| 			backbuffer_gen_mipmaps = false; | ||||
| 		} | ||||
| 
 | ||||
| 		if (backbuffer_gen_mipmaps) { | ||||
|  | @ -526,14 +532,18 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ | |||
| 		} | ||||
| 
 | ||||
| 		// just add all items for now
 | ||||
| 		items[item_count++] = ci; | ||||
| 		if (skip_item) { | ||||
| 			skip_item = false; | ||||
| 		} else { | ||||
| 			items[item_count++] = ci; | ||||
| 		} | ||||
| 
 | ||||
| 		if (!ci->next || item_count == MAX_RENDER_ITEMS - 1) { | ||||
| 			if (update_skeletons) { | ||||
| 				mesh_storage->update_mesh_instances(); | ||||
| 				update_skeletons = false; | ||||
| 			} | ||||
| 			_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used); | ||||
| 			_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, canvas_group_owner != nullptr); | ||||
| 			//then reset
 | ||||
| 			item_count = 0; | ||||
| 		} | ||||
|  | @ -586,11 +596,9 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou | |||
| 		} | ||||
| 
 | ||||
| 		RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material; | ||||
| 		if (ci->canvas_group != nullptr) { | ||||
| 		if (ci->use_canvas_group) { | ||||
| 			if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) { | ||||
| 				if (!p_to_backbuffer) { | ||||
| 					material = default_clip_children_material; | ||||
| 				} | ||||
| 				material = default_clip_children_material; | ||||
| 			} else { | ||||
| 				if (material.is_null()) { | ||||
| 					if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_ONLY) { | ||||
|  |  | |||
|  | @ -321,6 +321,7 @@ public: | |||
| 		}; | ||||
| 
 | ||||
| 		CanvasGroup *canvas_group = nullptr; | ||||
| 		bool use_canvas_group = false; | ||||
| 		int light_mask; | ||||
| 		int z_final; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1110,11 +1110,9 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co | |||
| 
 | ||||
| 		RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material; | ||||
| 
 | ||||
| 		if (ci->canvas_group != nullptr) { | ||||
| 		if (ci->use_canvas_group) { | ||||
| 			if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) { | ||||
| 				if (!p_to_backbuffer) { | ||||
| 					material = default_clip_children_material; | ||||
| 				} | ||||
| 				material = default_clip_children_material; | ||||
| 			} else { | ||||
| 				if (material.is_null()) { | ||||
| 					if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_ONLY) { | ||||
|  | @ -1381,6 +1379,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p | |||
| 	bool backbuffer_gen_mipmaps = false; | ||||
| 
 | ||||
| 	Item *canvas_group_owner = nullptr; | ||||
| 	bool skip_item = false; | ||||
| 
 | ||||
| 	bool update_skeletons = false; | ||||
| 	bool time_used = false; | ||||
|  | @ -1453,6 +1452,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p | |||
| 					Rect2i group_rect = ci->canvas_group_owner->global_rect_cache; | ||||
| 					texture_storage->render_target_copy_to_back_buffer(p_to_render_target, group_rect, false); | ||||
| 					if (ci->canvas_group_owner->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) { | ||||
| 						ci->canvas_group_owner->use_canvas_group = false; | ||||
| 						items[item_count++] = ci->canvas_group_owner; | ||||
| 					} | ||||
| 				} else if (!backbuffer_cleared) { | ||||
|  | @ -1467,9 +1467,8 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p | |||
| 			ci->canvas_group_owner = nullptr; //must be cleared
 | ||||
| 		} | ||||
| 
 | ||||
| 		if (!backbuffer_cleared && canvas_group_owner == nullptr && ci->canvas_group != nullptr && !backbuffer_copy) { | ||||
| 			texture_storage->render_target_clear_back_buffer(p_to_render_target, Rect2i(), Color(0, 0, 0, 0)); | ||||
| 			backbuffer_cleared = true; | ||||
| 		if (canvas_group_owner == nullptr && ci->canvas_group != nullptr && ci->canvas_group->mode != RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) { | ||||
| 			skip_item = true; | ||||
| 		} | ||||
| 
 | ||||
| 		if (ci == canvas_group_owner) { | ||||
|  | @ -1488,6 +1487,11 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p | |||
| 			canvas_group_owner = nullptr; | ||||
| 			// Backbuffer is dirty now and needs to be re-cleared if another CanvasGroup needs it.
 | ||||
| 			backbuffer_cleared = false; | ||||
| 
 | ||||
| 			// Tell the renderer to paint this as a canvas group
 | ||||
| 			ci->use_canvas_group = true; | ||||
| 		} else { | ||||
| 			ci->use_canvas_group = false; | ||||
| 		} | ||||
| 
 | ||||
| 		if (backbuffer_copy) { | ||||
|  | @ -1503,9 +1507,9 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p | |||
| 			texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps); | ||||
| 
 | ||||
| 			backbuffer_copy = false; | ||||
| 			backbuffer_gen_mipmaps = false; | ||||
| 			material_screen_texture_cached = true; // After a backbuffer copy, screen texture makes no further copies.
 | ||||
| 			material_screen_texture_mipmaps_cached = backbuffer_gen_mipmaps; | ||||
| 			backbuffer_gen_mipmaps = false; | ||||
| 		} | ||||
| 
 | ||||
| 		if (backbuffer_gen_mipmaps) { | ||||
|  | @ -1515,7 +1519,11 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p | |||
| 			material_screen_texture_mipmaps_cached = true; | ||||
| 		} | ||||
| 
 | ||||
| 		items[item_count++] = ci; | ||||
| 		if (skip_item) { | ||||
| 			skip_item = false; | ||||
| 		} else { | ||||
| 			items[item_count++] = ci; | ||||
| 		} | ||||
| 
 | ||||
| 		if (!ci->next || item_count == MAX_RENDER_ITEMS - 1) { | ||||
| 			if (update_skeletons) { | ||||
|  | @ -1523,7 +1531,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p | |||
| 				update_skeletons = false; | ||||
| 			} | ||||
| 
 | ||||
| 			_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, false); | ||||
| 			_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, canvas_group_owner != nullptr); | ||||
| 			//then reset
 | ||||
| 			item_count = 0; | ||||
| 		} | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 SlugFiller
						SlugFiller