Accurate Oculus frame timing

This commit is contained in:
barnold1953 2014-06-26 11:27:17 -07:00
parent adb6c445a2
commit 634e0f38e8
3 changed files with 59 additions and 12 deletions

View file

@ -12,6 +12,7 @@
#include "Application.h"
#include "GLCanvas.h"
#include "devices/OculusManager.h"
#include <QMimeData>
#include <QUrl>
#include <QMainWindow>
@ -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();
}
}
}

View file

@ -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);

View file

@ -14,15 +14,10 @@
#ifdef HAVE_LIBOVR
#include <OVR.h>
//#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
};