From da187ba73b68094bcc4132467294221d1bc2fcab Mon Sep 17 00:00:00 2001 From: jpark37 Date: Mon, 3 May 2021 21:16:24 -0700 Subject: [PATCH] image-source: Allow linear space alpha Add support for applying alpha in linear space to match Photoshop behavior in linear mode, and for just overall correctness. The default setting is still nonlinear to match common user expectation though. --- plugins/image-source/data/locale/en-US.ini | 1 + plugins/image-source/image-source.c | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/plugins/image-source/data/locale/en-US.ini b/plugins/image-source/data/locale/en-US.ini index 21c275ec7..2f5bd32d9 100644 --- a/plugins/image-source/data/locale/en-US.ini +++ b/plugins/image-source/data/locale/en-US.ini @@ -1,6 +1,7 @@ ImageInput="Image" File="Image File" UnloadWhenNotShowing="Unload image when not showing" +LinearAlpha="Apply alpha in linear space" SlideShow="Image Slide Show" SlideShow.TransitionSpeed="Transition Speed (milliseconds)" diff --git a/plugins/image-source/image-source.c b/plugins/image-source/image-source.c index dfebdae6b..980b98f80 100644 --- a/plugins/image-source/image-source.c +++ b/plugins/image-source/image-source.c @@ -17,6 +17,7 @@ struct image_source { char *file; bool persistent; + bool linear_alpha; time_t file_timestamp; float update_time_elapsed; uint64_t last_time; @@ -74,11 +75,13 @@ static void image_source_update(void *data, obs_data_t *settings) struct image_source *context = data; const char *file = obs_data_get_string(settings, "file"); const bool unload = obs_data_get_bool(settings, "unload"); + const bool linear_alpha = obs_data_get_bool(settings, "linear_alpha"); if (context->file) bfree(context->file); context->file = bstrdup(file); context->persistent = !unload; + context->linear_alpha = linear_alpha; /* Load the image if the source is persistent or showing */ if (context->persistent || obs_source_showing(context->source)) @@ -90,6 +93,7 @@ static void image_source_update(void *data, obs_data_t *settings) static void image_source_defaults(obs_data_t *settings) { obs_data_set_default_bool(settings, "unload", false); + obs_data_set_default_bool(settings, "linear_alpha", false); } static void image_source_show(void *data) @@ -147,15 +151,22 @@ static void image_source_render(void *data, gs_effect_t *effect) if (!context->if2.image.texture) return; + const char *tech_name = "DrawNonlinearAlpha"; + enum gs_blend_type blend_src_color = GS_BLEND_ONE; + if (context->linear_alpha) { + tech_name = "Draw"; + blend_src_color = GS_BLEND_SRCALPHA; + } + effect = obs_get_base_effect(OBS_EFFECT_DEFAULT); - gs_technique_t *tech = - gs_effect_get_technique(effect, "DrawNonlinearAlpha"); + gs_technique_t *tech = gs_effect_get_technique(effect, tech_name); const bool previous = gs_framebuffer_srgb_enabled(); gs_enable_framebuffer_srgb(true); gs_blend_state_push(); - gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); + gs_blend_function_separate(blend_src_color, GS_BLEND_INVSRCALPHA, + GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); gs_eparam_t *const param = gs_effect_get_param_by_name(effect, "image"); gs_effect_set_texture_srgb(param, context->if2.image.texture); @@ -265,6 +276,8 @@ static obs_properties_t *image_source_properties(void *data) OBS_PATH_FILE, image_filter, path.array); obs_properties_add_bool(props, "unload", obs_module_text("UnloadWhenNotShowing")); + obs_properties_add_bool(props, "linear_alpha", + obs_module_text("LinearAlpha")); dstr_free(&path); return props;