From 0f768b13b9a61c10ead0dc072a3ca08fbf3a024a Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Sat, 7 May 2016 18:42:43 -0700 Subject: [PATCH] Working on OSX Rift functionality --- .../display-plugins/OpenGLDisplayPlugin.cpp | 18 +-- .../src/display-plugins/OpenGLDisplayPlugin.h | 1 + .../display-plugins/hmd/HmdDisplayPlugin.cpp | 21 ++-- libraries/gl/src/gl/QOpenGLContextWrapper.cpp | 13 ++- libraries/gl/src/gl/QOpenGLContextWrapper.h | 3 + plugins/oculusLegacy/CMakeLists.txt | 8 +- .../src/OculusLegacyDisplayPlugin.cpp | 104 ++++++++++++++---- .../src/OculusLegacyDisplayPlugin.h | 31 +++--- 8 files changed, 144 insertions(+), 55 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 7d4eebb7a2..a0b6ae3939 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -237,12 +237,6 @@ bool OpenGLDisplayPlugin::activate() { _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 // Start the present thread if necessary @@ -258,8 +252,18 @@ bool OpenGLDisplayPlugin::activate() { // Start execution 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 presentThread->setNewDisplayPlugin(this); #else diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index defa57fc58..c87ff1bc93 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -103,6 +103,7 @@ protected: virtual void updateFrameData(); + QThread* _presentThread{ nullptr }; ProgramPtr _program; int32_t _mvpUniform { -1 }; int32_t _alphaUniform { -1 }; diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 79b50a7f88..372337ae4d 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -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 vec2 TexCoord; @@ -78,15 +78,15 @@ void main() { )VS"; -static const GLint REPROJECTION_MATRIX_LOCATION = 0; -static const GLint INVERSE_PROJECTION_MATRIX_LOCATION = 4; -static const GLint PROJECTION_MATRIX_LOCATION = 12; -static const char * REPROJECTION_FS = R"FS(#version 450 core +static GLint REPROJECTION_MATRIX_LOCATION = -1; +static GLint INVERSE_PROJECTION_MATRIX_LOCATION = -1; +static GLint PROJECTION_MATRIX_LOCATION = -1; +static const char * REPROJECTION_FS = R"FS(#version 410 core uniform sampler2D sampler; -layout (location = 0) uniform mat3 reprojection = mat3(1); -layout (location = 4) uniform mat4 inverseProjections[2]; -layout (location = 12) uniform mat4 projections[2]; +uniform mat3 reprojection = mat3(1); +uniform mat4 inverseProjections[2]; +uniform mat4 projections[2]; in vec2 vTexCoord; in vec3 vPosition; @@ -205,6 +205,11 @@ void HmdDisplayPlugin::customizeContext() { _enablePreview = !isVsyncEnabled(); _sphereSection = loadSphereSection(_program, CompositorHelper::VIRTUAL_UI_TARGET_FOV.y, CompositorHelper::VIRTUAL_UI_ASPECT_RATIO); compileProgram(_reprojectionProgram, REPROJECTION_VS, REPROJECTION_FS); + + using namespace oglplus; + REPROJECTION_MATRIX_LOCATION = Uniform(*_reprojectionProgram, "reprojection").Location(); + INVERSE_PROJECTION_MATRIX_LOCATION = Uniform(*_reprojectionProgram, "inverseProjections").Location(); + PROJECTION_MATRIX_LOCATION = Uniform(*_reprojectionProgram, "projections").Location(); } void HmdDisplayPlugin::uncustomizeContext() { diff --git a/libraries/gl/src/gl/QOpenGLContextWrapper.cpp b/libraries/gl/src/gl/QOpenGLContextWrapper.cpp index 185fdaf7f4..8c9a1ba113 100644 --- a/libraries/gl/src/gl/QOpenGLContextWrapper.cpp +++ b/libraries/gl/src/gl/QOpenGLContextWrapper.cpp @@ -17,8 +17,15 @@ QOpenGLContext* QOpenGLContextWrapper::currentContext() { return QOpenGLContext::currentContext(); } + 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; } +void QOpenGLContextWrapper::moveToThread(QThread* thread) { + _context->moveToThread(thread); +} + diff --git a/libraries/gl/src/gl/QOpenGLContextWrapper.h b/libraries/gl/src/gl/QOpenGLContextWrapper.h index 09f1d67280..33cc0b25e9 100644 --- a/libraries/gl/src/gl/QOpenGLContextWrapper.h +++ b/libraries/gl/src/gl/QOpenGLContextWrapper.h @@ -15,16 +15,19 @@ class QOpenGLContext; class QSurface; class QSurfaceFormat; +class QThread; class QOpenGLContextWrapper { public: QOpenGLContextWrapper(); + QOpenGLContextWrapper(QOpenGLContext* context); void setFormat(const QSurfaceFormat& format); bool create(); void swapBuffers(QSurface* surface); bool makeCurrent(QSurface* surface); void doneCurrent(); void setShareContext(QOpenGLContext* otherContext); + void moveToThread(QThread* thread); static QOpenGLContext* currentContext(); diff --git a/plugins/oculusLegacy/CMakeLists.txt b/plugins/oculusLegacy/CMakeLists.txt index 9e97b3791c..a4e00013f1 100644 --- a/plugins/oculusLegacy/CMakeLists.txt +++ b/plugins/oculusLegacy/CMakeLists.txt @@ -12,13 +12,17 @@ if (APPLE) set(TARGET_NAME oculusLegacy) 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) add_dependency_external_projects(LibOVR) find_package(LibOVR REQUIRED) 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() diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index 34e36d6a6b..6ceddec11b 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -16,7 +17,12 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -39,7 +45,7 @@ void OculusLegacyDisplayPlugin::beginFrameRender(uint32_t frameIndex) { _currentRenderFrameInfo = FrameInfo(); _currentRenderFrameInfo.predictedDisplayTime = _currentRenderFrameInfo.sensorSampleTime = ovr_GetTimeInSeconds(); _trackingState = ovrHmd_GetTrackingState(_hmd, _currentRenderFrameInfo.predictedDisplayTime); - _currentRenderFrameInfo.renderPose = toGlm(_trackingState.HeadPose.ThePose); + _currentRenderFrameInfo.rawRenderPose = _currentRenderFrameInfo.renderPose = toGlm(_trackingState.HeadPose.ThePose); Lock lock(_mutex); _frameInfos[frameIndex] = _currentRenderFrameInfo; } @@ -72,14 +78,34 @@ bool OculusLegacyDisplayPlugin::isSupported() const { } bool OculusLegacyDisplayPlugin::internalActivate() { - Parent::internalActivate(); - + if (!Parent::internalActivate()) { + return false; + } + if (!(ovr_Initialize(nullptr))) { Q_ASSERT(false); qFatal("Failed to Initialize SDK"); 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; _hmd = ovrHmd_Create(0); if (!_hmd) { @@ -96,7 +122,8 @@ bool OculusLegacyDisplayPlugin::internalActivate() { ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded); _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)); }); @@ -121,6 +148,11 @@ void OculusLegacyDisplayPlugin::internalDeactivate() { ovrHmd_Destroy(_hmd); _hmd = nullptr; ovr_Shutdown(); + _hmdWindow->showNormal(); + _hmdWindow->destroy(); + _hmdWindow->deleteLater(); + _hmdWindow = nullptr; + _container->makeRenderingContextCurrent(); } // DLL based display plugins MUST initialize GLEW inside the DLL code. @@ -131,20 +163,21 @@ void OculusLegacyDisplayPlugin::customizeContext() { glewInit(); glGetError(); }); + _hmdWindow->requestActivate(); + QThread::msleep(1000); Parent::customizeContext(); -#if 0 ovrGLConfig config; memset(&config, 0, sizeof(ovrRenderAPIConfig)); auto& header = config.Config.Header; header.API = ovrRenderAPI_OpenGL; header.BackBufferSize = _hmd->Resolution; header.Multisample = 1; - int distortionCaps = ovrDistortionCap_TimeWarp; + int distortionCaps = ovrDistortionCap_TimeWarp | ovrDistortionCap_Vignette; memset(_eyeTextures, 0, sizeof(ovrTexture) * 2); ovr_for_each_eye([&](ovrEyeType eye) { auto& header = _eyeTextures[eye].Header; 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.w /= 2; if (eye == ovrEye_Right) { @@ -152,29 +185,57 @@ void OculusLegacyDisplayPlugin::customizeContext() { } }); + if (_hmdWindow->makeCurrent()) { #ifndef NDEBUG - ovrBool result = -#endif - ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs); - assert(result); + ovrBool result = #endif + ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs); + assert(result); + _hmdWindow->doneCurrent(); + } + } -#if 0 void OculusLegacyDisplayPlugin::uncustomizeContext() { - HmdDisplayPlugin::uncustomizeContext(); + _hmdWindow->doneCurrent(); + QOpenGLContextWrapper(_hmdWindow->context()).moveToThread(qApp->thread()); + Parent::uncustomizeContext(); } -void OculusLegacyDisplayPlugin::internalPresent() { - ovrHmd_BeginFrame(_hmd, 0); - ovr_for_each_eye([&](ovrEyeType eye) { - reinterpret_cast(_eyeTextures[eye]).OGL.TexId = _currentSceneTexture; - }); - ovrHmd_EndFrame(_hmd, _eyePoses, _eyeTextures); -} +void OculusLegacyDisplayPlugin::hmdPresent() { + if (!_hswDismissed) { + ovrHSWDisplayState hswState; + ovrHmd_GetHSWDisplayState(_hmd, &hswState); + if (hswState.Displayed) { + 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(_eyeTextures[eye]).OGL.TexId = texture; + }); + ovrHmd_EndFrame(_hmd, eyePoses, _eyeTextures); + _hmdWindow->doneCurrent(); + } + static auto widget = _container->getPrimaryWidget(); + widget->makeCurrent(); +} int OculusLegacyDisplayPlugin::getHmdScreen() const { return _hmdScreen; @@ -184,4 +245,3 @@ float OculusLegacyDisplayPlugin::getTargetFrameRate() const { return TARGET_RATE_OculusLegacy; } - diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h index bebf3fa2c7..5900ad4c58 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h @@ -14,42 +14,43 @@ #include const float TARGET_RATE_OculusLegacy = 75.0f; +class GLWindow; class OculusLegacyDisplayPlugin : public HmdDisplayPlugin { using Parent = HmdDisplayPlugin; public: OculusLegacyDisplayPlugin(); - virtual bool isSupported() const override; - virtual const QString& getName() const override { return NAME; } + bool isSupported() const override; + const QString& getName() const override { return NAME; } - virtual int getHmdScreen() const override; + int getHmdScreen() const override; // Stereo specific methods - virtual void resetSensors() override; - virtual void beginFrameRender(uint32_t frameIndex) override; + void resetSensors() override; + void beginFrameRender(uint32_t frameIndex) override; - virtual float getTargetFrameRate() const override; + float getTargetFrameRate() const override; protected: - virtual bool internalActivate() override; - virtual void internalDeactivate() override; + bool internalActivate() override; + void internalDeactivate() override; - virtual void customizeContext() override; - void hmdPresent() override {} + void customizeContext() override; + void uncustomizeContext() override; + void hmdPresent() override; bool isHmdMounted() const override { return true; } -#if 0 - virtual void uncustomizeContext() override; - virtual void internalPresent() override; -#endif private: static const QString NAME; + GLWindow* _hmdWindow{ nullptr }; ovrHmd _hmd; mutable ovrTrackingState _trackingState; ovrEyeRenderDesc _eyeRenderDescs[2]; + ovrVector3f _ovrEyeOffsets[2]; + ovrFovPort _eyeFovs[2]; - //ovrTexture _eyeTextures[2]; // FIXME - not currently in use + ovrTexture _eyeTextures[2]; // FIXME - not currently in use mutable int _hmdScreen { -1 }; bool _hswDismissed { false }; };