diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c3773c3b73..0c3bbd8d34 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1118,7 +1118,16 @@ void Application::paintGL() { renderArgs._viewport = gpu::Vec4i(0, 0, size.width(), size.height()); if (displayPlugin->isStereo()) { - //_myCamera.setProjection(displayPlugin->getProjection(Mono, _myCamera.getProjection())); + // Stereo modes will typically have a larger projection matrix overall, + // so we ask for the 'mono' projection matrix, which for stereo and HMD + // plugins will imply the combined projection for both eyes. + // + // This is properly implemented for the Oculus plugins, but for OpenVR + // and Stereo displays I'm not sure how to get / calculate it, so we're + // just relying on the left FOV in each case and hoping that the + // overall culling margin of error doesn't cause popping in the + // right eye. There are FIXMEs in the relevant plugins + _myCamera.setProjection(displayPlugin->getProjection(Mono, _myCamera.getProjection())); renderArgs._context->enableStereo(true); mat4 eyeViews[2]; mat4 eyeProjections[2]; diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp index 2c5af1a52b..e823f456ce 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp @@ -136,6 +136,13 @@ void OculusLegacyDisplayPlugin::activate() { _eyeOffsets[eye] = erd.HmdToEyeViewOffset; eyeSizes[eye] = toGlm(ovrHmd_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f)); }); + ovrFovPort combined = _eyeFovs[Left]; + combined.LeftTan = std::max(_eyeFovs[Left].LeftTan, _eyeFovs[Right].LeftTan); + combined.RightTan = std::max(_eyeFovs[Left].RightTan, _eyeFovs[Right].RightTan); + ovrMatrix4f ovrPerspectiveProjection = + ovrMatrix4f_Projection(combined, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded); + _eyeProjections[Mono] = toGlm(ovrPerspectiveProjection); + _desiredFramebufferSize = uvec2( eyeSizes[0].x + eyeSizes[1].x, std::max(eyeSizes[0].y, eyeSizes[1].y)); diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h index ce91289cb0..219b6c54b3 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h @@ -52,7 +52,7 @@ private: ovrPosef _eyePoses[2]; ovrVector3f _eyeOffsets[2]; ovrFovPort _eyeFovs[2]; - mat4 _eyeProjections[2]; + mat4 _eyeProjections[3]; mat4 _compositeEyeProjections[2]; uvec2 _desiredFramebufferSize; ovrTexture _eyeTextures[2]; diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp index 1a5aa2f437..1e3e7699f4 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp @@ -149,6 +149,10 @@ uvec2 OpenVrDisplayPlugin::getRecommendedRenderSize() const { } mat4 OpenVrDisplayPlugin::getProjection(Eye eye, const mat4& baseProjection) const { + // FIXME hack to ensure that we don't crash trying to get the combined matrix + if (eye == Mono) { + eye = Left; + } return _eyesData[eye]._projectionMatrix; } diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp index 104d74097c..20613d6a2c 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp @@ -29,6 +29,8 @@ const float DEFAULT_IPD = 0.064f; const float HALF_DEFAULT_IPD = DEFAULT_IPD / 2.0f; glm::mat4 StereoDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseProjection) const { + // FIXME check for mono eye and provide a combined matrix, needed for proper + // culling // Refer to http://www.nvidia.com/content/gtc-2010/pdfs/2010_gtc2010.pdf on creating // stereo projection matrices. Do NOT use "toe-in", use translation.