From 1199b8cae7c2f6b18e7a20c6790d676266783d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Sun, 18 Nov 2018 19:18:01 +0200 Subject: [PATCH] Fixed|Renderer: Improved field of view The field of view is now specified as the horizontal FOV without any extra special cases. This fixes a problem with very tall windows where the projection would break down. --- doomsday/apps/client/src/render/rend_main.cpp | 26 +++++-------------- doomsday/sdk/libappfw/src/vr/vrconfig.cpp | 6 ++++- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/doomsday/apps/client/src/render/rend_main.cpp b/doomsday/apps/client/src/render/rend_main.cpp index a0ab89e8b8..0973ca6a60 100644 --- a/doomsday/apps/client/src/render/rend_main.cpp +++ b/doomsday/apps/client/src/render/rend_main.cpp @@ -436,20 +436,6 @@ dfloat Rend_FieldOfView() } else { - auto const viewRect = R_Console3DViewRect(displayPlayer); - - // Correction is applied for wide screens so that when the FOV is kept - // at a certain value (e.g., the default FOV), a 16:9 view has a wider angle - // than a 4:3, but not just scaled linearly since that would go too far - // into the fish eye territory. - dfloat widescreenCorrection = dfloat(viewRect.width()) / dfloat(viewRect.height()) / (4.f / 3.f); - if (widescreenCorrection < 1.5f) // up to ~16:9 - { - widescreenCorrection = (1 + 2 * widescreenCorrection) / 3; - return de::clamp(1.f, widescreenCorrection * fieldOfView, 179.f); - } - // This is an unusually wide (perhaps multimonitor) setup, so just use the - // configured FOV as is. return de::clamp(1.f, fieldOfView, 179.f); } } @@ -569,7 +555,8 @@ void Rend_ModelViewMatrix(bool inWorldSpace) DENG_ASSERT_GL_CONTEXT_ACTIVE(); DGL_MatrixMode(DGL_MODELVIEW); - DGL_LoadMatrix(Rend_GetModelViewMatrix(DoomsdayApp::players().indexOf(viewPlayer), inWorldSpace).values()); + DGL_LoadMatrix( + Rend_GetModelViewMatrix(DoomsdayApp::players().indexOf(viewPlayer), inWorldSpace).values()); } Matrix4f Rend_GetProjectionMatrix() @@ -579,12 +566,11 @@ Matrix4f Rend_GetProjectionMatrix() return fixedView->projectionMatrix; } - dfloat const fov = Rend_FieldOfView(); - //Vector2f const size(viewpw, viewph); - Vector2f const size = R_Console3DViewRect(displayPlayer).size(); + const dfloat fov = Rend_FieldOfView(); + const Vector2f size = R_Console3DViewRect(displayPlayer).size(); yfov = vrCfg().verticalFieldOfView(fov, size); - Rangef const clip = GL_DepthClipRange(); - return vrCfg().projectionMatrix(Rend_FieldOfView(), size, clip.start, clip.end) * + const Rangef clip = GL_DepthClipRange(); + return vrCfg().projectionMatrix(fov, size, clip.start, clip.end) * Matrix4f::scale(Vector3f(1, 1, -1)); } diff --git a/doomsday/sdk/libappfw/src/vr/vrconfig.cpp b/doomsday/sdk/libappfw/src/vr/vrconfig.cpp index 9836166d70..9832bbeece 100644 --- a/doomsday/sdk/libappfw/src/vr/vrconfig.cpp +++ b/doomsday/sdk/libappfw/src/vr/vrconfig.cpp @@ -218,7 +218,7 @@ float VRConfig::verticalFieldOfView(float horizFovDegrees, Vector2f const &viewP return radianToDegree(2.f * std::atan2(x / aspect, 1.f)); } - return horizFovDegrees / aspect; + return clamp(1.f, horizFovDegrees / aspect, 179.f); } Matrix4f VRConfig::projectionMatrix(float fovDegrees, @@ -232,7 +232,10 @@ Matrix4f VRConfig::projectionMatrix(float fovDegrees, return oculusRift().projection(nearClip, farClip) * Matrix4f::translate(oculusRift().eyeOffset() * mapUnits); } + return Matrix4f::perspective(fovDegrees, viewAspect(viewPortSize), nearClip, farClip) * + Matrix4f::translate(Vector3f(-eyeShift(), 0, 0)); +#if 0 float const yfov = verticalFieldOfView(fovDegrees, viewPortSize); float const fH = std::tan(.5f * degreeToRadian(yfov)) * nearClip; float const fW = fH * viewAspect(viewPortSize); @@ -256,6 +259,7 @@ Matrix4f VRConfig::projectionMatrix(float fovDegrees, -fH, fH, nearClip, farClip) * Matrix4f::translate(Vector3f(-eyeShift(), 0, 0)); +#endif } OculusRift &VRConfig::oculusRift()