mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-05 21:48:55 +00:00
[common, ui] Refining UI for FX shaders for PC (#4426)
Self-explanatory refinements on the already existing access/usage of post-processing shaders on Eden for PC UI. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4426 Reviewed-by: MaranBr <maranbr@eden-emu.dev> Reviewed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
@@ -151,6 +151,9 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent) {
|
|||||||
tr("The anti-aliasing method to use.\nSMAA offers the best quality.\nFXAA "
|
tr("The anti-aliasing method to use.\nSMAA offers the best quality.\nFXAA "
|
||||||
"can produce a more stable picture in lower resolutions."));
|
"can produce a more stable picture in lower resolutions."));
|
||||||
INSERT(Settings, post_shader_chain, QString(), QString());
|
INSERT(Settings, post_shader_chain, QString(), QString());
|
||||||
|
INSERT(Settings, post_shader_preset, QString(), QString());
|
||||||
|
INSERT(Settings, post_shader_enabled, tr("Enable post-processing effects"),
|
||||||
|
tr("Applies post-processing effects to the final image."));
|
||||||
INSERT(Settings, fullscreen_mode, tr("Fullscreen Mode:"),
|
INSERT(Settings, fullscreen_mode, tr("Fullscreen Mode:"),
|
||||||
tr("The method used to render the window in fullscreen.\nBorderless offers the best "
|
tr("The method used to render the window in fullscreen.\nBorderless offers the best "
|
||||||
"compatibility with the on-screen keyboard that some games request for "
|
"compatibility with the on-screen keyboard that some games request for "
|
||||||
|
|||||||
@@ -37,6 +37,10 @@
|
|||||||
#include "yuzu/configuration/configure_graphics.h"
|
#include "yuzu/configuration/configure_graphics.h"
|
||||||
#include "yuzu/configuration/shared_widget.h"
|
#include "yuzu/configuration/shared_widget.h"
|
||||||
|
|
||||||
|
#ifdef HAS_RESHADE
|
||||||
|
#include "yuzu/configuration/configure_post_processing.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
ConfigureGraphics::ConfigureGraphics(
|
ConfigureGraphics::ConfigureGraphics(
|
||||||
const Core::System& system_, std::vector<VkDeviceInfo::Record>& records_,
|
const Core::System& system_, std::vector<VkDeviceInfo::Record>& records_,
|
||||||
const std::function<void()>& expose_compute_option_,
|
const std::function<void()>& expose_compute_option_,
|
||||||
@@ -216,6 +220,12 @@ void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) {
|
|||||||
std::vector<QWidget*> hold_api;
|
std::vector<QWidget*> hold_api;
|
||||||
|
|
||||||
for (const auto setting : Settings::values.linkage.by_category[Settings::Category::Renderer]) {
|
for (const auto setting : Settings::values.linkage.by_category[Settings::Category::Renderer]) {
|
||||||
|
#ifndef HAS_RESHADE
|
||||||
|
if (setting->Id() == Settings::values.post_shader_enabled.Id()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ConfigurationShared::Widget* widget = [&]() {
|
ConfigurationShared::Widget* widget = [&]() {
|
||||||
if (setting->Id() == Settings::values.fsr_sharpening_slider.Id()) {
|
if (setting->Id() == Settings::values.fsr_sharpening_slider.Id()) {
|
||||||
// FSR needs a reversed slider and a 0.5 multiplier
|
// FSR needs a reversed slider and a 0.5 multiplier
|
||||||
@@ -295,6 +305,23 @@ void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) {
|
|||||||
// Keep track of the resolution combobox to update other UI tabs that need it
|
// Keep track of the resolution combobox to update other UI tabs that need it
|
||||||
resolution_combobox = widget->combobox;
|
resolution_combobox = widget->combobox;
|
||||||
hold_graphics.emplace(setting->Id(), widget);
|
hold_graphics.emplace(setting->Id(), widget);
|
||||||
|
#ifdef HAS_RESHADE
|
||||||
|
} else if (setting->Id() == Settings::values.post_shader_enabled.Id()) {
|
||||||
|
QPushButton* post_shader_button = new QPushButton(tr("Configure Effects..."), widget);
|
||||||
|
post_shader_button->setVisible(widget->checkbox->isChecked());
|
||||||
|
|
||||||
|
connect(post_shader_button, &QAbstractButton::clicked, this, [this]() {
|
||||||
|
ConfigurePostProcessing dialog(this);
|
||||||
|
dialog.exec();
|
||||||
|
});
|
||||||
|
connect(widget->checkbox, &QCheckBox::toggled, post_shader_button,
|
||||||
|
&QWidget::setVisible);
|
||||||
|
|
||||||
|
QBoxLayout* row = qobject_cast<QBoxLayout*>(widget->layout());
|
||||||
|
row->insertWidget(1, post_shader_button);
|
||||||
|
|
||||||
|
hold_graphics.emplace(setting->Id(), widget);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
hold_graphics.emplace(setting->Id(), widget);
|
hold_graphics.emplace(setting->Id(), widget);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,10 +70,8 @@ ConfigurePostProcessing::ConfigurePostProcessing(QWidget* parent) : QDialog(pare
|
|||||||
|
|
||||||
auto* root = new QVBoxLayout(this);
|
auto* root = new QVBoxLayout(this);
|
||||||
|
|
||||||
auto* description = new QLabel(
|
auto* description =
|
||||||
tr("ReShade FX effects are loaded from the post_shaders folder in the Eden data "
|
new QLabel(tr("Changes apply immediately while a game is running."), this);
|
||||||
"directory. Changes apply immediately while a game is running."),
|
|
||||||
this);
|
|
||||||
description->setWordWrap(true);
|
description->setWordWrap(true);
|
||||||
root->addWidget(description);
|
root->addWidget(description);
|
||||||
|
|
||||||
@@ -128,17 +126,15 @@ ConfigurePostProcessing::ConfigurePostProcessing(QWidget* parent) : QDialog(pare
|
|||||||
});
|
});
|
||||||
preset_row->addWidget(save_button);
|
preset_row->addWidget(save_button);
|
||||||
|
|
||||||
auto* delete_button = new QPushButton(tr("Delete"), this);
|
auto* clear_button = new QPushButton(tr("Clear"), this);
|
||||||
connect(delete_button, &QPushButton::clicked, this, [this]() {
|
clear_button->setToolTip(tr("Remove every effect in use and deselect the preset."));
|
||||||
const QString name = preset_combo->currentData().toString();
|
connect(clear_button, &QPushButton::clicked, this, [this]() {
|
||||||
if (name.isEmpty()) {
|
VideoCore::FxChain::Instance().Clear();
|
||||||
return;
|
VideoCore::SetActiveFxPreset(std::string());
|
||||||
}
|
preset_combo->setCurrentIndex(0);
|
||||||
VideoCore::DeleteFxPreset(name.toStdString());
|
ApplyStructuralChange();
|
||||||
PopulatePresetCombo();
|
|
||||||
RefreshPresetStatus();
|
|
||||||
});
|
});
|
||||||
preset_row->addWidget(delete_button);
|
preset_row->addWidget(clear_button);
|
||||||
|
|
||||||
root->addLayout(preset_row);
|
root->addLayout(preset_row);
|
||||||
|
|
||||||
@@ -203,6 +199,7 @@ void ConfigurePostProcessing::ApplyStructuralChange() {
|
|||||||
void ConfigurePostProcessing::PopulatePresetCombo() {
|
void ConfigurePostProcessing::PopulatePresetCombo() {
|
||||||
const QString previous = preset_combo->currentData().toString();
|
const QString previous = preset_combo->currentData().toString();
|
||||||
preset_combo->clear();
|
preset_combo->clear();
|
||||||
|
preset_combo->addItem(tr("None"), QString());
|
||||||
|
|
||||||
for (const auto& preset : VideoCore::GetFxPresetCatalog()) {
|
for (const auto& preset : VideoCore::GetFxPresetCatalog()) {
|
||||||
const QString name = QString::fromStdString(preset.name);
|
const QString name = QString::fromStdString(preset.name);
|
||||||
@@ -212,7 +209,7 @@ void ConfigurePostProcessing::PopulatePresetCombo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int restored = preset_combo->findData(previous);
|
const int restored = preset_combo->findData(previous);
|
||||||
if (restored >= 0) {
|
if (!previous.isEmpty() && restored >= 0) {
|
||||||
preset_combo->setCurrentIndex(restored);
|
preset_combo->setCurrentIndex(restored);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -220,12 +217,21 @@ void ConfigurePostProcessing::PopulatePresetCombo() {
|
|||||||
const int active = preset_combo->findData(QString::fromStdString(VideoCore::GetActiveFxPreset()));
|
const int active = preset_combo->findData(QString::fromStdString(VideoCore::GetActiveFxPreset()));
|
||||||
if (active >= 0) {
|
if (active >= 0) {
|
||||||
preset_combo->setCurrentIndex(active);
|
preset_combo->setCurrentIndex(active);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preset_combo->setCurrentIndex(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigurePostProcessing::RefreshPresetStatus() {
|
void ConfigurePostProcessing::RefreshPresetStatus() {
|
||||||
const std::string active = VideoCore::GetActiveFxPreset();
|
const std::string active = VideoCore::GetActiveFxPreset();
|
||||||
if (active.empty()) {
|
if (active.empty()) {
|
||||||
|
if (VideoCore::FxChain::Instance().Size() == 0) {
|
||||||
|
preset_status->setText(
|
||||||
|
tr("No effects in use. Pick a preset and press Apply, or add effects one "
|
||||||
|
"by one."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
preset_status->setText(tr("Custom chain. Pick a preset above and press Apply to replace it."));
|
preset_status->setText(tr("Custom chain. Pick a preset above and press Apply to replace it."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "render/performance_overlay.h"
|
#include "render/performance_overlay.h"
|
||||||
#ifdef HAS_RESHADE
|
#ifdef HAS_RESHADE
|
||||||
#include "configuration/configure_post_processing.h"
|
#include "configuration/configure_post_processing.h"
|
||||||
|
#include "video_core/post_processing/fx_preset.h"
|
||||||
#endif
|
#endif
|
||||||
#include "updater/update_dialog.h"
|
#include "updater/update_dialog.h"
|
||||||
|
|
||||||
@@ -1090,6 +1091,41 @@ void MainWindow::InitializeWidgets() {
|
|||||||
|
|
||||||
statusBar()->insertPermanentWidget(0, volume_button);
|
statusBar()->insertPermanentWidget(0, volume_button);
|
||||||
|
|
||||||
|
#ifdef HAS_RESHADE
|
||||||
|
post_shader_status_button = new QPushButton();
|
||||||
|
post_shader_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
|
||||||
|
post_shader_status_button->setFocusPolicy(Qt::NoFocus);
|
||||||
|
post_shader_status_button->setCheckable(true);
|
||||||
|
connect(post_shader_status_button, &QPushButton::clicked, this, [this] {
|
||||||
|
const bool enabled = Settings::values.post_shader_enabled.GetValue();
|
||||||
|
Settings::values.post_shader_enabled.SetValue(!enabled);
|
||||||
|
UpdatePostShaderText();
|
||||||
|
});
|
||||||
|
UpdatePostShaderText();
|
||||||
|
post_shader_status_button->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(post_shader_status_button, &QPushButton::customContextMenuRequested,
|
||||||
|
[this](const QPoint& menu_location) {
|
||||||
|
QMenu context_menu;
|
||||||
|
|
||||||
|
for (auto const& preset : VideoCore::GetFxPresetCatalog()) {
|
||||||
|
context_menu.addAction(QString::fromStdString(preset.name),
|
||||||
|
[this, name = preset.name] {
|
||||||
|
VideoCore::ApplyFxPreset(name);
|
||||||
|
Settings::values.post_shader_enabled.SetValue(true);
|
||||||
|
UpdatePostShaderText();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
context_menu.addSeparator();
|
||||||
|
context_menu.addAction(tr("Configure Effects..."), this,
|
||||||
|
&MainWindow::OnPostProcessingShaders);
|
||||||
|
|
||||||
|
context_menu.exec(post_shader_status_button->mapToGlobal(menu_location));
|
||||||
|
post_shader_status_button->repaint();
|
||||||
|
});
|
||||||
|
statusBar()->insertPermanentWidget(0, post_shader_status_button);
|
||||||
|
#endif
|
||||||
|
|
||||||
// setup AA button
|
// setup AA button
|
||||||
aa_status_button = new QPushButton();
|
aa_status_button = new QPushButton();
|
||||||
aa_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
|
aa_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
|
||||||
@@ -3908,6 +3944,7 @@ void MainWindow::OnPostProcessingShaders() {
|
|||||||
connect(post_processing_dialog, &QDialog::finished, post_processing_dialog, [this]() {
|
connect(post_processing_dialog, &QDialog::finished, post_processing_dialog, [this]() {
|
||||||
post_processing_dialog->deleteLater();
|
post_processing_dialog->deleteLater();
|
||||||
post_processing_dialog = nullptr;
|
post_processing_dialog = nullptr;
|
||||||
|
UpdatePostShaderText();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4262,6 +4299,26 @@ void MainWindow::UpdateAAText() {
|
|||||||
: aa_text.toUpper());
|
: aa_text.toUpper());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAS_RESHADE
|
||||||
|
void MainWindow::UpdatePostShaderText() {
|
||||||
|
const bool enabled = Settings::values.post_shader_enabled.GetValue();
|
||||||
|
post_shader_status_button->setChecked(enabled);
|
||||||
|
|
||||||
|
if (!enabled) {
|
||||||
|
post_shader_status_button->setText(tr("NO FX"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string preset = VideoCore::GetActiveFxPreset();
|
||||||
|
if (preset.empty()) {
|
||||||
|
post_shader_status_button->setText(tr("FX"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
post_shader_status_button->setText(QString::fromStdString(preset).toUpper());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void MainWindow::UpdateVolumeUI() {
|
void MainWindow::UpdateVolumeUI() {
|
||||||
const auto volume_value = static_cast<int>(Settings::values.volume.GetValue());
|
const auto volume_value = static_cast<int>(Settings::values.volume.GetValue());
|
||||||
volume_slider->setValue(volume_value);
|
volume_slider->setValue(volume_value);
|
||||||
|
|||||||
@@ -448,6 +448,7 @@ private:
|
|||||||
void UpdateAPIText();
|
void UpdateAPIText();
|
||||||
void UpdateFilterText();
|
void UpdateFilterText();
|
||||||
void UpdateAAText();
|
void UpdateAAText();
|
||||||
|
void UpdatePostShaderText();
|
||||||
void UpdateVolumeUI();
|
void UpdateVolumeUI();
|
||||||
void UpdateStatusBar();
|
void UpdateStatusBar();
|
||||||
void UpdateGPUAccuracyButton();
|
void UpdateGPUAccuracyButton();
|
||||||
@@ -524,6 +525,7 @@ private:
|
|||||||
QPushButton* dock_status_button = nullptr;
|
QPushButton* dock_status_button = nullptr;
|
||||||
QPushButton* filter_status_button = nullptr;
|
QPushButton* filter_status_button = nullptr;
|
||||||
QPushButton* aa_status_button = nullptr;
|
QPushButton* aa_status_button = nullptr;
|
||||||
|
QPushButton* post_shader_status_button = nullptr;
|
||||||
VolumeButton* volume_button = nullptr;
|
VolumeButton* volume_button = nullptr;
|
||||||
QWidget* volume_popup = nullptr;
|
QWidget* volume_popup = nullptr;
|
||||||
QSlider* volume_slider = nullptr;
|
QSlider* volume_slider = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user