浏览代码

libobs: Add support for nonlinear SRGB blending

jpark37 3 年之前
父节点
当前提交
e638cc9f82
共有 4 个文件被更改,包括 61 次插入1 次删除
  1. 11 0
      docs/sphinx/reference-scenes.rst
  2. 39 1
      libobs/obs-scene.c
  3. 1 0
      libobs/obs-scene.h
  4. 10 0
      libobs/obs.h

+ 11 - 0
docs/sphinx/reference-scenes.rst

@@ -507,6 +507,17 @@ Scene Item Functions
 
 ---------------------
 
+.. function:: void obs_sceneitem_set_blending_method(obs_sceneitem_t *item, enum obs_blending_method method)
+              enum obs_blending_method obs_sceneitem_get_blending_method(obs_sceneitem_t *item)
+
+   Sets/gets the blending method used for the scene item.
+
+   :param method: | Can be one of the following values:
+                  | OBS_BLEND_METHOD_DEFAULT
+                  | OBS_BLEND_METHOD_SRGB_OFF
+
+---------------------
+
 .. function:: void obs_sceneitem_set_blending_mode(obs_sceneitem_t *item, enum obs_blending_type type)
               enum obs_blending_type obs_sceneitem_get_blending_mode(obs_sceneitem_t *item)
 

+ 39 - 1
libobs/obs-scene.c

@@ -540,6 +540,7 @@ static inline bool item_is_scene(const struct obs_scene_item *item)
 static inline bool item_texture_enabled(const struct obs_scene_item *item)
 {
 	return crop_enabled(&item->crop) || scale_filter_enabled(item) ||
+	       (item->blend_method == OBS_BLEND_METHOD_SRGB_OFF) ||
 	       !default_blending_enabled(item) ||
 	       (item_is_scene(item) && !item->is_group);
 }
@@ -799,7 +800,10 @@ static inline void render_item(struct obs_scene_item *item)
 		}
 	}
 
-	const bool previous = gs_set_linear_srgb(true);
+	const bool linear_srgb =
+		!item->item_render ||
+		(item->blend_method != OBS_BLEND_METHOD_SRGB_OFF);
+	const bool previous = gs_set_linear_srgb(linear_srgb);
 	gs_matrix_push();
 	gs_matrix_mul(&item->draw_transform);
 	if (item->item_render) {
@@ -959,6 +963,7 @@ static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data)
 	const char *name = obs_data_get_string(item_data, "name");
 	obs_source_t *source;
 	const char *scale_filter_str;
+	const char *blend_method_str;
 	const char *blend_str;
 	struct obs_scene_item *item;
 	bool visible;
@@ -1039,6 +1044,14 @@ static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data)
 			item->scale_filter = OBS_SCALE_AREA;
 	}
 
+	blend_method_str = obs_data_get_string(item_data, "blend_method");
+	item->blend_method = OBS_BLEND_METHOD_DEFAULT;
+
+	if (blend_method_str) {
+		if (astrcmpi(blend_method_str, "srgb_off") == 0)
+			item->blend_method = OBS_BLEND_METHOD_SRGB_OFF;
+	}
+
 	blend_str = obs_data_get_string(item_data, "blend_type");
 	item->blend_type = OBS_BLEND_NORMAL;
 
@@ -1116,6 +1129,7 @@ static void scene_save_item(obs_data_array_t *array,
 	obs_data_t *item_data = obs_data_create();
 	const char *name = obs_source_get_name(item->source);
 	const char *scale_filter;
+	const char *blend_method;
 	const char *blend_type;
 	struct vec2 pos = item->pos;
 	struct vec2 scale = item->scale;
@@ -1175,6 +1189,13 @@ static void scene_save_item(obs_data_array_t *array,
 
 	obs_data_set_string(item_data, "scale_filter", scale_filter);
 
+	if (item->blend_method == OBS_BLEND_METHOD_SRGB_OFF)
+		blend_method = "srgb_off";
+	else
+		blend_method = "default";
+
+	obs_data_set_string(item_data, "blend_method", blend_method);
+
 	if (item->blend_type == OBS_BLEND_NORMAL)
 		blend_type = "normal";
 	else if (item->blend_type == OBS_BLEND_ADDITIVE)
@@ -2978,6 +2999,23 @@ enum obs_scale_type obs_sceneitem_get_scale_filter(obs_sceneitem_t *item)
 		       : OBS_SCALE_DISABLE;
 }
 
+void obs_sceneitem_set_blending_method(obs_sceneitem_t *item,
+				       enum obs_blending_method method)
+{
+	if (!obs_ptr_valid(item, "obs_sceneitem_set_blending_method"))
+		return;
+
+	item->blend_method = method;
+}
+
+enum obs_blending_method
+obs_sceneitem_get_blending_method(obs_sceneitem_t *item)
+{
+	return obs_ptr_valid(item, "obs_sceneitem_get_blending_method")
+		       ? item->blend_method
+		       : OBS_BLEND_NORMAL;
+}
+
 void obs_sceneitem_set_blending_mode(obs_sceneitem_t *item,
 				     enum obs_blending_type type)
 {

+ 1 - 0
libobs/obs-scene.h

@@ -63,6 +63,7 @@ struct obs_scene_item {
 	struct vec2 output_scale;
 	enum obs_scale_type scale_filter;
 
+	enum obs_blending_method blend_method;
 	enum obs_blending_type blend_type;
 
 	struct matrix4 box_transform;

+ 10 - 0
libobs/obs.h

@@ -124,6 +124,11 @@ enum obs_scale_type {
 	OBS_SCALE_AREA,
 };
 
+enum obs_blending_method {
+	OBS_BLEND_METHOD_DEFAULT,
+	OBS_BLEND_METHOD_SRGB_OFF,
+};
+
 enum obs_blending_type {
 	OBS_BLEND_NORMAL,
 	OBS_BLEND_ADDITIVE,
@@ -1799,6 +1804,11 @@ EXPORT void obs_sceneitem_set_scale_filter(obs_sceneitem_t *item,
 EXPORT enum obs_scale_type
 obs_sceneitem_get_scale_filter(obs_sceneitem_t *item);
 
+EXPORT void obs_sceneitem_set_blending_method(obs_sceneitem_t *item,
+					      enum obs_blending_method method);
+EXPORT enum obs_blending_method
+obs_sceneitem_get_blending_method(obs_sceneitem_t *item);
+
 EXPORT void obs_sceneitem_set_blending_mode(obs_sceneitem_t *item,
 					    enum obs_blending_type type);
 EXPORT enum obs_blending_type