Selaa lähdekoodia

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.
jpark37 4 vuotta sitten
vanhempi
sitoutus
da187ba73b

+ 1 - 0
plugins/image-source/data/locale/en-US.ini

@@ -1,6 +1,7 @@
 ImageInput="Image"
 ImageInput="Image"
 File="Image File"
 File="Image File"
 UnloadWhenNotShowing="Unload image when not showing"
 UnloadWhenNotShowing="Unload image when not showing"
+LinearAlpha="Apply alpha in linear space"
 
 
 SlideShow="Image Slide Show"
 SlideShow="Image Slide Show"
 SlideShow.TransitionSpeed="Transition Speed (milliseconds)"
 SlideShow.TransitionSpeed="Transition Speed (milliseconds)"

+ 16 - 3
plugins/image-source/image-source.c

@@ -17,6 +17,7 @@ struct image_source {
 
 
 	char *file;
 	char *file;
 	bool persistent;
 	bool persistent;
+	bool linear_alpha;
 	time_t file_timestamp;
 	time_t file_timestamp;
 	float update_time_elapsed;
 	float update_time_elapsed;
 	uint64_t last_time;
 	uint64_t last_time;
@@ -74,11 +75,13 @@ static void image_source_update(void *data, obs_data_t *settings)
 	struct image_source *context = data;
 	struct image_source *context = data;
 	const char *file = obs_data_get_string(settings, "file");
 	const char *file = obs_data_get_string(settings, "file");
 	const bool unload = obs_data_get_bool(settings, "unload");
 	const bool unload = obs_data_get_bool(settings, "unload");
+	const bool linear_alpha = obs_data_get_bool(settings, "linear_alpha");
 
 
 	if (context->file)
 	if (context->file)
 		bfree(context->file);
 		bfree(context->file);
 	context->file = bstrdup(file);
 	context->file = bstrdup(file);
 	context->persistent = !unload;
 	context->persistent = !unload;
+	context->linear_alpha = linear_alpha;
 
 
 	/* Load the image if the source is persistent or showing */
 	/* Load the image if the source is persistent or showing */
 	if (context->persistent || obs_source_showing(context->source))
 	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)
 static void image_source_defaults(obs_data_t *settings)
 {
 {
 	obs_data_set_default_bool(settings, "unload", false);
 	obs_data_set_default_bool(settings, "unload", false);
+	obs_data_set_default_bool(settings, "linear_alpha", false);
 }
 }
 
 
 static void image_source_show(void *data)
 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)
 	if (!context->if2.image.texture)
 		return;
 		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);
 	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();
 	const bool previous = gs_framebuffer_srgb_enabled();
 	gs_enable_framebuffer_srgb(true);
 	gs_enable_framebuffer_srgb(true);
 
 
 	gs_blend_state_push();
 	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_eparam_t *const param = gs_effect_get_param_by_name(effect, "image");
 	gs_effect_set_texture_srgb(param, context->if2.image.texture);
 	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_PATH_FILE, image_filter, path.array);
 	obs_properties_add_bool(props, "unload",
 	obs_properties_add_bool(props, "unload",
 				obs_module_text("UnloadWhenNotShowing"));
 				obs_module_text("UnloadWhenNotShowing"));
+	obs_properties_add_bool(props, "linear_alpha",
+				obs_module_text("LinearAlpha"));
 	dstr_free(&path);
 	dstr_free(&path);
 
 
 	return props;
 	return props;