Working on OSX Rift functionality

This commit is contained in:
Bradley Austin Davis 2016-05-07 18:42:43 -07:00
parent b234d94d25
commit 0f768b13b9
8 changed files with 144 additions and 55 deletions

View file

@ -237,12 +237,6 @@ bool OpenGLDisplayPlugin::activate() {
_vsyncSupported = _container->getPrimaryWidget()->isVsyncSupported(); _vsyncSupported = _container->getPrimaryWidget()->isVsyncSupported();
// Child classes may override this in order to do things like initialize
// libraries, etc
if (!internalActivate()) {
return false;
}
#if THREADED_PRESENT #if THREADED_PRESENT
// Start the present thread if necessary // Start the present thread if necessary
@ -258,8 +252,18 @@ bool OpenGLDisplayPlugin::activate() {
// Start execution // Start execution
presentThread->start(); presentThread->start();
} }
_presentThread = presentThread.data();
#endif
// Child classes may override this in order to do things like initialize
// libraries, etc
if (!internalActivate()) {
return false;
}
// This should not return until the new context has been customized #if THREADED_PRESENT
// This should not return until the new context has been customized
// and the old context (if any) has been uncustomized // and the old context (if any) has been uncustomized
presentThread->setNewDisplayPlugin(this); presentThread->setNewDisplayPlugin(this);
#else #else

View file

@ -103,6 +103,7 @@ protected:
virtual void updateFrameData(); virtual void updateFrameData();
QThread* _presentThread{ nullptr };
ProgramPtr _program; ProgramPtr _program;
int32_t _mvpUniform { -1 }; int32_t _mvpUniform { -1 };
int32_t _alphaUniform { -1 }; int32_t _alphaUniform { -1 };

View file

@ -63,7 +63,7 @@ bool HmdDisplayPlugin::internalActivate() {
} }
static const char * REPROJECTION_VS = R"VS(#version 450 core static const char * REPROJECTION_VS = R"VS(#version 410 core
in vec3 Position; in vec3 Position;
in vec2 TexCoord; in vec2 TexCoord;
@ -78,15 +78,15 @@ void main() {
)VS"; )VS";
static const GLint REPROJECTION_MATRIX_LOCATION = 0; static GLint REPROJECTION_MATRIX_LOCATION = -1;
static const GLint INVERSE_PROJECTION_MATRIX_LOCATION = 4; static GLint INVERSE_PROJECTION_MATRIX_LOCATION = -1;
static const GLint PROJECTION_MATRIX_LOCATION = 12; static GLint PROJECTION_MATRIX_LOCATION = -1;
static const char * REPROJECTION_FS = R"FS(#version 450 core static const char * REPROJECTION_FS = R"FS(#version 410 core
uniform sampler2D sampler; uniform sampler2D sampler;
layout (location = 0) uniform mat3 reprojection = mat3(1); uniform mat3 reprojection = mat3(1);
layout (location = 4) uniform mat4 inverseProjections[2]; uniform mat4 inverseProjections[2];
layout (location = 12) uniform mat4 projections[2]; uniform mat4 projections[2];
in vec2 vTexCoord; in vec2 vTexCoord;
in vec3 vPosition; in vec3 vPosition;
@ -205,6 +205,11 @@ void HmdDisplayPlugin::customizeContext() {
_enablePreview = !isVsyncEnabled(); _enablePreview = !isVsyncEnabled();
_sphereSection = loadSphereSection(_program, CompositorHelper::VIRTUAL_UI_TARGET_FOV.y, CompositorHelper::VIRTUAL_UI_ASPECT_RATIO); _sphereSection = loadSphereSection(_program, CompositorHelper::VIRTUAL_UI_TARGET_FOV.y, CompositorHelper::VIRTUAL_UI_ASPECT_RATIO);
compileProgram(_reprojectionProgram, REPROJECTION_VS, REPROJECTION_FS); compileProgram(_reprojectionProgram, REPROJECTION_VS, REPROJECTION_FS);
using namespace oglplus;
REPROJECTION_MATRIX_LOCATION = Uniform<glm::mat3>(*_reprojectionProgram, "reprojection").Location();
INVERSE_PROJECTION_MATRIX_LOCATION = Uniform<glm::mat4>(*_reprojectionProgram, "inverseProjections").Location();
PROJECTION_MATRIX_LOCATION = Uniform<glm::mat4>(*_reprojectionProgram, "projections").Location();
} }
void HmdDisplayPlugin::uncustomizeContext() { void HmdDisplayPlugin::uncustomizeContext() {

View file

@ -17,8 +17,15 @@ QOpenGLContext* QOpenGLContextWrapper::currentContext() {
return QOpenGLContext::currentContext(); return QOpenGLContext::currentContext();
} }
QOpenGLContextWrapper::QOpenGLContextWrapper() : QOpenGLContextWrapper::QOpenGLContextWrapper() :
_context(new QOpenGLContext) _context(new QOpenGLContext)
{
}
QOpenGLContextWrapper::QOpenGLContextWrapper(QOpenGLContext* context) :
_context(context)
{ {
} }
@ -50,3 +57,7 @@ bool isCurrentContext(QOpenGLContext* context) {
return QOpenGLContext::currentContext() == context; return QOpenGLContext::currentContext() == context;
} }
void QOpenGLContextWrapper::moveToThread(QThread* thread) {
_context->moveToThread(thread);
}

View file

@ -15,16 +15,19 @@
class QOpenGLContext; class QOpenGLContext;
class QSurface; class QSurface;
class QSurfaceFormat; class QSurfaceFormat;
class QThread;
class QOpenGLContextWrapper { class QOpenGLContextWrapper {
public: public:
QOpenGLContextWrapper(); QOpenGLContextWrapper();
QOpenGLContextWrapper(QOpenGLContext* context);
void setFormat(const QSurfaceFormat& format); void setFormat(const QSurfaceFormat& format);
bool create(); bool create();
void swapBuffers(QSurface* surface); void swapBuffers(QSurface* surface);
bool makeCurrent(QSurface* surface); bool makeCurrent(QSurface* surface);
void doneCurrent(); void doneCurrent();
void setShareContext(QOpenGLContext* otherContext); void setShareContext(QOpenGLContext* otherContext);
void moveToThread(QThread* thread);
static QOpenGLContext* currentContext(); static QOpenGLContext* currentContext();

View file

@ -12,13 +12,17 @@ if (APPLE)
set(TARGET_NAME oculusLegacy) set(TARGET_NAME oculusLegacy)
setup_hifi_plugin() setup_hifi_plugin()
link_hifi_libraries(shared gl gpu plugins display-plugins input-plugins) link_hifi_libraries(shared gl gpu plugins ui display-plugins input-plugins)
include_hifi_library_headers(octree) include_hifi_library_headers(octree)
add_dependency_external_projects(LibOVR) add_dependency_external_projects(LibOVR)
find_package(LibOVR REQUIRED) find_package(LibOVR REQUIRED)
target_include_directories(${TARGET_NAME} PRIVATE ${LIBOVR_INCLUDE_DIRS}) target_include_directories(${TARGET_NAME} PRIVATE ${LIBOVR_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES}) find_library(COCOA_LIBRARY Cocoa)
find_library(IOKIT_LIBRARY IOKit)
target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES} ${COCOA_LIBRARY} ${IOKIT_LIBRARY})
endif() endif()

View file

@ -9,6 +9,7 @@
#include <memory> #include <memory>
#include <QtCore/QThread.h>
#include <QtWidgets/QMainWindow> #include <QtWidgets/QMainWindow>
#include <QtOpenGL/QGLWidget> #include <QtOpenGL/QGLWidget>
#include <GLMHelpers.h> #include <GLMHelpers.h>
@ -16,7 +17,12 @@
#include <QtGui/QResizeEvent> #include <QtGui/QResizeEvent>
#include <QtGui/QGuiApplication> #include <QtGui/QGuiApplication>
#include <QtGui/QScreen> #include <QtGui/QScreen>
#include <gl/GLWindow.h>
#include <gl/GLWidget.h>
#include <gpu/GLBackend.h>
#include <MainWindow.h>
#include <gl/QOpenGLContextWrapper.h>
#include <PerfStat.h> #include <PerfStat.h>
#include <gl/OglplusHelpers.h> #include <gl/OglplusHelpers.h>
#include <ViewFrustum.h> #include <ViewFrustum.h>
@ -39,7 +45,7 @@ void OculusLegacyDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
_currentRenderFrameInfo = FrameInfo(); _currentRenderFrameInfo = FrameInfo();
_currentRenderFrameInfo.predictedDisplayTime = _currentRenderFrameInfo.sensorSampleTime = ovr_GetTimeInSeconds(); _currentRenderFrameInfo.predictedDisplayTime = _currentRenderFrameInfo.sensorSampleTime = ovr_GetTimeInSeconds();
_trackingState = ovrHmd_GetTrackingState(_hmd, _currentRenderFrameInfo.predictedDisplayTime); _trackingState = ovrHmd_GetTrackingState(_hmd, _currentRenderFrameInfo.predictedDisplayTime);
_currentRenderFrameInfo.renderPose = toGlm(_trackingState.HeadPose.ThePose); _currentRenderFrameInfo.rawRenderPose = _currentRenderFrameInfo.renderPose = toGlm(_trackingState.HeadPose.ThePose);
Lock lock(_mutex); Lock lock(_mutex);
_frameInfos[frameIndex] = _currentRenderFrameInfo; _frameInfos[frameIndex] = _currentRenderFrameInfo;
} }
@ -72,14 +78,34 @@ bool OculusLegacyDisplayPlugin::isSupported() const {
} }
bool OculusLegacyDisplayPlugin::internalActivate() { bool OculusLegacyDisplayPlugin::internalActivate() {
Parent::internalActivate(); if (!Parent::internalActivate()) {
return false;
}
if (!(ovr_Initialize(nullptr))) { if (!(ovr_Initialize(nullptr))) {
Q_ASSERT(false); Q_ASSERT(false);
qFatal("Failed to Initialize SDK"); qFatal("Failed to Initialize SDK");
return false; return false;
} }
_hmdWindow = new GLWindow();
_hmdWindow->create();
_hmdWindow->createContext(_container->getPrimaryContext());
auto hmdScreen = qApp->screens()[_hmdScreen];
auto hmdGeometry = hmdScreen->geometry();
_hmdWindow->setGeometry(hmdGeometry);
_hmdWindow->showFullScreen();
_hmdWindow->makeCurrent();
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
_hmdWindow->swapBuffers();
_container->makeRenderingContextCurrent();
QOpenGLContextWrapper(_hmdWindow->context()).moveToThread(_presentThread);
_hswDismissed = false; _hswDismissed = false;
_hmd = ovrHmd_Create(0); _hmd = ovrHmd_Create(0);
if (!_hmd) { if (!_hmd) {
@ -96,7 +122,8 @@ bool OculusLegacyDisplayPlugin::internalActivate() {
ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f ovrPerspectiveProjection =
ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded); ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
_eyeProjections[eye] = toGlm(ovrPerspectiveProjection); _eyeProjections[eye] = toGlm(ovrPerspectiveProjection);
_eyeOffsets[eye] = glm::translate(mat4(), toGlm(erd.HmdToEyeViewOffset)); _ovrEyeOffsets[eye] = erd.HmdToEyeViewOffset;
_eyeOffsets[eye] = glm::translate(mat4(), -1.0f * toGlm(_ovrEyeOffsets[eye]));
eyeSizes[eye] = toGlm(ovrHmd_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f)); eyeSizes[eye] = toGlm(ovrHmd_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f));
}); });
@ -121,6 +148,11 @@ void OculusLegacyDisplayPlugin::internalDeactivate() {
ovrHmd_Destroy(_hmd); ovrHmd_Destroy(_hmd);
_hmd = nullptr; _hmd = nullptr;
ovr_Shutdown(); ovr_Shutdown();
_hmdWindow->showNormal();
_hmdWindow->destroy();
_hmdWindow->deleteLater();
_hmdWindow = nullptr;
_container->makeRenderingContextCurrent();
} }
// DLL based display plugins MUST initialize GLEW inside the DLL code. // DLL based display plugins MUST initialize GLEW inside the DLL code.
@ -131,20 +163,21 @@ void OculusLegacyDisplayPlugin::customizeContext() {
glewInit(); glewInit();
glGetError(); glGetError();
}); });
_hmdWindow->requestActivate();
QThread::msleep(1000);
Parent::customizeContext(); Parent::customizeContext();
#if 0
ovrGLConfig config; memset(&config, 0, sizeof(ovrRenderAPIConfig)); ovrGLConfig config; memset(&config, 0, sizeof(ovrRenderAPIConfig));
auto& header = config.Config.Header; auto& header = config.Config.Header;
header.API = ovrRenderAPI_OpenGL; header.API = ovrRenderAPI_OpenGL;
header.BackBufferSize = _hmd->Resolution; header.BackBufferSize = _hmd->Resolution;
header.Multisample = 1; header.Multisample = 1;
int distortionCaps = ovrDistortionCap_TimeWarp; int distortionCaps = ovrDistortionCap_TimeWarp | ovrDistortionCap_Vignette;
memset(_eyeTextures, 0, sizeof(ovrTexture) * 2); memset(_eyeTextures, 0, sizeof(ovrTexture) * 2);
ovr_for_each_eye([&](ovrEyeType eye) { ovr_for_each_eye([&](ovrEyeType eye) {
auto& header = _eyeTextures[eye].Header; auto& header = _eyeTextures[eye].Header;
header.API = ovrRenderAPI_OpenGL; header.API = ovrRenderAPI_OpenGL;
header.TextureSize = { (int)_desiredFramebufferSize.x, (int)_desiredFramebufferSize.y }; header.TextureSize = { (int)_renderTargetSize.x, (int)_renderTargetSize.y };
header.RenderViewport.Size = header.TextureSize; header.RenderViewport.Size = header.TextureSize;
header.RenderViewport.Size.w /= 2; header.RenderViewport.Size.w /= 2;
if (eye == ovrEye_Right) { if (eye == ovrEye_Right) {
@ -152,29 +185,57 @@ void OculusLegacyDisplayPlugin::customizeContext() {
} }
}); });
if (_hmdWindow->makeCurrent()) {
#ifndef NDEBUG #ifndef NDEBUG
ovrBool result = ovrBool result =
#endif
ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs);
assert(result);
#endif #endif
ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs);
assert(result);
_hmdWindow->doneCurrent();
}
} }
#if 0
void OculusLegacyDisplayPlugin::uncustomizeContext() { void OculusLegacyDisplayPlugin::uncustomizeContext() {
HmdDisplayPlugin::uncustomizeContext(); _hmdWindow->doneCurrent();
QOpenGLContextWrapper(_hmdWindow->context()).moveToThread(qApp->thread());
Parent::uncustomizeContext();
} }
void OculusLegacyDisplayPlugin::internalPresent() { void OculusLegacyDisplayPlugin::hmdPresent() {
ovrHmd_BeginFrame(_hmd, 0); if (!_hswDismissed) {
ovr_for_each_eye([&](ovrEyeType eye) { ovrHSWDisplayState hswState;
reinterpret_cast<ovrGLTexture&>(_eyeTextures[eye]).OGL.TexId = _currentSceneTexture; ovrHmd_GetHSWDisplayState(_hmd, &hswState);
}); if (hswState.Displayed) {
ovrHmd_EndFrame(_hmd, _eyePoses, _eyeTextures); ovrHmd_DismissHSWDisplay(_hmd);
} }
#endif }
auto r = glm::quat_cast(_currentPresentFrameInfo.presentPose);
ovrQuatf ovrRotation = { r.x, r.y, r.z, r.w };
ovrPosef eyePoses[2];
memset(eyePoses, 0, sizeof(ovrPosef) * 2);
eyePoses[0].Orientation = eyePoses[1].Orientation = ovrRotation;
GLint texture = oglplus::GetName(_compositeFramebuffer->color);
auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
if (_hmdWindow->makeCurrent()) {
glClearColor(0, 0.4, 0.8, 1);
glClear(GL_COLOR_BUFFER_BIT);
ovrHmd_BeginFrame(_hmd, _currentPresentFrameIndex);
glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
glDeleteSync(sync);
ovr_for_each_eye([&](ovrEyeType eye) {
reinterpret_cast<ovrGLTexture&>(_eyeTextures[eye]).OGL.TexId = texture;
});
ovrHmd_EndFrame(_hmd, eyePoses, _eyeTextures);
_hmdWindow->doneCurrent();
}
static auto widget = _container->getPrimaryWidget();
widget->makeCurrent();
}
int OculusLegacyDisplayPlugin::getHmdScreen() const { int OculusLegacyDisplayPlugin::getHmdScreen() const {
return _hmdScreen; return _hmdScreen;
@ -184,4 +245,3 @@ float OculusLegacyDisplayPlugin::getTargetFrameRate() const {
return TARGET_RATE_OculusLegacy; return TARGET_RATE_OculusLegacy;
} }

View file

@ -14,42 +14,43 @@
#include <OVR_CAPI.h> #include <OVR_CAPI.h>
const float TARGET_RATE_OculusLegacy = 75.0f; const float TARGET_RATE_OculusLegacy = 75.0f;
class GLWindow;
class OculusLegacyDisplayPlugin : public HmdDisplayPlugin { class OculusLegacyDisplayPlugin : public HmdDisplayPlugin {
using Parent = HmdDisplayPlugin; using Parent = HmdDisplayPlugin;
public: public:
OculusLegacyDisplayPlugin(); OculusLegacyDisplayPlugin();
virtual bool isSupported() const override; bool isSupported() const override;
virtual const QString& getName() const override { return NAME; } const QString& getName() const override { return NAME; }
virtual int getHmdScreen() const override; int getHmdScreen() const override;
// Stereo specific methods // Stereo specific methods
virtual void resetSensors() override; void resetSensors() override;
virtual void beginFrameRender(uint32_t frameIndex) override; void beginFrameRender(uint32_t frameIndex) override;
virtual float getTargetFrameRate() const override; float getTargetFrameRate() const override;
protected: protected:
virtual bool internalActivate() override; bool internalActivate() override;
virtual void internalDeactivate() override; void internalDeactivate() override;
virtual void customizeContext() override; void customizeContext() override;
void hmdPresent() override {} void uncustomizeContext() override;
void hmdPresent() override;
bool isHmdMounted() const override { return true; } bool isHmdMounted() const override { return true; }
#if 0
virtual void uncustomizeContext() override;
virtual void internalPresent() override;
#endif
private: private:
static const QString NAME; static const QString NAME;
GLWindow* _hmdWindow{ nullptr };
ovrHmd _hmd; ovrHmd _hmd;
mutable ovrTrackingState _trackingState; mutable ovrTrackingState _trackingState;
ovrEyeRenderDesc _eyeRenderDescs[2]; ovrEyeRenderDesc _eyeRenderDescs[2];
ovrVector3f _ovrEyeOffsets[2];
ovrFovPort _eyeFovs[2]; ovrFovPort _eyeFovs[2];
//ovrTexture _eyeTextures[2]; // FIXME - not currently in use ovrTexture _eyeTextures[2]; // FIXME - not currently in use
mutable int _hmdScreen { -1 }; mutable int _hmdScreen { -1 };
bool _hswDismissed { false }; bool _hswDismissed { false };
}; };