mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
Merge pull request #8069 from iwubcode/passive_support
VideoCommon: Implement passive stereoscopic 3D
This commit is contained in:
commit
707266aeed
7
Data/Sys/Shaders/Passive/horizontal.glsl
Normal file
7
Data/Sys/Shaders/Passive/horizontal.glsl
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Passive (horizontal rows) shader
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
float screen_row = GetWindowResolution().y * GetCoordinates().y;
|
||||||
|
SetOutput(SampleLayer(int(screen_row) % 2));
|
||||||
|
}
|
@ -62,6 +62,7 @@
|
|||||||
#define THEMES_DIR "Themes"
|
#define THEMES_DIR "Themes"
|
||||||
#define STYLES_DIR "Styles"
|
#define STYLES_DIR "Styles"
|
||||||
#define ANAGLYPH_DIR "Anaglyph"
|
#define ANAGLYPH_DIR "Anaglyph"
|
||||||
|
#define PASSIVE_DIR "Passive"
|
||||||
#define PIPES_DIR "Pipes"
|
#define PIPES_DIR "Pipes"
|
||||||
#define MEMORYWATCHER_DIR "MemoryWatcher"
|
#define MEMORYWATCHER_DIR "MemoryWatcher"
|
||||||
#define WFSROOT_DIR "WFS"
|
#define WFSROOT_DIR "WFS"
|
||||||
|
@ -109,8 +109,8 @@ void EnhancementsWidget::CreateWidgets()
|
|||||||
auto* stereoscopy_layout = new QGridLayout();
|
auto* stereoscopy_layout = new QGridLayout();
|
||||||
stereoscopy_box->setLayout(stereoscopy_layout);
|
stereoscopy_box->setLayout(stereoscopy_layout);
|
||||||
|
|
||||||
m_3d_mode = new GraphicsChoice(
|
m_3d_mode = new GraphicsChoice({tr("Off"), tr("Side-by-Side"), tr("Top-and-Bottom"),
|
||||||
{tr("Off"), tr("Side-by-Side"), tr("Top-and-Bottom"), tr("Anaglyph"), tr("HDMI 3D")},
|
tr("Anaglyph"), tr("HDMI 3D"), tr("Passive")},
|
||||||
Config::GFX_STEREO_MODE);
|
Config::GFX_STEREO_MODE);
|
||||||
m_3d_depth = new GraphicsSlider(0, 100, Config::GFX_STEREO_DEPTH);
|
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_convergence = new GraphicsSlider(0, 200, Config::GFX_STEREO_CONVERGENCE, 100);
|
||||||
@ -151,14 +151,19 @@ void EnhancementsWidget::ConnectWidgets()
|
|||||||
|
|
||||||
void EnhancementsWidget::LoadPPShaders()
|
void EnhancementsWidget::LoadPPShaders()
|
||||||
{
|
{
|
||||||
const bool anaglyph = g_Config.stereo_mode == StereoMode::Anaglyph;
|
std::vector<std::string> shaders = VideoCommon::PostProcessing::GetShaderList();
|
||||||
std::vector<std::string> shaders = anaglyph ?
|
if (g_Config.stereo_mode == StereoMode::Anaglyph)
|
||||||
VideoCommon::PostProcessing::GetAnaglyphShaderList() :
|
{
|
||||||
VideoCommon::PostProcessing::GetShaderList();
|
shaders = VideoCommon::PostProcessing::GetAnaglyphShaderList();
|
||||||
|
}
|
||||||
|
else if (g_Config.stereo_mode == StereoMode::Passive)
|
||||||
|
{
|
||||||
|
shaders = VideoCommon::PostProcessing::GetPassiveShaderList();
|
||||||
|
}
|
||||||
|
|
||||||
m_pp_effect->clear();
|
m_pp_effect->clear();
|
||||||
|
|
||||||
if (!anaglyph)
|
if (g_Config.stereo_mode != StereoMode::Anaglyph && g_Config.stereo_mode != StereoMode::Passive)
|
||||||
m_pp_effect->addItem(tr("(off)"));
|
m_pp_effect->addItem(tr("(off)"));
|
||||||
|
|
||||||
auto selected_shader = Config::Get(Config::GFX_ENHANCE_POST_SHADER);
|
auto selected_shader = Config::Get(Config::GFX_ENHANCE_POST_SHADER);
|
||||||
@ -175,8 +180,10 @@ void EnhancementsWidget::LoadPPShaders()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anaglyph && !found)
|
if (g_Config.stereo_mode == StereoMode::Anaglyph && !found)
|
||||||
m_pp_effect->setCurrentIndex(m_pp_effect->findText(QStringLiteral("dubois")));
|
m_pp_effect->setCurrentIndex(m_pp_effect->findText(QStringLiteral("dubois")));
|
||||||
|
else if (g_Config.stereo_mode == StereoMode::Passive && !found)
|
||||||
|
m_pp_effect->setCurrentIndex(m_pp_effect->findText(QStringLiteral("horizontal")));
|
||||||
|
|
||||||
const bool supports_postprocessing = g_Config.backend_info.bSupportsPostProcessing;
|
const bool supports_postprocessing = g_Config.backend_info.bSupportsPostProcessing;
|
||||||
m_pp_effect->setEnabled(supports_postprocessing);
|
m_pp_effect->setEnabled(supports_postprocessing);
|
||||||
@ -221,7 +228,7 @@ void EnhancementsWidget::LoadSettings()
|
|||||||
bool supports_stereoscopy = g_Config.backend_info.bSupportsGeometryShaders;
|
bool supports_stereoscopy = g_Config.backend_info.bSupportsGeometryShaders;
|
||||||
bool supports_3dvision = g_Config.backend_info.bSupports3DVision;
|
bool supports_3dvision = g_Config.backend_info.bSupports3DVision;
|
||||||
|
|
||||||
bool has_3dvision = m_3d_mode->count() == 6;
|
bool has_3dvision = m_3d_mode->count() == 7;
|
||||||
|
|
||||||
if (has_3dvision && !supports_3dvision)
|
if (has_3dvision && !supports_3dvision)
|
||||||
m_3d_mode->removeItem(5);
|
m_3d_mode->removeItem(5);
|
||||||
@ -260,8 +267,9 @@ void EnhancementsWidget::SaveSettings()
|
|||||||
Config::SetBaseOrCurrent(Config::GFX_SSAA, is_ssaa);
|
Config::SetBaseOrCurrent(Config::GFX_SSAA, is_ssaa);
|
||||||
|
|
||||||
const bool anaglyph = g_Config.stereo_mode == StereoMode::Anaglyph;
|
const bool anaglyph = g_Config.stereo_mode == StereoMode::Anaglyph;
|
||||||
|
const bool passive = g_Config.stereo_mode == StereoMode::Passive;
|
||||||
Config::SetBaseOrCurrent(Config::GFX_ENHANCE_POST_SHADER,
|
Config::SetBaseOrCurrent(Config::GFX_ENHANCE_POST_SHADER,
|
||||||
(!anaglyph && m_pp_effect->currentIndex() == 0) ?
|
(!anaglyph && !passive && m_pp_effect->currentIndex() == 0) ?
|
||||||
"(off)" :
|
"(off)" :
|
||||||
m_pp_effect->currentText().toStdString());
|
m_pp_effect->currentText().toStdString());
|
||||||
|
|
||||||
@ -324,7 +332,8 @@ void EnhancementsWidget::AddDescriptions()
|
|||||||
"Selects the stereoscopic 3D mode. Stereoscopy allows a better feeling "
|
"Selects the stereoscopic 3D mode. Stereoscopy allows a better feeling "
|
||||||
"of depth if the necessary hardware is present.\n\nSide-by-Side and Top-and-Bottom are "
|
"of depth if the necessary hardware is present.\n\nSide-by-Side and Top-and-Bottom are "
|
||||||
"used by most 3D TVs.\nAnaglyph is used for Red-Cyan colored glasses.\nHDMI 3D is "
|
"used by most 3D TVs.\nAnaglyph is used for Red-Cyan colored glasses.\nHDMI 3D is "
|
||||||
"used when the monitor supports 3D display resolutions.\n\nHeavily decreases "
|
"used when the monitor supports 3D display resolutions.\nPassive is another type of 3D "
|
||||||
|
"used by some TVs.\n\nHeavily decreases "
|
||||||
"emulation speed and sometimes causes issues.\n\nIf unsure, select Off.");
|
"emulation speed and sometimes causes issues.\n\nIf unsure, select Off.");
|
||||||
static const char TR_3D_DEPTH_DESCRIPTION[] = QT_TR_NOOP(
|
static const char TR_3D_DEPTH_DESCRIPTION[] = QT_TR_NOOP(
|
||||||
"Controls the separation distance between the virtual cameras. \n\nA higher "
|
"Controls the separation distance between the virtual cameras. \n\nA higher "
|
||||||
|
@ -44,8 +44,16 @@ void PostProcessingConfiguration::LoadShader(const std::string& shader)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string sub_dir =
|
std::string sub_dir = "";
|
||||||
(g_Config.stereo_mode == StereoMode::Anaglyph) ? ANAGLYPH_DIR DIR_SEP : "";
|
|
||||||
|
if (g_Config.stereo_mode == StereoMode::Anaglyph)
|
||||||
|
{
|
||||||
|
sub_dir = ANAGLYPH_DIR DIR_SEP;
|
||||||
|
}
|
||||||
|
else if (g_Config.stereo_mode == StereoMode::Passive)
|
||||||
|
{
|
||||||
|
sub_dir = PASSIVE_DIR DIR_SEP;
|
||||||
|
}
|
||||||
|
|
||||||
// loading shader code
|
// loading shader code
|
||||||
std::string code;
|
std::string code;
|
||||||
@ -364,6 +372,11 @@ std::vector<std::string> PostProcessing::GetAnaglyphShaderList()
|
|||||||
return GetShaders(ANAGLYPH_DIR DIR_SEP);
|
return GetShaders(ANAGLYPH_DIR DIR_SEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> PostProcessing::GetPassiveShaderList()
|
||||||
|
{
|
||||||
|
return GetShaders(PASSIVE_DIR DIR_SEP);
|
||||||
|
}
|
||||||
|
|
||||||
bool PostProcessing::Initialize(AbstractTextureFormat format)
|
bool PostProcessing::Initialize(AbstractTextureFormat format)
|
||||||
{
|
{
|
||||||
m_framebuffer_format = format;
|
m_framebuffer_format = format;
|
||||||
@ -425,6 +438,7 @@ std::string PostProcessing::GetUniformBufferHeader() const
|
|||||||
|
|
||||||
// Builtin uniforms
|
// Builtin uniforms
|
||||||
ss << " float4 resolution;\n";
|
ss << " float4 resolution;\n";
|
||||||
|
ss << " float4 window_resolution;\n";
|
||||||
ss << " float4 src_rect;\n";
|
ss << " float4 src_rect;\n";
|
||||||
ss << " uint time;\n";
|
ss << " uint time;\n";
|
||||||
ss << " int layer;\n";
|
ss << " int layer;\n";
|
||||||
@ -508,6 +522,11 @@ float4 SampleLocation(float2 location) { return texture(samp0, float3(location,
|
|||||||
float4 SampleLayer(int layer) { return texture(samp0, float3(v_tex0.xy, float(layer))); }
|
float4 SampleLayer(int layer) { return texture(samp0, float3(v_tex0.xy, float(layer))); }
|
||||||
#define SampleOffset(offset) textureOffset(samp0, float3(v_tex0.xy, float(layer)), offset)
|
#define SampleOffset(offset) textureOffset(samp0, float3(v_tex0.xy, float(layer)), offset)
|
||||||
|
|
||||||
|
float2 GetWindowResolution()
|
||||||
|
{
|
||||||
|
return window_resolution.xy;
|
||||||
|
}
|
||||||
|
|
||||||
float2 GetResolution()
|
float2 GetResolution()
|
||||||
{
|
{
|
||||||
return resolution.xy;
|
return resolution.xy;
|
||||||
@ -599,6 +618,7 @@ bool PostProcessing::CompileVertexShader()
|
|||||||
struct BuiltinUniforms
|
struct BuiltinUniforms
|
||||||
{
|
{
|
||||||
float resolution[4];
|
float resolution[4];
|
||||||
|
float window_resolution[4];
|
||||||
float src_rect[4];
|
float src_rect[4];
|
||||||
s32 time;
|
s32 time;
|
||||||
u32 layer;
|
u32 layer;
|
||||||
@ -614,11 +634,14 @@ size_t PostProcessing::CalculateUniformsSize() const
|
|||||||
void PostProcessing::FillUniformBuffer(const MathUtil::Rectangle<int>& src,
|
void PostProcessing::FillUniformBuffer(const MathUtil::Rectangle<int>& src,
|
||||||
const AbstractTexture* src_tex, int src_layer)
|
const AbstractTexture* src_tex, int src_layer)
|
||||||
{
|
{
|
||||||
|
const auto& window_rect = g_renderer->GetTargetRectangle();
|
||||||
const float rcp_src_width = 1.0f / src_tex->GetWidth();
|
const float rcp_src_width = 1.0f / src_tex->GetWidth();
|
||||||
const float rcp_src_height = 1.0f / src_tex->GetHeight();
|
const float rcp_src_height = 1.0f / src_tex->GetHeight();
|
||||||
BuiltinUniforms builtin_uniforms = {
|
BuiltinUniforms builtin_uniforms = {
|
||||||
{static_cast<float>(src_tex->GetWidth()), static_cast<float>(src_tex->GetHeight()),
|
{static_cast<float>(src_tex->GetWidth()), static_cast<float>(src_tex->GetHeight()),
|
||||||
rcp_src_width, rcp_src_height},
|
rcp_src_width, rcp_src_height},
|
||||||
|
{static_cast<float>(window_rect.GetWidth()), static_cast<float>(window_rect.GetHeight()),
|
||||||
|
0.0f, 0.0f},
|
||||||
{static_cast<float>(src.left) * rcp_src_width, static_cast<float>(src.top) * rcp_src_height,
|
{static_cast<float>(src.left) * rcp_src_width, static_cast<float>(src.top) * rcp_src_height,
|
||||||
static_cast<float>(src.GetWidth()) * rcp_src_width,
|
static_cast<float>(src.GetWidth()) * rcp_src_width,
|
||||||
static_cast<float>(src.GetHeight()) * rcp_src_height},
|
static_cast<float>(src.GetHeight()) * rcp_src_height},
|
||||||
|
@ -94,6 +94,7 @@ public:
|
|||||||
virtual ~PostProcessing();
|
virtual ~PostProcessing();
|
||||||
|
|
||||||
static std::vector<std::string> GetShaderList();
|
static std::vector<std::string> GetShaderList();
|
||||||
|
static std::vector<std::string> GetPassiveShaderList();
|
||||||
static std::vector<std::string> GetAnaglyphShaderList();
|
static std::vector<std::string> GetAnaglyphShaderList();
|
||||||
|
|
||||||
PostProcessingConfiguration* GetConfig() { return &m_config; }
|
PostProcessingConfiguration* GetConfig() { return &m_config; }
|
||||||
|
@ -39,7 +39,8 @@ enum class StereoMode : int
|
|||||||
TAB,
|
TAB,
|
||||||
Anaglyph,
|
Anaglyph,
|
||||||
QuadBuffer,
|
QuadBuffer,
|
||||||
Nvidia3DVision
|
Passive,
|
||||||
|
Nvidia3DVision,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ShaderCompilationMode : int
|
enum class ShaderCompilationMode : int
|
||||||
|
Loading…
Reference in New Issue
Block a user