Bladeren bron

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 jaren geleden
bovenliggende
commit
da187ba73b
2 gewijzigde bestanden met toevoegingen van 17 en 3 verwijderingen
  1. 1 0
      plugins/image-source/data/locale/en-US.ini
  2. 16 3
      plugins/image-source/image-source.c

+ 1 - 0
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)"

+ 16 - 3
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;