From 779e6acb7bed8b0fa265c85fc63e28d039808512 Mon Sep 17 00:00:00 2001 From: Christopher Bruns Date: Sun, 9 Oct 2016 13:05:50 -0400 Subject: [PATCH] Create "final" two non-VR 3D modes: Column-interleaved and checkerboard. --- src/gl/renderer/gl_renderbuffers.h | 1 - src/gl/renderer/gl_renderer.cpp | 6 + src/gl/renderer/gl_renderer.h | 4 + src/gl/shaders/gl_present3dRowshader.cpp | 40 ++++-- src/gl/shaders/gl_present3dRowshader.h | 33 +++-- src/gl/shaders/gl_presentshader.cpp | 25 ++-- src/gl/shaders/gl_presentshader.h | 16 ++- src/gl/stereo3d/gl_interleaved3d.cpp | 133 +++++++++++++++--- src/gl/stereo3d/gl_interleaved3d.h | 21 ++- src/gl/stereo3d/gl_stereo_cvars.cpp | 6 + wadsrc/static/language.enu | 2 + wadsrc/static/menudef.zz | 2 + .../static/shaders/glsl/present_checker3d.fp | 37 +++++ .../static/shaders/glsl/present_column3d.fp | 35 +++++ wadsrc/static/shaders/glsl/present_row3d.fp | 6 +- 15 files changed, 300 insertions(+), 67 deletions(-) create mode 100644 wadsrc/static/shaders/glsl/present_checker3d.fp create mode 100644 wadsrc/static/shaders/glsl/present_column3d.fp diff --git a/src/gl/renderer/gl_renderbuffers.h b/src/gl/renderer/gl_renderbuffers.h index 5fe05f5ac..4477718f4 100644 --- a/src/gl/renderer/gl_renderbuffers.h +++ b/src/gl/renderer/gl_renderbuffers.h @@ -2,7 +2,6 @@ #define __GL_RENDERBUFFERS_H #include "gl/shaders/gl_shader.h" -#include "gl/renderer/gl_renderer.h" class FGLBloomTextureLevel { diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index be1b96f15..0ffafef49 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -105,6 +105,8 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) mTonemapPalette = nullptr; mBuffers = nullptr; mPresentShader = nullptr; + mPresent3dCheckerShader = nullptr; + mPresent3dColumnShader = nullptr; mPresent3dRowShader = nullptr; mBloomExtractShader = nullptr; mBloomCombineShader = nullptr; @@ -139,6 +141,8 @@ void FGLRenderer::Initialize(int width, int height) mFXAAShader = new FFXAAShader; mFXAALumaShader = new FFXAALumaShader; mPresentShader = new FPresentShader(); + mPresent3dCheckerShader = new FPresent3DCheckerShader(); + mPresent3dColumnShader = new FPresent3DColumnShader(); mPresent3dRowShader = new FPresent3DRowShader(); m2DDrawer = new F2DDrawer; @@ -192,6 +196,8 @@ FGLRenderer::~FGLRenderer() } if (mBuffers) delete mBuffers; if (mPresentShader) delete mPresentShader; + if (mPresent3dCheckerShader) delete mPresent3dCheckerShader; + if (mPresent3dColumnShader) delete mPresent3dColumnShader; if (mPresent3dRowShader) delete mPresent3dRowShader; if (mBloomExtractShader) delete mBloomExtractShader; if (mBloomCombineShader) delete mBloomCombineShader; diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 65e31c52f..19bc93af0 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -31,6 +31,8 @@ class FLensShader; class FFXAALumaShader; class FFXAAShader; class FPresentShader; +class FPresent3DCheckerShader; +class FPresent3DColumnShader; class FPresent3DRowShader; class F2DDrawer; class FHardwareTexture; @@ -109,6 +111,8 @@ public: FFXAALumaShader *mFXAALumaShader; FFXAAShader *mFXAAShader; FPresentShader *mPresentShader; + FPresent3DCheckerShader *mPresent3dCheckerShader; + FPresent3DColumnShader *mPresent3dColumnShader; FPresent3DRowShader *mPresent3dRowShader; FTexture *gllight; diff --git a/src/gl/shaders/gl_present3dRowshader.cpp b/src/gl/shaders/gl_present3dRowshader.cpp index 607e4ede6..d8369a3b6 100644 --- a/src/gl/shaders/gl_present3dRowshader.cpp +++ b/src/gl/shaders/gl_present3dRowshader.cpp @@ -38,23 +38,37 @@ #include "gl/system/gl_cvars.h" #include "gl/shaders/gl_present3dRowshader.h" +void FPresentStereoShaderBase::Init(const char * vtx_shader_name, const char * program_name) +{ + FPresentShaderBase::Init(vtx_shader_name, program_name); + LeftEyeTexture.Init(mShader, "LeftEyeTexture"); + RightEyeTexture.Init(mShader, "RightEyeTexture"); + WindowPositionParity.Init(mShader, "WindowPositionParity"); +} + +void FPresent3DCheckerShader::Bind() +{ + if (!mShader) + { + Init("shaders/glsl/present_checker3d.fp", "shaders/glsl/presentChecker3d"); + } + mShader.Bind(); +} + +void FPresent3DColumnShader::Bind() +{ + if (!mShader) + { + Init("shaders/glsl/present_column3d.fp", "shaders/glsl/presentColumn3d"); + } + mShader.Bind(); +} + void FPresent3DRowShader::Bind() { if (!mShader) { - mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquadscale.vp", "", 330); - mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/present_row3d.fp", "", 330); - mShader.SetFragDataLocation(0, "FragColor"); - mShader.Link("shaders/glsl/presentRow3d"); - mShader.SetAttribLocation(0, "PositionInProjection"); - mShader.SetAttribLocation(1, "UV"); - LeftEyeTexture.Init(mShader, "LeftEyeTexture"); - RightEyeTexture.Init(mShader, "RightEyeTexture"); - InvGamma.Init(mShader, "InvGamma"); - Contrast.Init(mShader, "Contrast"); - Brightness.Init(mShader, "Brightness"); - Scale.Init(mShader, "UVScale"); - VerticalPixelOffset.Init(mShader, "VerticalPixelOffset"); + Init("shaders/glsl/present_row3d.fp", "shaders/glsl/presentRow3d"); } mShader.Bind(); } diff --git a/src/gl/shaders/gl_present3dRowshader.h b/src/gl/shaders/gl_present3dRowshader.h index 8e3bd772d..10419d7f5 100644 --- a/src/gl/shaders/gl_present3dRowshader.h +++ b/src/gl/shaders/gl_present3dRowshader.h @@ -29,22 +29,35 @@ #define GL_PRESENT3DROWSHADER_H_ #include "gl_shaderprogram.h" +#include "gl_presentshader.h" -class FPresent3DRowShader +class FPresentStereoShaderBase : public FPresentShaderBase { public: - void Bind(); - FBufferedUniformSampler LeftEyeTexture; FBufferedUniformSampler RightEyeTexture; - FBufferedUniform1f InvGamma; - FBufferedUniform1f Contrast; - FBufferedUniform1f Brightness; - FBufferedUniform2f Scale; - FBufferedUniform1i VerticalPixelOffset; + FBufferedUniform1i WindowPositionParity; -private: - FShaderProgram mShader; +protected: + void Init(const char * vtx_shader_name, const char * program_name) override; +}; + +class FPresent3DCheckerShader : public FPresentStereoShaderBase +{ +public: + void Bind() override; +}; + +class FPresent3DColumnShader : public FPresentStereoShaderBase +{ +public: + void Bind() override; +}; + +class FPresent3DRowShader : public FPresentStereoShaderBase +{ +public: + void Bind() override; }; // GL_PRESENT3DROWSHADER_H_ diff --git a/src/gl/shaders/gl_presentshader.cpp b/src/gl/shaders/gl_presentshader.cpp index 39d20d0fc..15acc74fb 100644 --- a/src/gl/shaders/gl_presentshader.cpp +++ b/src/gl/shaders/gl_presentshader.cpp @@ -36,21 +36,26 @@ #include "gl/system/gl_cvars.h" #include "gl/shaders/gl_presentshader.h" +void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program_name) +{ + mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquadscale.vp", "", 330); + mShader.Compile(FShaderProgram::Fragment, vtx_shader_name, "", 330); + mShader.SetFragDataLocation(0, "FragColor"); + mShader.Link(program_name); + mShader.SetAttribLocation(0, "PositionInProjection"); + mShader.SetAttribLocation(1, "UV"); + InvGamma.Init(mShader, "InvGamma"); + Contrast.Init(mShader, "Contrast"); + Brightness.Init(mShader, "Brightness"); + Scale.Init(mShader, "UVScale"); +} + void FPresentShader::Bind() { if (!mShader) { - mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquadscale.vp", "", 330); - mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/present.fp", "", 330); - mShader.SetFragDataLocation(0, "FragColor"); - mShader.Link("shaders/glsl/present"); - mShader.SetAttribLocation(0, "PositionInProjection"); - mShader.SetAttribLocation(1, "UV"); + Init("shaders/glsl/present.fp", "shaders/glsl/present"); InputTexture.Init(mShader, "InputTexture"); - InvGamma.Init(mShader, "InvGamma"); - Contrast.Init(mShader, "Contrast"); - Brightness.Init(mShader, "Brightness"); - Scale.Init(mShader, "UVScale"); } mShader.Bind(); } diff --git a/src/gl/shaders/gl_presentshader.h b/src/gl/shaders/gl_presentshader.h index 6f4e899bb..6f9e1bfd7 100644 --- a/src/gl/shaders/gl_presentshader.h +++ b/src/gl/shaders/gl_presentshader.h @@ -3,19 +3,27 @@ #include "gl_shaderprogram.h" -class FPresentShader +class FPresentShaderBase { public: - void Bind(); + virtual void Bind() = 0; - FBufferedUniformSampler InputTexture; FBufferedUniform1f InvGamma; FBufferedUniform1f Contrast; FBufferedUniform1f Brightness; FBufferedUniform2f Scale; -private: +protected: + virtual void Init(const char * vtx_shader_name, const char * program_name); FShaderProgram mShader; }; +class FPresentShader : public FPresentShaderBase +{ +public: + void Bind() override; + + FBufferedUniformSampler InputTexture; +}; + #endif \ No newline at end of file diff --git a/src/gl/stereo3d/gl_interleaved3d.cpp b/src/gl/stereo3d/gl_interleaved3d.cpp index 036a84b0b..029d233e4 100644 --- a/src/gl/stereo3d/gl_interleaved3d.cpp +++ b/src/gl/stereo3d/gl_interleaved3d.cpp @@ -43,10 +43,25 @@ EXTERN_CVAR(Float, vid_brightness) EXTERN_CVAR(Float, vid_contrast) EXTERN_CVAR(Bool, fullscreen) -EXTERN_CVAR(Int, win_y) // pixel position of top of display window +EXTERN_CVAR(Int, win_x) // screen pixel position of left of display window +EXTERN_CVAR(Int, win_y) // screen pixel position of top of display window namespace s3d { +/* static */ +const CheckerInterleaved3D& CheckerInterleaved3D::getInstance(float ipd) +{ + static CheckerInterleaved3D instance(ipd); + return instance; +} + +/* static */ +const ColumnInterleaved3D& ColumnInterleaved3D::getInstance(float ipd) +{ + static ColumnInterleaved3D instance(ipd); + return instance; +} + /* static */ const RowInterleaved3D& RowInterleaved3D::getInstance(float ipd) { @@ -54,11 +69,7 @@ const RowInterleaved3D& RowInterleaved3D::getInstance(float ipd) return instance; } -RowInterleaved3D::RowInterleaved3D(double ipdMeters) - : TopBottom3D(ipdMeters) -{} - -void RowInterleaved3D::Present() const +static void prepareInterleavedPresent(FPresentStereoShaderBase& shader) { GLRenderer->mBuffers->BindOutputFB(); GLRenderer->ClearBorders(); @@ -79,27 +90,102 @@ void RowInterleaved3D::Present() const const GL_IRECT& box = GLRenderer->mOutputLetterbox; glViewport(box.left, box.top, box.width, box.height); - bool applyGamma = true; + shader.Bind(); + shader.LeftEyeTexture.Set(0); + shader.RightEyeTexture.Set(1); - GLRenderer->mPresent3dRowShader->Bind(); - GLRenderer->mPresent3dRowShader->LeftEyeTexture.Set(0); - GLRenderer->mPresent3dRowShader->RightEyeTexture.Set(1); - - if (!applyGamma || GLRenderer->framebuffer->IsHWGammaActive()) + if ( GLRenderer->framebuffer->IsHWGammaActive() ) { - GLRenderer->mPresent3dRowShader->InvGamma.Set(1.0f); - GLRenderer->mPresent3dRowShader->Contrast.Set(1.0f); - GLRenderer->mPresent3dRowShader->Brightness.Set(0.0f); + shader.InvGamma.Set(1.0f); + shader.Contrast.Set(1.0f); + shader.Brightness.Set(0.0f); } else { - GLRenderer->mPresent3dRowShader->InvGamma.Set(1.0f / clamp(Gamma, 0.1f, 4.f)); - GLRenderer->mPresent3dRowShader->Contrast.Set(clamp(vid_contrast, 0.1f, 3.f)); - GLRenderer->mPresent3dRowShader->Brightness.Set(clamp(vid_brightness, -0.8f, 0.8f)); + shader.InvGamma.Set(1.0f / clamp(Gamma, 0.1f, 4.f)); + shader.Contrast.Set(clamp(vid_contrast, 0.1f, 3.f)); + shader.Brightness.Set(clamp(vid_brightness, -0.8f, 0.8f)); } - GLRenderer->mPresent3dRowShader->Scale.Set( + shader.Scale.Set( GLRenderer->mScreenViewport.width / (float)GLRenderer->mBuffers->GetWidth(), GLRenderer->mScreenViewport.height / (float)GLRenderer->mBuffers->GetHeight()); +} + +// fixme: I don't know how to get absolute window position on Mac and Linux +// fixme: I don't know how to get window border decoration size anywhere +// So for now I'll hard code the border effect on my test machine. +// Workaround for others is to fuss with vr_swap_eyes CVAR until it looks right. +// Presumably the top/left window border on my test machine has an odd number of pixels +// in the horizontal direction, and an even number in the vertical direction. +#define WINDOW_BORDER_HORIZONTAL_PARITY 1 +#define WINDOW_BORDER_VERTICAL_PARITY 0 + +void CheckerInterleaved3D::Present() const +{ + prepareInterleavedPresent(*GLRenderer->mPresent3dCheckerShader); + + // Compute absolute offset from top of screen to top of current display window + // because we need screen-relative, not window-relative, scan line parity + int windowVOffset = 0; + int windowHOffset = 0; + +#ifdef _WIN32 + if (!fullscreen) { + I_SaveWindowedPos(); // update win_y CVAR + windowHOffset = (win_x + WINDOW_BORDER_HORIZONTAL_PARITY) % 2; + windowVOffset = (win_y + WINDOW_BORDER_VERTICAL_PARITY) % 2; + } +#endif // _WIN32 + + GLRenderer->mPresent3dCheckerShader->WindowPositionParity.Set( + (windowVOffset + + windowHOffset + + GLRenderer->mOutputLetterbox.height + 1 // +1 because of origin at bottom + ) % 2 // because we want the top pixel offset, but gl_FragCoord.y is the bottom pixel offset + ); + + GLRenderer->RenderScreenQuad(); +} + +void s3d::CheckerInterleaved3D::AdjustViewports() const +{ + // decrease the total pixel count by 2, but keep the same aspect ratio + const float sqrt2 = 1.41421356237f; + // Change size of renderbuffer, and align to screen + GLRenderer->mSceneViewport.height /= sqrt2; + GLRenderer->mSceneViewport.top /= sqrt2; + GLRenderer->mSceneViewport.width /= sqrt2; + GLRenderer->mSceneViewport.left /= sqrt2; + + GLRenderer->mScreenViewport.height /= sqrt2; + GLRenderer->mScreenViewport.top /= sqrt2; + GLRenderer->mScreenViewport.width /= sqrt2; + GLRenderer->mScreenViewport.left /= sqrt2; +} + +void ColumnInterleaved3D::Present() const +{ + prepareInterleavedPresent(*GLRenderer->mPresent3dColumnShader); + + // Compute absolute offset from top of screen to top of current display window + // because we need screen-relative, not window-relative, scan line parity + int windowHOffset = 0; + +#ifdef _WIN32 + if (!fullscreen) { + I_SaveWindowedPos(); // update win_y CVAR + windowHOffset = (win_x + WINDOW_BORDER_HORIZONTAL_PARITY) % 2; + } +#endif // _WIN32 + + GLRenderer->mPresent3dColumnShader->WindowPositionParity.Set(windowHOffset); + + GLRenderer->RenderScreenQuad(); +} + +void RowInterleaved3D::Present() const +{ + prepareInterleavedPresent(*GLRenderer->mPresent3dRowShader); // Compute absolute offset from top of screen to top of current display window // because we need screen-relative, not window-relative, scan line parity @@ -108,13 +194,14 @@ void RowInterleaved3D::Present() const #ifdef _WIN32 if (! fullscreen) { I_SaveWindowedPos(); // update win_y CVAR - windowVOffset = win_y; + windowVOffset = (win_y + WINDOW_BORDER_VERTICAL_PARITY) % 2; } #endif // _WIN32 - GLRenderer->mPresent3dRowShader->VerticalPixelOffset.Set( - windowVOffset // fixme: vary with window location - + box.height % 2 // because we want the top pixel offset, but gl_FragCoord.y is the bottom pixel offset + GLRenderer->mPresent3dRowShader->WindowPositionParity.Set( + (windowVOffset + + GLRenderer->mOutputLetterbox.height + 1 // +1 because of origin at bottom + ) % 2 ); GLRenderer->RenderScreenQuad(); diff --git a/src/gl/stereo3d/gl_interleaved3d.h b/src/gl/stereo3d/gl_interleaved3d.h index 30aef7d5a..78bd19483 100644 --- a/src/gl/stereo3d/gl_interleaved3d.h +++ b/src/gl/stereo3d/gl_interleaved3d.h @@ -42,15 +42,30 @@ #include "gl/system/gl_system.h" #include "gl/renderer/gl_renderstate.h" -class FPresent3DRowShader; - namespace s3d { +class CheckerInterleaved3D : public SideBySideSquished +{ +public: + static const CheckerInterleaved3D& getInstance(float ipd); + CheckerInterleaved3D(double ipdMeters) : SideBySideSquished(ipdMeters) {} + void Present() const override; + void AdjustViewports() const override; +}; + +class ColumnInterleaved3D : public SideBySideSquished +{ +public: + static const ColumnInterleaved3D& getInstance(float ipd); + ColumnInterleaved3D(double ipdMeters) : SideBySideSquished(ipdMeters) {} + void Present() const override; +}; + class RowInterleaved3D : public TopBottom3D { public: static const RowInterleaved3D& getInstance(float ipd); - RowInterleaved3D(double ipdMeters); + RowInterleaved3D(double ipdMeters) : TopBottom3D(ipdMeters) {} void Present() const override; }; diff --git a/src/gl/stereo3d/gl_stereo_cvars.cpp b/src/gl/stereo3d/gl_stereo_cvars.cpp index 16296393d..fe5ae3261 100644 --- a/src/gl/stereo3d/gl_stereo_cvars.cpp +++ b/src/gl/stereo3d/gl_stereo_cvars.cpp @@ -107,6 +107,12 @@ const Stereo3DMode& Stereo3DMode::getCurrentMode() case 12: setCurrentMode(RowInterleaved3D::getInstance(vr_ipd)); break; + case 13: + setCurrentMode(ColumnInterleaved3D::getInstance(vr_ipd)); + break; + case 14: + setCurrentMode(CheckerInterleaved3D::getInstance(vr_ipd)); + break; case 0: default: setCurrentMode(MonoView::getInstance()); diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 83cddb8c5..a5ffb4a2c 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -2707,6 +2707,8 @@ OPTVAL_SBSFULL = "Side-by-side Full"; OPTVAL_SBSNARROW = "Side-by-side Narrow"; OPTVAL_TOPBOTTOM = "Top/Bottom"; OPTVAL_ROWINTERLEAVED = "Row Interleaved"; +OPTVAL_COLUMNINTERLEAVED = "Column Interleaved"; +OPTVAL_CHECKERBOARD = "Checkerboard"; OPTVAL_QUADBUFFERED = "Quad-buffered"; OPTVAL_UNCHARTED2 = "Uncharted 2"; OPTVAL_HEJLDAWSON = "Hejl Dawson"; diff --git a/wadsrc/static/menudef.zz b/wadsrc/static/menudef.zz index 7e798a039..253f984eb 100644 --- a/wadsrc/static/menudef.zz +++ b/wadsrc/static/menudef.zz @@ -180,6 +180,8 @@ OptionValue VRMode 4, "$OPTVAL_SBSNARROW" 11, "$OPTVAL_TOPBOTTOM" 12, "$OPTVAL_ROWINTERLEAVED" + 13, "$OPTVAL_COLUMNINTERLEAVED" + 14, "$OPTVAL_CHECKERBOARD" 5, "$OPTVAL_LEFTEYE" 6, "$OPTVAL_RIGHTEYE" 7, "$OPTVAL_QUADBUFFERED" diff --git a/wadsrc/static/shaders/glsl/present_checker3d.fp b/wadsrc/static/shaders/glsl/present_checker3d.fp new file mode 100644 index 000000000..5247261e0 --- /dev/null +++ b/wadsrc/static/shaders/glsl/present_checker3d.fp @@ -0,0 +1,37 @@ + +in vec2 TexCoord; +out vec4 FragColor; + +uniform sampler2D LeftEyeTexture; +uniform sampler2D RightEyeTexture; +uniform float InvGamma; +uniform float Contrast; +uniform float Brightness; +uniform int WindowPositionParity; // top-of-window might not be top-of-screen + +vec4 ApplyGamma(vec4 c) +{ + vec3 val = c.rgb * Contrast - (Contrast - 1.0) * 0.5; + val += Brightness * 0.5; + val = pow(max(val, vec3(0.0)), vec3(InvGamma)); + return vec4(val, c.a); +} + +void main() +{ + int thisVerticalPixel = int(gl_FragCoord.y); // Bottom row is typically the right eye, when WindowHeight is even + int thisHorizontalPixel = int(gl_FragCoord.x); // column + bool isLeftEye = (thisVerticalPixel // because we want to alternate eye view on each row + + thisHorizontalPixel // and each column + + WindowPositionParity // because the window might not be aligned to the screen + ) % 2 == 0; + vec4 inputColor; + if (isLeftEye) { + inputColor = texture(LeftEyeTexture, TexCoord); + } + else { + // inputColor = vec4(0, 1, 0, 1); + inputColor = texture(RightEyeTexture, TexCoord); + } + FragColor = ApplyGamma(inputColor); +} diff --git a/wadsrc/static/shaders/glsl/present_column3d.fp b/wadsrc/static/shaders/glsl/present_column3d.fp new file mode 100644 index 000000000..b46246cf0 --- /dev/null +++ b/wadsrc/static/shaders/glsl/present_column3d.fp @@ -0,0 +1,35 @@ + +in vec2 TexCoord; +out vec4 FragColor; + +uniform sampler2D LeftEyeTexture; +uniform sampler2D RightEyeTexture; +uniform float InvGamma; +uniform float Contrast; +uniform float Brightness; +uniform int WindowPositionParity; // top-of-window might not be top-of-screen + +vec4 ApplyGamma(vec4 c) +{ + vec3 val = c.rgb * Contrast - (Contrast - 1.0) * 0.5; + val += Brightness * 0.5; + val = pow(max(val, vec3(0.0)), vec3(InvGamma)); + return vec4(val, c.a); +} + +void main() +{ + int thisHorizontalPixel = int(gl_FragCoord.x); // zero-based column index from left + bool isLeftEye = (thisHorizontalPixel // because we want to alternate eye view on each column + + WindowPositionParity // because the window might not be aligned to the screen + ) % 2 == 0; + vec4 inputColor; + if (isLeftEye) { + inputColor = texture(LeftEyeTexture, TexCoord); + } + else { + // inputColor = vec4(0, 1, 0, 1); + inputColor = texture(RightEyeTexture, TexCoord); + } + FragColor = ApplyGamma(inputColor); +} diff --git a/wadsrc/static/shaders/glsl/present_row3d.fp b/wadsrc/static/shaders/glsl/present_row3d.fp index 8ae72d1e0..50b27ac26 100644 --- a/wadsrc/static/shaders/glsl/present_row3d.fp +++ b/wadsrc/static/shaders/glsl/present_row3d.fp @@ -7,7 +7,7 @@ uniform sampler2D RightEyeTexture; uniform float InvGamma; uniform float Contrast; uniform float Brightness; -uniform int VerticalPixelOffset; // top-of-window might not be top-of-screen +uniform int WindowPositionParity; // top-of-window might not be top-of-screen vec4 ApplyGamma(vec4 c) { @@ -19,9 +19,9 @@ vec4 ApplyGamma(vec4 c) void main() { - int thisVerticalPixel = int(gl_FragCoord.y + 1.0); // Bottom row is typically the right eye, when WindowHeight is even + int thisVerticalPixel = int(gl_FragCoord.y); // Bottom row is typically the right eye, when WindowHeight is even bool isLeftEye = (thisVerticalPixel // because we want to alternate eye view on each row - + VerticalPixelOffset // because the window might not be aligned to the screen + + WindowPositionParity // because the window might not be aligned to the screen ) % 2 == 0; vec4 inputColor; if (isLeftEye) {