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

This commit is contained in:
clayjohn 2024-04-17 15:19:20 -07:00
parent 3b1806182a
commit adfc9ccc44
4 changed files with 20 additions and 3 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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]

View file

@ -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) {