From 163918e61573000832c745461bf6c2cf22a12e57 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 1 Jul 2015 08:27:18 -0700 Subject: [PATCH] Working on Oculus 0.5 support --- .../WindowOpenGLDisplayPlugin.cpp | 25 ++-- .../oculus/OculusBaseDisplayPlugin.cpp | 4 +- .../oculus/OculusBaseDisplayPlugin.h | 4 + .../oculus/Oculus_0_5_DisplayPlugin.cpp | 140 ++++++++++++++++++ .../oculus/Oculus_0_5_DisplayPlugin.h | 51 +++++++ ...lugin.cpp => Oculus_0_6_DisplayPlugin.cpp} | 40 ++--- ...layPlugin.h => Oculus_0_6_DisplayPlugin.h} | 6 +- 7 files changed, 238 insertions(+), 32 deletions(-) create mode 100644 libraries/display-plugins/src/display-plugins/oculus/Oculus_0_5_DisplayPlugin.cpp create mode 100644 libraries/display-plugins/src/display-plugins/oculus/Oculus_0_5_DisplayPlugin.h rename libraries/display-plugins/src/display-plugins/oculus/{OculusWin32DisplayPlugin.cpp => Oculus_0_6_DisplayPlugin.cpp} (91%) rename libraries/display-plugins/src/display-plugins/oculus/{OculusWin32DisplayPlugin.h => Oculus_0_6_DisplayPlugin.h} (92%) diff --git a/libraries/display-plugins/src/display-plugins/WindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/WindowOpenGLDisplayPlugin.cpp index 3307e05afe..1fe230980b 100644 --- a/libraries/display-plugins/src/display-plugins/WindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/WindowOpenGLDisplayPlugin.cpp @@ -39,30 +39,31 @@ void WindowOpenGLDisplayPlugin::initSurfaceFormat(QSurfaceFormat& format) { void WindowOpenGLDisplayPlugin::activate(PluginContainer * container) { OpenGLDisplayPlugin::activate(container); _window = createWindow(container); - - QSurfaceFormat format; - initSurfaceFormat(format); - _window->setFormat(format); - _window->create(); - _window->installEventFilter(this); - customizeWindow(container); - - makeCurrent(); - customizeContext(container); } void WindowOpenGLDisplayPlugin::deactivate() { OpenGLDisplayPlugin::deactivate(); destroyWindow(); + _window = nullptr; } GlWindow* WindowOpenGLDisplayPlugin::createWindow(PluginContainer * container) { - return new GlWindow(QOpenGLContext::currentContext()); + GlWindow* result = new GlWindow(QOpenGLContext::currentContext()); + QSurfaceFormat format; + initSurfaceFormat(format); + result->setFormat(format); + result->create(); + result->installEventFilter(this); + customizeWindow(container); + + result->makeCurrent(); + customizeContext(container); + + return result; } void WindowOpenGLDisplayPlugin::destroyWindow() { _window->deleteLater(); - _window = nullptr; } diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp index 808f4d41a8..86f5a539a8 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp @@ -30,11 +30,13 @@ void OculusBaseDisplayPlugin::activate(PluginContainer * container) { eyeSizes[0].x + eyeSizes[1].x, std::max(eyeSizes[0].y, eyeSizes[1].y)); + _frameIndex = 0; + if (!OVR_SUCCESS(ovrHmd_ConfigureTracking(_hmd, ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) { qFatal("Could not attach to sensor device"); } - _frameIndex = 0; + MainWindowOpenGLDisplayPlugin::activate(container); } diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h index 11a0a2593f..a2c6f417f8 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h @@ -36,3 +36,7 @@ protected: mat4 _compositeEyeProjections[2]; uvec2 _desiredFramebufferSize; }; + +#if (OVR_MAJOR_VERSION < 6) +#define OVR_SUCCESS(x) x +#endif diff --git a/libraries/display-plugins/src/display-plugins/oculus/Oculus_0_5_DisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/oculus/Oculus_0_5_DisplayPlugin.cpp new file mode 100644 index 0000000000..e7c60e858f --- /dev/null +++ b/libraries/display-plugins/src/display-plugins/oculus/Oculus_0_5_DisplayPlugin.cpp @@ -0,0 +1,140 @@ +// +// Created by Bradley Austin Davis on 2014/04/13. +// 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 "Oculus_0_5_DisplayPlugin.h" + +#if (OVR_MAJOR_VERSION == 5) + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "plugins/PluginContainer.h" + +#include "OculusHelpers.h" +#include +#include +#include +#include + +#include "../OglplusHelpers.h" + +const QString Oculus_0_5_DisplayPlugin::NAME("Oculus Rift (0.5)"); + +const QString & Oculus_0_5_DisplayPlugin::getName() const { + return NAME; +} + +bool Oculus_0_5_DisplayPlugin::isSupported() const { + if (!ovr_Initialize(nullptr)) { + return false; + } + bool result = false; + if (ovrHmd_Detect() > 0) { + result = true; + } + ovr_Shutdown(); + return result; +} + +void Oculus_0_5_DisplayPlugin::activate(PluginContainer * container) { + if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { + Q_ASSERT(false); + qFatal("Failed to Initialize SDK"); + } + _hmd = ovrHmd_Create(0); + if (!_hmd) { + qFatal("Failed to acquire HMD"); + } + + OculusBaseDisplayPlugin::activate(container); + + _window->makeCurrent(); + _hmdWindow = new GlWindow(QOpenGLContext::currentContext()); + + QSurfaceFormat format; + initSurfaceFormat(format); + _hmdWindow->setFormat(format); + _hmdWindow->create(); + _hmdWindow->installEventFilter(this); + _hmdWindow->makeCurrent(); +} + +void Oculus_0_5_DisplayPlugin::deactivate() { + _hmdWindow->deleteLater(); + _hmdWindow = nullptr; + + OculusBaseDisplayPlugin::deactivate(); + + ovrHmd_Destroy(_hmd); + _hmd = nullptr; + ovr_Shutdown(); +} + +void Oculus_0_5_DisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) { + ++_frameIndex; +} + +// Pass input events on to the application +bool Oculus_0_5_DisplayPlugin::eventFilter(QObject* receiver, QEvent* event) { + return OculusBaseDisplayPlugin::eventFilter(receiver, event); +} + +/* + The swapbuffer call here is only required if we want to mirror the content to the screen. + However, it should only be done if we can reliably disable v-sync on the mirror surface, + otherwise the swapbuffer delay will interefere with the framerate of the headset +*/ +void Oculus_0_5_DisplayPlugin::finishFrame() { + swapBuffers(); + doneCurrent(); +}; + + +#if 0 +/* +An alternative way to render the UI is to pass it specifically as a composition layer to +the Oculus SDK which should technically result in higher quality. However, the SDK doesn't +have a mechanism to present the image as a sphere section, which is our desired look. +*/ +ovrLayerQuad& uiLayer = getUiLayer(); +if (nullptr == uiLayer.ColorTexture || overlaySize != _uiFbo->size) { + _uiFbo->Resize(overlaySize); + uiLayer.ColorTexture = _uiFbo->color; + uiLayer.Viewport.Size.w = overlaySize.x; + uiLayer.Viewport.Size.h = overlaySize.y; + float overlayAspect = aspect(overlaySize); + uiLayer.QuadSize.x = 1.0f; + uiLayer.QuadSize.y = 1.0f / overlayAspect; +} + +_uiFbo->Bound([&] { + Q_ASSERT(0 == glGetError()); + using namespace oglplus; + Context::Viewport(_uiFbo->size.x, _uiFbo->size.y); + glClearColor(0, 0, 0, 0); + Context::Clear().ColorBuffer(); + + _program->Bind(); + glBindTexture(GL_TEXTURE_2D, overlayTexture); + _plane->Use(); + _plane->Draw(); + Q_ASSERT(0 == glGetError()); +}); +#endif + +#endif \ No newline at end of file diff --git a/libraries/display-plugins/src/display-plugins/oculus/Oculus_0_5_DisplayPlugin.h b/libraries/display-plugins/src/display-plugins/oculus/Oculus_0_5_DisplayPlugin.h new file mode 100644 index 0000000000..d55115abae --- /dev/null +++ b/libraries/display-plugins/src/display-plugins/oculus/Oculus_0_5_DisplayPlugin.h @@ -0,0 +1,51 @@ +// +// Created by Bradley Austin Davis on 2015/05/29 +// 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 +// +#pragma once + +#include "OculusBaseDisplayPlugin.h" + +#if (OVR_MAJOR_VERSION == 5) + +#include + +class OffscreenGlCanvas; +struct SwapFramebufferWrapper; +struct MirrorFramebufferWrapper; + +using SwapFboPtr = QSharedPointer; +using MirrorFboPtr = QSharedPointer; + +class Oculus_0_5_DisplayPlugin : public OculusBaseDisplayPlugin { +public: + virtual void init() override; + virtual void deinit() override; + + virtual bool isSupported() const override; + virtual const QString & getName() const override; + + virtual void activate(PluginContainer * container) override; + virtual void deactivate() override; + + + virtual bool eventFilter(QObject* receiver, QEvent* event) override; + +protected: + virtual void display(GLuint finalTexture, const glm::uvec2& sceneSize) override; + virtual void customizeContext(PluginContainer * container) override; + // Do not perform swap in finish + virtual void finishFrame() override; + +private: + + static const QString NAME; + GlWindow* _hmdWindow; +}; + + + +#endif diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusWin32DisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/oculus/Oculus_0_6_DisplayPlugin.cpp similarity index 91% rename from libraries/display-plugins/src/display-plugins/oculus/OculusWin32DisplayPlugin.cpp rename to libraries/display-plugins/src/display-plugins/oculus/Oculus_0_6_DisplayPlugin.cpp index a833a138ae..926fb3a8d8 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusWin32DisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/oculus/Oculus_0_6_DisplayPlugin.cpp @@ -5,7 +5,9 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "OculusWin32DisplayPlugin.h" +#include "Oculus_0_6_DisplayPlugin.h" + +#if (OVR_MAJOR_VERSION == 6) #include @@ -144,13 +146,13 @@ private: } }; -const QString OculusWin32DisplayPlugin::NAME("Oculus Rift"); +const QString Oculus_0_6_DisplayPlugin::NAME("Oculus Rift"); -const QString & OculusWin32DisplayPlugin::getName() const { +const QString & Oculus_0_6_DisplayPlugin::getName() const { return NAME; } -bool OculusWin32DisplayPlugin::isSupported() const { +bool Oculus_0_6_DisplayPlugin::isSupported() const { if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { return false; } @@ -162,13 +164,13 @@ bool OculusWin32DisplayPlugin::isSupported() const { return result; } -ovrLayerEyeFov& OculusWin32DisplayPlugin::getSceneLayer() { +ovrLayerEyeFov& Oculus_0_6_DisplayPlugin::getSceneLayer() { return _sceneLayer; } //static gpu::TexturePointer _texture; -void OculusWin32DisplayPlugin::activate(PluginContainer * container) { +void Oculus_0_6_DisplayPlugin::activate(PluginContainer * container) { if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { Q_ASSERT(false); qFatal("Failed to Initialize SDK"); @@ -178,6 +180,8 @@ void OculusWin32DisplayPlugin::activate(PluginContainer * container) { qFatal("Failed to acquire HMD"); } + OculusBaseDisplayPlugin::activate(container); + // Parent class relies on our _hmd intialization, so it must come after that. ovrLayerEyeFov& sceneLayer = getSceneLayer(); memset(&sceneLayer, 0, sizeof(ovrLayerEyeFov)); @@ -191,16 +195,14 @@ void OculusWin32DisplayPlugin::activate(PluginContainer * container) { PerformanceTimer::setActive(true); - //ovrLayerQuad& uiLayer = getUiLayer(); - //memset(&uiLayer, 0, sizeof(ovrLayerQuad)); - //uiLayer.Header.Type = ovrLayerType_QuadInWorld; - //uiLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft | ovrLayerFlag_HighQuality; - //uiLayer.QuadPoseCenter.Orientation = { 0, 0, 0, 1 }; - //uiLayer.QuadPoseCenter.Position = { 0, 0, -1 }; - OculusBaseDisplayPlugin::activate(container); + if (!OVR_SUCCESS(ovrHmd_ConfigureTracking(_hmd, + ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) { + qFatal("Could not attach to sensor device"); + } + } -void OculusWin32DisplayPlugin::customizeContext(PluginContainer * container) { +void Oculus_0_6_DisplayPlugin::customizeContext(PluginContainer * container) { OculusBaseDisplayPlugin::customizeContext(container); //_texture = DependencyManager::get()-> @@ -220,7 +222,7 @@ void OculusWin32DisplayPlugin::customizeContext(PluginContainer * container) { sceneLayer.ColorTexture[1] = nullptr; } -void OculusWin32DisplayPlugin::deactivate() { +void Oculus_0_6_DisplayPlugin::deactivate() { makeCurrent(); _sceneFbo.reset(); _mirrorFbo.reset(); @@ -234,7 +236,7 @@ void OculusWin32DisplayPlugin::deactivate() { ovr_Shutdown(); } -void OculusWin32DisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) { +void Oculus_0_6_DisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) { using namespace oglplus; // Need to make sure only the display plugin is responsible for // controlling vsync @@ -297,7 +299,7 @@ void OculusWin32DisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sc } // Pass input events on to the application -bool OculusWin32DisplayPlugin::eventFilter(QObject* receiver, QEvent* event) { +bool Oculus_0_6_DisplayPlugin::eventFilter(QObject* receiver, QEvent* event) { if (event->type() == QEvent::Resize) { QResizeEvent* resizeEvent = static_cast(event); qDebug() << resizeEvent->size().width() << " x " << resizeEvent->size().height(); @@ -314,7 +316,7 @@ bool OculusWin32DisplayPlugin::eventFilter(QObject* receiver, QEvent* event) { However, it should only be done if we can reliably disable v-sync on the mirror surface, otherwise the swapbuffer delay will interefere with the framerate of the headset */ -void OculusWin32DisplayPlugin::finishFrame() { +void Oculus_0_6_DisplayPlugin::finishFrame() { swapBuffers(); doneCurrent(); }; @@ -351,3 +353,5 @@ _uiFbo->Bound([&] { Q_ASSERT(0 == glGetError()); }); #endif + +#endif diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusWin32DisplayPlugin.h b/libraries/display-plugins/src/display-plugins/oculus/Oculus_0_6_DisplayPlugin.h similarity index 92% rename from libraries/display-plugins/src/display-plugins/oculus/OculusWin32DisplayPlugin.h rename to libraries/display-plugins/src/display-plugins/oculus/Oculus_0_6_DisplayPlugin.h index 2d892fdb67..18d6a183ec 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusWin32DisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/oculus/Oculus_0_6_DisplayPlugin.h @@ -11,6 +11,8 @@ #include +#if (OVR_MAJOR_VERSION == 6) + class OffscreenGlCanvas; struct SwapFramebufferWrapper; struct MirrorFramebufferWrapper; @@ -18,7 +20,7 @@ struct MirrorFramebufferWrapper; using SwapFboPtr = QSharedPointer; using MirrorFboPtr = QSharedPointer; -class OculusWin32DisplayPlugin : public OculusBaseDisplayPlugin { +class Oculus_0_6_DisplayPlugin : public OculusBaseDisplayPlugin { public: virtual bool isSupported() const override; virtual const QString & getName() const override; @@ -45,3 +47,5 @@ private: MirrorFboPtr _mirrorFbo; ovrLayerEyeFov _sceneLayer; }; + +#endif