Skip to content

Commit

Permalink
Qt: add color correction and HDR Qt settings widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
Filoppi committed Jun 18, 2023
1 parent a2702c6 commit daddf4c
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ add_executable(dolphin-emu
Config/Graphics/GraphicsWindow.h
Config/Graphics/HacksWidget.cpp
Config/Graphics/HacksWidget.h
Config/Graphics/ColorCorrectionConfigWindow.cpp
Config/Graphics/ColorCorrectionConfigWindow.h
Config/Graphics/PostProcessingConfigWindow.cpp
Config/Graphics/PostProcessingConfigWindow.h
Config/GraphicsModListWidget.cpp
Expand Down
181 changes: 181 additions & 0 deletions Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// Copyright 2018 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.h"

#include <QCheckBox>
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>

#include "Core/Config/GraphicsSettings.h"

#include "DolphinQt/Config/ConfigControls/ConfigBool.h"
#include "DolphinQt/Config/ConfigControls/ConfigChoice.h"
#include "DolphinQt/Config/ConfigControls/ConfigFloatSlider.h"

#include "VideoCommon/VideoConfig.h"

ColorCorrectionConfigWindow::ColorCorrectionConfigWindow(QWidget* parent) : QDialog(parent)
{
setWindowTitle(tr("Color Correction Configuration"));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);

Create();
ConnectWidgets();
}

void ColorCorrectionConfigWindow::Create()
{
static const char TR_COLOR_SPACE_CORRECTION_DESCRIPTION[] = QT_TR_NOOP(
"Converts the colors to the color spaces that GC/Wii were meant to work with to sRGB/Rec.709."
"<br><br>There's no way of knowing what exact color space games were meant for,"
"<br>given there were multiple standards and most games didn't acknowledge them,"
"<br>so it's not correct to assume a format from the game disc region."
"<br>Just pick the one that looks more natural to you,"
" or match it with the region the game was developed in."
"<br><br>HDR output is required to show all the colors from the PAL and NTSC-J color spaces."
"<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");
static const char TR_GAME_GAMMA_DESCRIPTION[] =
QT_TR_NOOP("NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8."
"<br>None of the two were necessarily followed by games or TVs. 2.35 is a good "
"generic value for all regions."
"<br>If a game allows you to chose a gamma value, match it here.");
static const char TR_GAMMA_CORRECTION_DESCRIPTION[] = QT_TR_NOOP(
"Converts the gamma from what the game targeted to what your current SDR display targets."
"<br>Monitors often target sRGB. TVs often target 2.2."
"<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");

// Color Space:

auto* const color_space_box = new QGroupBox(tr("Color Space"));
auto* const color_space_layout = new QGridLayout();
color_space_layout->setVerticalSpacing(7);
color_space_layout->setColumnStretch(1, 1);
color_space_box->setLayout(color_space_layout);

m_correct_color_space =
new ConfigBool(tr("Correct Color Space"), Config::GFX_CC_CORRECT_COLOR_SPACE);
color_space_layout->addWidget(m_correct_color_space, 0, 0);
m_correct_color_space->SetDescription(tr(TR_COLOR_SPACE_CORRECTION_DESCRIPTION));

// "ColorCorrectionRegion"
const QStringList game_color_space_enum{tr("NTSC-M (SMPTE 170M)"), tr("NTSC-J (ARIB TR-B9)"),
tr("PAL (EBU)")};

m_game_color_space = new ConfigChoice(game_color_space_enum, Config::GFX_CC_GAME_COLOR_SPACE);
color_space_layout->addWidget(new QLabel(tr("Game Color Space")), 1, 0);
color_space_layout->addWidget(m_game_color_space, 1, 1);

m_game_color_space->setEnabled(m_correct_color_space->isChecked());

// Gamma:

auto* const gamma_box = new QGroupBox(tr("Gamma"));
auto* const gamma_layout = new QGridLayout();
gamma_layout->setVerticalSpacing(7);
gamma_layout->setColumnStretch(1, 1);
gamma_box->setLayout(gamma_layout);

m_game_gamma = new ConfigFloatSlider(Config::GFX_CC_GAME_GAMMA_MIN, Config::GFX_CC_GAME_GAMMA_MAX,
Config::GFX_CC_GAME_GAMMA, 0.01f);
gamma_layout->addWidget(new QLabel(tr("Game Gamma")), 0, 0);
gamma_layout->addWidget(m_game_gamma, 0, 1);
m_game_gamma->SetDescription(tr(TR_GAME_GAMMA_DESCRIPTION));
m_game_gamma_value = new QLabel(tr(""));
gamma_layout->addWidget(m_game_gamma_value, 0, 2);

m_correct_gamma = new ConfigBool(tr("Correct SDR Gamma"), Config::GFX_CC_CORRECT_GAMMA);
gamma_layout->addWidget(m_correct_gamma, 1, 0);
m_correct_gamma->SetDescription(tr(TR_GAMMA_CORRECTION_DESCRIPTION));

m_sdr_display_gamma_srgb =
new ConfigBool(tr("SDR Display Gamma sRGB"), Config::GFX_CC_SDR_DISPLAY_GAMMA_SRGB);
gamma_layout->addWidget(m_sdr_display_gamma_srgb, 2, 0);

m_sdr_display_custom_gamma =
new ConfigFloatSlider(Config::GFX_CC_DISPLAY_GAMMA_MIN, Config::GFX_CC_DISPLAY_GAMMA_MAX,
Config::GFX_CC_SDR_DISPLAY_CUSTOM_GAMMA, 0.01f);
gamma_layout->addWidget(new QLabel(tr("SDR Display Custom Gamma")), 3, 0);
gamma_layout->addWidget(m_sdr_display_custom_gamma, 3, 1);
m_sdr_display_custom_gamma_value = new QLabel(tr(""));
gamma_layout->addWidget(m_sdr_display_custom_gamma_value, 3, 2);

m_sdr_display_gamma_srgb->setEnabled(m_correct_gamma->isChecked());
m_sdr_display_custom_gamma->setEnabled(m_correct_gamma->isChecked() &&
!m_sdr_display_gamma_srgb->isChecked());
m_game_gamma_value->setText(QString::asprintf("%f", m_game_gamma->GetValue()));
m_sdr_display_custom_gamma_value->setText(
QString::asprintf("%f", m_sdr_display_custom_gamma->GetValue()));

// HDR:

auto* const hdr_box = new QGroupBox(tr("HDR"));
auto* const hdr_layout = new QGridLayout();
hdr_layout->setVerticalSpacing(7);
hdr_layout->setColumnStretch(1, 1);
hdr_box->setLayout(hdr_layout);

m_hdr_paper_white_nits = new ConfigFloatSlider(Config::GFX_CC_HDR_PAPER_WHITE_NITS_MIN,
Config::GFX_CC_HDR_PAPER_WHITE_NITS_MAX,
Config::GFX_CC_HDR_PAPER_WHITE_NITS, 1.f);
hdr_layout->addWidget(new QLabel(tr("HDR Paper White Nits")), 0, 0);
hdr_layout->addWidget(m_hdr_paper_white_nits, 0, 1);
m_hdr_paper_white_nits_value = new QLabel(tr(""));
hdr_layout->addWidget(m_hdr_paper_white_nits_value, 0, 2);

m_hdr_paper_white_nits_value->setText(
QString::asprintf("%f", m_hdr_paper_white_nits->GetValue()));

// Other:

m_button_box = new QDialogButtonBox(QDialogButtonBox::Close);

auto* layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setAlignment(Qt::AlignTop);
layout->addWidget(color_space_box);
layout->addWidget(gamma_box);
layout->addWidget(hdr_box);
layout->addWidget(m_button_box);
setLayout(layout);
}

void ColorCorrectionConfigWindow::ConnectWidgets()
{
connect(m_correct_color_space, &QCheckBox::toggled, this,
[this] { m_game_color_space->setEnabled(m_correct_color_space->isChecked()); });

connect(m_game_gamma, &ConfigFloatSlider::valueChanged, this, [this] {
m_game_gamma_value->setText(QString::asprintf("%f", m_game_gamma->GetValue()));
});

connect(m_correct_gamma, &QCheckBox::toggled, this, [this] {
// The "m_game_gamma" shouldn't be grayed out as it can still affect the color space correction

// For the moment we leave this enabled even when we are outputting in HDR
// (which means they'd have no influence on the final image),
// mostly because we don't have a simple way to determine if HDR is engaged from here
m_sdr_display_gamma_srgb->setEnabled(m_correct_gamma->isChecked());
m_sdr_display_custom_gamma->setEnabled(m_correct_gamma->isChecked() &&
!m_sdr_display_gamma_srgb->isChecked());
});

connect(m_sdr_display_gamma_srgb, &QCheckBox::toggled, this, [this] {
m_sdr_display_custom_gamma->setEnabled(m_correct_gamma->isChecked() &&
!m_sdr_display_gamma_srgb->isChecked());
});

connect(m_sdr_display_custom_gamma, &ConfigFloatSlider::valueChanged, this, [this] {
m_sdr_display_custom_gamma_value->setText(
QString::asprintf("%f", m_sdr_display_custom_gamma->GetValue()));
});

connect(m_hdr_paper_white_nits, &ConfigFloatSlider::valueChanged, this, [this] {
m_hdr_paper_white_nits_value->setText(
QString::asprintf("%f", m_hdr_paper_white_nits->GetValue()));
});

connect(m_button_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2018 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <QDialog>

class QWidget;
class QLabel;
class ConfigBool;
class ConfigChoice;
class ConfigFloatSlider;
class QDialogButtonBox;

class ColorCorrectionConfigWindow final : public QDialog
{
Q_OBJECT
public:
explicit ColorCorrectionConfigWindow(QWidget* parent);

private:
void Create();
void ConnectWidgets();

ConfigBool* m_correct_color_space;
ConfigChoice* m_game_color_space;
ConfigFloatSlider* m_game_gamma;
QLabel* m_game_gamma_value;
ConfigBool* m_correct_gamma;
ConfigBool* m_sdr_display_gamma_srgb;
ConfigFloatSlider* m_sdr_display_custom_gamma;
QLabel* m_sdr_display_custom_gamma_value;
ConfigFloatSlider* m_hdr_paper_white_nits;
QLabel* m_hdr_paper_white_nits_value;
QDialogButtonBox* m_button_box;
};
36 changes: 36 additions & 0 deletions Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "DolphinQt/Config/ConfigControls/ConfigChoice.h"
#include "DolphinQt/Config/ConfigControls/ConfigRadio.h"
#include "DolphinQt/Config/ConfigControls/ConfigSlider.h"
#include "DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.h"
#include "DolphinQt/Config/Graphics/GraphicsWindow.h"
#include "DolphinQt/Config/Graphics/PostProcessingConfigWindow.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
Expand Down Expand Up @@ -102,6 +103,8 @@ void EnhancementsWidget::CreateWidgets()
m_texture_filtering_combo->addItem(tr("Force Linear and 16x Anisotropic"),
TEXTURE_FILTERING_FORCE_LINEAR_ANISO_16X);

m_configure_color_correction = new NonDefaultQPushButton(tr("Configure"));

m_pp_effect = new ToolTipComboBox();
m_configure_pp_effect = new NonDefaultQPushButton(tr("Configure"));
m_scaled_efb_copy = new ConfigBool(tr("Scaled EFB Copy"), Config::GFX_HACK_COPY_EFB_SCALED);
Expand All @@ -116,6 +119,7 @@ void EnhancementsWidget::CreateWidgets()
new ConfigBool(tr("Disable Copy Filter"), Config::GFX_ENHANCE_DISABLE_COPY_FILTER);
m_arbitrary_mipmap_detection = new ConfigBool(tr("Arbitrary Mipmap Detection"),
Config::GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION);
m_hdr = new ConfigBool(tr("HDR Post-Processing"), Config::GFX_ENHANCE_HDR_OUTPUT);

int row = 0;
enhancements_layout->addWidget(new QLabel(tr("Internal Resolution:")), row, 0);
Expand All @@ -130,6 +134,10 @@ void EnhancementsWidget::CreateWidgets()
enhancements_layout->addWidget(m_texture_filtering_combo, row, 1, 1, -1);
++row;

enhancements_layout->addWidget(new QLabel(tr("Color Correction:")), row, 0);
enhancements_layout->addWidget(m_configure_color_correction, row, 1, 1, -1);
++row;

enhancements_layout->addWidget(new QLabel(tr("Post-Processing Effect:")), row, 0);
enhancements_layout->addWidget(m_pp_effect, row, 1);
enhancements_layout->addWidget(m_configure_pp_effect, row, 2);
Expand All @@ -148,6 +156,7 @@ void EnhancementsWidget::CreateWidgets()
++row;

enhancements_layout->addWidget(m_disable_copy_filter, row, 0);
enhancements_layout->addWidget(m_hdr, row, 1, 1, -1);
++row;

// Stereoscopy
Expand Down Expand Up @@ -188,11 +197,14 @@ void EnhancementsWidget::ConnectWidgets()
[this](int) { SaveSettings(); });
connect(m_3d_mode, qOverload<int>(&QComboBox::currentIndexChanged), [this] {
m_block_save = true;
m_configure_color_correction->setEnabled(g_Config.backend_info.bSupportsPostProcessing);
LoadPPShaders();
m_block_save = false;

SaveSettings();
});
connect(m_configure_color_correction, &QPushButton::clicked, this,
&EnhancementsWidget::ConfigureColorCorrection);
connect(m_configure_pp_effect, &QPushButton::clicked, this,
&EnhancementsWidget::ConfigurePostProcessingShader);
}
Expand Down Expand Up @@ -311,6 +323,8 @@ void EnhancementsWidget::LoadSettings()
break;
}

m_configure_color_correction->setEnabled(g_Config.backend_info.bSupportsPostProcessing);

// Post Processing Shader
LoadPPShaders();

Expand All @@ -320,6 +334,9 @@ void EnhancementsWidget::LoadSettings()
m_3d_convergence->setEnabled(supports_stereoscopy);
m_3d_depth->setEnabled(supports_stereoscopy);
m_3d_swap_eyes->setEnabled(supports_stereoscopy);

m_hdr->setEnabled(g_Config.backend_info.bSupportsHDROutput);

m_block_save = false;
}

Expand Down Expand Up @@ -436,6 +453,9 @@ void EnhancementsWidget::AddDescriptions()
"scaling filter selected by the game.<br><br>Any option except 'Default' will alter the look "
"of the game's textures and might cause issues in a small number of "
"games.<br><br><dolphin_emphasis>If unsure, select 'Default'.</dolphin_emphasis>");
static const char TR_COLOR_CORRECTION_DESCRIPTION[] =
QT_TR_NOOP("A group of features to make the colors more accurate,"
" matching the color space Wii and GC games were meant for.");
static const char TR_POSTPROCESSING_DESCRIPTION[] =
QT_TR_NOOP("Applies a post-processing effect after rendering a frame.<br><br "
"/><dolphin_emphasis>If unsure, select (off).</dolphin_emphasis>");
Expand Down Expand Up @@ -498,6 +518,13 @@ void EnhancementsWidget::AddDescriptions()
"reduce stutter in games that frequently load new textures. This feature is not compatible "
"with GPU Texture Decoding.<br><br><dolphin_emphasis>If unsure, leave this "
"checked.</dolphin_emphasis>");
static const char TR_HDR_DESCRIPTION[] = QT_TR_NOOP(
"Enables scRGB HDR output (if supported by your graphics backend and monitor)."
" Fullscreen might be required."
"<br><br>This gives post process shaders more room for accuracy, allows \"AutoHDR\" "
"post-process shaders to work, and allows to fully display the PAL and NTSC-J color spaces."
"<br><br>Note that games still render in SDR internally."
"<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");

m_ir_combo->SetTitle(tr("Internal Resolution"));
m_ir_combo->SetDescription(tr(TR_INTERNAL_RESOLUTION_DESCRIPTION));
Expand All @@ -508,6 +535,8 @@ void EnhancementsWidget::AddDescriptions()
m_texture_filtering_combo->SetTitle(tr("Texture Filtering"));
m_texture_filtering_combo->SetDescription(tr(TR_FORCE_TEXTURE_FILTERING_DESCRIPTION));

m_configure_color_correction->setToolTip(tr(TR_COLOR_CORRECTION_DESCRIPTION));

m_pp_effect->SetTitle(tr("Post-Processing Effect"));
m_pp_effect->SetDescription(tr(TR_POSTPROCESSING_DESCRIPTION));

Expand All @@ -525,6 +554,8 @@ void EnhancementsWidget::AddDescriptions()

m_arbitrary_mipmap_detection->SetDescription(tr(TR_ARBITRARY_MIPMAP_DETECTION_DESCRIPTION));

m_hdr->SetDescription(tr(TR_HDR_DESCRIPTION));

m_3d_mode->SetTitle(tr("Stereoscopic 3D Mode"));
m_3d_mode->SetDescription(tr(TR_3D_MODE_DESCRIPTION));

Expand All @@ -537,6 +568,11 @@ void EnhancementsWidget::AddDescriptions()
m_3d_swap_eyes->SetDescription(tr(TR_3D_SWAP_EYES_DESCRIPTION));
}

void EnhancementsWidget::ConfigureColorCorrection()
{
ColorCorrectionConfigWindow(this).exec();
}

void EnhancementsWidget::ConfigurePostProcessingShader()
{
const std::string shader = Config::Get(Config::GFX_ENHANCE_POST_SHADER);
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class EnhancementsWidget final : public QWidget
void CreateWidgets();
void ConnectWidgets();
void AddDescriptions();
void ConfigureColorCorrection();
void ConfigurePostProcessingShader();
void LoadPPShaders();

Expand All @@ -38,6 +39,7 @@ class EnhancementsWidget final : public QWidget
ToolTipComboBox* m_aa_combo;
ToolTipComboBox* m_texture_filtering_combo;
ToolTipComboBox* m_pp_effect;
QPushButton* m_configure_color_correction;
QPushButton* m_configure_pp_effect;
ConfigBool* m_scaled_efb_copy;
ConfigBool* m_per_pixel_lighting;
Expand All @@ -46,6 +48,7 @@ class EnhancementsWidget final : public QWidget
ConfigBool* m_force_24bit_color;
ConfigBool* m_disable_copy_filter;
ConfigBool* m_arbitrary_mipmap_detection;
ConfigBool* m_hdr;

// Stereoscopy
ConfigChoice* m_3d_mode;
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/DolphinQt.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
<ClCompile Include="Config\Graphics\GeneralWidget.cpp" />
<ClCompile Include="Config\Graphics\GraphicsWindow.cpp" />
<ClCompile Include="Config\Graphics\HacksWidget.cpp" />
<ClCompile Include="Config\Graphics\ColorCorrectionConfigWindow.cpp" />
<ClCompile Include="Config\Graphics\PostProcessingConfigWindow.cpp" />
<ClCompile Include="Config\GraphicsModListWidget.cpp" />
<ClCompile Include="Config\GraphicsModWarningWidget.cpp" />
Expand Down Expand Up @@ -283,6 +284,7 @@
<QtMoc Include="Config\Graphics\GeneralWidget.h" />
<QtMoc Include="Config\Graphics\GraphicsWindow.h" />
<QtMoc Include="Config\Graphics\HacksWidget.h" />
<QtMoc Include="Config\Graphics\ColorCorrectionConfigWindow.h" />
<QtMoc Include="Config\Graphics\PostProcessingConfigWindow.h" />
<QtMoc Include="Config\GraphicsModListWidget.h" />
<QtMoc Include="Config\GraphicsModWarningWidget.h" />
Expand Down

0 comments on commit daddf4c

Please sign in to comment.