From f2b049c0e742d5e20a055bcdabdda2b9250a785f Mon Sep 17 00:00:00 2001 From: jpark37 Date: Thu, 31 Mar 2022 19:15:17 -0700 Subject: [PATCH] UI: Add support for nonlinear SRGB blending --- UI/data/locale/en-US.ini | 5 +++++ UI/window-basic-main.cpp | 37 ++++++++++++++++++++++++++++++- UI/window-basic-main.hpp | 6 ++++- UI/window-basic-source-select.cpp | 27 +++++++++++++--------- 4 files changed, 63 insertions(+), 12 deletions(-) diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini index 9f553bcaf..b787aa823 100644 --- a/UI/data/locale/en-US.ini +++ b/UI/data/locale/en-US.ini @@ -480,6 +480,11 @@ ScaleFiltering.Bicubic="Bicubic" ScaleFiltering.Lanczos="Lanczos" ScaleFiltering.Area="Area" +# blending methods +BlendingMethod="Blending Method" +BlendingMethod.Default="Default" +BlendingMethod.SrgbOff="SRGB Off" + # blending modes BlendingMode="Blending Mode" BlendingMode.Normal="Normal" diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index 50a350edc..8b5f4588e 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -5320,6 +5320,36 @@ QMenu *OBSBasic::AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item) return menu; } +void OBSBasic::SetBlendingMethod() +{ + QAction *action = reinterpret_cast(sender()); + obs_blending_method method = + (obs_blending_method)action->property("method").toInt(); + OBSSceneItem sceneItem = GetCurrentSceneItem(); + + obs_sceneitem_set_blending_method(sceneItem, method); +} + +QMenu *OBSBasic::AddBlendingMethodMenu(QMenu *menu, obs_sceneitem_t *item) +{ + obs_blending_method blendingMethod = + obs_sceneitem_get_blending_method(item); + QAction *action; + +#define ADD_MODE(name, method) \ + action = menu->addAction(QTStr("" name), this, \ + SLOT(SetBlendingMethod())); \ + action->setProperty("method", (int)method); \ + action->setCheckable(true); \ + action->setChecked(blendingMethod == method); + + ADD_MODE("BlendingMethod.Default", OBS_BLEND_METHOD_DEFAULT); + ADD_MODE("BlendingMethod.SrgbOff", OBS_BLEND_METHOD_SRGB_OFF); +#undef ADD_MODE + + return menu; +} + void OBSBasic::SetBlendingMode() { QAction *action = reinterpret_cast(sender()); @@ -5422,6 +5452,7 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) delete previewProjectorSource; delete sourceProjector; delete scaleFilteringMenu; + delete blendingMethodMenu; delete blendingModeMenu; delete colorMenu; delete colorWidgetAction; @@ -5554,6 +5585,9 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) AddScaleFilteringMenu(scaleFilteringMenu, sceneItem)); popup.addSeparator(); + blendingMethodMenu = new QMenu(QTStr("BlendingMethod")); + popup.addMenu( + AddBlendingMethodMenu(blendingMethodMenu, sceneItem)); blendingModeMenu = new QMenu(QTStr("BlendingMode")); popup.addMenu(AddBlendingModeMenu(blendingModeMenu, sceneItem)); popup.addSeparator(); @@ -9150,7 +9184,8 @@ void OBSBasic::on_actionCopySource_triggered() copyInfo.weak_source = OBSGetWeakRef(source); obs_sceneitem_get_info(item, ©Info.transform); obs_sceneitem_get_crop(item, ©Info.crop); - copyInfo.blend = obs_sceneitem_get_blending_mode(item); + copyInfo.blend_method = obs_sceneitem_get_blending_method(item); + copyInfo.blend_mode = obs_sceneitem_get_blending_mode(item); copyInfo.visible = obs_sceneitem_visible(item); clipboard.push_back(copyInfo); diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index b0914a8ab..ecb5742aa 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -94,7 +94,8 @@ struct SourceCopyInfo { bool visible; obs_sceneitem_crop crop; obs_transform_info transform; - obs_blending_type blend; + obs_blending_method blend_method; + obs_blending_type blend_mode; }; struct QuickTransition { @@ -313,6 +314,7 @@ private: QPointer sceneProjectorMenu; QPointer sourceProjector; QPointer scaleFilteringMenu; + QPointer blendingMethodMenu; QPointer blendingModeMenu; QPointer colorMenu; QPointer colorWidgetAction; @@ -715,6 +717,7 @@ private slots: void SetScaleFilter(); + void SetBlendingMethod(); void SetBlendingMode(); void IconActivated(QSystemTrayIcon::ActivationReason reason); @@ -890,6 +893,7 @@ public: QMenu *AddDeinterlacingMenu(QMenu *menu, obs_source_t *source); QMenu *AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item); + QMenu *AddBlendingMethodMenu(QMenu *menu, obs_sceneitem_t *item); QMenu *AddBlendingModeMenu(QMenu *menu, obs_sceneitem_t *item); QMenu *AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction, ColorSelect *select, diff --git a/UI/window-basic-source-select.cpp b/UI/window-basic-source-select.cpp index 256b9992f..a6c794168 100644 --- a/UI/window-basic-source-select.cpp +++ b/UI/window-basic-source-select.cpp @@ -26,7 +26,8 @@ struct AddSourceData { bool visible; obs_transform_info *transform = nullptr; obs_sceneitem_crop *crop = nullptr; - obs_blending_type *blend = nullptr; + obs_blending_method *blend_method = nullptr; + obs_blending_type *blend_mode = nullptr; }; bool OBSBasicSourceSelect::EnumSources(void *data, obs_source_t *source) @@ -124,8 +125,11 @@ static void AddSource(void *_data, obs_scene_t *scene) obs_sceneitem_set_info(sceneitem, data->transform); if (data->crop != nullptr) obs_sceneitem_set_crop(sceneitem, data->crop); - if (data->blend != nullptr) - obs_sceneitem_set_blending_mode(sceneitem, *data->blend); + if (data->blend_method != nullptr) + obs_sceneitem_set_blending_method(sceneitem, + *data->blend_method); + if (data->blend_mode != nullptr) + obs_sceneitem_set_blending_mode(sceneitem, *data->blend_mode); obs_sceneitem_set_visible(sceneitem, data->visible); } @@ -151,7 +155,8 @@ char *get_new_source_name(const char *name, const char *format) static void AddExisting(OBSSource source, bool visible, bool duplicate, obs_transform_info *transform, obs_sceneitem_crop *crop, - obs_blending_type *blend) + obs_blending_method *blend_method, + obs_blending_type *blend_mode) { OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); @@ -175,7 +180,8 @@ static void AddExisting(OBSSource source, bool visible, bool duplicate, data.visible = visible; data.transform = transform; data.crop = crop; - data.blend = blend; + data.blend_method = blend_method; + data.blend_mode = blend_mode; obs_enter_graphics(); obs_scene_atomic_update(scene, AddSource, &data); @@ -184,12 +190,13 @@ static void AddExisting(OBSSource source, bool visible, bool duplicate, static void AddExisting(const char *name, bool visible, bool duplicate, obs_transform_info *transform, obs_sceneitem_crop *crop, - obs_blending_type *blend) + obs_blending_method *blend_method, + obs_blending_type *blend_mode) { OBSSourceAutoRelease source = obs_get_source_by_name(name); if (source) { AddExisting(source.Get(), visible, duplicate, transform, crop, - blend); + blend_method, blend_mode); } } @@ -249,7 +256,7 @@ void OBSBasicSourceSelect::on_buttonBox_accepted() QString source_name = item->text(); AddExisting(QT_TO_UTF8(source_name), visible, false, nullptr, - nullptr, nullptr); + nullptr, nullptr, nullptr); OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); @@ -287,7 +294,7 @@ void OBSBasicSourceSelect::on_buttonBox_accepted() main->SetCurrentScene(scene_source, true); obs_source_release(scene_source); AddExisting(QT_TO_UTF8(source_name), visible, false, - nullptr, nullptr, nullptr); + nullptr, nullptr, nullptr, nullptr); }; undo_s.add_action(QTStr("Undo.Add").arg(source_name), undo, @@ -438,5 +445,5 @@ void OBSBasicSourceSelect::SourcePaste(SourceCopyInfo &info, bool dup) return; AddExisting(source, info.visible, dup, &info.transform, &info.crop, - &info.blend); + &info.blend_method, &info.blend_mode); }