diff --git a/interface/src/GLCanvas.cpp b/interface/src/GLCanvas.cpp index 49085e63df..17026b5d5c 100644 --- a/interface/src/GLCanvas.cpp +++ b/interface/src/GLCanvas.cpp @@ -12,6 +12,7 @@ #include "Application.h" #include "GLCanvas.h" +#include "devices/OculusManager.h" #include #include #include @@ -41,8 +42,17 @@ void GLCanvas::initializeGL() { void GLCanvas::paintGL() { if (!_throttleRendering && !Application::getInstance()->getWindow()->isMinimized()) { + //Need accurate frame timing for the oculus rift + if (OculusManager::isConnected()) { + OculusManager::beginFrameTiming(); + } + Application::getInstance()->paintGL(); swapBuffers(); + + if (OculusManager::isConnected()) { + OculusManager::endFrameTiming(); + } } } @@ -102,8 +112,17 @@ void GLCanvas::activeChanged(Qt::ApplicationState state) { void GLCanvas::throttleRender() { _frameTimer.start(_idleRenderInterval); if (!Application::getInstance()->getWindow()->isMinimized()) { + //Need accurate frame timing for the oculus rift + if (OculusManager::isConnected()) { + OculusManager::beginFrameTiming(); + } + Application::getInstance()->paintGL(); swapBuffers(); + + if (OculusManager::isConnected()) { + OculusManager::endFrameTiming(); + } } } diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 7fb098ab87..e23801754a 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -45,6 +45,8 @@ GLuint OculusManager::_vbo[ovrEye_Count]; GLuint OculusManager::_indicesVbo[ovrEye_Count]; GLsizei OculusManager::_meshSize[ovrEye_Count]; ovrFrameTiming OculusManager::_hmdFrameTiming; +unsigned int OculusManager::_frameIndex = 0; +bool OculusManager::_frameTimingActive = false; #endif @@ -169,6 +171,29 @@ bool OculusManager::isConnected() { #endif } +//Begins the frame timing for oculus prediction purposes +void OculusManager::beginFrameTiming() { +#ifdef HAVE_LIBOVR + + if (_frameTimingActive) { + printf("WARNING: Called OculusManager::beginFrameTiming() twice in a row, need to call OculusManager::endFrameTiming()."); + } + + _hmdFrameTiming = ovrHmd_BeginFrameTiming(_ovrHmd, _frameIndex); + _frameTimingActive = true; +#endif +} + +//Ends frame timing +void OculusManager::endFrameTiming() { +#ifdef HAVE_LIBOVR + ovrHmd_EndFrameTiming(_ovrHmd); + _frameIndex++; + _frameTimingActive = false; +#endif +} + +//Sets the camera FoV and aspect ratio void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenHeight) { #ifdef HAVE_LIBOVR ovrSizei recommendedTex0Size = ovrHmd_GetFovTextureSize(_ovrHmd, ovrEye_Left, @@ -187,11 +212,15 @@ void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenH #endif } +//Displays everything for the oculus, frame timing must be active void OculusManager::display(Camera& whichCamera) { #ifdef HAVE_LIBOVR - static unsigned int frameIndex = 0; - _hmdFrameTiming = ovrHmd_BeginFrameTiming(_ovrHmd, frameIndex); - + //beginFrameTiming must be called before display + if (!_frameTimingActive) { + printf("WARNING: Called OculusManager::display() without calling OculusManager::beginFrameTiming() first."); + return; + } + ovrEyeRenderDesc eyeDesc[ovrEye_Count]; eyeDesc[0] = ovrHmd_GetRenderDesc(_ovrHmd, ovrEye_Left, _eyeFov[0]); eyeDesc[1] = ovrHmd_GetRenderDesc(_ovrHmd, ovrEye_Right, _eyeFov[1]); @@ -225,7 +254,6 @@ void OculusManager::display(Camera& whichCamera) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glLoadMatrixf((GLfloat *)proj.M); - glTranslatef(0.0f, 0, 0); glViewport(eyeDesc[eye].DistortedViewport.Pos.x, eyeDesc[eye].DistortedViewport.Pos.y, eyeDesc[eye].DistortedViewport.Size.w, eyeDesc[eye].DistortedViewport.Size.h); @@ -270,6 +298,7 @@ void OculusManager::display(Camera& whichCamera) { _program.enableAttributeArray(_texCoord1AttributeLocation); _program.enableAttributeArray(_texCoord2AttributeLocation); + //Render the distortion meshes for each eye for (int eyeNum = 0; eyeNum < ovrEye_Count; eyeNum++) { GLfloat uvScale[2] = { _UVScaleOffset[eyeNum][0].x, _UVScaleOffset[eyeNum][0].y }; _program.setUniformValueArray(_eyeToSourceUVScaleLocation, uvScale, 1, 2); @@ -312,9 +341,6 @@ void OculusManager::display(Camera& whichCamera) { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); _program.release(); - - ovrHmd_EndFrameTiming(_ovrHmd); - frameIndex++; #endif } @@ -324,6 +350,7 @@ void OculusManager::reset() { #endif } +//Gets the current predicted angles from the oculus sensors void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) { #ifdef HAVE_LIBOVR ovrSensorState ss = ovrHmd_GetSensorState(_ovrHmd, _hmdFrameTiming.ScanoutMidpointSeconds); diff --git a/interface/src/devices/OculusManager.h b/interface/src/devices/OculusManager.h index 3d18f762a9..8a34caf84f 100644 --- a/interface/src/devices/OculusManager.h +++ b/interface/src/devices/OculusManager.h @@ -14,15 +14,10 @@ #ifdef HAVE_LIBOVR #include -//#include <../src/OVR_CAPI.h> #endif #include "../src/Util/Util_Render_Stereo.h" -using namespace OVR::Util::Render; -#include <../src/Kernel/OVR_SysFile.h> -#include <../src/Kernel/OVR_Log.h> -#include <../src/Kernel/OVR_Timer.h> #include "renderer/ProgramObject.h" @@ -40,6 +35,10 @@ public: static bool isConnected(); + static void beginFrameTiming(); + + static void endFrameTiming(); + static void configureCamera(Camera& camera, int screenWidth, int screenHeight); static void display(Camera& whichCamera); @@ -96,6 +95,8 @@ private: static GLuint _indicesVbo[ovrEye_Count]; static GLsizei _meshSize[ovrEye_Count]; static ovrFrameTiming _hmdFrameTiming; + static unsigned int _frameIndex; + static bool _frameTimingActive; #endif };