Skip to content

Commit

Permalink
Client|libdeng2: Replaced use of glFrustum with Matrix4::frustum()
Browse files Browse the repository at this point in the history
In the long run, we must stop using OpenGL matrix functions as they
are not present in GLES.
  • Loading branch information
skyjake committed Nov 16, 2013
1 parent 59b84f2 commit 1265ad8
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 21 deletions.
42 changes: 21 additions & 21 deletions doomsday/client/src/gl/gl_main.cpp
Expand Up @@ -589,13 +589,6 @@ void GL_ProjectionMatrix()
// We're assuming pixels are squares.
float aspect = viewpw / (float) viewph;


DENG_ASSERT_IN_MAIN_THREAD();
DENG_ASSERT_GL_CONTEXT_ACTIVE();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

if (VR::mode() == VR::MODE_OCULUS_RIFT)
{
aspect = VR::riftAspect();
Expand All @@ -608,27 +601,34 @@ void GL_ProjectionMatrix()
yfov = Rend_FieldOfView() / aspect;
}

// Replaced gluPerspective() with glFrustum() so we can do stereo 3D
// gluPerspective(yfov, aspect, glNearClip, glFarClip); // Replaced with lower-level glFrustum()
float fH = tan(0.5 * de::degreeToRadian(yfov)) * glNearClip;
float fW = fH*aspect;
// Asymmetric frustum shift is computed to realign screen-depth items after view point has shifted.
// Asymmetric frustum shift method is probably superior to competing toe-in stereo 3D method:
// * AFS preserves identical near and far clipping planes in both views
// * AFS shows items at/near infinity better
// * AFS conforms to what stereo 3D photographers call "ortho stereo"
// Asymmetric frustum shift is used for all stereo 3D modes except Oculus Rift mode, which only applies the viewpoint shift.
/*
* Asymmetric frustum shift is computed to realign screen-depth items after view point has shifted.
* Asymmetric frustum shift method is probably superior to competing toe-in stereo 3D method:
* - AFS preserves identical near and far clipping planes in both views
* - AFS shows items at/near infinity better
* - AFS conforms to what stereo 3D photographers call "ortho stereo"
* Asymmetric frustum shift is used for all stereo 3D modes except Oculus Rift mode, which only
* applies the viewpoint shift.
*/
float frustumShift = 0;
if (VR::applyFrustumShift)
{
frustumShift = VR::eyeShift * glNearClip / VR::hudDistance;
glFrustum(-fW - frustumShift, fW - frustumShift,
-fH, fH,
glNearClip, glFarClip);
// Actually shift the player viewpoint
glTranslatef(-VR::eyeShift, 0, 0);
}

DENG_ASSERT_IN_MAIN_THREAD();
DENG_ASSERT_GL_CONTEXT_ACTIVE();

// Actually shift the player viewpoint
// We'd like to have a left-handed coordinate system.
glScalef(1, 1, -1);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf((Matrix4f::frustum(-fW - frustumShift, fW - frustumShift,
-fH, fH,
glNearClip, glFarClip) *
Matrix4f::translate(Vector3f(-VR::eyeShift, 0, 0)) *
Matrix4f::scale(Vector3f(1, 1, -1))).values());
}

#undef GL_UseFog
Expand Down
16 changes: 16 additions & 0 deletions doomsday/libdeng2/include/de/core/matrix.h
Expand Up @@ -330,6 +330,22 @@ class Matrix4
m[14] = -(farDistance + nearDistance) / (farDistance - nearDistance);
return m;
}
static Matrix4 frustum(Type left, Type right, Type bottom, Type top, Type zNear, Type zFar) {
// This is identical to glFrustum.
Type const A = (right + left) / (right - left);
Type const B = (top + bottom) / (top - bottom);
Type const C = - (zFar + zNear) / (zFar - zNear);
Type const D = - (Type(2) * zFar * zNear) / (zFar - zNear);
Matrix4 m(Zero);
m.at(0, 0) = (Type(2) * zNear) / (right - left);
m.at(1, 1) = (Type(2) * zNear) / (top - bottom);
m.at(0, 2) = A;
m.at(1, 2) = B;
m.at(2, 2) = C;
m.at(3, 2) = -Type(1);
m.at(2, 3) = D;
return m;
}
static Matrix4 perspective(Type fov, Type aspectRatio, Type nearDistance = 1.f, Type farDistance = 1000.f) {
Type const halfWidth = std::tan(Type(.5) * degreeToRadian(fov));
Type const halfHeight = halfWidth / aspectRatio;
Expand Down

0 comments on commit 1265ad8

Please sign in to comment.