mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 22:59:47 -06:00
PostProcessing: Add layered stereoscopy support.
This commit is contained in:
@ -36,7 +36,7 @@ static char s_vertex_shader[] =
|
|||||||
" uv0 = rawpos * src_rect.zw + src_rect.xy;\n"
|
" uv0 = rawpos * src_rect.zw + src_rect.xy;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
OpenGLPostProcessing::OpenGLPostProcessing()
|
OpenGLPostProcessing::OpenGLPostProcessing() : m_initialized(false)
|
||||||
{
|
{
|
||||||
CreateHeader();
|
CreateHeader();
|
||||||
|
|
||||||
@ -46,8 +46,6 @@ OpenGLPostProcessing::OpenGLPostProcessing()
|
|||||||
glGenBuffers(1, &m_attribute_vbo);
|
glGenBuffers(1, &m_attribute_vbo);
|
||||||
glGenVertexArrays(1, &m_attribute_vao);
|
glGenVertexArrays(1, &m_attribute_vao);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_initialized = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLPostProcessing::~OpenGLPostProcessing()
|
OpenGLPostProcessing::~OpenGLPostProcessing()
|
||||||
@ -62,7 +60,7 @@ OpenGLPostProcessing::~OpenGLPostProcessing()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle dst,
|
void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle dst,
|
||||||
int src_texture, int src_width, int src_height)
|
int src_texture, int src_width, int src_height, int layer)
|
||||||
{
|
{
|
||||||
ApplyShader();
|
ApplyShader();
|
||||||
|
|
||||||
@ -79,6 +77,7 @@ void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle
|
|||||||
glUniform4f(m_uniform_src_rect, src.left / (float) src_width, src.bottom / (float) src_height,
|
glUniform4f(m_uniform_src_rect, src.left / (float) src_width, src.bottom / (float) src_height,
|
||||||
src.GetWidth() / (float) src_width, src.GetHeight() / (float) src_height);
|
src.GetWidth() / (float) src_width, src.GetHeight() / (float) src_height);
|
||||||
glUniform1ui(m_uniform_time, (GLuint)m_timer.GetTimeElapsed());
|
glUniform1ui(m_uniform_time, (GLuint)m_timer.GetTimeElapsed());
|
||||||
|
glUniform1i(m_uniform_layer, layer);
|
||||||
|
|
||||||
if (m_config.IsDirty())
|
if (m_config.IsDirty())
|
||||||
{
|
{
|
||||||
@ -151,9 +150,9 @@ void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle
|
|||||||
}
|
}
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0+9);
|
glActiveTexture(GL_TEXTURE0+9);
|
||||||
glBindTexture(GL_TEXTURE_2D, src_texture);
|
glBindTexture(GL_TEXTURE_2D_ARRAY, src_texture);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +166,7 @@ void OpenGLPostProcessing::ApplyShader()
|
|||||||
m_uniform_bindings.clear();
|
m_uniform_bindings.clear();
|
||||||
|
|
||||||
// load shader from disk
|
// load shader from disk
|
||||||
std::string default_shader = "void main() { SetOutput(Sample()); }";
|
std::string default_shader = "void main() { SetOutput(Sample()); }\n";
|
||||||
std::string code = "";
|
std::string code = "";
|
||||||
if (g_ActiveConfig.sPostProcessingShader != "")
|
if (g_ActiveConfig.sPostProcessingShader != "")
|
||||||
code = m_config.LoadShader();
|
code = m_config.LoadShader();
|
||||||
@ -195,6 +194,7 @@ void OpenGLPostProcessing::ApplyShader()
|
|||||||
m_uniform_resolution = glGetUniformLocation(m_shader.glprogid, "resolution");
|
m_uniform_resolution = glGetUniformLocation(m_shader.glprogid, "resolution");
|
||||||
m_uniform_time = glGetUniformLocation(m_shader.glprogid, "time");
|
m_uniform_time = glGetUniformLocation(m_shader.glprogid, "time");
|
||||||
m_uniform_src_rect = glGetUniformLocation(m_shader.glprogid, "src_rect");
|
m_uniform_src_rect = glGetUniformLocation(m_shader.glprogid, "src_rect");
|
||||||
|
m_uniform_layer = glGetUniformLocation(m_shader.glprogid, "layer");
|
||||||
|
|
||||||
if (m_attribute_workaround)
|
if (m_attribute_workaround)
|
||||||
{
|
{
|
||||||
@ -228,7 +228,7 @@ void OpenGLPostProcessing::CreateHeader()
|
|||||||
// Shouldn't be accessed directly by the PP shader
|
// Shouldn't be accessed directly by the PP shader
|
||||||
// Texture sampler
|
// Texture sampler
|
||||||
"SAMPLER_BINDING(8) uniform sampler2D samp8;\n"
|
"SAMPLER_BINDING(8) uniform sampler2D samp8;\n"
|
||||||
"SAMPLER_BINDING(9) uniform sampler2D samp9;\n"
|
"SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
|
||||||
|
|
||||||
// Output variable
|
// Output variable
|
||||||
"out float4 ocol0;\n"
|
"out float4 ocol0;\n"
|
||||||
@ -238,16 +238,18 @@ void OpenGLPostProcessing::CreateHeader()
|
|||||||
"uniform float4 resolution;\n"
|
"uniform float4 resolution;\n"
|
||||||
// Time
|
// Time
|
||||||
"uniform uint time;\n"
|
"uniform uint time;\n"
|
||||||
|
// Layer
|
||||||
|
"uniform int layer;\n"
|
||||||
|
|
||||||
// Interfacing functions
|
// Interfacing functions
|
||||||
"float4 Sample()\n"
|
"float4 Sample()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"\treturn texture(samp9, uv0);\n"
|
"\treturn texture(samp9, float3(uv0, layer));\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
"float4 SampleLocation(float2 location)\n"
|
"float4 SampleLocation(float2 location)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"\treturn texture(samp9, location);\n"
|
"\treturn texture(samp9, float3(location, layer));\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
"#define SampleOffset(offset) textureOffset(samp9, uv0, offset)\n"
|
"#define SampleOffset(offset) textureOffset(samp9, uv0, offset)\n"
|
||||||
|
@ -23,7 +23,7 @@ public:
|
|||||||
~OpenGLPostProcessing();
|
~OpenGLPostProcessing();
|
||||||
|
|
||||||
void BlitFromTexture(TargetRectangle src, TargetRectangle dst,
|
void BlitFromTexture(TargetRectangle src, TargetRectangle dst,
|
||||||
int src_texture, int src_width, int src_height) override;
|
int src_texture, int src_width, int src_height, int layer) override;
|
||||||
void ApplyShader() override;
|
void ApplyShader() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -32,6 +32,7 @@ private:
|
|||||||
GLuint m_uniform_resolution;
|
GLuint m_uniform_resolution;
|
||||||
GLuint m_uniform_src_rect;
|
GLuint m_uniform_src_rect;
|
||||||
GLuint m_uniform_time;
|
GLuint m_uniform_time;
|
||||||
|
GLuint m_uniform_layer;
|
||||||
std::string m_glsl_header;
|
std::string m_glsl_header;
|
||||||
|
|
||||||
// These are only used when working around Qualcomm's broken attributeless rendering
|
// These are only used when working around Qualcomm's broken attributeless rendering
|
||||||
|
@ -1505,7 +1505,20 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
|
|||||||
|
|
||||||
sourceRc.right -= fbStride - fbWidth;
|
sourceRc.right -= fbStride - fbWidth;
|
||||||
|
|
||||||
m_post_processor->BlitFromTexture(sourceRc, drawRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight);
|
if (g_ActiveConfig.bStereo)
|
||||||
|
{
|
||||||
|
TargetRectangle leftRc = drawRc, rightRc = drawRc;
|
||||||
|
int width = drawRc.right - drawRc.left;
|
||||||
|
leftRc.right -= width / 2;
|
||||||
|
rightRc.left += width / 2;
|
||||||
|
|
||||||
|
m_post_processor->BlitFromTexture(sourceRc, leftRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight, 0);
|
||||||
|
m_post_processor->BlitFromTexture(sourceRc, rightRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_post_processor->BlitFromTexture(sourceRc, drawRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1515,7 +1528,20 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
|
|||||||
// for msaa mode, we must resolve the efb content to non-msaa
|
// for msaa mode, we must resolve the efb content to non-msaa
|
||||||
GLuint tex = FramebufferManager::ResolveAndGetRenderTarget(rc);
|
GLuint tex = FramebufferManager::ResolveAndGetRenderTarget(rc);
|
||||||
|
|
||||||
m_post_processor->BlitFromTexture(targetRc, flipped_trc, tex, s_target_width, s_target_height);
|
if (g_ActiveConfig.bStereo)
|
||||||
|
{
|
||||||
|
TargetRectangle leftRc = flipped_trc, rightRc = flipped_trc;
|
||||||
|
int width = flipped_trc.right - flipped_trc.left;
|
||||||
|
leftRc.right -= width / 2;
|
||||||
|
rightRc.left += width / 2;
|
||||||
|
|
||||||
|
m_post_processor->BlitFromTexture(targetRc, leftRc, tex, s_target_width, s_target_height, 0);
|
||||||
|
m_post_processor->BlitFromTexture(targetRc, rightRc, tex, s_target_width, s_target_height, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_post_processor->BlitFromTexture(targetRc, flipped_trc, tex, s_target_width, s_target_height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
|
@ -91,7 +91,7 @@ public:
|
|||||||
|
|
||||||
// Should be implemented by the backends for backend specific code
|
// Should be implemented by the backends for backend specific code
|
||||||
virtual void BlitFromTexture(TargetRectangle src, TargetRectangle dst,
|
virtual void BlitFromTexture(TargetRectangle src, TargetRectangle dst,
|
||||||
int src_texture, int src_width, int src_height) = 0;
|
int src_texture, int src_width, int src_height, int layer = 0) = 0;
|
||||||
virtual void ApplyShader() = 0;
|
virtual void ApplyShader() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Reference in New Issue
Block a user