Browse Source

Use a src rect for copying from screen with CanvasGroup in the mobile backend

clayjohn 1 year ago
parent
commit
adfc9ccc44

+ 9 - 1
servers/rendering/renderer_rd/effects/copy_effects.cpp

@@ -533,7 +533,7 @@ void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuff
 	RD::get_singleton()->draw_list_draw(draw_list, true);
 }
 
-void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview, bool p_alpha_to_one, bool p_linear, bool p_normal) {
+void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview, bool p_alpha_to_one, bool p_linear, bool p_normal, const Rect2 &p_src_rect) {
 	UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
 	ERR_FAIL_NULL(uniform_set_cache);
 	MaterialStorage *material_storage = MaterialStorage::get_singleton();
@@ -568,6 +568,14 @@ void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffe
 		copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_NORMAL;
 	}
 
+	if (p_src_rect != Rect2()) {
+		copy_to_fb.push_constant.section[0] = p_src_rect.position.x;
+		copy_to_fb.push_constant.section[1] = p_src_rect.position.y;
+		copy_to_fb.push_constant.section[2] = p_src_rect.size.x;
+		copy_to_fb.push_constant.section[3] = p_src_rect.size.y;
+		copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_USE_SRC_SECTION;
+	}
+
 	// setup our uniforms
 	RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
 

+ 2 - 1
servers/rendering/renderer_rd/effects/copy_effects.h

@@ -191,6 +191,7 @@ private:
 		COPY_TO_FB_FLAG_ALPHA_TO_ONE = (1 << 5),
 		COPY_TO_FB_FLAG_LINEAR = (1 << 6),
 		COPY_TO_FB_FLAG_NORMAL = (1 << 7),
+		COPY_TO_FB_FLAG_USE_SRC_SECTION = (1 << 8),
 	};
 
 	struct CopyToFbPushConstant {
@@ -329,7 +330,7 @@ public:
 	void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array);
 	void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false);
 	void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far);
-	void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false, bool alpha_to_one = false, bool p_linear = false, bool p_normal = false);
+	void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false, bool alpha_to_one = false, bool p_linear = false, bool p_normal = false, const Rect2 &p_src_rect = Rect2());
 	void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false);
 	void copy_to_drawlist(RD::DrawListID p_draw_list, RD::FramebufferFormatID p_fb_format, RID p_source_rd_texture, bool p_linear = false);
 	void copy_raster(RID p_source_texture, RID p_dest_framebuffer);

+ 5 - 0
servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl

@@ -21,6 +21,7 @@
 #define FLAG_ALPHA_TO_ONE (1 << 5)
 #define FLAG_LINEAR (1 << 6)
 #define FLAG_NORMAL (1 << 7)
+#define FLAG_USE_SRC_SECTION (1 << 8)
 
 #ifdef USE_MULTIVIEW
 layout(location = 0) out vec3 uv_interp;
@@ -54,6 +55,10 @@ void main() {
 	if (bool(params.flags & FLAG_FLIP_Y)) {
 		uv_interp.y = 1.0 - uv_interp.y;
 	}
+
+	if (bool(params.flags & FLAG_USE_SRC_SECTION)) {
+		uv_interp = params.section.xy + uv_interp * params.section.zw;
+	}
 }
 
 #[fragment]

+ 4 - 1
servers/rendering/renderer_rd/storage_rd/texture_storage.cpp

@@ -3820,7 +3820,10 @@ void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, cons
 	if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
 		copy_effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, !rt->use_hdr, true);
 	} else {
-		copy_effects->copy_to_fb_rect(rt->color, rt->backbuffer_fb, region, false, false, false, false, RID(), false, true);
+		Rect2 src_rect = Rect2(region);
+		src_rect.position /= Size2(rt->size);
+		src_rect.size /= Size2(rt->size);
+		copy_effects->copy_to_fb_rect(rt->color, rt->backbuffer_fb, region, false, false, false, false, RID(), false, true, false, false, src_rect);
 	}
 
 	if (!p_gen_mipmaps) {