Skip to content

Commit

Permalink
Fixed|Renderer: Improved field of view
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
skyjake committed Nov 18, 2018
1 parent 4dca6fe commit 1199b8c
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 21 deletions.
26 changes: 6 additions & 20 deletions doomsday/apps/client/src/render/rend_main.cpp
Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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()
Expand All @@ -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));
}

Expand Down
6 changes: 5 additions & 1 deletion doomsday/sdk/libappfw/src/vr/vrconfig.cpp
Expand Up @@ -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,
Expand All @@ -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);
Expand All @@ -256,6 +259,7 @@ Matrix4f VRConfig::projectionMatrix(float fovDegrees,
-fH, fH,
nearClip, farClip) *
Matrix4f::translate(Vector3f(-eyeShift(), 0, 0));
#endif
}

OculusRift &VRConfig::oculusRift()
Expand Down

0 comments on commit 1199b8c

Please sign in to comment.