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.
This commit is contained in:
jpark37 2021-05-03 21:16:24 -07:00 committed by Jim
parent 7b4e4b99d2
commit da187ba73b
2 changed files with 17 additions and 3 deletions

View file

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

View file

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