From 9a72ef1bf1c985e34f21c3fe5817b37e82b0b65c Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 8 Oct 2016 15:47:16 +0300 Subject: [PATCH 1/4] Added detection of current macOS version --- src/posix/cocoa/i_main.mm | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/posix/cocoa/i_main.mm b/src/posix/cocoa/i_main.mm index bbe344809..d8f0e74cf 100644 --- a/src/posix/cocoa/i_main.mm +++ b/src/posix/cocoa/i_main.mm @@ -130,6 +130,53 @@ void Mac_I_FatalError(const char* const message) } +static void I_DetectOS() +{ + SInt32 majorVersion = 0; + Gestalt(gestaltSystemVersionMajor, &majorVersion); + + SInt32 minorVersion = 0; + Gestalt(gestaltSystemVersionMinor, &minorVersion); + + SInt32 bugFixVersion = 0; + Gestalt(gestaltSystemVersionBugFix, &bugFixVersion); + + const char* name = "Unknown version"; + + if (10 == majorVersion) switch (minorVersion) + { + case 4: name = "Mac OS X Tiger"; break; + case 5: name = "Mac OS X Leopard"; break; + case 6: name = "Mac OS X Snow Leopard"; break; + case 7: name = "Mac OS X Lion"; break; + case 8: name = "OS X Mountain Lion"; break; + case 9: name = "OS X Mavericks"; break; + case 10: name = "OS X Yosemite"; break; + case 11: name = "OS X El Capitan"; break; + case 12: name = "macOS Sierra"; break; + } + + char release[16] = {}; + size_t size = sizeof release - 1; + sysctlbyname("kern.osversion", release, &size, nullptr, 0); + + const char* const architecture = +#ifdef __i386__ + "32-bit Intel"; +#elif defined __x86_64__ + "64-bit Intel"; +#elif defined __ppc__ + "32-bit PowerPC"; +#elif defined __ppc64__ + "64-bit PowerPC"; +#else + "Unknown"; +#endif + + Printf("OS: %s %d.%d.%d (%s) %s\n", name, majorVersion, minorVersion, bugFixVersion, release, architecture); +} + + DArgs* Args; // command line arguments @@ -165,6 +212,8 @@ void OriginalMainTry(int argc, char** argv) progdir += "/"; C_InitConsole(80 * 8, 25 * 8, false); + + I_DetectOS(); D_DoomMain(); } From 779e6acb7bed8b0fa265c85fc63e28d039808512 Mon Sep 17 00:00:00 2001 From: Christopher Bruns Date: Sun, 9 Oct 2016 13:05:50 -0400 Subject: [PATCH 2/4] 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) { From a771a3edd4b9794a1afea4317250ad0b2c95642a Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 8 Oct 2016 18:36:34 +0300 Subject: [PATCH 3/4] Fixed potential crash caused by A_Warp() ACSF_Warp case was refactored to express its intention clearly http://forum.zdoom.org/viewtopic.php?f=2&t=53734 --- src/p_acs.cpp | 79 +++++++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 0a2ccddac..71ef65f22 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5821,43 +5821,54 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) // [ZK] A_Warp in ACS case ACSF_Warp: { - int tid_dest = args[0]; - int xofs = args[1]; - int yofs = args[2]; - int zofs = args[3]; - int angle = args[4]; - int flags = args[5]; - const char *statename = argCount > 6 ? FBehavior::StaticLookupString(args[6]) : ""; - bool exact = argCount > 7 ? !!args[7] : false; - int heightoffset = argCount > 8 ? args[8] : 0; - int radiusoffset = argCount > 9 ? args[9] : 0; - int pitch = argCount > 10 ? args[10] : 0; - - FState *state = argCount > 6 ? activator->GetClass()->FindStateByString(statename, exact) : 0; - - AActor *reference; - if((flags & WARPF_USEPTR) && tid_dest != AAPTR_DEFAULT) + if (nullptr == activator) { - reference = COPY_AAPTR(activator, tid_dest); - } - else - { - reference = SingleActorFromTID(tid_dest, activator); - } - - // If there is no activator or actor to warp to, fail. - if (activator == NULL || !reference) return false; - - if (P_Thing_Warp(activator, reference, ACSToDouble(xofs), ACSToDouble(yofs), ACSToDouble(zofs), ACSToAngle(angle), flags, ACSToDouble(heightoffset), ACSToDouble(radiusoffset), ACSToAngle(pitch))) - { - if (state && argCount > 6) - { - activator->SetState(state); - } - return true; } - return false; + + const int dest = args[0]; + const int flags = args[5]; + + AActor* const reference = ((flags & WARPF_USEPTR) && (AAPTR_DEFAULT != dest)) + ? COPY_AAPTR(activator, dest) + : SingleActorFromTID(dest, activator); + + if (nullptr == reference) + { + // there is no actor to warp to + return false; + } + + const double xofs = ACSToDouble(args[1]); + const double yofs = ACSToDouble(args[2]); + const double zofs = ACSToDouble(args[3]); + const DAngle angle = ACSToAngle(args[4]); + const double heightoffset = argCount > 8 ? ACSToDouble(args[8]) : 0.0; + const double radiusoffset = argCount > 9 ? ACSToDouble(args[9]) : 0.0; + const DAngle pitch = ACSToAngle(argCount > 10 ? args[10] : 0); + + if (!P_Thing_Warp(activator, reference, xofs, yofs, zofs, angle, flags, heightoffset, radiusoffset, pitch)) + { + return false; + } + + if (argCount > 6) + { + const char* const statename = FBehavior::StaticLookupString(args[6]); + + if (nullptr != statename) + { + const bool exact = argCount > 7 && !!args[7]; + FState* const state = activator->GetClass()->FindStateByString(statename, exact); + + if (nullptr != state) + { + activator->SetState(state); + } + } + } + + return true; } case ACSF_GetMaxInventory: actor = SingleActorFromTID(args[0], activator); From 31ca5a1900062e5e5bee074d8b2c4919361cf55b Mon Sep 17 00:00:00 2001 From: Major Cooke Date: Sat, 8 Oct 2016 11:04:12 -0500 Subject: [PATCH 4/4] Added OverlayX/Y(int layer) - Retrieves the X/Y positions of an overlay. - A_OverlayFlags and A_OverlayOffset now interpret a layer of 0 to mean 'use this calling layer'. --- src/p_pspr.cpp | 52 ++++++++++++++++++++++++++++++++-- wadsrc/static/actors/actor.txt | 2 ++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index fab7e38d8..e5b076acd 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -1006,7 +1006,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayOffset) PARAM_FLOAT_OPT(wx) { wx = 0.; } PARAM_FLOAT_OPT(wy) { wy = 32.; } PARAM_INT_OPT(flags) { flags = 0; } - A_OverlayOffset(self, layer, wx, wy, flags); + A_OverlayOffset(self, ((layer != 0) ? layer : stateinfo->mPSPIndex), wx, wy, flags); return 0; } @@ -1033,10 +1033,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayFlags) PARAM_INT(flags); PARAM_BOOL(set); - if (self->player == nullptr) + if (!ACTION_CALL_FROM_PSPRITE()) return 0; - DPSprite *pspr = self->player->FindPSprite(layer); + DPSprite *pspr = self->player->FindPSprite(((layer != 0) ? layer : stateinfo->mPSPIndex)); if (pspr == nullptr) return 0; @@ -1049,6 +1049,52 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayFlags) return 0; } +//--------------------------------------------------------------------------- +// +// PROC OverlayX/Y +// Action function to return the X/Y of an overlay. +//--------------------------------------------------------------------------- + +static double GetOverlayPosition(AActor *self, int layer, bool gety) +{ + if (layer) + { + DPSprite *pspr = self->player->FindPSprite(layer); + + if (pspr != nullptr) + { + return gety ? (pspr->y) : (pspr->x); + } + } + return 0.; +} + +DEFINE_ACTION_FUNCTION(AActor, OverlayX) +{ + PARAM_ACTION_PROLOGUE; + PARAM_INT_OPT(layer) { layer = 0; } + + if (ACTION_CALL_FROM_PSPRITE()) + { + double res = GetOverlayPosition(self, ((layer != 0) ? layer : stateinfo->mPSPIndex), false); + ACTION_RETURN_FLOAT(res); + } + ACTION_RETURN_FLOAT(0.); +} + +DEFINE_ACTION_FUNCTION(AActor, OverlayY) +{ + PARAM_ACTION_PROLOGUE; + PARAM_INT_OPT(layer) { layer = 0; } + + if (ACTION_CALL_FROM_PSPRITE()) + { + double res = GetOverlayPosition(self, ((layer != 0) ? layer : stateinfo->mPSPIndex), true); + ACTION_RETURN_FLOAT(res); + } + ACTION_RETURN_FLOAT(0.); +} + //--------------------------------------------------------------------------- // // PROC OverlayID diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 44b801f51..fb6b4c832 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -58,6 +58,8 @@ ACTOR Actor native //: Thinker native float GetSpriteRotation(int ptr = AAPTR_DEFAULT); native int GetMissileDamage(int mask, int add, int ptr = AAPTR_DEFAULT); action native int OverlayID(); + action native float OverlayX(int layer = 0); + action native float OverlayY(int layer = 0); // Action functions // Meh, MBF redundant functions. Only for DeHackEd support.