From 532fba5c26c3bb732df9a3af8ebb66dda04d4805 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Jun 2018 10:47:42 +0200 Subject: [PATCH] - moved the Stereo3D EyePose to their own file in hwrenderer/. --- src/CMakeLists.txt | 2 + src/d_main.cpp | 1 + src/gl/renderer/gl_postprocess.cpp | 4 +- src/gl/renderer/gl_renderer.h | 3 - src/gl/scene/gl_scene.cpp | 2 +- src/gl/stereo3d/gl_sidebyside3d.h | 16 ---- src/gl/stereo3d/gl_stereo3d.cpp | 28 ------- src/gl/stereo3d/gl_stereo3d.h | 25 +------ src/gl/stereo3d/gl_stereo_leftright.cpp | 43 ----------- src/gl/stereo3d/gl_stereo_leftright.h | 36 --------- src/hwrenderer/stereo3d/hw_eyepose.cpp | 97 +++++++++++++++++++++++++ src/hwrenderer/stereo3d/hw_eyepose.h | 63 ++++++++++++++++ src/v_video.h | 3 + 13 files changed, 170 insertions(+), 153 deletions(-) create mode 100644 src/hwrenderer/stereo3d/hw_eyepose.cpp create mode 100644 src/hwrenderer/stereo3d/hw_eyepose.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 69b010dcf..40a3925c5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -697,6 +697,7 @@ file( GLOB HEADER_FILES hwrenderer/dynlights/*.h hwrenderer/postprocessing/*.h hwrenderer/scene/*.h + hwrenderer/stereo3d/*.h hwrenderer/textures/*.h hwrenderer/utility/*.h gl/*.h @@ -1073,6 +1074,7 @@ set (PCH_SOURCES hwrenderer/data/flatvertices.cpp hwrenderer/dynlights/hw_aabbtree.cpp hwrenderer/dynlights/hw_shadowmap.cpp + hwrenderer/stereo3d/hw_eyepose.cpp hwrenderer/scene/hw_skydome.cpp hwrenderer/postprocessing/hw_postprocess_cvars.cpp hwrenderer/postprocessing/hw_postprocessshader.cpp diff --git a/src/d_main.cpp b/src/d_main.cpp index 66c0e3c33..9a2089954 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -707,6 +707,7 @@ void D_Display () wipe = false; wipegamestate = gamestate; } + // No wipes when in a stereo3D VR mode else if (gamestate != wipegamestate && gamestate != GS_FULLCONSOLE && gamestate != GS_TITLELEVEL && (vr_mode == 0 || vid_rendermode != 4)) { // save the current screen if about to wipe switch (wipegamestate) diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index 61e69f2d7..e371699d7 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -114,8 +114,8 @@ void FGLRenderer::AmbientOccludeScene(float m5) mBuffers->BindSceneColorTexture(1); mLinearDepthShader->Bind(NOQUEUE); if (gl_multisample > 1) mLinearDepthShader->Uniforms->SampleIndex = 0; - mLinearDepthShader->Uniforms->LinearizeDepthA = 1.0f / GetZFar() - 1.0f / GetZNear(); - mLinearDepthShader->Uniforms->LinearizeDepthB = MAX(1.0f / GetZNear(), 1.e-8f); + mLinearDepthShader->Uniforms->LinearizeDepthA = 1.0f / screen->GetZFar() - 1.0f / screen->GetZNear(); + mLinearDepthShader->Uniforms->LinearizeDepthB = MAX(1.0f / screen->GetZNear(), 1.e-8f); mLinearDepthShader->Uniforms->InverseDepthRangeA = 1.0f; mLinearDepthShader->Uniforms->InverseDepthRangeB = 0.0f; mLinearDepthShader->Uniforms->Scale = sceneScale; diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 44ccfe1a5..c89d85705 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -158,9 +158,6 @@ public: void FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip); - - static float GetZNear() { return 5.f; } - static float GetZFar() { return 65536.f; } }; #include "hwrenderer/scene/hw_fakeflat.h" diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index c5a500922..2e1b004aa 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -470,7 +470,7 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came stereo3dMode.SetUp(); for (int eye_ix = 0; eye_ix < stereo3dMode.eye_count(); ++eye_ix) { - const s3d::EyePose * eye = stereo3dMode.getEyePose(eye_ix); + const auto eye = stereo3dMode.getEyePose(eye_ix); eye->SetUp(); screen->SetViewportRects(bounds); Set3DViewport(mainview); diff --git a/src/gl/stereo3d/gl_sidebyside3d.h b/src/gl/stereo3d/gl_sidebyside3d.h index 071474c46..d3817c43d 100644 --- a/src/gl/stereo3d/gl_sidebyside3d.h +++ b/src/gl/stereo3d/gl_sidebyside3d.h @@ -61,22 +61,6 @@ private: RightEyePose rightEye; }; -class SBSFLeftEyePose : public LeftEyePose { -public: - SBSFLeftEyePose(double ipdMeters) : LeftEyePose(ipdMeters) {} - virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const override { - return LeftEyePose::GetProjection(fov, 0.5f * aspectRatio, fovRatio); - } -}; - -class SBSFRightEyePose : public RightEyePose { -public: - SBSFRightEyePose(double ipdMeters) : RightEyePose(ipdMeters) {} - virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const override { - return RightEyePose::GetProjection(fov, 0.5f * aspectRatio, fovRatio); - } -}; - class SideBySideFull : public SideBySideBase { public: diff --git a/src/gl/stereo3d/gl_stereo3d.cpp b/src/gl/stereo3d/gl_stereo3d.cpp index 5a5a115d9..609e037db 100644 --- a/src/gl/stereo3d/gl_stereo3d.cpp +++ b/src/gl/stereo3d/gl_stereo3d.cpp @@ -31,34 +31,6 @@ namespace s3d { -/* virtual */ -VSMatrix EyePose::GetProjection(float fov, float aspectRatio, float fovRatio) const -{ - VSMatrix result; - - float fovy = (float)(2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio))); - result.perspective(fovy, aspectRatio, FGLRenderer::GetZNear(), FGLRenderer::GetZFar()); - - return result; -} - -/* virtual */ -Viewport EyePose::GetViewport(const Viewport& fullViewport) const -{ - return fullViewport; -} - - -/* virtual */ -void EyePose::GetViewShift(float yaw, float outViewShift[3]) const -{ - // pass-through for Mono view - outViewShift[0] = 0; - outViewShift[1] = 0; - outViewShift[2] = 0; -} - - Stereo3DMode::Stereo3DMode() { } diff --git a/src/gl/stereo3d/gl_stereo3d.h b/src/gl/stereo3d/gl_stereo3d.h index 542d45551..8468d5ad9 100644 --- a/src/gl/stereo3d/gl_stereo3d.h +++ b/src/gl/stereo3d/gl_stereo3d.h @@ -32,34 +32,11 @@ #include "tarray.h" #include "r_data/matrix.h" #include "gl/renderer/gl_renderer.h" - +#include "hwrenderer/stereo3d/hw_eyepose.h" /* stereoscopic 3D API */ namespace s3d { - -/* Subregion of current display window */ -class Viewport -{ -public: - int x, y; - int width, height; -}; - - -/* Viewpoint of one eye */ -class EyePose -{ -public: - EyePose() {} - virtual ~EyePose() {} - virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const; - virtual Viewport GetViewport(const Viewport& fullViewport) const; - virtual void GetViewShift(float yaw, float outViewShift[3]) const; - virtual void SetUp() const {}; -}; - - /* Base class for stereoscopic 3D rendering modes */ class Stereo3DMode { diff --git a/src/gl/stereo3d/gl_stereo_leftright.cpp b/src/gl/stereo3d/gl_stereo_leftright.cpp index f6eebc509..be1d0a3d9 100644 --- a/src/gl/stereo3d/gl_stereo_leftright.cpp +++ b/src/gl/stereo3d/gl_stereo_leftright.cpp @@ -34,52 +34,9 @@ #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderbuffers.h" -EXTERN_CVAR(Float, vr_screendist) -EXTERN_CVAR(Float, vr_hunits_per_meter) -EXTERN_CVAR(Bool, vr_swap_eyes) - namespace s3d { -/* virtual */ -VSMatrix ShiftedEyePose::GetProjection(float fov, float aspectRatio, float fovRatio) const -{ - double zNear = 5.0; - double zFar = 65536.0; - - // For stereo 3D, use asymmetric frustum shift in projection matrix - // Q: shouldn't shift vary with roll angle, at least for desktop display? - // A: No. (lab) roll is not measured on desktop display (yet) - double frustumShift = zNear * getShift() / vr_screendist; // meters cancel, leaving doom units - // double frustumShift = 0; // Turning off shift for debugging - double fH = zNear * tan(DEG2RAD(fov) / 2) / fovRatio; - double fW = fH * aspectRatio; - double left = -fW - frustumShift; - double right = fW - frustumShift; - double bottom = -fH; - double top = fH; - - VSMatrix result(1); - result.frustum(left, right, bottom, top, zNear, zFar); - return result; -} - - -/* virtual */ -void ShiftedEyePose::GetViewShift(float yaw, float outViewShift[3]) const -{ - float dx = -cos(DEG2RAD(yaw)) * vr_hunits_per_meter * getShift(); - float dy = sin(DEG2RAD(yaw)) * vr_hunits_per_meter * getShift(); - outViewShift[0] = dx; - outViewShift[1] = dy; - outViewShift[2] = 0; -} - -float ShiftedEyePose::getShift() const -{ - return vr_swap_eyes ? -shift : shift; -} - /* static */ const LeftEyeView& LeftEyeView::getInstance(float ipd) { diff --git a/src/gl/stereo3d/gl_stereo_leftright.h b/src/gl/stereo3d/gl_stereo_leftright.h index 9fa7b40bc..ad4ccb769 100644 --- a/src/gl/stereo3d/gl_stereo_leftright.h +++ b/src/gl/stereo3d/gl_stereo_leftright.h @@ -33,40 +33,6 @@ namespace s3d { -class ShiftedEyePose : public EyePose -{ -public: - ShiftedEyePose(float shift) : shift(shift) {}; - float getShift() const; - virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const; - virtual void GetViewShift(float yaw, float outViewShift[3]) const; - -protected: - void setShift(float shift) { this->shift = shift; } - -private: - float shift; -}; - - -class LeftEyePose : public ShiftedEyePose -{ -public: - LeftEyePose(float ipd) : ShiftedEyePose( float(-0.5) * ipd) {} - float getIpd() const { return float(fabs(2.0f*getShift())); } - void setIpd(float ipd) { setShift(float(-0.5)*ipd); } -}; - - -class RightEyePose : public ShiftedEyePose -{ -public: - RightEyePose(float ipd) : ShiftedEyePose(float(+0.5)*ipd) {} - float getIpd() const { return float(fabs(2.0f*getShift())); } - void setIpd(float ipd) { setShift(float(+0.5)*ipd); } -}; - - /** * As if viewed through the left eye only */ @@ -76,7 +42,6 @@ public: static const LeftEyeView& getInstance(float ipd); LeftEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); } - float getIpd() const { return eye.getIpd(); } void setIpd(float ipd) { eye.setIpd(ipd); } void Present() const override; protected: @@ -90,7 +55,6 @@ public: static const RightEyeView& getInstance(float ipd); RightEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); } - float getIpd() const { return eye.getIpd(); } void setIpd(float ipd) { eye.setIpd(ipd); } void Present() const override; protected: diff --git a/src/hwrenderer/stereo3d/hw_eyepose.cpp b/src/hwrenderer/stereo3d/hw_eyepose.cpp new file mode 100644 index 000000000..e8ac56d6b --- /dev/null +++ b/src/hwrenderer/stereo3d/hw_eyepose.cpp @@ -0,0 +1,97 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2015 Christopher Bruns +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// +/* +** gl_stereo_leftright.cpp +** Offsets for left and right eye views +** +*/ + +#include "vectors.h" // RAD2DEG +#include "doomtype.h" // M_PI +#include "hwrenderer/utility/hw_cvars.h" +#include "hw_eyepose.h" +#include "v_video.h" + +EXTERN_CVAR(Float, vr_screendist) +EXTERN_CVAR(Float, vr_hunits_per_meter) +EXTERN_CVAR(Bool, vr_swap_eyes) + + +/* virtual */ +VSMatrix EyePose::GetProjection(float fov, float aspectRatio, float fovRatio) const +{ + VSMatrix result; + + float fovy = (float)(2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovRatio))); + result.perspective(fovy, aspectRatio, screen->GetZNear(), screen->GetZFar()); + + return result; +} + +/* virtual */ +void EyePose::GetViewShift(float yaw, float outViewShift[3]) const +{ + // pass-through for Mono view + outViewShift[0] = 0; + outViewShift[1] = 0; + outViewShift[2] = 0; +} + +/* virtual */ +VSMatrix ShiftedEyePose::GetProjection(float fov, float aspectRatio, float fovRatio) const +{ + double zNear = screen->GetZNear(); + double zFar = screen->GetZFar(); + + // For stereo 3D, use asymmetric frustum shift in projection matrix + // Q: shouldn't shift vary with roll angle, at least for desktop display? + // A: No. (lab) roll is not measured on desktop display (yet) + double frustumShift = zNear * getShift() / vr_screendist; // meters cancel, leaving doom units + // double frustumShift = 0; // Turning off shift for debugging + double fH = zNear * tan(DEG2RAD(fov) / 2) / fovRatio; + double fW = fH * aspectRatio; + double left = -fW - frustumShift; + double right = fW - frustumShift; + double bottom = -fH; + double top = fH; + + VSMatrix result(1); + result.frustum((float)left, (float)right, (float)bottom, (float)top, (float)zNear, (float)zFar); + return result; +} + + +/* virtual */ +void ShiftedEyePose::GetViewShift(float yaw, float outViewShift[3]) const +{ + float dx = -cos(DEG2RAD(yaw)) * vr_hunits_per_meter * getShift(); + float dy = sin(DEG2RAD(yaw)) * vr_hunits_per_meter * getShift(); + outViewShift[0] = dx; + outViewShift[1] = dy; + outViewShift[2] = 0; +} + +float ShiftedEyePose::getShift() const +{ + return vr_swap_eyes ? -shift : shift; +} + diff --git a/src/hwrenderer/stereo3d/hw_eyepose.h b/src/hwrenderer/stereo3d/hw_eyepose.h new file mode 100644 index 000000000..64ff9c27c --- /dev/null +++ b/src/hwrenderer/stereo3d/hw_eyepose.h @@ -0,0 +1,63 @@ +#pragma once + +#include "r_data/matrix.h" + + +/* Viewpoint of one eye */ +class EyePose +{ +public: + EyePose() {} + virtual ~EyePose() {} + virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const; + virtual void GetViewShift(float yaw, float outViewShift[3]) const; + virtual void SetUp() const {} +}; + +class ShiftedEyePose : public EyePose +{ +public: + ShiftedEyePose(float shift) : shift(shift) {}; + float getShift() const; + virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const; + virtual void GetViewShift(float yaw, float outViewShift[3]) const; + +protected: + void setShift(float shift) { this->shift = shift; } + +private: + float shift; +}; + + +class LeftEyePose : public ShiftedEyePose +{ +public: + LeftEyePose(float ipd) : ShiftedEyePose( -0.5f * ipd) {} + void setIpd(float ipd) { setShift(-0.5f * ipd); } +}; + + +class RightEyePose : public ShiftedEyePose +{ +public: + RightEyePose(float ipd) : ShiftedEyePose(0.5f * ipd) {} + void setIpd(float ipd) { setShift(0.5f * ipd); } +}; + + +class SBSFLeftEyePose : public LeftEyePose { +public: + SBSFLeftEyePose(float ipdMeters) : LeftEyePose(ipdMeters) {} + virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const override { + return LeftEyePose::GetProjection(fov, 0.5f * aspectRatio, fovRatio); + } +}; + +class SBSFRightEyePose : public RightEyePose { +public: + SBSFRightEyePose(float ipdMeters) : RightEyePose(ipdMeters) {} + virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const override { + return RightEyePose::GetProjection(fov, 0.5f * aspectRatio, fovRatio); + } +}; diff --git a/src/v_video.h b/src/v_video.h index de16b85eb..ec17b86fa 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -527,6 +527,9 @@ public: // points to the last row in the buffer, which will be the first row output. virtual void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) {} + static float GetZNear() { return 5.f; } + static float GetZFar() { return 65536.f; } + // The original size of the framebuffer as selected in the video menu. uint64_t FrameTime = 0;