UI: Add support for nonlinear SRGB blending

master
jpark37 2022-03-31 19:15:17 -07:00 committed by Jim
parent e638cc9f82
commit f2b049c0e7
4 changed files with 63 additions and 12 deletions

View File

@ -480,6 +480,11 @@ ScaleFiltering.Bicubic="Bicubic"
ScaleFiltering.Lanczos="Lanczos" ScaleFiltering.Lanczos="Lanczos"
ScaleFiltering.Area="Area" ScaleFiltering.Area="Area"
# blending methods
BlendingMethod="Blending Method"
BlendingMethod.Default="Default"
BlendingMethod.SrgbOff="SRGB Off"
# blending modes # blending modes
BlendingMode="Blending Mode" BlendingMode="Blending Mode"
BlendingMode.Normal="Normal" BlendingMode.Normal="Normal"

View File

@ -5320,6 +5320,36 @@ QMenu *OBSBasic::AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item)
return menu; return menu;
} }
void OBSBasic::SetBlendingMethod()
{
QAction *action = reinterpret_cast<QAction *>(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() void OBSBasic::SetBlendingMode()
{ {
QAction *action = reinterpret_cast<QAction *>(sender()); QAction *action = reinterpret_cast<QAction *>(sender());
@ -5422,6 +5452,7 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview)
delete previewProjectorSource; delete previewProjectorSource;
delete sourceProjector; delete sourceProjector;
delete scaleFilteringMenu; delete scaleFilteringMenu;
delete blendingMethodMenu;
delete blendingModeMenu; delete blendingModeMenu;
delete colorMenu; delete colorMenu;
delete colorWidgetAction; delete colorWidgetAction;
@ -5554,6 +5585,9 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview)
AddScaleFilteringMenu(scaleFilteringMenu, sceneItem)); AddScaleFilteringMenu(scaleFilteringMenu, sceneItem));
popup.addSeparator(); popup.addSeparator();
blendingMethodMenu = new QMenu(QTStr("BlendingMethod"));
popup.addMenu(
AddBlendingMethodMenu(blendingMethodMenu, sceneItem));
blendingModeMenu = new QMenu(QTStr("BlendingMode")); blendingModeMenu = new QMenu(QTStr("BlendingMode"));
popup.addMenu(AddBlendingModeMenu(blendingModeMenu, sceneItem)); popup.addMenu(AddBlendingModeMenu(blendingModeMenu, sceneItem));
popup.addSeparator(); popup.addSeparator();
@ -9150,7 +9184,8 @@ void OBSBasic::on_actionCopySource_triggered()
copyInfo.weak_source = OBSGetWeakRef(source); copyInfo.weak_source = OBSGetWeakRef(source);
obs_sceneitem_get_info(item, &copyInfo.transform); obs_sceneitem_get_info(item, &copyInfo.transform);
obs_sceneitem_get_crop(item, &copyInfo.crop); obs_sceneitem_get_crop(item, &copyInfo.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); copyInfo.visible = obs_sceneitem_visible(item);
clipboard.push_back(copyInfo); clipboard.push_back(copyInfo);

View File

@ -94,7 +94,8 @@ struct SourceCopyInfo {
bool visible; bool visible;
obs_sceneitem_crop crop; obs_sceneitem_crop crop;
obs_transform_info transform; obs_transform_info transform;
obs_blending_type blend; obs_blending_method blend_method;
obs_blending_type blend_mode;
}; };
struct QuickTransition { struct QuickTransition {
@ -313,6 +314,7 @@ private:
QPointer<QMenu> sceneProjectorMenu; QPointer<QMenu> sceneProjectorMenu;
QPointer<QMenu> sourceProjector; QPointer<QMenu> sourceProjector;
QPointer<QMenu> scaleFilteringMenu; QPointer<QMenu> scaleFilteringMenu;
QPointer<QMenu> blendingMethodMenu;
QPointer<QMenu> blendingModeMenu; QPointer<QMenu> blendingModeMenu;
QPointer<QMenu> colorMenu; QPointer<QMenu> colorMenu;
QPointer<QWidgetAction> colorWidgetAction; QPointer<QWidgetAction> colorWidgetAction;
@ -715,6 +717,7 @@ private slots:
void SetScaleFilter(); void SetScaleFilter();
void SetBlendingMethod();
void SetBlendingMode(); void SetBlendingMode();
void IconActivated(QSystemTrayIcon::ActivationReason reason); void IconActivated(QSystemTrayIcon::ActivationReason reason);
@ -890,6 +893,7 @@ public:
QMenu *AddDeinterlacingMenu(QMenu *menu, obs_source_t *source); QMenu *AddDeinterlacingMenu(QMenu *menu, obs_source_t *source);
QMenu *AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item); 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 *AddBlendingModeMenu(QMenu *menu, obs_sceneitem_t *item);
QMenu *AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction, QMenu *AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction,
ColorSelect *select, ColorSelect *select,

View File

@ -26,7 +26,8 @@ struct AddSourceData {
bool visible; bool visible;
obs_transform_info *transform = nullptr; obs_transform_info *transform = nullptr;
obs_sceneitem_crop *crop = 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) 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); obs_sceneitem_set_info(sceneitem, data->transform);
if (data->crop != nullptr) if (data->crop != nullptr)
obs_sceneitem_set_crop(sceneitem, data->crop); obs_sceneitem_set_crop(sceneitem, data->crop);
if (data->blend != nullptr) if (data->blend_method != nullptr)
obs_sceneitem_set_blending_mode(sceneitem, *data->blend); 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); 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, static void AddExisting(OBSSource source, bool visible, bool duplicate,
obs_transform_info *transform, obs_sceneitem_crop *crop, 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<OBSBasic *>(App()->GetMainWindow()); OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene(); OBSScene scene = main->GetCurrentScene();
@ -175,7 +180,8 @@ static void AddExisting(OBSSource source, bool visible, bool duplicate,
data.visible = visible; data.visible = visible;
data.transform = transform; data.transform = transform;
data.crop = crop; data.crop = crop;
data.blend = blend; data.blend_method = blend_method;
data.blend_mode = blend_mode;
obs_enter_graphics(); obs_enter_graphics();
obs_scene_atomic_update(scene, AddSource, &data); 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, static void AddExisting(const char *name, bool visible, bool duplicate,
obs_transform_info *transform, obs_sceneitem_crop *crop, 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); OBSSourceAutoRelease source = obs_get_source_by_name(name);
if (source) { if (source) {
AddExisting(source.Get(), visible, duplicate, transform, crop, 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(); QString source_name = item->text();
AddExisting(QT_TO_UTF8(source_name), visible, false, nullptr, AddExisting(QT_TO_UTF8(source_name), visible, false, nullptr,
nullptr, nullptr); nullptr, nullptr, nullptr);
OBSBasic *main = OBSBasic *main =
reinterpret_cast<OBSBasic *>(App()->GetMainWindow()); reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
@ -287,7 +294,7 @@ void OBSBasicSourceSelect::on_buttonBox_accepted()
main->SetCurrentScene(scene_source, true); main->SetCurrentScene(scene_source, true);
obs_source_release(scene_source); obs_source_release(scene_source);
AddExisting(QT_TO_UTF8(source_name), visible, false, 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, undo_s.add_action(QTStr("Undo.Add").arg(source_name), undo,
@ -438,5 +445,5 @@ void OBSBasicSourceSelect::SourcePaste(SourceCopyInfo &info, bool dup)
return; return;
AddExisting(source, info.visible, dup, &info.transform, &info.crop, AddExisting(source, info.visible, dup, &info.transform, &info.crop,
&info.blend); &info.blend_method, &info.blend_mode);
} }