From 978d39b7f4f29a8db11c6fff19021d12da0b8e3f Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 18 Nov 2015 15:20:29 -0800 Subject: [PATCH 1/3] Moving OpenVR to external plugin and updating to latest version --- cmake/externals/openvr/CMakeLists.txt | 5 +- .../src/display-plugins/DisplayPlugin.cpp | 12 +- .../display-plugins/OpenGLDisplayPlugin.cpp | 9 +- .../src/display-plugins/OpenGLDisplayPlugin.h | 2 +- libraries/input-plugins/CMakeLists.txt | 12 +- .../src/input-plugins/InputPlugin.cpp | 2 - libraries/script-engine/src/ScriptEngine.cpp | 2 +- plugins/openvr/CMakeLists.txt | 25 +++++ .../openvr/src}/OpenVrDisplayPlugin.cpp | 103 +++++++++--------- .../openvr/src}/OpenVrDisplayPlugin.h | 11 +- .../openvr/src}/OpenVrHelpers.cpp | 25 ++--- .../openvr/src}/OpenVrHelpers.h | 5 - plugins/openvr/src/OpenVrProvider.cpp | 60 ++++++++++ .../openvr/src}/ViveControllerManager.cpp | 27 ++--- .../openvr/src}/ViveControllerManager.h | 2 +- plugins/openvr/src/plugin.json | 1 + 16 files changed, 175 insertions(+), 128 deletions(-) create mode 100644 plugins/openvr/CMakeLists.txt rename {libraries/display-plugins/src/display-plugins/openvr => plugins/openvr/src}/OpenVrDisplayPlugin.cpp (65%) rename {libraries/display-plugins/src/display-plugins/openvr => plugins/openvr/src}/OpenVrDisplayPlugin.h (84%) rename {libraries/display-plugins/src/display-plugins/openvr => plugins/openvr/src}/OpenVrHelpers.cpp (80%) rename {libraries/display-plugins/src/display-plugins/openvr => plugins/openvr/src}/OpenVrHelpers.h (89%) create mode 100644 plugins/openvr/src/OpenVrProvider.cpp rename {libraries/input-plugins/src/input-plugins => plugins/openvr/src}/ViveControllerManager.cpp (97%) rename {libraries/input-plugins/src/input-plugins => plugins/openvr/src}/ViveControllerManager.h (98%) create mode 100644 plugins/openvr/src/plugin.json diff --git a/cmake/externals/openvr/CMakeLists.txt b/cmake/externals/openvr/CMakeLists.txt index f9d0ef5a71..9ef95b17da 100644 --- a/cmake/externals/openvr/CMakeLists.txt +++ b/cmake/externals/openvr/CMakeLists.txt @@ -7,9 +7,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) ExternalProject_Add( ${EXTERNAL_NAME} - #URL https://github.com/ValveSoftware/openvr/archive/0.9.1.zip - URL http://hifi-public.s3.amazonaws.com/dependencies/openvr-0.9.1.zip - URL_MD5 f986f5a6815e9454c53c5bf58ce02fdc + URL https://github.com/ValveSoftware/openvr/archive/v0.9.12.zip + URL_MD5 c08dced68ce4e341e1467e6814ae419d CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp index 6c34612e8c..08368597d0 100644 --- a/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp @@ -14,8 +14,6 @@ #include "stereo/InterleavedStereoDisplayPlugin.h" #include "Basic2DWindowOpenGLDisplayPlugin.h" -#include "openvr/OpenVrDisplayPlugin.h" - const QString& DisplayPlugin::MENU_PATH() { static const QString value = "Display"; return value; @@ -25,22 +23,14 @@ const QString& DisplayPlugin::MENU_PATH() { DisplayPluginList getDisplayPlugins() { DisplayPlugin* PLUGIN_POOL[] = { new Basic2DWindowOpenGLDisplayPlugin(), - new NullDisplayPlugin(), #ifdef DEBUG + new NullDisplayPlugin(), #endif - // Stereo modes - // SBS left/right new SideBySideStereoDisplayPlugin(), // Interleaved left/right new InterleavedStereoDisplayPlugin(), - - // HMDs -//#ifdef Q_OS_WIN -// // SteamVR SDK -// new OpenVrDisplayPlugin(), -//#endif nullptr }; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 80710e9b96..db7acf8bf1 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -103,8 +104,12 @@ public: // take the latest texture and present it _context->makeCurrent(); - currentPlugin->present(); - _context->doneCurrent(); + if (QOpenGLContext::currentContext() == _context->contextHandle()) { + _activePlugin->present(); + _context->doneCurrent(); + } else { + qWarning() << "Makecurrent failed"; + } } _context->makeCurrent(); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 88ccddc125..72211056d9 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -74,7 +74,7 @@ protected: ProgramPtr _program; ShapeWrapperPtr _plane; - Mutex _mutex; + mutable Mutex _mutex; SimpleMovingAverage _usecsPerFrame { 10 }; QMap _sceneTextureToFrameIndexMap; diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt index 0e21d4a40c..b81554511d 100644 --- a/libraries/input-plugins/CMakeLists.txt +++ b/libraries/input-plugins/CMakeLists.txt @@ -1,15 +1,5 @@ set(TARGET_NAME input-plugins) setup_hifi_library() -link_hifi_libraries(shared plugins controllers script-engine render-utils) +link_hifi_libraries(shared plugins controllers) GroupSources("src/input-plugins") - -if (WIN32) - add_dependency_external_projects(OpenVR) - find_package(OpenVR REQUIRED) - target_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS}) - target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES}) -endif() - -target_sdl2() -target_sixense() diff --git a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp index 6db35572b5..4b79572a07 100644 --- a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp +++ b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp @@ -15,7 +15,6 @@ #include "KeyboardMouseDevice.h" #include "SDL2Manager.h" #include "SixenseManager.h" -#include "ViveControllerManager.h" // TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class InputPluginList getInputPlugins() { @@ -23,7 +22,6 @@ InputPluginList getInputPlugins() { new KeyboardMouseDevice(), new SDL2Manager(), new SixenseManager(), - new ViveControllerManager(), nullptr }; diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 3306659c80..a075b0a91d 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -82,7 +82,7 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) { } Q_DECLARE_METATYPE(controller::InputController*) -static int inputControllerPointerId = qRegisterMetaType(); +//static int inputControllerPointerId = qRegisterMetaType(); QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) { return engine->newQObject(in); diff --git a/plugins/openvr/CMakeLists.txt b/plugins/openvr/CMakeLists.txt new file mode 100644 index 0000000000..e7fab5903d --- /dev/null +++ b/plugins/openvr/CMakeLists.txt @@ -0,0 +1,25 @@ +# +# Created by Bradley Austin Davis on 2015/11/18 +# Copyright 2015 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html +# + +if (WIN32) + # we're using static GLEW, so define GLEW_STATIC + add_definitions(-DGLEW_STATIC) + set(TARGET_NAME openvr) + setup_hifi_plugin(OpenGL Script Qml Widgets) + link_hifi_libraries(shared gl networking controllers + plugins display-plugins input-plugins script-engine + render-utils model gpu render model-networking fbx) + + include_hifi_library_headers(octree) + + add_dependency_external_projects(OpenVR) + find_package(OpenVR REQUIRED) + target_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES}) + +endif() \ No newline at end of file diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp similarity index 65% rename from libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp rename to plugins/openvr/src/OpenVrDisplayPlugin.cpp index 68a711a847..58f7536856 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -7,24 +7,23 @@ // #include "OpenVrDisplayPlugin.h" -#if defined(Q_OS_WIN) - #include #include +#include #include -#include #include #include +#include +#include + #include #include #include #include "OpenVrHelpers.h" -#include "GLMHelpers.h" -#include Q_DECLARE_LOGGING_CATEGORY(displayplugins) Q_LOGGING_CATEGORY(displayplugins, "hifi.displayplugins") @@ -41,12 +40,11 @@ vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount]; mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount]; static mat4 _sensorResetMat; static uvec2 _windowSize; -static ivec2 _windowPosition; static uvec2 _renderTargetSize; struct PerEyeData { - uvec2 _viewportOrigin; - uvec2 _viewportSize; + //uvec2 _viewportOrigin; + //uvec2 _viewportSize; mat4 _projectionMatrix; mat4 _eyeOffset; mat4 _pose; @@ -89,36 +87,17 @@ void OpenVrDisplayPlugin::activate() { } Q_ASSERT(_hmd); - _hmd->GetWindowBounds(&_windowPosition.x, &_windowPosition.y, &_windowSize.x, &_windowSize.y); _hmd->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y); // Recommended render target size is per-eye, so double the X size for // left + right eyes _renderTargetSize.x *= 2; openvr_for_each_eye([&](vr::Hmd_Eye eye) { PerEyeData& eyeData = _eyesData[eye]; - _hmd->GetEyeOutputViewport(eye, - &eyeData._viewportOrigin.x, &eyeData._viewportOrigin.y, - &eyeData._viewportSize.x, &eyeData._viewportSize.y); eyeData._projectionMatrix = toGlm(_hmd->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL)); eyeData._eyeOffset = toGlm(_hmd->GetEyeToHeadTransform(eye)); }); - - - vr::HmdError eError = vr::HmdError_None; - _compositor = (vr::IVRCompositor*)vr::VR_GetGenericInterface(vr::IVRCompositor_Version, &eError); - Q_ASSERT(eError == vr::HmdError_None); + _compositor = vr::VRCompositor(); Q_ASSERT(_compositor); - - _compositor->SetGraphicsDevice(vr::Compositor_DeviceType_OpenGL, NULL); - - uint32_t unSize = _compositor->GetLastError(NULL, 0); - if (unSize > 1) { - char* buffer = new char[unSize]; - _compositor->GetLastError(buffer, unSize); - printf("Compositor - %s\n", buffer); - delete[] buffer; - } - Q_ASSERT(unSize <= 1); WindowOpenGLDisplayPlugin::activate(); } @@ -132,6 +111,16 @@ void OpenVrDisplayPlugin::deactivate() { WindowOpenGLDisplayPlugin::deactivate(); } +void OpenVrDisplayPlugin::customizeContext() { + static std::once_flag once; + std::call_once(once, []{ + glewExperimental = true; + GLenum err = glewInit(); + glGetError(); + }); + WindowOpenGLDisplayPlugin::customizeContext(); +} + uvec2 OpenVrDisplayPlugin::getRecommendedRenderSize() const { return _renderTargetSize; } @@ -153,33 +142,41 @@ glm::mat4 OpenVrDisplayPlugin::getEyeToHeadTransform(Eye eye) const { } glm::mat4 OpenVrDisplayPlugin::getHeadPose(uint32_t frameIndex) const { - return _trackedDevicePoseMat4[0]; + glm::mat4 result; + { + Lock lock(_mutex); + result = _trackedDevicePoseMat4[0]; + + } + return result; } -void OpenVrDisplayPlugin::customizeContext() { - WindowOpenGLDisplayPlugin::customizeContext(); + +void OpenVrDisplayPlugin::submitSceneTexture(uint32_t frameIndex, uint32_t sceneTexture, const glm::uvec2& sceneSize) { + WindowOpenGLDisplayPlugin::submitSceneTexture(frameIndex, sceneTexture, sceneSize); } -//void OpenVrDisplayPlugin::display(uint32_t frameIndex, uint32_t finalTexture, const glm::uvec2& sceneSize) { -// // Flip y-axis since GL UV coords are backwards. -// static vr::Compositor_TextureBounds leftBounds{ 0, 1, 0.5f, 0 }; -// static vr::Compositor_TextureBounds rightBounds{ 0.5f, 1, 1, 0 }; -// _compositor->Submit(vr::Eye_Left, (void*)finalTexture, &leftBounds); -// _compositor->Submit(vr::Eye_Right, (void*)finalTexture, &rightBounds); -// glFinish(); -//} - -//void OpenVrDisplayPlugin::finishFrame() { -//// swapBuffers(); -// doneCurrent(); -// _compositor->WaitGetPoses(_trackedDevicePose, vr::k_unMaxTrackedDeviceCount); -// for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) { -// _trackedDevicePoseMat4[i] = _sensorResetMat * toGlm(_trackedDevicePose[i].mDeviceToAbsoluteTracking); -// } -// openvr_for_each_eye([&](vr::Hmd_Eye eye) { -// _eyesData[eye]._pose = _trackedDevicePoseMat4[0]; -// }); -//}; - -#endif +void OpenVrDisplayPlugin::internalPresent() { + // Flip y-axis since GL UV coords are backwards. + static vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 }; + static vr::VRTextureBounds_t rightBounds{ 0.5f, 0, 1, 1 }; + vr::Texture_t texture{ (void*)_currentSceneTexture, vr::API_OpenGL, vr::ColorSpace_Auto }; + { + Lock lock(_mutex); + _compositor->Submit(vr::Eye_Left, &texture, &leftBounds); + _compositor->Submit(vr::Eye_Right, &texture, &rightBounds); + } + glFinish(); + { + Lock lock(_mutex); + _compositor->WaitGetPoses(_trackedDevicePose, vr::k_unMaxTrackedDeviceCount, nullptr, 0); + for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) { + _trackedDevicePoseMat4[i] = _sensorResetMat * toGlm(_trackedDevicePose[i].mDeviceToAbsoluteTracking); + } + openvr_for_each_eye([&](vr::Hmd_Eye eye) { + _eyesData[eye]._pose = _trackedDevicePoseMat4[0]; + }); + } + //WindowOpenGLDisplayPlugin::internalPresent(); +} diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h similarity index 84% rename from libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h rename to plugins/openvr/src/OpenVrDisplayPlugin.h index c8887276b7..4b5639d52b 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -9,10 +9,9 @@ #include -#if defined(Q_OS_WIN) #include -#include "../WindowOpenGLDisplayPlugin.h" +#include class OpenVrDisplayPlugin : public WindowOpenGLDisplayPlugin { public: @@ -23,6 +22,8 @@ public: virtual void activate() override; virtual void deactivate() override; + virtual void customizeContext() override; + virtual glm::uvec2 getRecommendedRenderSize() const override; virtual glm::uvec2 getRecommendedUiSize() const override { return uvec2(1920, 1080); } @@ -32,15 +33,13 @@ public: virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override; virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override; + virtual void submitSceneTexture(uint32_t frameIndex, uint32_t sceneTexture, const glm::uvec2& sceneSize) override; protected: -// virtual void display(uint32_t frameIndex, uint32_t finalTexture, const glm::uvec2& sceneSize) override; - virtual void customizeContext() override; + virtual void internalPresent() override; private: vr::IVRSystem* _hmd { nullptr }; static const QString NAME; }; -#endif - diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp similarity index 80% rename from libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.cpp rename to plugins/openvr/src/OpenVrHelpers.cpp index f8e810beaf..7020fcb40d 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -7,14 +7,15 @@ // #include "OpenVrHelpers.h" -#if defined(Q_OS_WIN) - -#include - #include #include -#include "../Logging.h" +#include +#include +#include + + +Q_DECLARE_LOGGING_CATEGORY(displayplugins) using Mutex = std::mutex; using Lock = std::unique_lock; @@ -30,13 +31,13 @@ vr::IVRSystem* acquireOpenVrSystem() { if (hmdPresent) { Lock lock(mutex); if (!activeHmd) { - qCDebug(displayPlugins) << "openvr: No vr::IVRSystem instance active, building"; - vr::HmdError eError = vr::HmdError_None; + qCDebug(displayplugins) << "openvr: No vr::IVRSystem instance active, building"; + vr::EVRInitError eError = vr::VRInitError_None; activeHmd = vr::VR_Init(&eError); - qCDebug(displayPlugins) << "openvr display: HMD is " << activeHmd << " error is " << eError; + qCDebug(displayplugins) << "openvr display: HMD is " << activeHmd << " error is " << eError; } if (activeHmd) { - qCDebug(displayPlugins) << "openvr: incrementing refcount"; + qCDebug(displayplugins) << "openvr: incrementing refcount"; ++refCount; } } @@ -46,10 +47,10 @@ vr::IVRSystem* acquireOpenVrSystem() { void releaseOpenVrSystem() { if (activeHmd) { Lock lock(mutex); - qDebug() << "openvr: decrementing refcount"; + qCDebug(displayplugins) << "openvr: decrementing refcount"; --refCount; if (0 == refCount) { - qDebug() << "openvr: zero refcount, deallocate VR system"; + qCDebug(displayplugins) << "openvr: zero refcount, deallocate VR system"; // Avoid spamming the VR system with activate/deactivate calls at system startup by // putting in a delay before we destory the shutdown the VR subsystem @@ -71,5 +72,3 @@ void releaseOpenVrSystem() { } } } - -#endif diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.h b/plugins/openvr/src/OpenVrHelpers.h similarity index 89% rename from libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.h rename to plugins/openvr/src/OpenVrHelpers.h index 3e445d90ba..513e1702d2 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.h +++ b/plugins/openvr/src/OpenVrHelpers.h @@ -7,9 +7,6 @@ // #pragma once -#include - -#if defined(Q_OS_WIN) #include #include #include @@ -18,5 +15,3 @@ vr::IVRSystem* acquireOpenVrSystem(); void releaseOpenVrSystem(); -#endif - diff --git a/plugins/openvr/src/OpenVrProvider.cpp b/plugins/openvr/src/OpenVrProvider.cpp new file mode 100644 index 0000000000..66227a9543 --- /dev/null +++ b/plugins/openvr/src/OpenVrProvider.cpp @@ -0,0 +1,60 @@ +// +// Created by Bradley Austin Davis on 2015/10/25 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include +#include +#include + +#include + +#include "OpenVrDisplayPlugin.h" +#include "ViveControllerManager.h" + +class OpenVrProvider : public QObject, public DisplayProvider, InputProvider +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DisplayProvider_iid FILE "plugin.json") + Q_INTERFACES(DisplayProvider) + Q_PLUGIN_METADATA(IID InputProvider_iid FILE "plugin.json") + Q_INTERFACES(InputProvider) + +public: + OpenVrProvider(QObject* parent = nullptr) : QObject(parent) {} + virtual ~OpenVrProvider() {} + + virtual DisplayPluginList getDisplayPlugins() override { + static std::once_flag once; + std::call_once(once, [&] { + DisplayPluginPointer plugin(new OpenVrDisplayPlugin()); + if (plugin->isSupported()) { + _displayPlugins.push_back(plugin); + } + }); + return _displayPlugins; + } + + virtual InputPluginList getInputPlugins() override { + static std::once_flag once; + std::call_once(once, [&] { + InputPluginPointer plugin(new ViveControllerManager()); + if (plugin->isSupported()) { + _inputPlugins.push_back(plugin); + } + }); + return _inputPlugins; + } + + +private: + DisplayPluginList _displayPlugins; + InputPluginList _inputPlugins; +}; + +#include "OpenVrProvider.moc" diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp similarity index 97% rename from libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp rename to plugins/openvr/src/ViveControllerManager.cpp index 5315152cea..39056cd46f 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -26,10 +25,10 @@ #include -#ifdef Q_OS_WIN +#include "OpenVrHelpers.h" + extern vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount]; extern mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount]; -#endif vr::IVRSystem* acquireOpenVrSystem(); void releaseOpenVrSystem(); @@ -39,7 +38,7 @@ static const float CONTROLLER_LENGTH_OFFSET = 0.0762f; // three inches static const glm::vec3 CONTROLLER_OFFSET = glm::vec3(CONTROLLER_LENGTH_OFFSET / 2.0f, CONTROLLER_LENGTH_OFFSET / 2.0f, CONTROLLER_LENGTH_OFFSET * 2.0f); -static const QString CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b"; +static const char* CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b"; static const QString MENU_PARENT = "Avatar"; static const QString MENU_NAME = "Vive Controllers"; @@ -49,19 +48,14 @@ static const QString RENDER_CONTROLLERS = "Render Hand Controllers"; const QString ViveControllerManager::NAME = "OpenVR"; bool ViveControllerManager::isSupported() const { -#ifdef Q_OS_WIN auto hmd = acquireOpenVrSystem(); bool success = hmd != nullptr; releaseOpenVrSystem(); return success; -#else - return false; -#endif } void ViveControllerManager::activate() { InputPlugin::activate(); -#ifdef Q_OS_WIN _container->addMenu(MENU_PATH); _container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, RENDER_CONTROLLERS, [this] (bool clicked) { this->setRenderControllers(clicked); }, @@ -72,8 +66,11 @@ void ViveControllerManager::activate() { } Q_ASSERT(_hmd); + auto renderModels = vr::VRRenderModels(); + vr::RenderModel_t model; - if (!_hmd->LoadRenderModel(CONTROLLER_MODEL_STRING.toStdString().c_str(), &model)) { + /* + if (!_hmd->LoadRenderModel(CONTROLLER_MODEL_STRING, &model)) { qDebug() << QString("Unable to load render model %1\n").arg(CONTROLLER_MODEL_STRING); } else { model::Mesh* mesh = new model::Mesh(); @@ -118,7 +115,7 @@ void ViveControllerManager::activate() { _modelLoaded = true; _renderControllers = true; } -#endif + */ // unregister with UserInputMapper auto userInputMapper = DependencyManager::get(); @@ -129,7 +126,6 @@ void ViveControllerManager::activate() { void ViveControllerManager::deactivate() { InputPlugin::deactivate(); -#ifdef Q_OS_WIN _container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS); _container->removeMenu(MENU_PATH); @@ -139,7 +135,6 @@ void ViveControllerManager::deactivate() { } _inputDevice->_poseStateMap.clear(); -#endif // unregister with UserInputMapper auto userInputMapper = DependencyManager::get(); @@ -225,7 +220,6 @@ void ViveControllerManager::pluginUpdate(float deltaTime, bool jointsCaptured) { } void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCaptured) { -#ifdef Q_OS_WIN _poseStateMap.clear(); _buttonPressedMap.clear(); @@ -276,7 +270,6 @@ void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCapt } _trackedControllers = numTrackedControllers; -#endif } void ViveControllerManager::InputDevice::focusOutEvent() { @@ -286,7 +279,6 @@ void ViveControllerManager::InputDevice::focusOutEvent() { // These functions do translation from the Steam IDs to the standard controller IDs void ViveControllerManager::InputDevice::handleAxisEvent(uint32_t axis, float x, float y, bool left) { -#ifdef Q_OS_WIN //FIX ME? It enters here every frame: probably we want to enter only if an event occurs axis += vr::k_EButton_Axis0; using namespace controller; @@ -296,12 +288,10 @@ void ViveControllerManager::InputDevice::handleAxisEvent(uint32_t axis, float x, } else if (axis == vr::k_EButton_SteamVR_Trigger) { _axisStateMap[left ? LT : RT] = x; } -#endif } // These functions do translation from the Steam IDs to the standard controller IDs void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool pressed, bool left) { -#ifdef Q_OS_WIN if (!pressed) { return; } @@ -319,7 +309,6 @@ void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool //FIX ME: not able to ovrewrite the behaviour of this button _buttonPressedMap.insert(left ? controller::LEFT_SECONDARY_THUMB : controller::RIGHT_SECONDARY_THUMB); } -#endif } void ViveControllerManager::InputDevice::handlePoseEvent(const mat4& mat, bool left) { diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h similarity index 98% rename from libraries/input-plugins/src/input-plugins/ViveControllerManager.h rename to plugins/openvr/src/ViveControllerManager.h index 02bdecb10a..077aec7fc3 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -20,7 +20,7 @@ #include #include #include -#include "InputPlugin.h" +#include #include #include diff --git a/plugins/openvr/src/plugin.json b/plugins/openvr/src/plugin.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/plugins/openvr/src/plugin.json @@ -0,0 +1 @@ +{} From fd5fb3096f2eacaeddf98977be9caa06ab258c7b Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 8 Dec 2015 17:55:46 -0800 Subject: [PATCH 2/3] Disabling OpenVR plugin --- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 2 +- plugins/openvr/CMakeLists.txt | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index db7acf8bf1..880e4a16b3 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -105,7 +105,7 @@ public: // take the latest texture and present it _context->makeCurrent(); if (QOpenGLContext::currentContext() == _context->contextHandle()) { - _activePlugin->present(); + currentPlugin->present(); _context->doneCurrent(); } else { qWarning() << "Makecurrent failed"; diff --git a/plugins/openvr/CMakeLists.txt b/plugins/openvr/CMakeLists.txt index e7fab5903d..c3c4771276 100644 --- a/plugins/openvr/CMakeLists.txt +++ b/plugins/openvr/CMakeLists.txt @@ -6,7 +6,10 @@ # See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html # -if (WIN32) +# OpenVR is disabled until a) it works with threaded present and +# b) it doesn't interfere with Oculus SDK 0.8 +if (FALSE) +#if (WIN32) # we're using static GLEW, so define GLEW_STATIC add_definitions(-DGLEW_STATIC) set(TARGET_NAME openvr) @@ -21,5 +24,4 @@ if (WIN32) find_package(OpenVR REQUIRED) target_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES}) - -endif() \ No newline at end of file +endif() From 1644bda9080983237524dea8d5db6636976af1aa Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 8 Dec 2015 14:21:14 -0800 Subject: [PATCH 3/3] Migrate to latest Oculus SDK (0.8) --- cmake/externals/LibOVR/CMakeLists.txt | 11 ++- .../oculus/src/OculusBaseDisplayPlugin.cpp | 71 ++++++++++--------- plugins/oculus/src/OculusBaseDisplayPlugin.h | 8 +-- plugins/oculus/src/OculusDisplayPlugin.cpp | 51 ++++++------- 4 files changed, 70 insertions(+), 71 deletions(-) diff --git a/cmake/externals/LibOVR/CMakeLists.txt b/cmake/externals/LibOVR/CMakeLists.txt index 8d13882d48..a98745b404 100644 --- a/cmake/externals/LibOVR/CMakeLists.txt +++ b/cmake/externals/LibOVR/CMakeLists.txt @@ -15,17 +15,16 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) # 0.6 public # URL http://static.oculus.com/sdk-downloads/0.6.0.1/Public/1435190862/ovr_sdk_win_0.6.0.1.zip # URL_MD5 4b3ef825f9a1d6d3035c9f6820687da9 -# 0.7 alpha -# URL https://s3.amazonaws.com/static.oculus.com/sdk-downloads/0.7.0.0/Public/Alpha/ovr_sdk_win_0.7.0.0_RC1.zip -# URL_MD5 a562bb9d117087b2cf9d86653ea70fd8 - +# 0.8 public +# URL http://static.oculus.com/sdk-downloads/0.8.0.0/Public/1445451746/ovr_sdk_win_0.8.0.0.zip +# URL_MD5 54944b03b95149d6010f84eb701b9647 if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://static.oculus.com/sdk-downloads/0.6.0.1/Public/1435190862/ovr_sdk_win_0.6.0.1.zip - URL_MD5 4b3ef825f9a1d6d3035c9f6820687da9 + URL http://static.oculus.com/sdk-downloads/0.8.0.0/Public/1445451746/ovr_sdk_win_0.8.0.0.zip + URL_MD5 54944b03b95149d6010f84eb701b9647 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index 7c057c7152..d6811c3529 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -20,9 +20,7 @@ glm::mat4 OculusBaseDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseP } void OculusBaseDisplayPlugin::resetSensors() { -#if (OVR_MAJOR_VERSION >= 6) - ovr_RecenterPose(_hmd); -#endif + ovr_RecenterPose(_session); } glm::mat4 OculusBaseDisplayPlugin::getEyeToHeadTransform(Eye eye) const { @@ -30,27 +28,39 @@ glm::mat4 OculusBaseDisplayPlugin::getEyeToHeadTransform(Eye eye) const { } glm::mat4 OculusBaseDisplayPlugin::getHeadPose(uint32_t frameIndex) const { -#if (OVR_MAJOR_VERSION >= 6) - auto frameTiming = ovr_GetFrameTiming(_hmd, frameIndex); - auto trackingState = ovr_GetTrackingState(_hmd, frameTiming.DisplayMidpointSeconds); + static uint32_t lastFrameSeen = 0; + auto displayTime = ovr_GetPredictedDisplayTime(_session, frameIndex); + auto trackingState = ovr_GetTrackingState(_session, displayTime, frameIndex > lastFrameSeen); + if (frameIndex > lastFrameSeen) { + lastFrameSeen = frameIndex; + } return toGlm(trackingState.HeadPose.ThePose); -#endif } bool OculusBaseDisplayPlugin::isSupported() const { -#if (OVR_MAJOR_VERSION >= 6) if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { return false; } - bool result = false; - if (ovrHmd_Detect() > 0) { - result = true; + + ovrSession session { nullptr }; + ovrGraphicsLuid luid; + auto result = ovr_Create(&session, &luid); + if (!OVR_SUCCESS(result)) { + ovrErrorInfo error; + ovr_GetLastErrorInfo(&error); + ovr_Shutdown(); + return false; } + + auto hmdDesc = ovr_GetHmdDesc(session); + if (hmdDesc.Type == ovrHmd_None) { + ovr_Destroy(session); + ovr_Shutdown(); + return false; + } + ovr_Shutdown(); - return result; -#else - return false; -#endif + return true; } // DLL based display plugins MUST initialize GLEW inside the DLL code. @@ -69,28 +79,22 @@ void OculusBaseDisplayPlugin::deinit() { void OculusBaseDisplayPlugin::activate() { WindowOpenGLDisplayPlugin::activate(); -#if (OVR_MAJOR_VERSION >= 6) if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { qFatal("Could not init OVR"); } -#if (OVR_MAJOR_VERSION == 6) - if (!OVR_SUCCESS(ovr_Create(0, &_hmd))) { -#elif (OVR_MAJOR_VERSION == 7) - if (!OVR_SUCCESS(ovr_Create(&_hmd, &_luid))) { -#endif - Q_ASSERT(false); + if (!OVR_SUCCESS(ovr_Create(&_session, &_luid))) { qFatal("Failed to acquire HMD"); } - _hmdDesc = ovr_GetHmdDesc(_hmd); + _hmdDesc = ovr_GetHmdDesc(_session); - _ipd = ovr_GetFloat(_hmd, OVR_KEY_IPD, _ipd); + _ipd = ovr_GetFloat(_session, OVR_KEY_IPD, _ipd); glm::uvec2 eyeSizes[2]; ovr_for_each_eye([&](ovrEyeType eye) { _eyeFovs[eye] = _hmdDesc.DefaultEyeFov[eye]; - ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_hmd, eye, _eyeFovs[eye]); + ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_session, eye, _eyeFovs[eye]); ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded); _eyeProjections[eye] = toGlm(ovrPerspectiveProjection); @@ -100,7 +104,7 @@ void OculusBaseDisplayPlugin::activate() { _compositeEyeProjections[eye] = toGlm(ovrPerspectiveProjection); _eyeOffsets[eye] = erd.HmdToEyeViewOffset; - eyeSizes[eye] = toGlm(ovr_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f)); + eyeSizes[eye] = toGlm(ovr_GetFovTextureSize(_session, eye, erd.Fov, 1.0f)); }); ovrFovPort combined = _eyeFovs[Left]; combined.LeftTan = std::max(_eyeFovs[Left].LeftTan, _eyeFovs[Right].LeftTan); @@ -115,34 +119,33 @@ void OculusBaseDisplayPlugin::activate() { eyeSizes[0].x + eyeSizes[1].x, std::max(eyeSizes[0].y, eyeSizes[1].y)); - if (!OVR_SUCCESS(ovr_ConfigureTracking(_hmd, + if (!OVR_SUCCESS(ovr_ConfigureTracking(_session, ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) { qFatal("Could not attach to sensor device"); } - // Parent class relies on our _hmd intialization, so it must come after that. + // Parent class relies on our _session intialization, so it must come after that. memset(&_sceneLayer, 0, sizeof(ovrLayerEyeFov)); _sceneLayer.Header.Type = ovrLayerType_EyeFov; _sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; ovr_for_each_eye([&](ovrEyeType eye) { ovrFovPort & fov = _sceneLayer.Fov[eye] = _eyeRenderDescs[eye].Fov; - ovrSizei & size = _sceneLayer.Viewport[eye].Size = ovr_GetFovTextureSize(_hmd, eye, fov, 1.0f); + ovrSizei & size = _sceneLayer.Viewport[eye].Size = ovr_GetFovTextureSize(_session, eye, fov, 1.0f); _sceneLayer.Viewport[eye].Pos = { eye == ovrEye_Left ? 0 : size.w, 0 }; }); - if (!OVR_SUCCESS(ovr_ConfigureTracking(_hmd, + if (!OVR_SUCCESS(ovr_ConfigureTracking(_session, ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) { qFatal("Could not attach to sensor device"); } -#endif } void OculusBaseDisplayPlugin::deactivate() { WindowOpenGLDisplayPlugin::deactivate(); #if (OVR_MAJOR_VERSION >= 6) - ovr_Destroy(_hmd); - _hmd = nullptr; + ovr_Destroy(_session); + _session = nullptr; ovr_Shutdown(); #endif } @@ -151,7 +154,7 @@ void OculusBaseDisplayPlugin::deactivate() { float OculusBaseDisplayPlugin::getIPD() const { float result = OVR_DEFAULT_IPD; #if (OVR_MAJOR_VERSION >= 6) - result = ovr_GetFloat(_hmd, OVR_KEY_IPD, result); + result = ovr_GetFloat(_session, OVR_KEY_IPD, result); #endif return result; } diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index 711be6aa5e..1a26c6958b 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -43,17 +43,13 @@ protected: mat4 _compositeEyeProjections[2]; uvec2 _desiredFramebufferSize; -#if (OVR_MAJOR_VERSION >= 6) - ovrHmd _hmd; + ovrSession _session; + ovrGraphicsLuid _luid; float _ipd{ OVR_DEFAULT_IPD }; ovrEyeRenderDesc _eyeRenderDescs[2]; ovrFovPort _eyeFovs[2]; ovrHmdDesc _hmdDesc; ovrLayerEyeFov _sceneLayer; -#endif -#if (OVR_MAJOR_VERSION == 7) - ovrGraphicsLuid _luid; -#endif }; #if (OVR_MAJOR_VERSION == 6) diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index e6eae2cf02..c8fb0ba080 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -23,12 +23,16 @@ // ovr_CreateMirrorTextureGL, etc template struct RiftFramebufferWrapper : public FramebufferWrapper { - ovrHmd hmd; - RiftFramebufferWrapper(const ovrHmd & hmd) : hmd(hmd) { + ovrSession session; + RiftFramebufferWrapper(const ovrSession& session) : session(session) { color = 0; depth = 0; }; + ~RiftFramebufferWrapper() { + destroyColor(); + } + void Resize(const uvec2 & size) { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oglplus::GetName(fbo)); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); @@ -39,6 +43,9 @@ struct RiftFramebufferWrapper : public FramebufferWrapper { } protected: + virtual void destroyColor() { + } + virtual void initDepth() override final { } }; @@ -53,12 +60,6 @@ struct SwapFramebufferWrapper : public RiftFramebufferWrapperCurrentIndex; @@ -66,13 +67,17 @@ struct SwapFramebufferWrapper : public RiftFramebufferWrapper { MirrorFramebufferWrapper(const ovrHmd & hmd) : RiftFramebufferWrapper(hmd) { } - virtual ~MirrorFramebufferWrapper() { +private: + virtual void destroyColor() override { if (color) { - ovr_DestroyMirrorTexture(hmd, (ovrTexture*)color); + ovr_DestroyMirrorTexture(session, (ovrTexture*)color); color = nullptr; } } -private: void initColor() override { - if (color) { - ovr_DestroyMirrorTexture(hmd, (ovrTexture*)color); - color = nullptr; - } - ovrResult result = ovr_CreateMirrorTextureGL(hmd, GL_RGBA, size.x, size.y, (ovrTexture**)&color); + destroyColor(); + ovrResult result = ovr_CreateMirrorTextureGL(session, GL_SRGB8_ALPHA8, size.x, size.y, (ovrTexture**)&color); Q_ASSERT(OVR_SUCCESS(result)); } @@ -154,8 +156,7 @@ void OculusDisplayPlugin::activate() { void OculusDisplayPlugin::customizeContext() { OculusBaseDisplayPlugin::customizeContext(); -#if (OVR_MAJOR_VERSION >= 6) - _sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_hmd)); + _sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_session)); _sceneFbo->Init(getRecommendedRenderSize()); // We're rendering both eyes to the same texture, so only one of the @@ -163,7 +164,7 @@ void OculusDisplayPlugin::customizeContext() { _sceneLayer.ColorTexture[0] = _sceneFbo->color; // not needed since the structure was zeroed on init, but explicit _sceneLayer.ColorTexture[1] = nullptr; -#endif + enableVsync(false); // Only enable mirroring if we know vsync is disabled _enablePreview = !isVsyncEnabled(); @@ -177,7 +178,6 @@ void OculusDisplayPlugin::uncustomizeContext() { } void OculusDisplayPlugin::internalPresent() { -#if (OVR_MAJOR_VERSION >= 6) if (!_currentSceneTexture) { return; } @@ -206,8 +206,10 @@ void OculusDisplayPlugin::internalPresent() { auto size = _sceneFbo->size; Context::Viewport(size.x, size.y); glBindTexture(GL_TEXTURE_2D, _currentSceneTexture); + //glEnable(GL_FRAMEBUFFER_SRGB); GLenum err = glGetError(); drawUnitQuad(); + //glDisable(GL_FRAMEBUFFER_SRGB); }); uint32_t frameIndex { 0 }; @@ -230,13 +232,12 @@ void OculusDisplayPlugin::internalPresent() { viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1]; ovrLayerHeader* layers = &_sceneLayer.Header; - ovrResult result = ovr_SubmitFrame(_hmd, frameIndex, &viewScaleDesc, &layers, 1); + ovrResult result = ovr_SubmitFrame(_session, frameIndex, &viewScaleDesc, &layers, 1); if (!OVR_SUCCESS(result)) { qDebug() << result; } } _sceneFbo->Increment(); -#endif /* The swapbuffer call here is only required if we want to mirror the content to the screen.