From e638cc9f82eccdba5aeaa331073d2eb15ea497d0 Mon Sep 17 00:00:00 2001 From: jpark37 Date: Thu, 31 Mar 2022 19:15:10 -0700 Subject: [PATCH] libobs: Add support for nonlinear SRGB blending --- docs/sphinx/reference-scenes.rst | 11 +++++++++ libobs/obs-scene.c | 40 +++++++++++++++++++++++++++++++- libobs/obs-scene.h | 1 + libobs/obs.h | 10 ++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/reference-scenes.rst b/docs/sphinx/reference-scenes.rst index 0c380e449..a4f701e21 100644 --- a/docs/sphinx/reference-scenes.rst +++ b/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) diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c index 96d83ff6b..1f969aea7 100644 --- a/libobs/obs-scene.c +++ b/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) { diff --git a/libobs/obs-scene.h b/libobs/obs-scene.h index ccd23122c..8af2dd7cf 100644 --- a/libobs/obs-scene.h +++ b/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; diff --git a/libobs/obs.h b/libobs/obs.h index 2769e1e86..c1e3b6f90 100644 --- a/libobs/obs.h +++ b/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