mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-24 21:27:40 +02:00
Accurate Oculus frame timing
This commit is contained in:
parent
adb6c445a2
commit
634e0f38e8
3 changed files with 59 additions and 12 deletions
|
@ -12,6 +12,7 @@
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
|
||||||
#include "GLCanvas.h"
|
#include "GLCanvas.h"
|
||||||
|
#include "devices/OculusManager.h"
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
@ -41,8 +42,17 @@ void GLCanvas::initializeGL() {
|
||||||
|
|
||||||
void GLCanvas::paintGL() {
|
void GLCanvas::paintGL() {
|
||||||
if (!_throttleRendering && !Application::getInstance()->getWindow()->isMinimized()) {
|
if (!_throttleRendering && !Application::getInstance()->getWindow()->isMinimized()) {
|
||||||
|
//Need accurate frame timing for the oculus rift
|
||||||
|
if (OculusManager::isConnected()) {
|
||||||
|
OculusManager::beginFrameTiming();
|
||||||
|
}
|
||||||
|
|
||||||
Application::getInstance()->paintGL();
|
Application::getInstance()->paintGL();
|
||||||
swapBuffers();
|
swapBuffers();
|
||||||
|
|
||||||
|
if (OculusManager::isConnected()) {
|
||||||
|
OculusManager::endFrameTiming();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +112,17 @@ void GLCanvas::activeChanged(Qt::ApplicationState state) {
|
||||||
void GLCanvas::throttleRender() {
|
void GLCanvas::throttleRender() {
|
||||||
_frameTimer.start(_idleRenderInterval);
|
_frameTimer.start(_idleRenderInterval);
|
||||||
if (!Application::getInstance()->getWindow()->isMinimized()) {
|
if (!Application::getInstance()->getWindow()->isMinimized()) {
|
||||||
|
//Need accurate frame timing for the oculus rift
|
||||||
|
if (OculusManager::isConnected()) {
|
||||||
|
OculusManager::beginFrameTiming();
|
||||||
|
}
|
||||||
|
|
||||||
Application::getInstance()->paintGL();
|
Application::getInstance()->paintGL();
|
||||||
swapBuffers();
|
swapBuffers();
|
||||||
|
|
||||||
|
if (OculusManager::isConnected()) {
|
||||||
|
OculusManager::endFrameTiming();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,8 @@ GLuint OculusManager::_vbo[ovrEye_Count];
|
||||||
GLuint OculusManager::_indicesVbo[ovrEye_Count];
|
GLuint OculusManager::_indicesVbo[ovrEye_Count];
|
||||||
GLsizei OculusManager::_meshSize[ovrEye_Count];
|
GLsizei OculusManager::_meshSize[ovrEye_Count];
|
||||||
ovrFrameTiming OculusManager::_hmdFrameTiming;
|
ovrFrameTiming OculusManager::_hmdFrameTiming;
|
||||||
|
unsigned int OculusManager::_frameIndex = 0;
|
||||||
|
bool OculusManager::_frameTimingActive = false;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -169,6 +171,29 @@ bool OculusManager::isConnected() {
|
||||||
#endif
|
#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) {
|
void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenHeight) {
|
||||||
#ifdef HAVE_LIBOVR
|
#ifdef HAVE_LIBOVR
|
||||||
ovrSizei recommendedTex0Size = ovrHmd_GetFovTextureSize(_ovrHmd, ovrEye_Left,
|
ovrSizei recommendedTex0Size = ovrHmd_GetFovTextureSize(_ovrHmd, ovrEye_Left,
|
||||||
|
@ -187,10 +212,14 @@ void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenH
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Displays everything for the oculus, frame timing must be active
|
||||||
void OculusManager::display(Camera& whichCamera) {
|
void OculusManager::display(Camera& whichCamera) {
|
||||||
#ifdef HAVE_LIBOVR
|
#ifdef HAVE_LIBOVR
|
||||||
static unsigned int frameIndex = 0;
|
//beginFrameTiming must be called before display
|
||||||
_hmdFrameTiming = ovrHmd_BeginFrameTiming(_ovrHmd, frameIndex);
|
if (!_frameTimingActive) {
|
||||||
|
printf("WARNING: Called OculusManager::display() without calling OculusManager::beginFrameTiming() first.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ovrEyeRenderDesc eyeDesc[ovrEye_Count];
|
ovrEyeRenderDesc eyeDesc[ovrEye_Count];
|
||||||
eyeDesc[0] = ovrHmd_GetRenderDesc(_ovrHmd, ovrEye_Left, _eyeFov[0]);
|
eyeDesc[0] = ovrHmd_GetRenderDesc(_ovrHmd, ovrEye_Left, _eyeFov[0]);
|
||||||
|
@ -225,7 +254,6 @@ void OculusManager::display(Camera& whichCamera) {
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glLoadMatrixf((GLfloat *)proj.M);
|
glLoadMatrixf((GLfloat *)proj.M);
|
||||||
glTranslatef(0.0f, 0, 0);
|
|
||||||
|
|
||||||
glViewport(eyeDesc[eye].DistortedViewport.Pos.x, eyeDesc[eye].DistortedViewport.Pos.y,
|
glViewport(eyeDesc[eye].DistortedViewport.Pos.x, eyeDesc[eye].DistortedViewport.Pos.y,
|
||||||
eyeDesc[eye].DistortedViewport.Size.w, eyeDesc[eye].DistortedViewport.Size.h);
|
eyeDesc[eye].DistortedViewport.Size.w, eyeDesc[eye].DistortedViewport.Size.h);
|
||||||
|
@ -270,6 +298,7 @@ void OculusManager::display(Camera& whichCamera) {
|
||||||
_program.enableAttributeArray(_texCoord1AttributeLocation);
|
_program.enableAttributeArray(_texCoord1AttributeLocation);
|
||||||
_program.enableAttributeArray(_texCoord2AttributeLocation);
|
_program.enableAttributeArray(_texCoord2AttributeLocation);
|
||||||
|
|
||||||
|
//Render the distortion meshes for each eye
|
||||||
for (int eyeNum = 0; eyeNum < ovrEye_Count; eyeNum++) {
|
for (int eyeNum = 0; eyeNum < ovrEye_Count; eyeNum++) {
|
||||||
GLfloat uvScale[2] = { _UVScaleOffset[eyeNum][0].x, _UVScaleOffset[eyeNum][0].y };
|
GLfloat uvScale[2] = { _UVScaleOffset[eyeNum][0].x, _UVScaleOffset[eyeNum][0].y };
|
||||||
_program.setUniformValueArray(_eyeToSourceUVScaleLocation, uvScale, 1, 2);
|
_program.setUniformValueArray(_eyeToSourceUVScaleLocation, uvScale, 1, 2);
|
||||||
|
@ -312,9 +341,6 @@ void OculusManager::display(Camera& whichCamera) {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
_program.release();
|
_program.release();
|
||||||
|
|
||||||
ovrHmd_EndFrameTiming(_ovrHmd);
|
|
||||||
frameIndex++;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,6 +350,7 @@ void OculusManager::reset() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Gets the current predicted angles from the oculus sensors
|
||||||
void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) {
|
void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) {
|
||||||
#ifdef HAVE_LIBOVR
|
#ifdef HAVE_LIBOVR
|
||||||
ovrSensorState ss = ovrHmd_GetSensorState(_ovrHmd, _hmdFrameTiming.ScanoutMidpointSeconds);
|
ovrSensorState ss = ovrHmd_GetSensorState(_ovrHmd, _hmdFrameTiming.ScanoutMidpointSeconds);
|
||||||
|
|
|
@ -14,15 +14,10 @@
|
||||||
|
|
||||||
#ifdef HAVE_LIBOVR
|
#ifdef HAVE_LIBOVR
|
||||||
#include <OVR.h>
|
#include <OVR.h>
|
||||||
//#include <../src/OVR_CAPI.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../src/Util/Util_Render_Stereo.h"
|
#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"
|
#include "renderer/ProgramObject.h"
|
||||||
|
|
||||||
|
@ -40,6 +35,10 @@ public:
|
||||||
|
|
||||||
static bool isConnected();
|
static bool isConnected();
|
||||||
|
|
||||||
|
static void beginFrameTiming();
|
||||||
|
|
||||||
|
static void endFrameTiming();
|
||||||
|
|
||||||
static void configureCamera(Camera& camera, int screenWidth, int screenHeight);
|
static void configureCamera(Camera& camera, int screenWidth, int screenHeight);
|
||||||
|
|
||||||
static void display(Camera& whichCamera);
|
static void display(Camera& whichCamera);
|
||||||
|
@ -96,6 +95,8 @@ private:
|
||||||
static GLuint _indicesVbo[ovrEye_Count];
|
static GLuint _indicesVbo[ovrEye_Count];
|
||||||
static GLsizei _meshSize[ovrEye_Count];
|
static GLsizei _meshSize[ovrEye_Count];
|
||||||
static ovrFrameTiming _hmdFrameTiming;
|
static ovrFrameTiming _hmdFrameTiming;
|
||||||
|
static unsigned int _frameIndex;
|
||||||
|
static bool _frameTimingActive;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue