From e64a2d4e098987518af7e32e8c06fda328f61841 Mon Sep 17 00:00:00 2001 From: spycrab Date: Fri, 16 Jun 2017 01:43:38 +0200 Subject: [PATCH] Qt/GraphicsSettings: Implement enhancements tab --- .../Config/Graphics/EnhancementsWidget.cpp | 301 ++++++++++++++++++ .../Config/Graphics/EnhancementsWidget.h | 50 +++ 2 files changed, 351 insertions(+) create mode 100644 Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h diff --git a/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp new file mode 100644 index 0000000000..263dc50248 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp @@ -0,0 +1,301 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/EnhancementsWidget.h" + +#include + +#include +#include +#include +#include +#include + +#include "Core/Config/GraphicsSettings.h" +#include "Core/ConfigManager.h" +#include "DolphinQt2/Config/Graphics/GraphicsBool.h" +#include "DolphinQt2/Config/Graphics/GraphicsChoice.h" +#include "DolphinQt2/Config/Graphics/GraphicsSlider.h" +#include "DolphinQt2/Config/Graphics/GraphicsWindow.h" +#include "DolphinQt2/Settings.h" +#include "UICommon/VideoUtils.h" +#include "VideoCommon/PostProcessing.h" +#include "VideoCommon/VideoConfig.h" + +EnhancementsWidget::EnhancementsWidget(GraphicsWindow* parent) + : GraphicsWidget(parent), m_block_save(false) +{ + CreateWidgets(); + LoadSettings(); + ConnectWidgets(); + AddDescriptions(); + connect(parent, &GraphicsWindow::BackendChanged, + [this](const QString& backend) { LoadSettings(); }); +} + +void EnhancementsWidget::CreateWidgets() +{ + auto* main_layout = new QVBoxLayout; + + // Enhancements + auto* enhancements_box = new QGroupBox(tr("Enhancements")); + auto* enhancements_layout = new QGridLayout(); + enhancements_box->setLayout(enhancements_layout); + + m_ir_combo = new GraphicsChoice( + {tr("Auto (Window Size)"), tr("Auto (Multiple of 640x528)"), tr("Native (640x528)"), + tr("1.5x Native (960x792)"), tr("2x Native (1280x1056) for 720p"), + tr("2.5x Native (1600x1320)"), tr("3x Native (1920x1584) for 1080p"), + tr("4x Native (2560x2112) for 1440p"), tr("5x Native (3200x2640)"), + tr("6x Native (3840x3168) for 4K"), tr("7x Native (4480x3696)"), + tr("8x Native (5120x4224) for 5K")}, + Config::GFX_EFB_SCALE); + + if (g_Config.iEFBScale > 11) + { + m_ir_combo->addItem(tr("Custom")); + m_ir_combo->setCurrentIndex(m_ir_combo->count() - 1); + } + + m_ir_combo->setMaxVisibleItems(m_ir_combo->count()); + + m_aa_combo = new QComboBox(); + m_af_combo = new GraphicsChoice({tr("1x"), tr("2x"), tr("4x"), tr("8x"), tr("16x")}, + Config::GFX_ENHANCE_MAX_ANISOTROPY); + m_pp_effect = new QComboBox(); + m_configure_pp_effect = new QPushButton(tr("Configure")); + m_scaled_efb_copy = new GraphicsBool(tr("Scaled EFB Copy"), Config::GFX_HACK_COPY_EFB_ENABLED); + m_per_pixel_lighting = + new GraphicsBool(tr("Per-Pixel Lighting"), Config::GFX_ENABLE_PIXEL_LIGHTING); + m_force_texture_filtering = + new GraphicsBool(tr("Force Texture Filtering"), Config::GFX_ENHANCE_FORCE_FILTERING); + m_widescreen_hack = new GraphicsBool(tr("Widescreen Hack"), Config::GFX_WIDESCREEN_HACK); + m_disable_fog = new GraphicsBool(tr("Disable Fog"), Config::GFX_DISABLE_FOG); + m_force_24bit_color = + new GraphicsBool(tr("Force 24-bit Color"), Config::GFX_ENHANCE_FORCE_TRUE_COLOR); + + enhancements_layout->addWidget(new QLabel(tr("Internal Resolution:")), 0, 0); + enhancements_layout->addWidget(m_ir_combo, 0, 1, 1, -1); + enhancements_layout->addWidget(new QLabel(tr("Anti-Aliasing")), 1, 0); + enhancements_layout->addWidget(m_aa_combo, 1, 1, 1, -1); + enhancements_layout->addWidget(new QLabel(tr("Antisotrophic Filtering:")), 2, 0); + enhancements_layout->addWidget(m_af_combo, 2, 1, 1, -1); + enhancements_layout->addWidget(new QLabel(tr("Post-Processing Effect:")), 3, 0); + enhancements_layout->addWidget(m_pp_effect, 3, 1); + enhancements_layout->addWidget(m_configure_pp_effect, 3, 2); + + enhancements_layout->addWidget(m_scaled_efb_copy, 4, 0); + enhancements_layout->addWidget(m_per_pixel_lighting, 4, 1); + enhancements_layout->addWidget(m_force_texture_filtering, 5, 0); + enhancements_layout->addWidget(m_widescreen_hack, 5, 1); + enhancements_layout->addWidget(m_disable_fog, 6, 0); + enhancements_layout->addWidget(m_force_24bit_color, 6, 1); + + // Stereoscopy + auto* stereoscopy_box = new QGroupBox(tr("Stereoscopy")); + auto* stereoscopy_layout = new QGridLayout(); + stereoscopy_box->setLayout(stereoscopy_layout); + + m_3d_mode = + new GraphicsChoice({tr("Off"), tr("Side-by-Side"), tr("Top-and-Bottom"), tr("Anaglyph")}, + Config::GFX_STEREO_MODE); + m_3d_depth = new GraphicsSlider(0, 100, Config::GFX_STEREO_DEPTH); + m_3d_convergence = new GraphicsSlider(0, 200, Config::GFX_STEREO_CONVERGENCE, 100); + m_3d_swap_eyes = new GraphicsBool(tr("Swap Eyes"), Config::GFX_STEREO_SWAP_EYES); + + stereoscopy_layout->addWidget(new QLabel(tr("Stereoscopic 3D Mode:")), 0, 0); + stereoscopy_layout->addWidget(m_3d_mode, 0, 1); + stereoscopy_layout->addWidget(new QLabel(tr("Depth:")), 1, 0); + stereoscopy_layout->addWidget(m_3d_depth, 1, 1); + stereoscopy_layout->addWidget(new QLabel(tr("Convergence:")), 2, 0); + stereoscopy_layout->addWidget(m_3d_convergence, 2, 1); + stereoscopy_layout->addWidget(m_3d_swap_eyes, 3, 0); + + main_layout->addWidget(enhancements_box); + main_layout->addWidget(stereoscopy_box); + + setLayout(main_layout); +} + +void EnhancementsWidget::ConnectWidgets() +{ + connect(m_aa_combo, static_cast(&QComboBox::currentIndexChanged), + [this](int) { SaveSettings(); }); + connect(m_pp_effect, static_cast(&QComboBox::currentIndexChanged), + [this](int) { SaveSettings(); }); + connect(m_3d_mode, static_cast(&QComboBox::currentIndexChanged), + [this](int) { SaveSettings(); }); +} + +void EnhancementsWidget::LoadSettings() +{ + m_block_save = true; + // Anti-Aliasing + + int aa_selection = Config::Get(Config::GFX_MSAA); + bool ssaa = Config::Get(Config::GFX_SSAA); + + m_aa_combo->clear(); + for (const auto& option : VideoUtils::GetAvailableAntialiasingModes(m_msaa_modes)) + m_aa_combo->addItem(option == "None" ? tr("None") : QString::fromStdString(option)); + + m_aa_combo->setCurrentText( + QString::fromStdString(std::to_string(aa_selection) + "x " + (ssaa ? "SSAA" : "MSAA"))); + m_aa_combo->setEnabled(m_aa_combo->count() > 1); + + // Post Processing Shader + std::vector shaders = + g_Config.iStereoMode == STEREO_ANAGLYPH ? + PostProcessingShaderImplementation::GetAnaglyphShaderList( + g_Config.backend_info.api_type) : + PostProcessingShaderImplementation::GetShaderList(g_Config.backend_info.api_type); + + m_pp_effect->clear(); + m_pp_effect->addItem(tr("(off)")); + + const auto selected_shader = Config::Get(Config::GFX_ENHANCE_POST_SHADER); + + for (const auto& shader : shaders) + { + m_pp_effect->addItem(QString::fromStdString(shader)); + if (selected_shader == shader) + m_pp_effect->setCurrentIndex(m_pp_effect->count() - 1); + } + + PostProcessingShaderConfiguration pp_shader; + if (selected_shader != "(off)") + { + pp_shader.LoadShader(selected_shader); + m_configure_pp_effect->setEnabled(pp_shader.HasOptions()); + } + bool supports_stereoscopy = g_Config.backend_info.bSupportsGeometryShaders; + + m_3d_mode->setEnabled(supports_stereoscopy); + m_3d_convergence->setEnabled(supports_stereoscopy); + m_3d_depth->setEnabled(supports_stereoscopy); + m_3d_swap_eyes->setEnabled(supports_stereoscopy); + m_block_save = false; +} + +void EnhancementsWidget::SaveSettings() +{ + if (m_block_save) + return; + + bool is_ssaa = m_aa_combo->currentText().endsWith(QStringLiteral("SSAA")); + + int aa_value = m_aa_combo->currentIndex(); + + if (aa_value == 0) + { + aa_value = 1; + } + else + { + if (aa_value > m_msaa_modes) + aa_value -= m_msaa_modes; + aa_value = std::pow(2, aa_value); + } + Config::SetBaseOrCurrent(Config::GFX_MSAA, static_cast(aa_value)); + + Config::SetBaseOrCurrent(Config::GFX_SSAA, is_ssaa); + + Config::SetBaseOrCurrent(Config::GFX_ENHANCE_POST_SHADER, + m_pp_effect->currentText().toStdString()); + + PostProcessingShaderConfiguration pp_shader; + if (Config::Get(Config::GFX_ENHANCE_POST_SHADER) != "(off)") + { + pp_shader.LoadShader(Config::Get(Config::GFX_ENHANCE_POST_SHADER)); + m_configure_pp_effect->setEnabled(pp_shader.HasOptions()); + } + else + { + m_configure_pp_effect->setEnabled(false); + } +} + +void EnhancementsWidget::AddDescriptions() +{ + static const char* TR_INTERNAL_RESOLUTION_DESCRIPTION = + QT_TR_NOOP("Specifies the resolution used to render at. A high resolution greatly improves " + "visual quality, but also greatly increases GPU load and can cause issues in " + "certain games.\n\"Multiple of 640x528\" will result in a size slightly larger " + "than \"Window Size\" but yield fewer issues. Generally speaking, the lower the " + "internal resolution is, the better your performance will be. Auto (Window Size), " + "1.5x, and 2.5x may cause issues in some games.\n\nIf unsure, select Native."); + + static const char* TR_ANTIALIAS_DESCRIPTION = + QT_TR_NOOP("Reduces the amount of aliasing caused by rasterizing 3D graphics. This smooths " + "out jagged edges on objects.\nIncreases GPU load and sometimes causes graphical " + "issues. SSAA is significantly more demanding than MSAA, but provides top quality " + "geometry anti-aliasing and also applies anti-aliasing to lighting, shader " + "effects, and textures.\n\nIf unsure, select None."); + + static const char* TR_ANTISTROPIC_FILTERING_DESCRIPTION = QT_TR_NOOP( + "Enable anisotropic filtering.\nEnhances visual quality of textures that are at oblique " + "viewing angles.\nMight cause issues in a small number of games.\n\nIf unsure, select 1x."); + + static const char* TR_POSTPROCESSING_DESCRIPTION = QT_TR_NOOP( + "Apply a post-processing effect after finishing a frame.\n\nIf unsure, select (off)."); + + static const char* TR_SCALED_EFB_COPY_DESCRIPTION = QT_TR_NOOP( + "Greatly increases quality of textures generated using render-to-texture " + "effects.\nRaising the " + "internal resolution will improve the effect of this setting.\nSlightly increases GPU " + "load and " + "causes relatively few graphical issues.\n\nIf unsure, leave this checked."); + static const char* TR_PER_PIXEL_LIGHTING_DESCRIPTION = QT_TR_NOOP( + "Calculates lighting of 3D objects per-pixel rather than per-vertex, smoothing out the " + "appearance of lit polygons and making individual triangles less noticeable.\nRarely causes " + "slowdowns or graphical issues.\n\nIf unsure, leave this unchecked."); + static const char* TR_WIDESCREEN_HACK_DESCRIPTION = QT_TR_NOOP( + "Forces the game to output graphics for any aspect ratio.\nUse with \"Aspect Ratio\" set to " + "\"Force 16:9\" to force 4:3-only games to run at 16:9.\nRarely produces good results and " + "often partially breaks graphics and game UIs.\nUnnecessary (and detrimental) if using any " + "AR/Gecko-code widescreen patches.\n\nIf unsure, leave this unchecked."); + static const char* TR_REMOVE_FOG_DESCRIPTION = + QT_TR_NOOP("Makes distant objects more visible by removing fog, thus increasing the overall " + "detail.\nDisabling fog will break some games which rely on proper fog " + "emulation.\n\nIf unsure, leave this unchecked."); + + static const char* TR_3D_MODE_DESCRIPTION = QT_TR_NOOP( + "Selects the stereoscopic 3D mode. Stereoscopy allows you to get a better feeling " + "of depth if you have the necessary hardware.\nSide-by-Side and Top-and-Bottom are " + "used by most 3D TVs.\nAnaglyph is used for Red-Cyan colored glasses.\nHeavily " + "decreases emulation speed and sometimes causes issues.\n\nIf unsure, select Off."); + static const char* TR_3D_DEPTH_DESCRIPTION = + QT_TR_NOOP("Controls the separation distance between the virtual cameras.\nA higher value " + "creates a stronger feeling of depth while a lower value is more comfortable."); + static const char* TR_3D_CONVERGENCE_DESCRIPTION = QT_TR_NOOP( + "Controls the distance of the convergence plane. This is the distance at which " + "virtual objects will appear to be in front of the screen.\nA higher value creates " + "stronger out-of-screen effects while a lower value is more comfortable."); + static const char* TR_3D_SWAP_EYES_DESCRIPTION = + QT_TR_NOOP("Swaps the left and right eye. Mostly useful if you want to view side-by-side " + "cross-eyed.\n\nIf unsure, leave this unchecked."); + static const char* TR_FORCE_24BIT_DESCRIPTION = + QT_TR_NOOP("Forces the game to render the RGB color channels in 24-bit, thereby increasing " + "quality by reducing color banding.\nIt has no impact on performance and causes " + "few graphical issues.\n\n\nIf unsure, leave this checked."); + static const char* TR_FORCE_TEXTURE_FILTERING_DESCRIPTION = + QT_TR_NOOP("Filter all textures, including any that the game explicitly set as " + "unfiltered.\nMay improve quality of certain textures in some games, but will " + "cause issues in others.\n\nIf unsure, leave this unchecked."); + + AddDescription(m_ir_combo, TR_INTERNAL_RESOLUTION_DESCRIPTION); + AddDescription(m_aa_combo, TR_ANTIALIAS_DESCRIPTION); + AddDescription(m_af_combo, TR_ANTISTROPIC_FILTERING_DESCRIPTION); + AddDescription(m_pp_effect, TR_POSTPROCESSING_DESCRIPTION); + AddDescription(m_scaled_efb_copy, TR_SCALED_EFB_COPY_DESCRIPTION); + AddDescription(m_per_pixel_lighting, TR_PER_PIXEL_LIGHTING_DESCRIPTION); + AddDescription(m_widescreen_hack, TR_WIDESCREEN_HACK_DESCRIPTION); + AddDescription(m_disable_fog, TR_REMOVE_FOG_DESCRIPTION); + AddDescription(m_force_24bit_color, TR_FORCE_24BIT_DESCRIPTION); + AddDescription(m_force_texture_filtering, TR_FORCE_TEXTURE_FILTERING_DESCRIPTION); + AddDescription(m_3d_mode, TR_3D_MODE_DESCRIPTION); + AddDescription(m_3d_depth, TR_3D_DEPTH_DESCRIPTION); + AddDescription(m_3d_convergence, TR_3D_CONVERGENCE_DESCRIPTION); + AddDescription(m_3d_swap_eyes, TR_3D_SWAP_EYES_DESCRIPTION); +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h b/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h new file mode 100644 index 0000000000..ac23ed84e9 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h @@ -0,0 +1,50 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "DolphinQt2/Config/Graphics/GraphicsWidget.h" + +class GraphicsWindow; +class QCheckBox; +class QComboBox; +class QPushButton; +class QSlider; + +class EnhancementsWidget final : public GraphicsWidget +{ + Q_OBJECT +public: + explicit EnhancementsWidget(GraphicsWindow* parent); + +private: + void LoadSettings() override; + void SaveSettings() override; + + void CreateWidgets(); + void ConnectWidgets(); + void AddDescriptions(); + + // Enhancements + QComboBox* m_ir_combo; + QComboBox* m_aa_combo; + QComboBox* m_af_combo; + QComboBox* m_pp_effect; + QPushButton* m_configure_pp_effect; + QCheckBox* m_scaled_efb_copy; + QCheckBox* m_per_pixel_lighting; + QCheckBox* m_force_texture_filtering; + QCheckBox* m_widescreen_hack; + QCheckBox* m_disable_fog; + QCheckBox* m_force_24bit_color; + + // Stereoscopy + QComboBox* m_3d_mode; + QSlider* m_3d_depth; + QSlider* m_3d_convergence; + QCheckBox* m_3d_swap_eyes; + + int m_msaa_modes; + bool m_block_save; +};