diff --git a/cmake/externals/openvr/CMakeLists.txt b/cmake/externals/openvr/CMakeLists.txt index b5cd477c02..826c3dbb13 100644 --- a/cmake/externals/openvr/CMakeLists.txt +++ b/cmake/externals/openvr/CMakeLists.txt @@ -7,8 +7,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://github.com/ValveSoftware/openvr/archive/0.9.0.zip - URL_MD5 4fbde7759f604aaa68b9c40d628cc34a + URL https://github.com/ValveSoftware/openvr/archive/0.9.1.zip + URL_MD5 f986f5a6815e9454c53c5bf58ce02fdc CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index acae517373..f72be6ac5b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -116,7 +116,7 @@ #include "gpu/Batch.h" #include "gpu/GLBackend.h" -#include "plugins/render/DisplayPlugin.h" +#include "plugins/display/DisplayPlugin.h" #include "scripting/AccountScriptingInterface.h" #include "scripting/AudioDeviceScriptingInterface.h" @@ -341,6 +341,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _maxOctreePPS(maxOctreePacketsPerSecond.get()), _lastFaceTrackerUpdate(0) { + _offscreenContext = new OffscreenGlCanvas(); setInstance(this); #ifdef Q_OS_WIN installNativeEventFilter(&MyNativeEventFilter::getInstance()); @@ -823,13 +824,10 @@ void Application::paintGL() { PerformanceTimer perfTimer("paintGL"); _offscreenContext->makeCurrent(); - Q_ASSERT(_offscreenContext->getContext() == QOpenGLContext::currentContext()); - PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::paintGL()"); resizeGL(); - Q_ASSERT(_offscreenContext->getContext() == QOpenGLContext::currentContext()); { PerformanceTimer perfTimer("renderOverlay"); @@ -853,6 +851,7 @@ void Application::paintGL() { // is orthongonal to the (body's) Y axis _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation()); } + } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { static const float THIRD_PERSON_CAMERA_DISTANCE = 1.5f; _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + @@ -862,6 +861,7 @@ void Application::paintGL() { } else { _myCamera.setRotation(_myAvatar->getHead()->getOrientation()); } + } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + @@ -890,26 +890,51 @@ void Application::paintGL() { auto primaryFbo = DependencyManager::get()->getPrimaryFramebuffer(); auto finalFbo = primaryFbo; glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFbo)); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - // Viewport is assigned to the size of the framebuffer QSize size = DependencyManager::get()->getFrameBufferSize(); - glViewport(0, 0, size.width(), size.height()); + if (displayPlugin->isStereo()) { + QRect r(QPoint(0, 0), QSize(size.width() / 2, size.height())); + glEnable(GL_SCISSOR_TEST); + for (int i = 0; i < 2; ++i) { + glViewport(r.x(), r.y(), r.width(), r.height()); + glScissor(r.x(), r.y(), r.width(), r.height()); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - displaySide(_myCamera); - glPopMatrix(); + glMatrixMode(GL_PROJECTION); + // FIXME Fetch the projection matrix from the plugin - if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { - glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition(); - _rearMirrorTools->render(true, QPoint(mpos.x, mpos.y)); - } else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { - renderRearViewMirror(_mirrorViewRect); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + Camera eyeCamera; + eyeCamera.setRotation(_myCamera.getRotation()); + eyeCamera.setPosition(_myCamera.getPosition()); + displaySide(eyeCamera); + glPopMatrix(); + if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { + glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition(); + _rearMirrorTools->render(true, QPoint(mpos.x, mpos.y)); + } else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { + renderRearViewMirror(_mirrorViewRect); + } + r.moveLeft(r.width()); + } + glDisable(GL_SCISSOR_TEST); + } else { + glViewport(0, 0, size.width(), size.height()); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + displaySide(_myCamera); + glPopMatrix(); + if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { + glm::vec2 mpos = getActiveDisplayPlugin()->getUiMousePosition(); + _rearMirrorTools->render(true, QPoint(mpos.x, mpos.y)); + } else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { + renderRearViewMirror(_mirrorViewRect); + } } - finalFbo = DependencyManager::get()->render(); } @@ -1123,8 +1148,6 @@ bool Application::eventFilter(QObject* object, QEvent* event) { } } - // auto offscreenUi = DependencyManager::get(); - // return offscreenUi->eventFilter(object, event); return false; } @@ -1876,14 +1899,6 @@ ivec2 Application::getMouseDragStarted() const { return getActiveDisplayPlugin()->trueMouseToUiMouse(getTrueMouseDragStarted()); } -int Application::getMouseDragStartedX() const { - return getMouseDragStarted().x; -} - -int Application::getMouseDragStartedY() const { - return getMouseDragStarted().y; -} - FaceTracker* Application::getActiveFaceTracker() { auto faceshift = DependencyManager::get(); auto dde = DependencyManager::get(); @@ -2460,7 +2475,7 @@ void Application::update(float deltaTime) { PerformanceTimer perfTimer("overlays"); _overlays.update(deltaTime); } - + { PerformanceTimer perfTimer("myAvatar"); updateMyAvatarLookAtPosition(); @@ -3422,8 +3437,6 @@ void Application::getProjectionMatrix(glm::dmat4* projectionMatrix) { void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal, float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const { _displayViewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - // allow 3DTV/Oculus to override parameters from camera - getActiveDisplayPlugin()->overrideOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); } bool Application::getShadowsEnabled() { @@ -4573,136 +4586,10 @@ void Application::friendsWindowClosed() { _friendsWindow = NULL; } - void Application::postLambdaEvent(std::function f) { QCoreApplication::postEvent(this, new LambdaEvent(f)); } -PickRay Application::computePickRay() const { - return computePickRay(getTrueMouseX(), getTrueMouseY()); -} - -glm::uvec2 Application::getCanvasSize() const { - return getActiveDisplayPlugin()->getCanvasSize(); -} - -QSize Application::getDeviceSize() const { - return getActiveDisplayPlugin()->getDeviceSize(); -} - -bool Application::hasFocus() const { - return getActiveDisplayPlugin()->hasFocus(); -} - -glm::vec2 Application::getViewportDimensions() const { - return toGlm(getDeviceSize()); -} - -glm::ivec2 Application::getTrueMousePosition() const { - return getActiveDisplayPlugin()->getTrueMousePosition(); -} - -glm::quat Application::getHeadOrientation() const { - return getActiveDisplayPlugin()->headOrientation(); -} - -glm::vec3 Application::getHeadPosition() const { - return getActiveDisplayPlugin()->headTranslation(); -} - -bool Application::isThrottleRendering() const { - return getActiveDisplayPlugin()->isThrottled(); -} - - -using DisplayPluginPointer = QSharedPointer; - -#include "plugins/render/NullDisplayPlugin.h" -#include "plugins/render/WindowDisplayPlugin.h" -#include "plugins/render/LegacyDisplayPlugin.h" -#include "plugins/render/OculusDisplayPlugin.h" - -static DisplayPluginPointer _displayPlugin{ nullptr }; - -DisplayPlugin * Application::getActiveDisplayPlugin() { - if (nullptr == _displayPlugin) { - updateDisplayMode(); - Q_ASSERT(_displayPlugin); - } - return _displayPlugin.data(); -} - -const DisplayPlugin * Application::getActiveDisplayPlugin() const { - return ((Application*)this)->getActiveDisplayPlugin(); -} - -static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) { - auto menu = Menu::getInstance(); - MenuItemProperties item(MenuOption::OutputMenu, displayPlugin->getName(), "", true, active); - item.isSeparator = false; - Q_ASSERT(!menu->menuItemExists(MenuOption::OutputMenu, item.menuItemName)); - menu->addMenuItem(item); - Q_ASSERT(menu->menuItemExists(MenuOption::OutputMenu, item.menuItemName)); -} - -using DisplayPluginList = QVector; - -// FIXME move to a plugin manager class -static const DisplayPluginList & getDisplayPlugins() { - static DisplayPluginList RENDER_PLUGINS; - static bool init = false; - if (!init) { - DisplayPluginPointer displayPlugin = DisplayPluginPointer(new LegacyDisplayPlugin()); // new WindowDisplayPlugin(); - if (displayPlugin->isSupported()) { - displayPlugin->init(); - RENDER_PLUGINS.push_back(DisplayPluginPointer(displayPlugin)); - QObject::connect(displayPlugin.data(), &DisplayPlugin::requestRender, [] { - qApp->paintGL(); - }); - QObject::connect(displayPlugin.data(), &DisplayPlugin::recommendedFramebufferSizeChanged, [](const QSize & size) { - DependencyManager::get()->setFrameBufferSize(size * qApp->getRenderResolutionScale()); - qApp->resizeGL(); - }); - addDisplayPluginToMenu(displayPlugin, true); - } - - displayPlugin = DisplayPluginPointer(new NullDisplayPlugin()); - if (displayPlugin->isSupported()) { -#ifdef DEBUG - addDisplayPluginToMenu(displayPlugin); -#endif - displayPlugin->init(); - RENDER_PLUGINS.push_back(DisplayPluginPointer(displayPlugin)); - } - } - return RENDER_PLUGINS; -} - -void Application::updateDisplayMode() { - auto menu = Menu::getInstance(); - DisplayPluginPointer newDisplayPlugin; - foreach(DisplayPluginPointer displayPlugin, getDisplayPlugins()) { - QString name = displayPlugin->getName(); - QAction* action = menu->getActionForOption(name); - if (action->isChecked()) { - newDisplayPlugin = displayPlugin; - break; - } - } - if (_displayPlugin != newDisplayPlugin) { - if (_displayPlugin) { - _displayPlugin->deactivate(); - } - _offscreenContext->makeCurrent(); - _displayPlugin = newDisplayPlugin; - if (_displayPlugin) { - _displayPlugin->activate(); - } - _offscreenContext->makeCurrent(); - } - Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); -} - void Application::initPlugins() { #if 0 OculusManager::init(); @@ -4715,9 +4602,40 @@ void Application::shutdownPlugins() { #endif } +glm::vec3 Application::getHeadPosition() const { + return getActiveDisplayPlugin()->headTranslation(); +} -glm::ivec2 Application::getMouse() const { - return getActiveDisplayPlugin()->getUiMousePosition(); +glm::quat Application::getHeadOrientation() const { + return getActiveDisplayPlugin()->headOrientation(); +} + +glm::uvec2 Application::getCanvasSize() const { + return getActiveDisplayPlugin()->getCanvasSize(); +} + +QSize Application::getDeviceSize() const { + return getActiveDisplayPlugin()->getDeviceSize(); +} + +PickRay Application::computePickRay() const { + return computePickRay(getTrueMouseX(), getTrueMouseY()); +} + +bool Application::isThrottleRendering() const { + return getActiveDisplayPlugin()->isThrottled(); +} + +bool Application::hasFocus() const { + return getActiveDisplayPlugin()->hasFocus(); +} + +glm::vec2 Application::getViewportDimensions() const { + return toGlm(getDeviceSize()); +} + +glm::ivec2 Application::getTrueMousePosition() const { + return getActiveDisplayPlugin()->getTrueMousePosition(); } void Application::setMaxOctreePacketsPerSecond(int maxOctreePPS) { @@ -4735,3 +4653,131 @@ qreal Application::getDevicePixelRatio() { return _window ? _window->windowHandle()->devicePixelRatio() : 1.0; } + + +using DisplayPluginPointer = QSharedPointer; + +#include "plugins/display/NullDisplayPlugin.h" +#include "plugins/display/WindowDisplayPlugin.h" +#include "plugins/display/LegacyDisplayPlugin.h" +#include "plugins/display/OculusDisplayPlugin.h" +#include "plugins/display/Tv3dDisplayPlugin.h" +#include "plugins/display/WindowDisplayPlugin.h" + +static DisplayPluginPointer _displayPlugin{ nullptr }; + +DisplayPlugin * Application::getActiveDisplayPlugin() { + if (nullptr == _displayPlugin) { + updateDisplayMode(); + Q_ASSERT(_displayPlugin); + } + return _displayPlugin.data(); +} + +const DisplayPlugin * Application::getActiveDisplayPlugin() const { + return ((Application*)this)->getActiveDisplayPlugin(); +} + +static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) { + auto menu = Menu::getInstance(); + QString name = displayPlugin->getName(); + Q_ASSERT(!menu->menuItemExists(MenuOption::OutputMenu, name)); + + static QActionGroup* displayPluginGroup = nullptr; + if (!displayPluginGroup) { + displayPluginGroup = new QActionGroup(menu); + displayPluginGroup->setExclusive(true); + } + auto parent = menu->getMenu(MenuOption::OutputMenu); + auto action = menu->addActionToQMenuAndActionHash(parent, + name, 0, qApp, + SLOT(updateDisplayMode())); + action->setCheckable(true); + action->setChecked(active); + displayPluginGroup->addAction(action); + Q_ASSERT(menu->menuItemExists(MenuOption::OutputMenu, name)); +} + +using DisplayPluginList = QVector; + +// FIXME move to a plugin manager class +static const DisplayPluginList & getDisplayPlugins() { + static DisplayPluginList RENDER_PLUGINS; + static bool init = false; + if (!init) { + init = true; + DisplayPluginPointer displayPlugin = DisplayPluginPointer(new LegacyDisplayPlugin()); // new WindowDisplayPlugin(); + if (displayPlugin->isSupported()) { + displayPlugin->init(); + RENDER_PLUGINS.push_back(DisplayPluginPointer(displayPlugin)); + QObject::connect(displayPlugin.data(), &DisplayPlugin::requestRender, [] { + qApp->paintGL(); + }); + QObject::connect(displayPlugin.data(), &DisplayPlugin::recommendedFramebufferSizeChanged, [](const QSize & size) { + qApp->resizeGL(); + }); + addDisplayPluginToMenu(displayPlugin, true); + } + +#ifdef DEBUG + displayPlugin = DisplayPluginPointer(new NullDisplayPlugin()); + if (displayPlugin->isSupported()) { + addDisplayPluginToMenu(displayPlugin); + displayPlugin->init(); + RENDER_PLUGINS.push_back(DisplayPluginPointer(displayPlugin)); + } +#endif + + displayPlugin = DisplayPluginPointer(new Tv3dDisplayPlugin()); + if (displayPlugin->isSupported()) { + addDisplayPluginToMenu(displayPlugin); + displayPlugin->init(); + RENDER_PLUGINS.push_back(DisplayPluginPointer(displayPlugin)); + } + + displayPlugin = DisplayPluginPointer(new WindowDisplayPlugin()); + if (displayPlugin->isSupported()) { + addDisplayPluginToMenu(displayPlugin); + displayPlugin->init(); + RENDER_PLUGINS.push_back(DisplayPluginPointer(displayPlugin)); + QObject::connect(displayPlugin.data(), &DisplayPlugin::requestRender, [] { + qApp->paintGL(); + }); + QObject::connect(displayPlugin.data(), &DisplayPlugin::recommendedFramebufferSizeChanged, [](const QSize & size) { + qApp->resizeGL(); + }); + } + } + return RENDER_PLUGINS; +} + +void Application::updateDisplayMode() { + auto menu = Menu::getInstance(); + DisplayPluginPointer newDisplayPlugin; + foreach(DisplayPluginPointer displayPlugin, getDisplayPlugins()) { + QString name = displayPlugin->getName(); + QAction* action = menu->getActionForOption(name); + if (action->isChecked()) { + newDisplayPlugin = displayPlugin; + break; + } + } + if (_displayPlugin != newDisplayPlugin) { + if (newDisplayPlugin) { + _offscreenContext->makeCurrent(); + newDisplayPlugin->activate(); + _offscreenContext->makeCurrent(); + } + std::swap(newDisplayPlugin, _displayPlugin); + if (newDisplayPlugin) { + newDisplayPlugin->deactivate(); + _offscreenContext->makeCurrent(); + } + } + Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); +} + +glm::ivec2 Application::getMouse() const { + return getActiveDisplayPlugin()->getUiMousePosition(); +} + diff --git a/interface/src/Application.h b/interface/src/Application.h index 9114224a2d..5c03df953e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -40,7 +40,6 @@ #include #include #include -#include #include "AudioClient.h" #include "Bookmarks.h" @@ -84,6 +83,7 @@ class QMouseEvent; class QSystemTrayIcon; class QTouchEvent; class QWheelEvent; +class OffscreenGlCanvas; class FaceTracker; class MainWindow; @@ -222,23 +222,22 @@ public: const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; } bool mouseOnScreen() const; - glm::ivec2 getMouse() const; - int getMouseX() const { return getMouse().x; } - int getMouseY() const { return getMouse().y; } + inline glm::ivec2 getMouse() const; + inline int getMouseX() const { return getMouse().x; } + inline int getMouseY() const { return getMouse().y; } - glm::ivec2 getTrueMousePosition() const; - int getTrueMouseX() const { return getTrueMousePosition().x; } - int getTrueMouseY() const { return getTrueMousePosition().y; } + inline glm::ivec2 getTrueMousePosition() const; + inline int getTrueMouseX() const { return getTrueMousePosition().x; } + inline int getTrueMouseY() const { return getTrueMousePosition().y; } - glm::ivec2 getMouseDragStarted() const; - int getMouseDragStartedX() const; - int getMouseDragStartedY() const; + inline glm::ivec2 getMouseDragStarted() const; + inline int getMouseDragStartedX() const { return getMouseDragStarted().x; } + inline int getMouseDragStartedY() const { return getMouseDragStarted().y; } - const glm::ivec2 & getTrueMouseDragStarted() const { return _mouseDragStarted; } - int getTrueMouseDragStartedX() const { return getTrueMouseDragStarted().x; } - int getTrueMouseDragStartedY() const { return getTrueMouseDragStarted().y; } + inline const glm::ivec2& getTrueMouseDragStarted() const { return _mouseDragStarted; } + inline int getTrueMouseDragStartedX() const { return getTrueMouseDragStarted().x; } + inline int getTrueMouseDragStartedY() const { return getTrueMouseDragStarted().y; } - bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; } FaceTracker* getActiveFaceTracker(); @@ -521,7 +520,7 @@ private: bool _dependencyManagerIsSetup; - OffscreenGlContext* _offscreenContext{ new OffscreenGlContext() }; + OffscreenGlCanvas* _offscreenContext; MainWindow* _window; @@ -666,8 +665,6 @@ private: QThread _settingsThread; QTimer _settingsTimer; - - void checkSkeleton(); QWidget* _fullscreenMenuWidget = new QWidget(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 34c0215d80..0ba4d1637b 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -34,7 +34,7 @@ #include #include "Application.h" -#include "plugins/render/DisplayPlugin.h" +#include "plugins/display/DisplayPlugin.h" #include "AvatarManager.h" #include "Environment.h" #include "Menu.h" diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 58a2ce21d1..13ca17355b 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -92,7 +92,9 @@ int main(int argc, const char* argv[]) { usecTimestampNowForceClockSkew(clockSkew); qCDebug(interfaceapp, "clockSkewOption=%s clockSkew=%d", clockSkewOption, clockSkew); } - + // Oculus initialization MUST PRECEDE OpenGL context creation. + // The nature of the Application constructor means this has to be either here, + // or in the main window ctor, before GL startup. Application::initPlugins(); int exitCode; @@ -109,7 +111,6 @@ int main(int argc, const char* argv[]) { } Application::shutdownPlugins(); - #ifdef Q_OS_WIN ReleaseMutex(mutex); #endif diff --git a/interface/src/plugins/PluginManager.h b/interface/src/plugins/PluginManager.h index 2d8ab9a9f4..2526490eea 100644 --- a/interface/src/plugins/PluginManager.h +++ b/interface/src/plugins/PluginManager.h @@ -1,7 +1,7 @@ #pragma once #include "plugins/Plugin.h" -#include "plugins/render/DisplayPlugin.h" +#include "plugins/display/DisplayPlugin.h" #include #include diff --git a/interface/src/plugins/render/DisplayPlugin.cpp b/interface/src/plugins/display/DisplayPlugin.cpp similarity index 100% rename from interface/src/plugins/render/DisplayPlugin.cpp rename to interface/src/plugins/display/DisplayPlugin.cpp diff --git a/interface/src/plugins/render/DisplayPlugin.h b/interface/src/plugins/display/DisplayPlugin.h similarity index 93% rename from interface/src/plugins/render/DisplayPlugin.h rename to interface/src/plugins/display/DisplayPlugin.h index 111f0ecee5..b68edf5f6a 100644 --- a/interface/src/plugins/render/DisplayPlugin.h +++ b/interface/src/plugins/display/DisplayPlugin.h @@ -70,24 +70,31 @@ public: // Convert from screen mouse coordinates to UI mouse coordinates virtual glm::ivec2 trueMouseToUiMouse(const glm::ivec2 & position) const { return position; }; - virtual PickRay computePickRay(const glm::vec2 & pos) const = 0; + virtual PickRay computePickRay(const glm::vec2 & pos) const { + // FIXME make pure virtual + return PickRay(); + }; virtual bool isMouseOnScreen() const; - virtual void overrideOffAxisFrustum( - float& left, float& right, float& bottom, float& top, - float& nearVal, float& farVal, - glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const { } + + // Stereo specific methods + virtual glm::mat4 getProjection(Eye eye) const { + return glm::mat4(); + } // HMD specific methods // TODO move these into another class virtual glm::mat4 headPose() const { static const glm::mat4 pose; return pose; } + virtual glm::quat headOrientation() const { static const glm::quat orientation; return orientation; } + virtual glm::vec3 headTranslation() const { static const glm::vec3 tranlsation; return tranlsation; } + virtual void abandonCalibration() {} virtual void resetSensors() {} virtual float devicePixelRatio() { return 1.0; } diff --git a/interface/src/plugins/render/HmdDisplayPlugin.cpp b/interface/src/plugins/display/HmdDisplayPlugin.cpp similarity index 100% rename from interface/src/plugins/render/HmdDisplayPlugin.cpp rename to interface/src/plugins/display/HmdDisplayPlugin.cpp diff --git a/interface/src/plugins/render/HmdDisplayPlugin.h b/interface/src/plugins/display/HmdDisplayPlugin.h similarity index 100% rename from interface/src/plugins/render/HmdDisplayPlugin.h rename to interface/src/plugins/display/HmdDisplayPlugin.h diff --git a/interface/src/plugins/render/LegacyDisplayPlugin.cpp b/interface/src/plugins/display/LegacyDisplayPlugin.cpp similarity index 89% rename from interface/src/plugins/render/LegacyDisplayPlugin.cpp rename to interface/src/plugins/display/LegacyDisplayPlugin.cpp index d5a3b2fc46..00d922c37a 100644 --- a/interface/src/plugins/render/LegacyDisplayPlugin.cpp +++ b/interface/src/plugins/display/LegacyDisplayPlugin.cpp @@ -27,6 +27,8 @@ void LegacyDisplayPlugin::activate() { QOpenGLContext * sourceContext = QOpenGLContext::currentContext(); QSurfaceFormat format; format.setOption(QSurfaceFormat::DebugContext); + + QOpenGLContext * newContext = new QOpenGLContext(); newContext->setFormat(format); _window->setContext( @@ -49,9 +51,10 @@ void LegacyDisplayPlugin::activate() { void LegacyDisplayPlugin::deactivate() { _window->removeEventFilter(DependencyManager::get().data()); _window->removeEventFilter(qApp); - if (qApp->getWindow()) { - qApp->getWindow()->setCentralWidget(oldWidget); - } + // FIXME, during shutdown, this causes an NPE. Need to deactivate the plugin before the main window is destroyed. +// if (qApp->getWindow()) { +// qApp->getWindow()->setCentralWidget(oldWidget); +// } // stop the glWidget frame timer so it doesn't call paintGL _window->stopFrameTimer(); _window->doneCurrent(); @@ -63,18 +66,6 @@ QSize LegacyDisplayPlugin::getDeviceSize() const { return _window->getDeviceSize(); } -void LegacyDisplayPlugin::makeCurrent() { - _window->makeCurrent(); -} - -void LegacyDisplayPlugin::doneCurrent() { - _window->doneCurrent(); -} - -void LegacyDisplayPlugin::swapBuffers() { - _window->swapBuffers(); -} - void LegacyDisplayPlugin::idle() { _window->updateGL(); } diff --git a/interface/src/plugins/render/LegacyDisplayPlugin.h b/interface/src/plugins/display/LegacyDisplayPlugin.h similarity index 90% rename from interface/src/plugins/render/LegacyDisplayPlugin.h rename to interface/src/plugins/display/LegacyDisplayPlugin.h index 481667d3d4..33ea6187c3 100644 --- a/interface/src/plugins/render/LegacyDisplayPlugin.h +++ b/interface/src/plugins/display/LegacyDisplayPlugin.h @@ -30,8 +30,5 @@ public: virtual void preDisplay(); protected: - virtual void makeCurrent(); - virtual void doneCurrent(); - virtual void swapBuffers(); virtual void idle(); }; diff --git a/interface/src/plugins/render/NullDisplayPlugin.cpp b/interface/src/plugins/display/NullDisplayPlugin.cpp similarity index 100% rename from interface/src/plugins/render/NullDisplayPlugin.cpp rename to interface/src/plugins/display/NullDisplayPlugin.cpp diff --git a/interface/src/plugins/render/NullDisplayPlugin.h b/interface/src/plugins/display/NullDisplayPlugin.h similarity index 100% rename from interface/src/plugins/render/NullDisplayPlugin.h rename to interface/src/plugins/display/NullDisplayPlugin.h diff --git a/interface/src/plugins/render/OculusDisplayPlugin.cpp b/interface/src/plugins/display/OculusDisplayPlugin.cpp similarity index 100% rename from interface/src/plugins/render/OculusDisplayPlugin.cpp rename to interface/src/plugins/display/OculusDisplayPlugin.cpp diff --git a/interface/src/plugins/render/OculusDisplayPlugin.h b/interface/src/plugins/display/OculusDisplayPlugin.h similarity index 100% rename from interface/src/plugins/render/OculusDisplayPlugin.h rename to interface/src/plugins/display/OculusDisplayPlugin.h diff --git a/interface/src/plugins/render/SimpleDisplayPlugin.cpp b/interface/src/plugins/display/SimpleDisplayPlugin.cpp similarity index 93% rename from interface/src/plugins/render/SimpleDisplayPlugin.cpp rename to interface/src/plugins/display/SimpleDisplayPlugin.cpp index 40e0ba4d87..af02b0e1ce 100644 --- a/interface/src/plugins/render/SimpleDisplayPlugin.cpp +++ b/interface/src/plugins/display/SimpleDisplayPlugin.cpp @@ -35,10 +35,11 @@ void SimpleGlDisplayPlugin::display(GLuint sceneTexture, const glm::uvec2& scene glPushMatrix(); glLoadIdentity(); - glClearColor(0, 0, 0, 1); + glClearColor(0, 0, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); + glViewport(0, 0, getDeviceSize().width(), getDeviceSize().height()); if (sceneTexture) { glBindTexture(GL_TEXTURE_2D, sceneTexture); glBegin(GL_QUADS); @@ -74,7 +75,7 @@ void SimpleGlDisplayPlugin::display(GLuint sceneTexture, const glm::uvec2& scene glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); - Q_ASSERT(!glGetError()); + //Q_ASSERT(!glGetError()); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); @@ -84,5 +85,5 @@ void SimpleGlDisplayPlugin::display(GLuint sceneTexture, const glm::uvec2& scene glEnable(GL_DEPTH_TEST); glFinish(); - doneCurrent(); } + diff --git a/interface/src/plugins/display/SimpleDisplayPlugin.h b/interface/src/plugins/display/SimpleDisplayPlugin.h new file mode 100644 index 0000000000..036b50d44a --- /dev/null +++ b/interface/src/plugins/display/SimpleDisplayPlugin.h @@ -0,0 +1,82 @@ +// +// SimpleDisplayPlugin.h +// +// 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 +// +#pragma once + +#include "DisplayPlugin.h" + +#include + +#include +#include +#include +#include + +class SimpleGlDisplayPlugin : public DisplayPlugin { +public: + virtual void activate(); + virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize, + GLuint overlayTexture, const glm::uvec2& overlaySize); +}; + +template +class SimpleDisplayPlugin : public SimpleGlDisplayPlugin { +public: + virtual glm::ivec2 getTrueMousePosition() const { + return toGlm(_window->mapFromGlobal(QCursor::pos())); + } + +protected: + void makeCurrent() final { + _window->makeCurrent(); + } + + void doneCurrent() final { + _window->doneCurrent(); + } + + void swapBuffers() final { + _window->swapBuffers(); + } + +protected: + T * _window{ nullptr }; +}; + + +class GlWindowDisplayPlugin : public SimpleDisplayPlugin { +public: + virtual void activate() { + Q_ASSERT(nullptr == _window); + _window = new GlWindow(QOpenGLContext::currentContext()); + } + + virtual void deactivate() { + Q_ASSERT(nullptr != _window); + _window->hide(); + _window->destroy(); + _window->deleteLater(); + _window = nullptr; + } + + virtual QSize getDeviceSize() const final { + return _window->geometry().size() * _window->devicePixelRatio(); + } + + virtual glm::ivec2 getCanvasSize() const final { + return toGlm(_window->geometry().size()); + } + + virtual bool hasFocus() const { + return _window->isActive(); + } + + +}; + diff --git a/interface/src/plugins/render/StereoDisplayPlugin.cpp b/interface/src/plugins/display/StereoDisplayPlugin.cpp similarity index 100% rename from interface/src/plugins/render/StereoDisplayPlugin.cpp rename to interface/src/plugins/display/StereoDisplayPlugin.cpp diff --git a/interface/src/plugins/render/StereoDisplayPlugin.h b/interface/src/plugins/display/StereoDisplayPlugin.h similarity index 100% rename from interface/src/plugins/render/StereoDisplayPlugin.h rename to interface/src/plugins/display/StereoDisplayPlugin.h diff --git a/interface/src/plugins/display/Tv3dDisplayPlugin.cpp b/interface/src/plugins/display/Tv3dDisplayPlugin.cpp new file mode 100644 index 0000000000..0173a6fc33 --- /dev/null +++ b/interface/src/plugins/display/Tv3dDisplayPlugin.cpp @@ -0,0 +1,278 @@ +// +// Tv3dDisplayPlugin.cpp +// +// 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 "Tv3dDisplayPlugin.h" +#include + +const QString Tv3dDisplayPlugin::NAME("Tv3dDisplayPlugin"); + +const QString & Tv3dDisplayPlugin::getName() { + return NAME; +} + +void Tv3dDisplayPlugin::display( + GLuint sceneTexture, const glm::uvec2& sceneSize, + GLuint overlayTexture, const glm::uvec2& overlaySize) { + makeCurrent(); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_TEXTURE_2D); + + if (sceneTexture) { + glBindTexture(GL_TEXTURE_2D, sceneTexture); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2f(-1, -1); + glTexCoord2f(1, 0); + glVertex2f(+1, -1); + glTexCoord2f(1, 1); + glVertex2f(+1, +1); + glTexCoord2f(0, 1); + glVertex2f(-1, +1); + glEnd(); + } + + if (overlayTexture) { + glEnable(GL_BLEND); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); + glBindTexture(GL_TEXTURE_2D, overlayTexture); + + QSize size = getDeviceSize(); + QRect r(QPoint(0, 0), QSize(size.width() / 2, size.height())); + for (int i = 0; i < 2; ++i) { + glViewport(r.x(), r.y(), r.width(), r.height()); + glScissor(r.x(), r.y(), r.width(), r.height()); + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2f(-1, -1); + glTexCoord2f(1, 0); + glVertex2f(+1, -1); + glTexCoord2f(1, 1); + glVertex2f(+1, +1); + glTexCoord2f(0, 1); + glVertex2f(-1, +1); + glEnd(); + + r.moveLeft(r.width()); + } + + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_BLEND); + } + glDisable(GL_TEXTURE_2D); + Q_ASSERT(!glGetError()); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + + glFinish(); +} + +/* +void Tv3dDisplayPlugin::activate() { + GlWindowDisplayPlugin::activate(); + _window->setFlags(Qt::FramelessWindowHint); + _window->setPosition(100, 100); + _window->resize(512, 512); + _window->setVisible(true); + _window->show(); +} + +void Tv3dDisplayPlugin::deactivate() { + GlWindowDisplayPlugin::deactivate(); +} +*/ + +/* +glm::ivec2 LegacyDisplayPlugin::getCanvasSize() const { + return toGlm(_window->size()); +} + +bool LegacyDisplayPlugin::hasFocus() const { + return _window->hasFocus(); +} + +PickRay LegacyDisplayPlugin::computePickRay(const glm::vec2 & pos) const { + return PickRay(); +} + +bool isMouseOnScreen() { + return false; +} + +void LegacyDisplayPlugin::preDisplay() { + SimpleDisplayPlugin::preDisplay(); + auto size = toGlm(_window->size()); + glViewport(0, 0, size.x, size.y); +} + +bool LegacyDisplayPlugin::isThrottled() const { + return _window->isThrottleRendering(); + + + */ + +#if 0 + +int TV3DManager::_screenWidth = 1; +int TV3DManager::_screenHeight = 1; +double TV3DManager::_aspect = 1.0; +eyeFrustum TV3DManager::_leftEye; +eyeFrustum TV3DManager::_rightEye; +eyeFrustum* TV3DManager::_activeEye = NULL; + + +bool TV3DManager::isConnected() { + return Menu::getInstance()->isOptionChecked(MenuOption::Enable3DTVMode); +} + +void TV3DManager::connect() { + auto deviceSize = qApp->getDeviceSize(); + configureCamera(*(qApp->getCamera()), deviceSize.width(), deviceSize.height()); +} + + +// The basic strategy of this stereoscopic rendering is explained here: +// http://www.orthostereo.com/geometryopengl.html +void TV3DManager::setFrustum(const Camera& whichCamera) { + const double DTR = 0.0174532925; // degree to radians + const double IOD = 0.05; //intraocular distance + double fovy = DEFAULT_FIELD_OF_VIEW_DEGREES; // field of view in y-axis + double nearZ = DEFAULT_NEAR_CLIP; // near clipping plane + double screenZ = 0.25f; // screen projection plane + + double top = nearZ * tan(DTR * fovy / 2.0); //sets top of frustum based on fovy and near clipping plane + double right = _aspect * top; // sets right of frustum based on aspect ratio + double frustumshift = (IOD / 2) * nearZ / screenZ; + + _leftEye.top = top; + _leftEye.bottom = -top; + _leftEye.left = -right + frustumshift; + _leftEye.right = right + frustumshift; + _leftEye.modelTranslation = IOD / 2; + + _rightEye.top = top; + _rightEye.bottom = -top; + _rightEye.left = -right - frustumshift; + _rightEye.right = right - frustumshift; + _rightEye.modelTranslation = -IOD / 2; +} + +void TV3DManager::configureCamera(Camera& whichCamera_, int screenWidth, int screenHeight) { + const Camera& whichCamera = whichCamera_; + + if (screenHeight == 0) { + screenHeight = 1; // prevent divide by 0 + } + _screenWidth = screenWidth; + _screenHeight = screenHeight; + _aspect = (double)_screenWidth / (double)_screenHeight; + setFrustum(whichCamera); + + glViewport(0, 0, _screenWidth, _screenHeight); // sets drawing viewport + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void TV3DManager::display(Camera& whichCamera) { + double nearZ = DEFAULT_NEAR_CLIP; // near clipping plane + double farZ = DEFAULT_FAR_CLIP; // far clipping plane + + // left eye portal + int portalX = 0; + int portalY = 0; + QSize deviceSize = qApp->getDeviceSize() * + qApp->getRenderResolutionScale(); + int portalW = deviceSize.width() / 2; + int portalH = deviceSize.height(); + + + DependencyManager::get()->prepare(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + Camera eyeCamera; + eyeCamera.setRotation(whichCamera.getRotation()); + eyeCamera.setPosition(whichCamera.getPosition()); + + glEnable(GL_SCISSOR_TEST); + glPushMatrix(); + forEachEye([&](eyeFrustum& eye) { + _activeEye = &eye; + glViewport(portalX, portalY, portalW, portalH); + glScissor(portalX, portalY, portalW, portalH); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); // reset projection matrix + glFrustum(eye.left, eye.right, eye.bottom, eye.top, nearZ, farZ); // set left view frustum + GLfloat p[4][4]; + // Really? + glGetFloatv(GL_PROJECTION_MATRIX, &(p[0][0])); + float cotangent = p[1][1]; + GLfloat fov = atan(1.0f / cotangent); + glTranslatef(eye.modelTranslation, 0.0, 0.0); // translate to cancel parallax + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + qApp->displaySide(eyeCamera, false, RenderArgs::MONO); +#if 0 + qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov); +#endif + _activeEye = NULL; + }, [&] { + // render right side view + portalX = deviceSize.width() / 2; + }); + glPopMatrix(); + glDisable(GL_SCISSOR_TEST); + + auto finalFbo = DependencyManager::get()->render(); + auto fboSize = finalFbo->getSize(); + // Get the ACTUAL device size for the BLIT + deviceSize = qApp->getDeviceSize(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo)); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, 0, fboSize.x, fboSize.y, + 0, 0, deviceSize.width(), deviceSize.height(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + + // reset the viewport to how we started + glViewport(0, 0, deviceSize.width(), deviceSize.height()); +} + +void TV3DManager::overrideOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal, + float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) { + if (_activeEye) { + left = _activeEye->left; + right = _activeEye->right; + bottom = _activeEye->bottom; + top = _activeEye->top; + } +} + +#endif diff --git a/interface/src/plugins/display/Tv3dDisplayPlugin.h b/interface/src/plugins/display/Tv3dDisplayPlugin.h new file mode 100644 index 0000000000..5dbfc543b8 --- /dev/null +++ b/interface/src/plugins/display/Tv3dDisplayPlugin.h @@ -0,0 +1,28 @@ +// +// Tv3dDisplayPlugin.h +// +// 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 +// + +#pragma once + +#include "SimpleDisplayPlugin.h" +#include "LegacyDisplayPlugin.h" + +class Tv3dDisplayPlugin : public LegacyDisplayPlugin { + Q_OBJECT +public: + static const QString NAME; + virtual const QString & getName(); + + virtual bool isStereo() const final { return true; } + void display(GLuint sceneTexture, const glm::uvec2& sceneSize, + GLuint overlayTexture, const glm::uvec2& overlaySize); + //virtual bool isMouseOnScreen() const { return true; } + //virtual bool isThrottled() const; + //virtual void preDisplay(); +}; diff --git a/interface/src/plugins/render/WindowDisplayPlugin.cpp b/interface/src/plugins/display/WindowDisplayPlugin.cpp similarity index 91% rename from interface/src/plugins/render/WindowDisplayPlugin.cpp rename to interface/src/plugins/display/WindowDisplayPlugin.cpp index 4c786d9f63..662c527821 100644 --- a/interface/src/plugins/render/WindowDisplayPlugin.cpp +++ b/interface/src/plugins/display/WindowDisplayPlugin.cpp @@ -25,41 +25,15 @@ const QString & WindowDisplayPlugin::getName() { } void WindowDisplayPlugin::activate() { - Q_ASSERT(nullptr == _window); - - _context = new QOpenGLContext; - - _window = new QWindow; - _window->setSurfaceType(QSurface::OpenGLSurface); + GlWindowDisplayPlugin::activate(); _window->installEventFilter(this); - glMatrixMode(0); - { - QSurfaceFormat format; - format.setDepthBufferSize(0); - format.setStencilBufferSize(0); - format.setVersion(4, 1); - // Ugh.... - format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile); - _window->setFormat(format); - _context->setFormat(format); - } - - _context->setShareContext(QOpenGLContext::currentContext()); - _context->create(); - _window->show(); - _timer.start(8); } void WindowDisplayPlugin::deactivate() { _timer.stop(); - _context->doneCurrent(); - _context->deleteLater(); - _context = nullptr; - _window->hide(); - _window->destroy(); - _window = nullptr; + GlWindowDisplayPlugin::deactivate(); } bool WindowDisplayPlugin::eventFilter(QObject* object, QEvent* event) { @@ -80,25 +54,6 @@ bool WindowDisplayPlugin::eventFilter(QObject* object, QEvent* event) { return false; } -QSize WindowDisplayPlugin::getRecommendedFramebufferSize() const { - return _window->size(); -} - -void WindowDisplayPlugin::makeCurrent() { - _context->makeCurrent(_window); - QSize windowSize = _window->size(); - glViewport(0, 0, windowSize.width(), windowSize.height()); -} - -void WindowDisplayPlugin::doneCurrent() { - _context->doneCurrent(); -} - -void WindowDisplayPlugin::swapBuffers() { - _context->swapBuffers(_window); -} - - #if 0 // diff --git a/interface/src/plugins/render/WindowDisplayPlugin.h b/interface/src/plugins/display/WindowDisplayPlugin.h similarity index 65% rename from interface/src/plugins/render/WindowDisplayPlugin.h rename to interface/src/plugins/display/WindowDisplayPlugin.h index 9fc28c77d9..1b1d3f81b9 100644 --- a/interface/src/plugins/render/WindowDisplayPlugin.h +++ b/interface/src/plugins/display/WindowDisplayPlugin.h @@ -11,11 +11,10 @@ #include "SimpleDisplayPlugin.h" -#include -#include +#include #include -class WindowDisplayPlugin : public SimpleDisplayPlugin { +class WindowDisplayPlugin : public GlWindowDisplayPlugin { Q_OBJECT public: static const QString NAME; @@ -27,14 +26,6 @@ public: virtual void activate(); virtual void deactivate(); virtual bool eventFilter(QObject* object, QEvent* event); - virtual QSize getRecommendedFramebufferSize() const; - -protected: - virtual void makeCurrent(); - virtual void doneCurrent(); - virtual void swapBuffers(); - private: QTimer _timer; - QOpenGLContext * _context{ nullptr }; }; diff --git a/interface/src/plugins/render/SimpleDisplayPlugin.h b/interface/src/plugins/render/SimpleDisplayPlugin.h deleted file mode 100644 index aca9366b24..0000000000 --- a/interface/src/plugins/render/SimpleDisplayPlugin.h +++ /dev/null @@ -1,36 +0,0 @@ -// -// SimpleDisplayPlugin.h -// -// 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 -// -#pragma once - -#include "DisplayPlugin.h" - -#include - -#include -#include -#include - -class SimpleGlDisplayPlugin : public DisplayPlugin { -public: - virtual void activate(); - virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize, - GLuint overlayTexture, const glm::uvec2& overlaySize); -}; - -template -class SimpleDisplayPlugin : public SimpleGlDisplayPlugin { -public: - virtual glm::ivec2 getTrueMousePosition() const { - return toGlm(_window->mapFromGlobal(QCursor::pos())); - } - -protected: - T * _window; -}; diff --git a/interface/src/plugins/render/Tv3dDisplayPlugin.cpp b/interface/src/plugins/render/Tv3dDisplayPlugin.cpp deleted file mode 100644 index b86e20831f..0000000000 --- a/interface/src/plugins/render/Tv3dDisplayPlugin.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// Tv3dDisplayPlugin.cpp -// -// 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 "Tv3dDisplayPlugin.h" - -const QString Tv3dDisplayPlugin::NAME("Tv3dDisplayPlugin"); - -const QString & Tv3dDisplayPlugin::getName() { - return NAME; -} - - -void Tv3dDisplayPlugin::overrideOffAxisFrustum( - float& left, float& right, float& bottom, float& top, - float& nearVal, float& farVal, - glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const { - -#if 0 - if (_activeEye) { - left = _activeEye->left; - right = _activeEye->right; - bottom = _activeEye->bottom; - top = _activeEye->top; - } -#endif - -} - - -#if 0 - } else if (TV3DManager::isConnected()) { - - TV3DManager::display(_myCamera); - - } else { -#endif diff --git a/interface/src/plugins/render/Tv3dDisplayPlugin.h b/interface/src/plugins/render/Tv3dDisplayPlugin.h deleted file mode 100644 index 5c178b7260..0000000000 --- a/interface/src/plugins/render/Tv3dDisplayPlugin.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Tv3dDisplayPlugin.h -// -// 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 -// - -#pragma once - -#include "StereoDisplayPlugin.h" - -class Tv3dDisplayPlugin : public StereoDisplayPlugin { - Q_OBJECT -public: - static const QString NAME; - virtual const QString & getName(); - - virtual void overrideOffAxisFrustum( - float& left, float& right, float& bottom, float& top, - float& nearVal, float& farVal, - glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const; - -}; diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 6e59f4452f..7c6620e9e1 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -194,7 +194,7 @@ void ApplicationOverlay::renderOverlay() { Overlays& overlays = qApp->getOverlays(); glm::uvec2 size = qApp->getCanvasSize(); - if (!_framebufferObject || size == toGlm(_framebufferObject->size())) { + if (!_framebufferObject || size != toGlm(_framebufferObject->size())) { if(_framebufferObject) { delete _framebufferObject; } @@ -511,7 +511,7 @@ void ApplicationOverlay::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origi // Intersection UI overlay space glm::vec3 worldSpaceDirection = overlayOrientation * overlaySpaceDirection; - glm::vec3 intersectionWithUi = glm::normalize(worldSpaceDirection) * _oculusUIRadius; + glm::vec3 intersectionWithUi = glm::normalize(worldSpaceDirection) * _hmdUIRadius; intersectionWithUi += overlayPosition; // Intersection in world space diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index 29f4934c82..c18cbdbe30 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -82,6 +82,8 @@ private: float _magSizeMult[NUMBER_OF_RETICLES]; quint64 _lastMouseMove; bool _magnifier; + float _hmdUIRadius{ 1.0 }; + float _alpha = 1.0f; float _trailingAudioLoudness; diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index e9d7e1509c..0537c62b38 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -294,7 +294,7 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { if (qApp->isHMDMode()) { pointCopy = qApp->getApplicationOverlay().screenToOverlay(point); } - + QReadLocker lock(&_lock); QMapIterator i(_overlaysHUD); i.toBack(); diff --git a/libraries/render-utils/src/GlWindow.cpp b/libraries/render-utils/src/GlWindow.cpp new file mode 100644 index 0000000000..011198e7c0 --- /dev/null +++ b/libraries/render-utils/src/GlWindow.cpp @@ -0,0 +1,77 @@ +// +// Created by Bradley Austin Davis on 2015/05/21 +// Copyright 2013 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 "GlWindow.h" + +#include +#include + +static QSurfaceFormat getDefaultFormat() { + QSurfaceFormat format; + // Qt Quick may need a depth and stencil buffer. Always make sure these are available. + format.setDepthBufferSize(16); + format.setStencilBufferSize(8); + format.setVersion(4, 1); +#ifdef DEBUG + format.setOption(QSurfaceFormat::DebugContext); +#endif + format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile); + return format; +} + +GlWindow::GlWindow(QOpenGLContext * shareContext) : GlWindow(getDefaultFormat(), shareContext) { +} + +GlWindow::GlWindow(const QSurfaceFormat& format, QOpenGLContext * shareContext) { + setSurfaceType(QSurface::OpenGLSurface); + setFormat(format); + _context = new QOpenGLContext; + _context->setFormat(format); + if (shareContext) { + _context->setShareContext(shareContext); + } + _context->create(); +} + +static QOpenGLDebugLogger* logger{ nullptr }; + +GlWindow::~GlWindow() { + if (logger) { + makeCurrent(); + delete logger; + logger = nullptr; + } + _context->doneCurrent(); + _context->deleteLater(); + _context = nullptr; +} + + +void GlWindow::makeCurrent() { + _context->makeCurrent(this); +#ifdef DEBUG + if (!logger) { + logger = new QOpenGLDebugLogger(this); + if (logger->initialize()) { + connect(logger, &QOpenGLDebugLogger::messageLogged, [](const QOpenGLDebugMessage& message) { + qDebug() << message; + }); + logger->startLogging(QOpenGLDebugLogger::LoggingMode::SynchronousLogging); + } + } +#endif +} + +void GlWindow::doneCurrent() { + _context->doneCurrent(); +} + +void GlWindow::swapBuffers() { + _context->swapBuffers(this); +} + diff --git a/libraries/render-utils/src/GlWindow.h b/libraries/render-utils/src/GlWindow.h new file mode 100644 index 0000000000..5d391d0d7b --- /dev/null +++ b/libraries/render-utils/src/GlWindow.h @@ -0,0 +1,29 @@ +// +// Created by Bradley Austin Davis on 2015/05/21 +// Copyright 2013 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 +#ifndef hifi_GlWindow_h +#define hifi_GlWindow_h + +#include +#include + +class QOpenGLContext; + +class GlWindow : public QWindow { + QOpenGLContext * _context{ nullptr }; +public: + GlWindow(QOpenGLContext * shareContext = nullptr); + GlWindow(const QSurfaceFormat& format, QOpenGLContext * shareContext = nullptr); + virtual ~GlWindow(); + void makeCurrent(); + void doneCurrent(); + void swapBuffers(); +}; + +#endif \ No newline at end of file diff --git a/libraries/render-utils/src/GlowEffect.cpp b/libraries/render-utils/src/GlowEffect.cpp index 4413a3c5cc..07c2e0e9c6 100644 --- a/libraries/render-utils/src/GlowEffect.cpp +++ b/libraries/render-utils/src/GlowEffect.cpp @@ -175,11 +175,12 @@ gpu::FramebufferPointer GlowEffect::render() { _diffuseProgram->release(); } + destFBO = oldDiffusedFBO; + glBindFramebuffer(GL_FRAMEBUFFER, 0); // add diffused texture to the primary glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(newDiffusedFBO->getRenderBuffer(0))); - destFBO = oldDiffusedFBO; glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(destFBO)); glViewport(0, 0, framebufferSize.width(), framebufferSize.height()); _addSeparateProgram->bind(); diff --git a/libraries/render-utils/src/OffscreenGlCanvas.cpp b/libraries/render-utils/src/OffscreenGlCanvas.cpp index 0e5d4928d8..dc9205a246 100644 --- a/libraries/render-utils/src/OffscreenGlCanvas.cpp +++ b/libraries/render-utils/src/OffscreenGlCanvas.cpp @@ -11,6 +11,7 @@ #include "OffscreenGlCanvas.h" +#include OffscreenGlCanvas::OffscreenGlCanvas() { } @@ -27,16 +28,35 @@ void OffscreenGlCanvas::create(QOpenGLContext* sharedContext) { format.setMajorVersion(4); format.setMinorVersion(1); format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile); +#ifdef DEBUG + format.setOption(QSurfaceFormat::DebugContext); +#endif _context.setFormat(format); } _context.create(); _offscreenSurface.setFormat(_context.format()); _offscreenSurface.create(); + } bool OffscreenGlCanvas::makeCurrent() { - return _context.makeCurrent(&_offscreenSurface); + bool result = _context.makeCurrent(&_offscreenSurface); + +#ifdef DEBUG + if (result && !_logger) { + _logger = new QOpenGLDebugLogger(this); + if (_logger->initialize()) { + connect(_logger, &QOpenGLDebugLogger::messageLogged, [](const QOpenGLDebugMessage& message) { + qDebug() << message; + }); + _logger->enableMessages(QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::AnyType, QOpenGLDebugMessage::HighSeverity); + _logger->startLogging(QOpenGLDebugLogger::LoggingMode::SynchronousLogging); + } + } +#endif + + return result; } void OffscreenGlCanvas::doneCurrent() { diff --git a/libraries/render-utils/src/OffscreenGlCanvas.h b/libraries/render-utils/src/OffscreenGlCanvas.h index 5a64a4cf10..545d2269b7 100644 --- a/libraries/render-utils/src/OffscreenGlCanvas.h +++ b/libraries/render-utils/src/OffscreenGlCanvas.h @@ -15,16 +15,22 @@ #include #include +class QOpenGLDebugLogger; + class OffscreenGlCanvas : public QObject { public: OffscreenGlCanvas(); void create(QOpenGLContext* sharedContext = nullptr); bool makeCurrent(); void doneCurrent(); + QOpenGLContext* getContext() { + return &_context; + } protected: QOpenGLContext _context; QOffscreenSurface _offscreenSurface; + QOpenGLDebugLogger * _logger{ nullptr }; }; diff --git a/libraries/render-utils/src/OffscreenGlContext.cpp b/libraries/render-utils/src/OffscreenGlContext.cpp deleted file mode 100644 index 96f0a93c3a..0000000000 --- a/libraries/render-utils/src/OffscreenGlContext.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// OffscreenGlCanvas.cpp -// interface/src/renderer -// -// Created by Bradley Austin Davis on 2014/04/09. -// 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 "OffscreenGlContext.h" - -OffscreenGlContext::OffscreenGlContext() { -} - -void OffscreenGlContext::create(QOpenGLContext * sharedContext) { - QSurfaceFormat format; - format.setDepthBufferSize(16); - format.setStencilBufferSize(8); - format.setMajorVersion(4); - format.setMinorVersion(1); - format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile); - - _context.setFormat(format); - if (nullptr != sharedContext) { - _context.setShareContext(sharedContext); - } - _context.create(); - - _offscreenSurface.setFormat(_context.format()); - _offscreenSurface.create(); -} - -bool OffscreenGlContext::makeCurrent() { - return _context.makeCurrent(&_offscreenSurface); -} - -void OffscreenGlContext::doneCurrent() { - _context.doneCurrent(); -} - diff --git a/libraries/render-utils/src/OffscreenGlContext.h b/libraries/render-utils/src/OffscreenGlContext.h deleted file mode 100644 index c0d22b268f..0000000000 --- a/libraries/render-utils/src/OffscreenGlContext.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// OffscreenGlCanvas.h -// interface/src/renderer -// -// Created by Bradley Austin Davis on 2014/04/09. -// 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 -#ifndef hifi_OffscreenGlContext_h -#define hifi_OffscreenGlContext_h - -#include -#include - -class OffscreenGlContext : public QObject { -public: - OffscreenGlContext(); - void create(QOpenGLContext * sharedContext = nullptr); - bool makeCurrent(); - void doneCurrent(); - QOpenGLContext * getContext() { - return &_context; - } - -protected: - QOpenGLContext _context; - QOffscreenSurface _offscreenSurface; -}; - -#endif // hifi_OffscreenGlCanvas_h