From 912c003d58e7932ff59b717169ee977000216883 Mon Sep 17 00:00:00 2001 From: Brad Davis <bdavis@saintandreas.org> Date: Fri, 29 May 2015 16:49:11 -0700 Subject: [PATCH] Making (most) plugins into a library --- cmake/macros/SetupHifiOpenGL.cmake | 43 +++ interface/CMakeLists.txt | 21 +- interface/src/Application.cpp | 28 +- interface/src/Application.h | 5 +- .../display => }/LegacyDisplayPlugin.cpp | 62 +++-- .../display => }/LegacyDisplayPlugin.h | 20 +- interface/src/avatar/MyAvatar.cpp | 1 - interface/src/plugins/Plugin.cpp | 1 - interface/src/plugins/Plugin.h | 22 -- .../src/plugins/display/HmdDisplayPlugin.cpp | 11 - .../src/plugins/display/HmdDisplayPlugin.h | 15 -- .../plugins/display/SimpleDisplayPlugin.cpp | 161 ------------ .../src/plugins/display/SimpleDisplayPlugin.h | 62 ----- .../plugins/display/StereoDisplayPlugin.cpp | 10 - .../src/plugins/display/StereoDisplayPlugin.h | 17 -- .../src/plugins/display/Tv3dDisplayPlugin.cpp | 245 ------------------ .../plugins/display/WindowDisplayPlugin.cpp | 38 --- libraries/display-plugins/CMakeLists.txt | 30 +++ .../display-plugins/src}/OculusHelpers.h | 2 +- .../display-plugins/src/OglplusHelpers.cpp | 122 +++++++++ .../display-plugins/src}/OglplusHelpers.h | 16 +- .../src/display-plugins}/DisplayPlugin.cpp | 6 +- .../src/display-plugins}/DisplayPlugin.h | 50 ++-- .../display-plugins/GlWindowDisplayPlugin.cpp | 127 +++++++++ .../display-plugins/GlWindowDisplayPlugin.h | 41 +++ .../display-plugins}/NullDisplayPlugin.cpp | 13 + .../src/display-plugins}/NullDisplayPlugin.h | 14 +- .../OculusBaseDisplayPlugin.cpp | 9 +- .../OculusBaseDisplayPlugin.h | 11 +- .../OculusWin32DisplayPlugin.cpp | 10 +- .../OculusWin32DisplayPlugin.h | 2 +- .../display-plugins/OpenGlDisplayPlugin.cpp | 88 +++++++ .../src/display-plugins/OpenGlDisplayPlugin.h | 24 ++ .../src/display-plugins/Tv3dDisplayPlugin.cpp | 176 +++++++++++++ .../src/display-plugins}/Tv3dDisplayPlugin.h | 19 +- .../display-plugins/WindowDisplayPlugin.cpp | 18 ++ .../display-plugins}/WindowDisplayPlugin.h | 13 +- libraries/plugins/CMakeLists.txt | 2 +- libraries/plugins/src/Plugin.h | 20 -- libraries/plugins/src/plugins/Plugin.cpp | 9 + libraries/plugins/src/plugins/Plugin.h | 29 +++ .../src/{ => plugins}/PluginContainer.h | 0 .../plugins}/src/plugins/PluginManager.cpp | 0 .../plugins}/src/plugins/PluginManager.h | 4 +- 44 files changed, 889 insertions(+), 728 deletions(-) create mode 100644 cmake/macros/SetupHifiOpenGL.cmake rename interface/src/{plugins/display => }/LegacyDisplayPlugin.cpp (73%) rename interface/src/{plugins/display => }/LegacyDisplayPlugin.h (60%) delete mode 100644 interface/src/plugins/Plugin.cpp delete mode 100644 interface/src/plugins/Plugin.h delete mode 100644 interface/src/plugins/display/HmdDisplayPlugin.cpp delete mode 100644 interface/src/plugins/display/HmdDisplayPlugin.h delete mode 100644 interface/src/plugins/display/SimpleDisplayPlugin.cpp delete mode 100644 interface/src/plugins/display/SimpleDisplayPlugin.h delete mode 100644 interface/src/plugins/display/StereoDisplayPlugin.cpp delete mode 100644 interface/src/plugins/display/StereoDisplayPlugin.h delete mode 100644 interface/src/plugins/display/Tv3dDisplayPlugin.cpp delete mode 100644 interface/src/plugins/display/WindowDisplayPlugin.cpp create mode 100644 libraries/display-plugins/CMakeLists.txt rename {interface/src/plugins/display => libraries/display-plugins/src}/OculusHelpers.h (97%) create mode 100644 libraries/display-plugins/src/OglplusHelpers.cpp rename {interface/src/plugins/display => libraries/display-plugins/src}/OglplusHelpers.h (55%) rename {interface/src/plugins/display => libraries/display-plugins/src/display-plugins}/DisplayPlugin.cpp (86%) rename {interface/src/plugins/display => libraries/display-plugins/src/display-plugins}/DisplayPlugin.h (72%) create mode 100644 libraries/display-plugins/src/display-plugins/GlWindowDisplayPlugin.cpp create mode 100644 libraries/display-plugins/src/display-plugins/GlWindowDisplayPlugin.h rename {interface/src/plugins/display => libraries/display-plugins/src/display-plugins}/NullDisplayPlugin.cpp (69%) rename {interface/src/plugins/display => libraries/display-plugins/src/display-plugins}/NullDisplayPlugin.h (72%) rename {interface/src/plugins/display => libraries/display-plugins/src/display-plugins}/OculusBaseDisplayPlugin.cpp (87%) rename {interface/src/plugins/display => libraries/display-plugins/src/display-plugins}/OculusBaseDisplayPlugin.h (74%) rename {interface/src/plugins/display => libraries/display-plugins/src/display-plugins}/OculusWin32DisplayPlugin.cpp (97%) rename {interface/src/plugins/display => libraries/display-plugins/src/display-plugins}/OculusWin32DisplayPlugin.h (87%) create mode 100644 libraries/display-plugins/src/display-plugins/OpenGlDisplayPlugin.cpp create mode 100644 libraries/display-plugins/src/display-plugins/OpenGlDisplayPlugin.h create mode 100644 libraries/display-plugins/src/display-plugins/Tv3dDisplayPlugin.cpp rename {interface/src/plugins/display => libraries/display-plugins/src/display-plugins}/Tv3dDisplayPlugin.h (67%) create mode 100644 libraries/display-plugins/src/display-plugins/WindowDisplayPlugin.cpp rename {interface/src/plugins/display => libraries/display-plugins/src/display-plugins}/WindowDisplayPlugin.h (62%) delete mode 100644 libraries/plugins/src/Plugin.h create mode 100644 libraries/plugins/src/plugins/Plugin.cpp create mode 100644 libraries/plugins/src/plugins/Plugin.h rename libraries/plugins/src/{ => plugins}/PluginContainer.h (100%) rename {interface => libraries/plugins}/src/plugins/PluginManager.cpp (100%) rename {interface => libraries/plugins}/src/plugins/PluginManager.h (51%) diff --git a/cmake/macros/SetupHifiOpenGL.cmake b/cmake/macros/SetupHifiOpenGL.cmake new file mode 100644 index 0000000000..c62e43c27e --- /dev/null +++ b/cmake/macros/SetupHifiOpenGL.cmake @@ -0,0 +1,43 @@ + + +macro(SETUP_HIFI_OPENGL) + + if (APPLE) + + # link in required OS X frameworks and include the right GL headers + find_library(OpenGL OpenGL) + target_link_libraries(${TARGET_NAME} ${OpenGL}) + + elseif (WIN32) + + add_dependency_external_projects(glew) + find_package(GLEW REQUIRED) + target_include_directories(${TARGET_NAME} PUBLIC ${GLEW_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARIES} opengl32.lib) + + if (USE_NSIGHT) + # try to find the Nsight package and add it to the build if we find it + find_package(NSIGHT) + if (NSIGHT_FOUND) + include_directories(${NSIGHT_INCLUDE_DIRS}) + add_definitions(-DNSIGHT_FOUND) + target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") + endif() + endif() + + elseif(ANDROID) + + target_link_libraries(${TARGET_NAME} "-lGLESv3" "-lEGL") + + else() + + find_package(OpenGL REQUIRED) + if (${OPENGL_INCLUDE_DIR}) + include_directories(SYSTEM "${OPENGL_INCLUDE_DIR}") + endif() + target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}") + target_include_directories(${TARGET_NAME} PUBLIC ${OPENGL_INCLUDE_DIR}) + + endif() + +endmacro() diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index bb9960643c..458b6a7d7c 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -128,25 +128,6 @@ add_dependency_external_projects(glm bullet) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PRIVATE ${GLM_INCLUDE_DIRS}) -add_dependency_external_projects(boostconfig) -find_package(BOOSTCONFIG REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${BOOSTCONFIG_INCLUDE_DIRS}) - -add_dependency_external_projects(oglplus) -find_package(OGLPLUS REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${OGLPLUS_INCLUDE_DIRS}) - - -add_dependency_external_projects(LibOVR) -find_package(LibOVR REQUIRED) -target_include_directories(${TARGET_NAME} PRIVATE ${LIBOVR_INCLUDE_DIRS}) -target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES}) - -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}) - find_package(Bullet REQUIRED) target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) @@ -154,7 +135,7 @@ target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) # link required hifi libraries link_hifi_libraries(shared octree environment gpu model fbx networking entities avatars audio audio-client animation script-engine physics - render-utils entities-renderer ui) + render-utils entities-renderer ui plugins display-plugins) add_dependency_external_projects(sdl2) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 90730e8c82..f42d86d8eb 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/display/DisplayPlugin.h" +#include <display-plugins/DisplayPlugin.h> #include "scripting/AccountScriptingInterface.h" #include "scripting/AudioDeviceScriptingInterface.h" @@ -4582,12 +4582,11 @@ qreal Application::getDevicePixelRatio() { using DisplayPluginPointer = QSharedPointer<DisplayPlugin>; -#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" +#include <display-plugins/NullDisplayPlugin.h> +#include "LegacyDisplayPlugin.h" +//#include <display-plugins/Oculus.h> +#include <display-plugins/Tv3dDisplayPlugin.h> +//#include <display-plugins/WindowDisplayPlugin.h> static DisplayPluginPointer _displayPlugin{ nullptr }; @@ -4631,7 +4630,7 @@ static DisplayPlugin* PLUGIN_POOL[] = { new NullDisplayPlugin(), #endif new Tv3dDisplayPlugin(), - new WindowDisplayPlugin(), +// new WindowDisplayPlugin(), nullptr }; @@ -4674,9 +4673,17 @@ void Application::updateDisplayMode() { if (_displayPlugin != newDisplayPlugin) { if (newDisplayPlugin) { _offscreenContext->makeCurrent(); - newDisplayPlugin->activate(); + newDisplayPlugin->activate(this); + QWindow* pluginWindow = newDisplayPlugin->getWindow(); + if (pluginWindow) { + // Event filter queue is 'last in, first used' + pluginWindow->installEventFilter(DependencyManager::get<OffscreenUi>().data()); + pluginWindow->installEventFilter(qApp); + DependencyManager::get<OffscreenUi>()->setProxyWindow(pluginWindow); + } _offscreenContext->makeCurrent(); } + std::swap(newDisplayPlugin, _displayPlugin); if (newDisplayPlugin) { newDisplayPlugin->deactivate(); @@ -4694,3 +4701,6 @@ glm::ivec2 Application::getMouse() const { return getActiveDisplayPlugin()->getUiMousePosition(); } +void Application::addMenuItem(const QString& path, std::function<void()> onClicked, bool checkable, bool checked, const QString& groupName) { + +} diff --git a/interface/src/Application.h b/interface/src/Application.h index a94859263a..a91e5f77f2 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -40,6 +40,7 @@ #include <StDev.h> #include <TextureCache.h> #include <ViewFrustum.h> +#include <plugins/PluginContainer.h> #include "AudioClient.h" #include "Bookmarks.h" @@ -136,7 +137,7 @@ class Application; typedef bool (Application::* AcceptURLMethod)(const QString &); -class Application : public QApplication, public AbstractViewStateInterface, AbstractScriptingServicesInterface { +class Application : public QApplication, public AbstractViewStateInterface, AbstractScriptingServicesInterface, PluginContainer { Q_OBJECT friend class OctreePacketProcessor; @@ -280,6 +281,8 @@ public: QImage renderAvatarBillboard(); void displaySide(const Camera& camera, bool selfAvatarOnly = false); + + virtual void addMenuItem(const QString& path, std::function<void()> onClicked, bool checkable, bool checked, const QString& groupName); /* /// Stores the current modelview matrix as the untranslated view matrix to use for transforms and the supplied vector as diff --git a/interface/src/plugins/display/LegacyDisplayPlugin.cpp b/interface/src/LegacyDisplayPlugin.cpp similarity index 73% rename from interface/src/plugins/display/LegacyDisplayPlugin.cpp rename to interface/src/LegacyDisplayPlugin.cpp index a6b79fa5ef..4fbb02e454 100644 --- a/interface/src/plugins/display/LegacyDisplayPlugin.cpp +++ b/interface/src/LegacyDisplayPlugin.cpp @@ -19,38 +19,46 @@ const QString & LegacyDisplayPlugin::getName() { return NAME; } +LegacyDisplayPlugin::LegacyDisplayPlugin() { + connect(&_timer, &QTimer::timeout, this, [&] { + emit requestRender(); + }); +} + static QWidget * oldWidget = nullptr; -void LegacyDisplayPlugin::activate() { +void LegacyDisplayPlugin::activate(PluginContainer * container) { _window = new GLCanvas(); QOpenGLContext * sourceContext = QOpenGLContext::currentContext(); - QSurfaceFormat format; - format.setOption(QSurfaceFormat::DebugContext); QOpenGLContext * newContext = new QOpenGLContext(); - newContext->setFormat(format); + + { + QSurfaceFormat format; + format.setOption(QSurfaceFormat::DebugContext); + newContext->setFormat(format); + } + _window->setContext( QGLContext::fromOpenGLContext(newContext), QGLContext::fromOpenGLContext(sourceContext)); - _window->makeCurrent(); - oldWidget = qApp->getWindow()->centralWidget(); + + // FIXME necessary? + makeCurrent(); qApp->getWindow()->setCentralWidget(_window); - _window->doneCurrent(); + doneCurrent(); _window->setFocusPolicy(Qt::StrongFocus); _window->setFocus(); _window->setMouseTracking(true); - - _window->installEventFilter(qApp); - _window->installEventFilter(DependencyManager::get<OffscreenUi>().data()); - - DependencyManager::get<OffscreenUi>()->setProxyWindow(_window->windowHandle()); - SimpleDisplayPlugin::activate(); + _timer.start(8); } + void LegacyDisplayPlugin::deactivate() { + _timer.stop(); _window->removeEventFilter(DependencyManager::get<OffscreenUi>().data()); _window->removeEventFilter(qApp); // FIXME, during shutdown, this causes an NPE. Need to deactivate the plugin before the main window is destroyed. @@ -84,16 +92,32 @@ PickRay LegacyDisplayPlugin::computePickRay(const glm::vec2 & pos) const { return PickRay(); } -bool isMouseOnScreen() { - return false; -} - void LegacyDisplayPlugin::preDisplay() { - SimpleDisplayPlugin::preDisplay(); + OpenGlDisplayPlugin::preDisplay(); auto size = toGlm(_window->size()); glViewport(0, 0, size.x, size.y); } bool LegacyDisplayPlugin::isThrottled() const { return _window->isThrottleRendering(); -} \ No newline at end of file +} + +void LegacyDisplayPlugin::makeCurrent() { + _window->makeCurrent(); +} + +void LegacyDisplayPlugin::doneCurrent() { + _window->doneCurrent(); +} + +void LegacyDisplayPlugin::swapBuffers() { + _window->swapBuffers(); +} + +ivec2 LegacyDisplayPlugin::getTrueMousePosition() const { + return toGlm(_window->mapFromGlobal(QCursor::pos())); +} + +QWindow* LegacyDisplayPlugin::getWindow() const { + return _window->windowHandle(); +} diff --git a/interface/src/plugins/display/LegacyDisplayPlugin.h b/interface/src/LegacyDisplayPlugin.h similarity index 60% rename from interface/src/plugins/display/LegacyDisplayPlugin.h rename to interface/src/LegacyDisplayPlugin.h index 33ea6187c3..223f4d9e01 100644 --- a/interface/src/plugins/display/LegacyDisplayPlugin.h +++ b/interface/src/LegacyDisplayPlugin.h @@ -9,26 +9,36 @@ // #pragma once -#include "SimpleDisplayPlugin.h" +#include <display-plugins/OpenGlDisplayPlugin.h> #include "GLCanvas.h" -class LegacyDisplayPlugin : public SimpleDisplayPlugin<GLCanvas> { +class LegacyDisplayPlugin : public OpenGlDisplayPlugin { Q_OBJECT public: + LegacyDisplayPlugin(); static const QString NAME; virtual const QString & getName(); - virtual void activate(); + virtual void activate(PluginContainer * container); virtual void deactivate(); virtual QSize getDeviceSize() const; - virtual glm::ivec2 getCanvasSize() const; + virtual ivec2 getCanvasSize() const; virtual bool hasFocus() const; virtual PickRay computePickRay(const glm::vec2 & pos) const; virtual bool isMouseOnScreen() const { return true; } virtual bool isThrottled() const; virtual void preDisplay(); + virtual void idle(); + virtual ivec2 getTrueMousePosition() const; + virtual QWindow* getWindow() const; protected: - virtual void idle(); + virtual void makeCurrent() final; + virtual void doneCurrent() final; + virtual void swapBuffers() final; + +private: + GLCanvas * _window; + QTimer _timer; }; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 0ba4d1637b..e573110157 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -34,7 +34,6 @@ #include <UserActivityLogger.h> #include "Application.h" -#include "plugins/display/DisplayPlugin.h" #include "AvatarManager.h" #include "Environment.h" #include "Menu.h" diff --git a/interface/src/plugins/Plugin.cpp b/interface/src/plugins/Plugin.cpp deleted file mode 100644 index d882c538b4..0000000000 --- a/interface/src/plugins/Plugin.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Plugin.h" diff --git a/interface/src/plugins/Plugin.h b/interface/src/plugins/Plugin.h deleted file mode 100644 index ff91a6e1e2..0000000000 --- a/interface/src/plugins/Plugin.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include <QString> -#include <QObject> - -class PluginContainer { - virtual void addMenuItem(const QString& path, std::function<void()> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") = 0; -}; - -class Plugin : public QObject { -public: - virtual const QString & getName() = 0; - virtual bool isSupported() const { return true; } - - virtual void init() {} - virtual void deinit() {} - - virtual void activate(PluginContainer * container) {} - virtual void deactivate() {} - - virtual void idle() {} -}; diff --git a/interface/src/plugins/display/HmdDisplayPlugin.cpp b/interface/src/plugins/display/HmdDisplayPlugin.cpp deleted file mode 100644 index bfe4a088fa..0000000000 --- a/interface/src/plugins/display/HmdDisplayPlugin.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// -// HmdDisplayPlugin.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 "HmdDisplayPlugin.h" diff --git a/interface/src/plugins/display/HmdDisplayPlugin.h b/interface/src/plugins/display/HmdDisplayPlugin.h deleted file mode 100644 index 1156bafcda..0000000000 --- a/interface/src/plugins/display/HmdDisplayPlugin.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// HmdDisplayPlugin.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 HmdDisplayPlugin : public StereoDisplayPlugin { - virtual bool isHmd() const final { return true; } -}; diff --git a/interface/src/plugins/display/SimpleDisplayPlugin.cpp b/interface/src/plugins/display/SimpleDisplayPlugin.cpp deleted file mode 100644 index 3c7ec2fb3f..0000000000 --- a/interface/src/plugins/display/SimpleDisplayPlugin.cpp +++ /dev/null @@ -1,161 +0,0 @@ -// -// SimpleDisplayPlugin.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 "SimpleDisplayPlugin.h" -#include <QOpenGLContext> -#include <QCursor> -#include <QCoreApplication> - -#include <RenderUtil.h> -#include "DependencyManager.h" -#include "TextureCache.h" -#include "gpu/GLBackend.h" -#include "OffscreenUi.h" - -void SimpleGlDisplayPlugin::activate() { - makeCurrent(); - doneCurrent(); -} - -void SimpleGlDisplayPlugin::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, 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); - 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); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, overlayTexture); - 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(); - } - - - glDisable(GL_BLEND); - - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); - //Q_ASSERT(!glGetError()); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); - - glFinish(); -} - -bool GlWindowDisplayPlugin::eventFilter(QObject* object, QEvent* event) { - if (qApp->eventFilter(object, event)) { - return true; - } - - auto offscreenUi = DependencyManager::get<OffscreenUi>(); - if (offscreenUi->eventFilter(object, event)) { - return true; - } - - switch (event->type()) { - case QEvent::KeyPress: - case QEvent::KeyRelease: - QCoreApplication::sendEvent(QCoreApplication::instance(), event); - break; - - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::FocusIn: - case QEvent::FocusOut: - case QEvent::Resize: - case QEvent::MouseMove: - QCoreApplication::sendEvent(QCoreApplication::instance(), event); - break; - default: - break; - } - return false; -} - - -static QSurfaceFormat getPluginFormat() { - 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::CoreProfile); - return format; -} - - -void GlWindowDisplayPlugin::activate() { - Q_ASSERT(nullptr == _window); - _window = new GlWindow(getPluginFormat(), QOpenGLContext::currentContext()); - _window->installEventFilter(this); - DependencyManager::get<OffscreenUi>()->setProxyWindow(_window); -} - -void GlWindowDisplayPlugin::deactivate() { - Q_ASSERT(nullptr != _window); - _window->hide(); - _window->destroy(); - _window->deleteLater(); - _window = nullptr; -} - -QSize GlWindowDisplayPlugin::getDeviceSize() const { - return _window->geometry().size() * _window->devicePixelRatio(); -} - -glm::ivec2 GlWindowDisplayPlugin::getCanvasSize() const { - return toGlm(_window->geometry().size()); -} - -bool GlWindowDisplayPlugin::hasFocus() const { - return _window->isActive(); -} diff --git a/interface/src/plugins/display/SimpleDisplayPlugin.h b/interface/src/plugins/display/SimpleDisplayPlugin.h deleted file mode 100644 index ca86d85875..0000000000 --- a/interface/src/plugins/display/SimpleDisplayPlugin.h +++ /dev/null @@ -1,62 +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 <QCursor> - -#include <QOpenGLContext> -#include <GLMHelpers.h> -#include <RenderUtil.h> -#include <GlWindow.h> - -class SimpleGlDisplayPlugin : public DisplayPlugin { -public: - virtual void activate(); - virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize, - GLuint overlayTexture, const glm::uvec2& overlaySize); -}; - -template <typename T> -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<GlWindow> { -public: - virtual void activate(); - virtual void deactivate(); - virtual QSize getDeviceSize() const final; - virtual glm::ivec2 getCanvasSize() const final; - virtual bool hasFocus() const; - virtual bool eventFilter(QObject* object, QEvent* event); -}; - diff --git a/interface/src/plugins/display/StereoDisplayPlugin.cpp b/interface/src/plugins/display/StereoDisplayPlugin.cpp deleted file mode 100644 index 25070a4967..0000000000 --- a/interface/src/plugins/display/StereoDisplayPlugin.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// StereoDisplayPlugin.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 "StereoDisplayPlugin.h" diff --git a/interface/src/plugins/display/StereoDisplayPlugin.h b/interface/src/plugins/display/StereoDisplayPlugin.h deleted file mode 100644 index e3944ff878..0000000000 --- a/interface/src/plugins/display/StereoDisplayPlugin.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// StereoDisplayPlugin.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" - -class StereoDisplayPlugin : public DisplayPlugin { - virtual bool isStereo() const final { return true; } -}; - diff --git a/interface/src/plugins/display/Tv3dDisplayPlugin.cpp b/interface/src/plugins/display/Tv3dDisplayPlugin.cpp deleted file mode 100644 index efd6c055c9..0000000000 --- a/interface/src/plugins/display/Tv3dDisplayPlugin.cpp +++ /dev/null @@ -1,245 +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" -#include <GlWindow.h> -#include <QApplication> -#include <QDesktopWidget> - -#include "gpu/Texture.h" -#include "gpu/GLBackend.h" -#include "PathUtils.h" - -#include "Application.h" -#include "ui/ApplicationOverlay.h" - - -#include <GL/glew.h> -#define OGLPLUS_LOW_PROFILE 1 -#define OGLPLUS_USE_GLEW 1 -#define OGLPLUS_USE_BOOST_CONFIG 1 -#define OGLPLUS_NO_SITE_CONFIG 1 -#define OGLPLUS_USE_GLCOREARB_H 0 -#include <oglplus/gl.hpp> - -#pragma warning(disable : 4068) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" -#pragma warning( disable : 4244 4267 4065 4101) -#include <oglplus/all.hpp> -#include <oglplus/interop/glm.hpp> -#include <oglplus/bound/texture.hpp> -#include <oglplus/bound/framebuffer.hpp> -#include <oglplus/bound/renderbuffer.hpp> -#include <oglplus/shapes/wrapper.hpp> -#include <oglplus/shapes/plane.hpp> -#pragma warning( default : 4244 4267 4065 4101) -#pragma clang diagnostic pop - -typedef std::shared_ptr<oglplus::shapes::ShapeWrapper> ShapeWrapperPtr; -typedef std::shared_ptr<oglplus::Buffer> BufferPtr; -typedef std::shared_ptr<oglplus::VertexArray> VertexArrayPtr; -typedef std::shared_ptr<oglplus::Program> ProgramPtr; -typedef oglplus::Uniform<mat4> Mat4Uniform; - -const QString Tv3dDisplayPlugin::NAME("Tv3dDisplayPlugin"); - -const QString & Tv3dDisplayPlugin::getName() { - return NAME; -} - -Tv3dDisplayPlugin::Tv3dDisplayPlugin() { - connect(&_timer, &QTimer::timeout, this, [&] { - emit requestRender(); - }); -} - -bool Tv3dDisplayPlugin::isSupported() const { - // FIXME this should attempt to do a scan for supported 3D output - return true; -} - -gpu::TexturePointer _crosshairTexture; - - -void compileProgram(ProgramPtr & result, std::string vs, std::string fs) { - using namespace oglplus; - try { - result = ProgramPtr(new Program()); - // attach the shaders to the program - result->AttachShader( - VertexShader() - .Source(GLSLSource(vs)) - .Compile() - ); - result->AttachShader( - FragmentShader() - .Source(GLSLSource(fs)) - .Compile() - ); - result->Link(); - } catch (ProgramBuildError & err) { - qFatal((const char*)err.Message); - result.reset(); - } -} - - -ShapeWrapperPtr loadPlane(ProgramPtr program, float aspect) { - using namespace oglplus; - Vec3f a(1, 0, 0); - Vec3f b(0, 1, 0); - if (aspect > 1) { - b[1] /= aspect; - } else { - a[0] *= aspect; - } - return ShapeWrapperPtr( - new shapes::ShapeWrapper({ "Position", "TexCoord" }, shapes::Plane(a, b), *program) - ); -} - - -static const char * QUAD_VS = R"VS(#version 330 - -uniform mat4 Projection = mat4(1); -uniform mat4 ModelView = mat4(1); -uniform vec2 UvMultiplier = vec2(1); - -layout(location = 0) in vec3 Position; -layout(location = 1) in vec2 TexCoord; - -out vec2 vTexCoord; - -void main() { - gl_Position = Projection * ModelView * vec4(Position, 1); - vTexCoord = TexCoord * UvMultiplier; -} -)VS"; - -static const char * QUAD_FS = R"FS(#version 330 -uniform sampler2D sampler; -uniform float Alpha = 1.0; - -in vec2 vTexCoord; -out vec4 vFragColor; - -void main() { - vec4 c = texture(sampler, vTexCoord); - c.a = min(Alpha, c.a); - vFragColor = c; - //vFragColor = vec4(fract(vTexCoord), log(vTexCoord.x), 1.0); -} -)FS"; - -static ProgramPtr program; -static ShapeWrapperPtr plane; - -void Tv3dDisplayPlugin::display( - GLuint sceneTexture, const glm::uvec2& sceneSize, - GLuint overlayTexture, const glm::uvec2& overlaySize) { - QSize size = getDeviceSize(); - makeCurrent(); - - - if (!program) { - using namespace oglplus; - Context::BlendFunc(BlendFunction::SrcAlpha, BlendFunction::OneMinusSrcAlpha); - Context::Disable(Capability::Blend); - Context::Disable(Capability::DepthTest); - Context::Disable(Capability::CullFace); - - program = ProgramPtr(new oglplus::Program()); - compileProgram(program, QUAD_VS, QUAD_FS); - plane = loadPlane(program, 1.0f); - _crosshairTexture = DependencyManager::get<TextureCache>()-> - getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png"); - } - - - - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glViewport(0, 0, size.width(), size.height()); - Mat4Uniform(*program, "ModelView").Set(mat4()); - Mat4Uniform(*program, "Projection").Set(mat4()); - glBindTexture(GL_TEXTURE_2D, sceneTexture); - plane->Draw(); - - const float overlayAspect = aspect(toGlm(size)); - const GLfloat distance = 1.0f; - const GLfloat halfQuadHeight = distance * tan(DEFAULT_FIELD_OF_VIEW_DEGREES); - const GLfloat halfQuadWidth = halfQuadHeight * (float)size.width() / (float)size.height(); - const GLfloat quadWidth = halfQuadWidth * 2.0f; - const GLfloat quadHeight = halfQuadHeight * 2.0f; - - vec3 quadSize(quadWidth, quadHeight, 1.0f); - quadSize = vec3(1.0f) / quadSize; - - using namespace oglplus; - - Context::Enable(Capability::Blend); - glBindTexture(GL_TEXTURE_2D, overlayTexture); - - mat4 pr = glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), aspect(toGlm(size)), DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP); - Mat4Uniform(*program, "Projection").Set(pr); - - MatrixStack mv; - mv.translate(vec3(0, 0, -distance)).scale(vec3(0.7f, 0.7f / overlayAspect, 1.0f)); // .scale(vec3(quadWidth, quadHeight, 1.0)); - - QRect r(QPoint(0, 0), QSize(size.width() / 2, size.height())); - for (int i = 0; i < 2; ++i) { - Context::Viewport(r.x(), r.y(), r.width(), r.height()); - Mat4Uniform(*program, "ModelView").Set(mv.top()); - plane->Draw(); - r.moveLeft(r.width()); - } - - glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture)); - glm::vec2 canvasSize = qApp->getCanvasSize(); - glm::vec2 mouse = qApp->getMouse(); - mouse /= canvasSize; - mouse *= 2.0f; - mouse -= 1.0f; - mouse.y *= -1.0f; - mv.translate(mouse); - mv.scale(0.1f); - Mat4Uniform(*program, "ModelView").Set(mv.top()); - r = QRect(QPoint(0, 0), QSize(size.width() / 2, size.height())); - for (int i = 0; i < 2; ++i) { - Context::Viewport(r.x(), r.y(), r.width(), r.height()); - plane->Draw(); - r.moveLeft(r.width()); - } - Context::Disable(Capability::Blend); -} - - -void Tv3dDisplayPlugin::activate() { - GlWindowDisplayPlugin::activate(); - _window->installEventFilter(this); - _window->setFlags(Qt::FramelessWindowHint); - auto desktop = QApplication::desktop(); - _window->setGeometry(desktop->screenGeometry()); - _window->setCursor(Qt::BlankCursor); - _window->show(); - - _timer.start(8); -} - -void Tv3dDisplayPlugin::deactivate() { - makeCurrent(); - if (plane) { - plane.reset(); - program.reset(); - _crosshairTexture.reset(); - } - _timer.stop(); - GlWindowDisplayPlugin::deactivate(); -} diff --git a/interface/src/plugins/display/WindowDisplayPlugin.cpp b/interface/src/plugins/display/WindowDisplayPlugin.cpp deleted file mode 100644 index 25162e9343..0000000000 --- a/interface/src/plugins/display/WindowDisplayPlugin.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// WindowDisplayPlugin.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 "WindowDisplayPlugin.h" -#include "RenderUtil.h" -#include "Application.h" - -WindowDisplayPlugin::WindowDisplayPlugin() { - connect(&_timer, &QTimer::timeout, this, [&] { -// if (qApp->getActiveDisplayPlugin() == this) { - emit requestRender(); -// } - }); -} - -const QString WindowDisplayPlugin::NAME("QWindow 2D Renderer"); - -const QString & WindowDisplayPlugin::getName() { - return NAME; -} - -void WindowDisplayPlugin::activate() { - GlWindowDisplayPlugin::activate(); - _window->show(); - _timer.start(8); -} - -void WindowDisplayPlugin::deactivate() { - _timer.stop(); - GlWindowDisplayPlugin::deactivate(); -} - diff --git a/libraries/display-plugins/CMakeLists.txt b/libraries/display-plugins/CMakeLists.txt new file mode 100644 index 0000000000..cbfecfb0da --- /dev/null +++ b/libraries/display-plugins/CMakeLists.txt @@ -0,0 +1,30 @@ +set(TARGET_NAME display-plugins) + +# use setup_hifi_library macro to setup our project and link appropriate Qt modules +setup_hifi_library(OpenGL) + +setup_hifi_opengl() + +link_hifi_libraries(shared plugins ) + +add_dependency_external_projects(glm) +find_package(GLM REQUIRED) +target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) + +add_dependency_external_projects(boostconfig) +find_package(BOOSTCONFIG REQUIRED) +target_include_directories(${TARGET_NAME} PUBLIC ${BOOSTCONFIG_INCLUDE_DIRS}) + +add_dependency_external_projects(oglplus) +find_package(OGLPLUS REQUIRED) +target_include_directories(${TARGET_NAME} PUBLIC ${OGLPLUS_INCLUDE_DIRS}) + +add_dependency_external_projects(LibOVR) +find_package(LibOVR REQUIRED) +target_include_directories(${TARGET_NAME} PRIVATE ${LIBOVR_INCLUDE_DIRS}) +target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES}) + +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}) diff --git a/interface/src/plugins/display/OculusHelpers.h b/libraries/display-plugins/src/OculusHelpers.h similarity index 97% rename from interface/src/plugins/display/OculusHelpers.h rename to libraries/display-plugins/src/OculusHelpers.h index 553a1671e5..acd02e1af9 100644 --- a/interface/src/plugins/display/OculusHelpers.h +++ b/libraries/display-plugins/src/OculusHelpers.h @@ -1,5 +1,5 @@ // -// Created by Bradley Austin Davis on 2015/05/26. +// Created by Bradley Austin Davis on 2015/05/26 // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. diff --git a/libraries/display-plugins/src/OglplusHelpers.cpp b/libraries/display-plugins/src/OglplusHelpers.cpp new file mode 100644 index 0000000000..fd9d9500f1 --- /dev/null +++ b/libraries/display-plugins/src/OglplusHelpers.cpp @@ -0,0 +1,122 @@ +// +// 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 +// +#include "OglplusHelpers.h" + + +static const char * SIMPLE_TEXTURED_VS = R"VS(#version 410 core +#pragma line __LINE__ + +uniform mat4 Projection = mat4(1); +uniform mat4 ModelView = mat4(1); + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec2 TexCoord; + +out vec2 vTexCoord; + +void main() { + gl_Position = Projection * ModelView * vec4(Position, 1); + vTexCoord = TexCoord; +} + +)VS"; + +static const char * SIMPLE_TEXTURED_FS = R"FS(#version 410 core +#pragma line __LINE__ + +uniform sampler2D sampler; +uniform float Alpha = 1.0; + +in vec2 vTexCoord; +out vec4 vFragColor; + +void main() { + vec4 c = texture(sampler, vTexCoord); + c.a = min(Alpha, c.a); + vFragColor = c; +} + +)FS"; + + +ProgramPtr loadDefaultShader() { + ProgramPtr result; + compileProgram(result, SIMPLE_TEXTURED_VS, SIMPLE_TEXTURED_FS); + return result; +} + +void compileProgram(ProgramPtr & result, const std::string& vs, const std::string& fs) { + using namespace oglplus; + try { + result = ProgramPtr(new Program()); + // attach the shaders to the program + result->AttachShader( + VertexShader() + .Source(GLSLSource(vs)) + .Compile() + ); + result->AttachShader( + FragmentShader() + .Source(GLSLSource(fs)) + .Compile() + ); + result->Link(); + } catch (ProgramBuildError & err) { + Q_UNUSED(err); + Q_ASSERT_X(false, "compileProgram", "Failed to build shader program"); + qFatal((const char*)err.Message); + result.reset(); + } +} + + +ShapeWrapperPtr loadPlane(ProgramPtr program, float aspect) { + using namespace oglplus; + Vec3f a(1, 0, 0); + Vec3f b(0, 1, 0); + if (aspect > 1) { + b[1] /= aspect; + } else { + a[0] *= aspect; + } + return ShapeWrapperPtr( + new shapes::ShapeWrapper({ "Position", "TexCoord" }, shapes::Plane(a, b), *program) + ); +} + + +static const char * QUAD_VS = R"VS(#version 330 + +uniform mat4 Projection = mat4(1); +uniform mat4 ModelView = mat4(1); +uniform vec2 UvMultiplier = vec2(1); + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec2 TexCoord; + +out vec2 vTexCoord; + +void main() { + gl_Position = Projection * ModelView * vec4(Position, 1); + vTexCoord = TexCoord * UvMultiplier; +} +)VS"; + +static const char * QUAD_FS = R"FS(#version 330 +uniform sampler2D sampler; +uniform float Alpha = 1.0; + +in vec2 vTexCoord; +out vec4 vFragColor; + +void main() { + vec4 c = texture(sampler, vTexCoord); + c.a = min(Alpha, c.a); + vFragColor = c; +} +)FS"; diff --git a/interface/src/plugins/display/OglplusHelpers.h b/libraries/display-plugins/src/OglplusHelpers.h similarity index 55% rename from interface/src/plugins/display/OglplusHelpers.h rename to libraries/display-plugins/src/OglplusHelpers.h index b74362a617..ddeff20506 100644 --- a/interface/src/plugins/display/OglplusHelpers.h +++ b/libraries/display-plugins/src/OglplusHelpers.h @@ -1,5 +1,5 @@ // -// Created by Bradley Austin Davis on 2015/05/26. +// Created by Bradley Austin Davis on 2015/05/26 // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -7,6 +7,10 @@ // #pragma once +#include <GLMHelpers.h> + +#pragma warning(disable : 4068) + #define OGLPLUS_USE_GLEW 1 #define OGLPLUS_USE_GLCOREARB_H 0 #define OGLPLUS_USE_BOOST_CONFIG 1 @@ -24,3 +28,13 @@ #include <oglplus/shapes/plane.hpp> typedef std::shared_ptr<oglplus::Framebuffer> FramebufferPtr; +typedef std::shared_ptr<oglplus::shapes::ShapeWrapper> ShapeWrapperPtr; +typedef std::shared_ptr<oglplus::Buffer> BufferPtr; +typedef std::shared_ptr<oglplus::VertexArray> VertexArrayPtr; +typedef std::shared_ptr<oglplus::Program> ProgramPtr; +typedef oglplus::Uniform<mat4> Mat4Uniform; + +ProgramPtr loadDefaultShader(); +void compileProgram(ProgramPtr & result, const std::string& vs, const std::string& fs); +ShapeWrapperPtr loadPlane(ProgramPtr program, float aspect = 1.0f); + diff --git a/interface/src/plugins/display/DisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp similarity index 86% rename from interface/src/plugins/display/DisplayPlugin.cpp rename to libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp index d9d649019f..55e4dbd8ae 100644 --- a/interface/src/plugins/display/DisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp @@ -1,7 +1,5 @@ // -// DisplayPlugin.cpp -// -// Created by Bradley Austin Davis on 2014/04/13. +// Created by Bradley Austin Davis on 2015/05/29 // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -13,4 +11,4 @@ bool DisplayPlugin::isMouseOnScreen() const { glm::ivec2 mousePosition = getTrueMousePosition(); return (glm::all(glm::greaterThanEqual(mousePosition, glm::ivec2(0))) && glm::all(glm::lessThanEqual(mousePosition, glm::ivec2(getCanvasSize())))); -} \ No newline at end of file +} diff --git a/interface/src/plugins/display/DisplayPlugin.h b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h similarity index 72% rename from interface/src/plugins/display/DisplayPlugin.h rename to libraries/display-plugins/src/display-plugins/DisplayPlugin.h index 711b53e9f4..b2726288cf 100644 --- a/interface/src/plugins/display/DisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h @@ -1,7 +1,5 @@ // -// DisplayPlugin.h -// -// Created by Bradley Austin Davis on 2014/04/13. +// Created by Bradley Austin Davis on 2015/05/29 // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -46,28 +44,43 @@ void for_each_eye(F f, FF ff) { f(Eye::Right); } +class QWindow; + class DisplayPlugin : public Plugin { Q_OBJECT public: virtual bool isHmd() const { return false; } - virtual bool isStereo() const { return false; } + /// By default, all HMDs are stereo + virtual bool isStereo() const { return isHmd(); } virtual bool isThrottled() const { return false; } // Rendering support - virtual void preRender() {}; - - virtual void preDisplay() { - makeCurrent(); - }; + /** + * Called by the application before the frame rendering. Can be used for + * render timing related calls (for instance, the Oculus begin frame timing + * call) + */ + virtual void preRender() = 0; + /** + * Called by the application immediately before calling the display function. + * For OpenGL based plugins, this is the best place to put activate the output + * OpenGL context + */ + virtual void preDisplay() = 0; + /** + * Sends the scene texture and the overlay texture to the display plugin. + * The plugin is responsible for compositing these and adding rendering of + * additional elements like mouse and hydra pointers as required + */ virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize, GLuint overlayTexture, const glm::uvec2& overlaySize) = 0; + /** + * Called by the application immeidately after display. For OpenGL based + * displays, this is the best place to put the buffer swap + */ + virtual void finishFrame() = 0; - virtual void finishFrame() { - swapBuffers(); - doneCurrent(); - }; - // Does the rendering surface have current focus? virtual bool hasFocus() const = 0; // The size of the rendering surface @@ -76,13 +89,15 @@ public: virtual QSize getRecommendedFramebufferSize() const { return getDeviceSize(); }; // The size of the window (differs from the framebuffers size in instances like Retina macs) virtual glm::ivec2 getCanvasSize() const = 0; + // The window for the surface, used for event interception. May be null. + virtual QWindow* getWindow() const = 0; // The mouse position relative to the window (or proxy window) surface virtual glm::ivec2 getTrueMousePosition() const = 0; // The mouse position relative to the UI elements virtual glm::ivec2 getUiMousePosition() const { - return trueMouseToUiMouse(getTrueMousePosition()); + return trueMouseToUiMouse(getTrueMousePosition()); } virtual std::function<QPointF(const QPointF&)> getMouseTranslator() { return [](const QPointF& p) { return p; }; }; @@ -123,10 +138,5 @@ public: signals: void recommendedFramebufferSizeChanged(const QSize & size); void requestRender(); - -protected: - virtual void makeCurrent() {} - virtual void doneCurrent() {} - virtual void swapBuffers() {} }; diff --git a/libraries/display-plugins/src/display-plugins/GlWindowDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/GlWindowDisplayPlugin.cpp new file mode 100644 index 0000000000..a456bf667b --- /dev/null +++ b/libraries/display-plugins/src/display-plugins/GlWindowDisplayPlugin.cpp @@ -0,0 +1,127 @@ +// +// 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 +// +#include "GlWindowDisplayPlugin.h" + +#include <QOpenGLContext> +#include <QCursor> +#include <QTimer> +#include <QCoreApplication> + +#include <GLWindow.h> +#include <GLMHelpers.h> + +GlWindowDisplayPlugin::GlWindowDisplayPlugin() : _timer(new QTimer()) { + connect(_timer, &QTimer::timeout, this, [&] { + // if (qApp->getActiveDisplayPlugin() == this) { + emit requestRender(); + // } + }); +} + +GlWindowDisplayPlugin::~GlWindowDisplayPlugin() { + delete _timer; +} + +void GlWindowDisplayPlugin::makeCurrent() { + _window->makeCurrent(); +} + +void GlWindowDisplayPlugin::doneCurrent() { + _window->doneCurrent(); +} + +void GlWindowDisplayPlugin::swapBuffers() { + _window->swapBuffers(); +} + +glm::ivec2 GlWindowDisplayPlugin::getTrueMousePosition() const { + return toGlm(_window->mapFromGlobal(QCursor::pos())); +} + +QWindow* GlWindowDisplayPlugin::getWindow() const { + return _window; +} + +bool GlWindowDisplayPlugin::eventFilter(QObject* object, QEvent* event) { + if (qApp->eventFilter(object, event)) { + return true; + } + + // FIXME + /* + auto offscreenUi = DependencyManager::get<OffscreenUi>(); + if (offscreenUi->eventFilter(object, event)) { + return true; + } + */ + + // distinct calls for easier debugging with breakpoints + switch (event->type()) { + case QEvent::KeyPress: + QCoreApplication::sendEvent(QCoreApplication::instance(), event); + break; + case QEvent::KeyRelease: + QCoreApplication::sendEvent(QCoreApplication::instance(), event); + break; + case QEvent::MouseButtonPress: + QCoreApplication::sendEvent(QCoreApplication::instance(), event); + break; + case QEvent::MouseButtonRelease: + QCoreApplication::sendEvent(QCoreApplication::instance(), event); + break; + case QEvent::FocusIn: + QCoreApplication::sendEvent(QCoreApplication::instance(), event); + break; + case QEvent::FocusOut: + QCoreApplication::sendEvent(QCoreApplication::instance(), event); + break; + case QEvent::Resize: + QCoreApplication::sendEvent(QCoreApplication::instance(), event); + break; + case QEvent::MouseMove: + QCoreApplication::sendEvent(QCoreApplication::instance(), event); + break; + default: + break; + } + return false; +} + +void GlWindowDisplayPlugin::activate(PluginContainer * container) { + Q_ASSERT(nullptr == _window); + _window = new GlWindow(QOpenGLContext::currentContext()); + _window->installEventFilter(this); + customizeWindow(); + _window->show(); + _timer->start(8); + makeCurrent(); + customizeContext(); + // FIXME + //DependencyManager::get<OffscreenUi>()->setProxyWindow(_window); +} + +void GlWindowDisplayPlugin::deactivate() { + _timer->stop(); + Q_ASSERT(nullptr != _window); + _window->hide(); + _window->destroy(); + _window->deleteLater(); + _window = nullptr; +} + +QSize GlWindowDisplayPlugin::getDeviceSize() const { + return _window->geometry().size() * _window->devicePixelRatio(); +} + +glm::ivec2 GlWindowDisplayPlugin::getCanvasSize() const { + return toGlm(_window->geometry().size()); +} + +bool GlWindowDisplayPlugin::hasFocus() const { + return _window->isActive(); +} diff --git a/libraries/display-plugins/src/display-plugins/GlWindowDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/GlWindowDisplayPlugin.h new file mode 100644 index 0000000000..1833ab3a84 --- /dev/null +++ b/libraries/display-plugins/src/display-plugins/GlWindowDisplayPlugin.h @@ -0,0 +1,41 @@ +// +// 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 "OpenGlDisplayPlugin.h" + +class GlWindow; +class QTimer; + +class GlWindowDisplayPlugin : public OpenGlDisplayPlugin { +public: + GlWindowDisplayPlugin(); + virtual ~GlWindowDisplayPlugin(); + virtual void activate(PluginContainer * container); + virtual void deactivate(); + virtual QSize getDeviceSize() const final; + virtual glm::ivec2 getCanvasSize() const final; + virtual bool hasFocus() const; + virtual bool eventFilter(QObject* object, QEvent* event); + + virtual glm::ivec2 getTrueMousePosition() const; + virtual QWindow* getWindow() const; + +protected: + virtual void makeCurrent() final; + virtual void doneCurrent() final; + virtual void swapBuffers() final; + virtual void customizeWindow() = 0; + virtual void customizeContext() = 0; + +private: + QTimer* _timer{ nullptr }; +protected: + GlWindow* _window{ nullptr }; +}; + diff --git a/interface/src/plugins/display/NullDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp similarity index 69% rename from interface/src/plugins/display/NullDisplayPlugin.cpp rename to libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp index 9b5ab8ed0a..2204c0499c 100644 --- a/interface/src/plugins/display/NullDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp @@ -42,3 +42,16 @@ PickRay NullDisplayPlugin::computePickRay(const glm::vec2 & pos) const { bool NullDisplayPlugin::isMouseOnScreen() const { return false; } + +QWindow* NullDisplayPlugin::getWindow() const { + return nullptr; +} + +void NullDisplayPlugin::preRender() {} +void NullDisplayPlugin::preDisplay() {} +void NullDisplayPlugin::display(GLuint sceneTexture, const glm::uvec2& sceneSize, + GLuint overlayTexture, const glm::uvec2& overlaySize) {} +void NullDisplayPlugin::finishFrame() {} + +void NullDisplayPlugin::activate(PluginContainer * container) {} +void NullDisplayPlugin::deactivate() {} diff --git a/interface/src/plugins/display/NullDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h similarity index 72% rename from interface/src/plugins/display/NullDisplayPlugin.h rename to libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h index 8a06febb7b..0fedf872b1 100644 --- a/interface/src/plugins/display/NullDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h @@ -1,7 +1,5 @@ // -// NullDisplayPlugin.h -// -// Created by Bradley Austin Davis on 2014/04/13. +// Created by Bradley Austin Davis on 2015/05/29 // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -18,6 +16,9 @@ public: virtual ~NullDisplayPlugin() final {} virtual const QString & getName(); + void activate(PluginContainer * container); + void deactivate(); + virtual QSize getDeviceSize() const; virtual glm::ivec2 getCanvasSize() const; virtual bool hasFocus() const; @@ -25,8 +26,11 @@ public: virtual glm::ivec2 getTrueMousePosition() const; virtual PickRay computePickRay(const glm::vec2 & pos) const; virtual bool isMouseOnScreen() const; - + virtual QWindow* getWindow() const; + virtual void preRender(); + virtual void preDisplay(); virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize, - GLuint overlayTexture, const glm::uvec2& overlaySize) {}; + GLuint overlayTexture, const glm::uvec2& overlaySize); + virtual void finishFrame(); }; diff --git a/interface/src/plugins/display/OculusBaseDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OculusBaseDisplayPlugin.cpp similarity index 87% rename from interface/src/plugins/display/OculusBaseDisplayPlugin.cpp rename to libraries/display-plugins/src/display-plugins/OculusBaseDisplayPlugin.cpp index 50e1583548..7648be1d25 100644 --- a/interface/src/plugins/display/OculusBaseDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OculusBaseDisplayPlugin.cpp @@ -1,7 +1,5 @@ // -// OculusBaseDisplayPlugin.cpp -// -// Created by Bradley Austin Davis on 2014/04/13. +// Created by Bradley Austin Davis on 2015/05/29 // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -11,10 +9,9 @@ #include <ViewFrustum.h> -#include "OculusHelpers.h" +#include "../OculusHelpers.h" - -void OculusBaseDisplayPlugin::activate() { +void OculusBaseDisplayPlugin::activate(PluginContainer * container) { ovr_for_each_eye([&](ovrEyeType eye) { ovrEyeRenderDesc erd = ovrHmd_GetRenderDesc(_hmd, eye, _hmd->MaxEyeFov[eye]); ovrMatrix4f ovrPerspectiveProjection = diff --git a/interface/src/plugins/display/OculusBaseDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OculusBaseDisplayPlugin.h similarity index 74% rename from interface/src/plugins/display/OculusBaseDisplayPlugin.h rename to libraries/display-plugins/src/display-plugins/OculusBaseDisplayPlugin.h index 94f73522b5..0462f00321 100644 --- a/interface/src/plugins/display/OculusBaseDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OculusBaseDisplayPlugin.h @@ -1,7 +1,5 @@ // -// OculusBaseDisplayPlugin.h -// -// Created by Bradley Austin Davis on 2014/04/13. +// Created by Bradley Austin Davis on 2015/05/29 // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -9,16 +7,17 @@ // #pragma once -#include "HmdDisplayPlugin.h" +#include "DisplayPlugin.h" #include <OVR_CAPI.h> -class OculusBaseDisplayPlugin : public HmdDisplayPlugin { +class OculusBaseDisplayPlugin : public DisplayPlugin { public: // Stereo specific methods + virtual bool isHmd() const { return true; } virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const; virtual glm::mat4 getModelview(Eye eye, const glm::mat4& baseModelview) const; - virtual void activate(); + virtual void activate(PluginContainer * container); virtual void deactivate(); virtual void preRender(); virtual void configureRendering() = 0; diff --git a/interface/src/plugins/display/OculusWin32DisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OculusWin32DisplayPlugin.cpp similarity index 97% rename from interface/src/plugins/display/OculusWin32DisplayPlugin.cpp rename to libraries/display-plugins/src/display-plugins/OculusWin32DisplayPlugin.cpp index f7414cc551..a15550a20b 100644 --- a/interface/src/plugins/display/OculusWin32DisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OculusWin32DisplayPlugin.cpp @@ -7,11 +7,16 @@ // #include "OculusWin32DisplayPlugin.h" +#include <memory> +#include <GLMHelpers.h> #include <OVR_CAPI_GL.h> +#include "../OglplusHelpers.h" + +#if 0 bool OculusWin32DisplayPlugin::isSupported() { - ovr_Initialize(); + ovr_Initialize(nullptr); bool result = false; if (ovrHmd_Detect() != 0) { result = true; @@ -29,7 +34,7 @@ bool OculusWin32DisplayPlugin::isSupported() { // the screen. template <typename C = GLuint, typename D = GLuint> struct FramebufferWrapper { - glm::uvec2 size; + uvec2 size; oglplus::Framebuffer fbo; C color{ 0 }; GLuint depth{ 0 }; @@ -198,3 +203,4 @@ private: }; using MirrorFboPtr = std::shared_ptr<MirrorFramebufferWrapper>; +#endif \ No newline at end of file diff --git a/interface/src/plugins/display/OculusWin32DisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OculusWin32DisplayPlugin.h similarity index 87% rename from interface/src/plugins/display/OculusWin32DisplayPlugin.h rename to libraries/display-plugins/src/display-plugins/OculusWin32DisplayPlugin.h index 436efb5742..6866f096fc 100644 --- a/interface/src/plugins/display/OculusWin32DisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OculusWin32DisplayPlugin.h @@ -1,5 +1,5 @@ // -// Created by Bradley Austin Davis on 2015/05/26. +// Created by Bradley Austin Davis on 2015/05/29 // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. diff --git a/libraries/display-plugins/src/display-plugins/OpenGlDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGlDisplayPlugin.cpp new file mode 100644 index 0000000000..f2bd328915 --- /dev/null +++ b/libraries/display-plugins/src/display-plugins/OpenGlDisplayPlugin.cpp @@ -0,0 +1,88 @@ +// +// 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 +// +#include "OpenGlDisplayPlugin.h" + +#include <QOpenGLContext> + +void OpenGlDisplayPlugin::preDisplay() { + makeCurrent(); +}; + +void OpenGlDisplayPlugin::preRender() { + // NOOP +} + +void OpenGlDisplayPlugin::finishFrame() { + swapBuffers(); + doneCurrent(); +}; + +void OpenGlDisplayPlugin::display(GLuint sceneTexture, const glm::uvec2& sceneSize, + GLuint overlayTexture, const glm::uvec2& overlaySize) { + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + 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); + 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); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, overlayTexture); + 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(); + } + + + glDisable(GL_BLEND); + + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + //Q_ASSERT(!glGetError()); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + + glFinish(); +} + diff --git a/libraries/display-plugins/src/display-plugins/OpenGlDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGlDisplayPlugin.h new file mode 100644 index 0000000000..19587b997e --- /dev/null +++ b/libraries/display-plugins/src/display-plugins/OpenGlDisplayPlugin.h @@ -0,0 +1,24 @@ +// +// 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 "DisplayPlugin.h" + +class OpenGlDisplayPlugin : public DisplayPlugin { +public: + virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize, + GLuint overlayTexture, const glm::uvec2& overlaySize); + virtual void preRender(); + virtual void preDisplay(); + virtual void finishFrame(); + +protected: + virtual void makeCurrent() = 0; + virtual void doneCurrent() = 0; + virtual void swapBuffers() = 0; +}; diff --git a/libraries/display-plugins/src/display-plugins/Tv3dDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Tv3dDisplayPlugin.cpp new file mode 100644 index 0000000000..b6607e5518 --- /dev/null +++ b/libraries/display-plugins/src/display-plugins/Tv3dDisplayPlugin.cpp @@ -0,0 +1,176 @@ +// +// 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 +// + +#include "Tv3dDisplayPlugin.h" + +#include <QApplication> +#include <QDesktopWidget> + +#include <GlWindow.h> +#include <ViewFrustum.h> +#include <MatrixStack.h> +#include <PathUtils.h> + + +#include "../OglplusHelpers.h" + +const QString Tv3dDisplayPlugin::NAME("Tv3dDisplayPlugin"); + +const QString & Tv3dDisplayPlugin::getName() { + return NAME; +} + +Tv3dDisplayPlugin::Tv3dDisplayPlugin() { +} + +bool Tv3dDisplayPlugin::isSupported() const { + // FIXME this should attempt to do a scan for supported 3D output + return true; +} + +static ProgramPtr program; +static ShapeWrapperPtr plane; + +void Tv3dDisplayPlugin::customizeWindow() { + _window->setFlags(Qt::FramelessWindowHint); + auto desktop = QApplication::desktop(); + QRect primaryGeometry = desktop->screenGeometry(); + for (int i = 0; i < desktop->screenCount(); ++i) { + QRect geometry = desktop->screen(i)->geometry(); + if (geometry.topLeft() == primaryGeometry.topLeft()) { + continue; + } + float aspect = (float)geometry.width() / (float)geometry.height(); + if (aspect < 1.0f) { + continue; + } + _window->setGeometry(geometry); + break; + } + _window->setCursor(Qt::BlankCursor); +} + +void Tv3dDisplayPlugin::customizeContext() { + using namespace oglplus; + Context::BlendFunc(BlendFunction::SrcAlpha, BlendFunction::OneMinusSrcAlpha); + Context::Disable(Capability::Blend); + Context::Disable(Capability::DepthTest); + Context::Disable(Capability::CullFace); + program = loadDefaultShader(); + plane = loadPlane(program); + Context::ClearColor(0, 0, 0, 1); + // _crosshairTexture = DependencyManager::get<TextureCache>()-> + // getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png"); +} + + +const float DEFAULT_IPD = 0.064f; +const float HALF_DEFAULT_IPD = DEFAULT_IPD / 2.0f; + +glm::mat4 Tv3dDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseProjection) const { + float nearZ = DEFAULT_NEAR_CLIP; // near clipping plane + float screenZ = 0.25f; // screen projection plane + // FIXME verify this is the right calculation + float frustumshift = HALF_DEFAULT_IPD * nearZ / screenZ; + if (eye == Right) { + frustumshift = -frustumshift; + } + return glm::translate(baseProjection, vec3(frustumshift, 0, 0)); +} + +glm::mat4 Tv3dDisplayPlugin::getModelview(Eye eye, const glm::mat4& baseModelview) const { + float modelviewShift = HALF_DEFAULT_IPD; + if (eye == Left) { + modelviewShift = -modelviewShift; + } + return baseModelview * glm::translate(mat4(), vec3(modelviewShift, 0, 0)); +} + + + +void Tv3dDisplayPlugin::display( + GLuint sceneTexture, const glm::uvec2& sceneSize, + GLuint overlayTexture, const glm::uvec2& overlaySize) { + + QSize size = getDeviceSize(); + using namespace oglplus; + Context::Viewport(size.width(), size.height()); + Context::Clear().ColorBuffer().DepthBuffer(); + + Mat4Uniform(*program, "ModelView").Set(mat4()); + Mat4Uniform(*program, "Projection").Set(mat4()); + + glBindTexture(GL_TEXTURE_2D, sceneTexture); + + plane->Draw(); + + const float overlayAspect = aspect(toGlm(size)); + const GLfloat distance = 1.0f; + const GLfloat halfQuadHeight = distance * tan(DEFAULT_FIELD_OF_VIEW_DEGREES); + const GLfloat halfQuadWidth = halfQuadHeight * (float)size.width() / (float)size.height(); + const GLfloat quadWidth = halfQuadWidth * 2.0f; + const GLfloat quadHeight = halfQuadHeight * 2.0f; + + vec3 quadSize(quadWidth, quadHeight, 1.0f); + quadSize = vec3(1.0f) / quadSize; + + using namespace oglplus; + Context::Enable(Capability::Blend); + glBindTexture(GL_TEXTURE_2D, overlayTexture); + + mat4 pr = glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), aspect(toGlm(size)), DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP); + Mat4Uniform(*program, "Projection").Set(pr); + + MatrixStack mv; + mv.translate(vec3(0, 0, -distance)).scale(vec3(0.7f, 0.7f / overlayAspect, 1.0f)); // .scale(vec3(quadWidth, quadHeight, 1.0)); + + QRect r(QPoint(0, 0), QSize(size.width() / 2, size.height())); + for (int i = 0; i < 2; ++i) { + Context::Viewport(r.x(), r.y(), r.width(), r.height()); + Mat4Uniform(*program, "ModelView").Set(mv.top()); + plane->Draw(); + r.moveLeft(r.width()); + } + +#if 0 + glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture)); + glm::vec2 canvasSize = qApp->getCanvasSize(); + glm::vec2 mouse = qApp->getMouse(); + mouse /= canvasSize; + mouse *= 2.0f; + mouse -= 1.0f; + mouse.y *= -1.0f; + mv.translate(mouse); + mv.scale(0.1f); + Mat4Uniform(*program, "ModelView").Set(mv.top()); + r = QRect(QPoint(0, 0), QSize(size.width() / 2, size.height())); + for (int i = 0; i < 2; ++i) { + Context::Viewport(r.x(), r.y(), r.width(), r.height()); + plane->Draw(); + r.moveLeft(r.width()); + } +#endif + Context::Disable(Capability::Blend); +} + + +void Tv3dDisplayPlugin::activate(PluginContainer * container) { + GlWindowDisplayPlugin::activate(container); + _window->show(); +} + +void Tv3dDisplayPlugin::deactivate() { + makeCurrent(); + if (plane) { + plane.reset(); + program.reset(); +// _crosshairTexture.reset(); + } + doneCurrent(); + GlWindowDisplayPlugin::deactivate(); +} diff --git a/interface/src/plugins/display/Tv3dDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/Tv3dDisplayPlugin.h similarity index 67% rename from interface/src/plugins/display/Tv3dDisplayPlugin.h rename to libraries/display-plugins/src/display-plugins/Tv3dDisplayPlugin.h index ad2ccc7369..9baa9261ef 100644 --- a/interface/src/plugins/display/Tv3dDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/Tv3dDisplayPlugin.h @@ -1,17 +1,13 @@ // -// Tv3dDisplayPlugin.h -// -// Created by Bradley Austin Davis on 2014/04/13. +// 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 "SimpleDisplayPlugin.h" -#include <QTimer> +#include "GlWindowDisplayPlugin.h" class Tv3dDisplayPlugin : public GlWindowDisplayPlugin { Q_OBJECT @@ -23,12 +19,15 @@ public: virtual bool isSupported() const final; void display(GLuint sceneTexture, const glm::uvec2& sceneSize, GLuint overlayTexture, const glm::uvec2& overlaySize); - virtual void activate(); + virtual void activate(PluginContainer * container); virtual void deactivate(); + virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const; + virtual glm::mat4 getModelview(Eye eye, const glm::mat4& baseModelview) const; + +protected: + virtual void customizeWindow(); + virtual void customizeContext(); //virtual std::function<QPointF(const QPointF&)> getMouseTranslator(); //virtual glm::ivec2 trueMouseToUiMouse(const glm::ivec2 & position) const; - -private: - QTimer _timer; }; diff --git a/libraries/display-plugins/src/display-plugins/WindowDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/WindowDisplayPlugin.cpp new file mode 100644 index 0000000000..0298d6b823 --- /dev/null +++ b/libraries/display-plugins/src/display-plugins/WindowDisplayPlugin.cpp @@ -0,0 +1,18 @@ +// +// 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 +// +#include "WindowDisplayPlugin.h" + +WindowDisplayPlugin::WindowDisplayPlugin() { +} + +const QString WindowDisplayPlugin::NAME("QWindow 2D Renderer"); + +const QString & WindowDisplayPlugin::getName() { + return NAME; +} + diff --git a/interface/src/plugins/display/WindowDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/WindowDisplayPlugin.h similarity index 62% rename from interface/src/plugins/display/WindowDisplayPlugin.h rename to libraries/display-plugins/src/display-plugins/WindowDisplayPlugin.h index 7bc0d5163d..208dc26975 100644 --- a/interface/src/plugins/display/WindowDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/WindowDisplayPlugin.h @@ -1,7 +1,5 @@ // -// WindowDisplayPlugin.h -// -// Created by Bradley Austin Davis on 2014/04/13. +// Created by Bradley Austin Davis on 2015/05/29 // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -9,10 +7,7 @@ // #pragma once -#include "SimpleDisplayPlugin.h" - -#include <GlWindow.h> -#include <QTimer> +#include "GlWindowDisplayPlugin.h" class WindowDisplayPlugin : public GlWindowDisplayPlugin { Q_OBJECT @@ -22,9 +17,5 @@ public: WindowDisplayPlugin(); virtual const QString & getName(); - - virtual void activate(); - virtual void deactivate(); private: - QTimer _timer; }; diff --git a/libraries/plugins/CMakeLists.txt b/libraries/plugins/CMakeLists.txt index 9401f73174..28b136ccf4 100644 --- a/libraries/plugins/CMakeLists.txt +++ b/libraries/plugins/CMakeLists.txt @@ -1,7 +1,7 @@ set(TARGET_NAME plugins) # use setup_hifi_library macro to setup our project and link appropriate Qt modules -setup_hifi_library(OpenGL Network Qml Quick Script XmlPatterns) +setup_hifi_library(OpenGL) link_hifi_libraries(shared) diff --git a/libraries/plugins/src/Plugin.h b/libraries/plugins/src/Plugin.h deleted file mode 100644 index db01aa74ca..0000000000 --- a/libraries/plugins/src/Plugin.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include <QString> -#include <QObject> - -class PluginContainer; - -class Plugin : public QObject { -public: - virtual const QString& getName() = 0; - virtual bool isSupported() const { return true; } - - virtual void init() {} - virtual void deinit() {} - - virtual void activate(PluginContainer * container) {} - virtual void deactivate() {} - - virtual void idle() {} -}; diff --git a/libraries/plugins/src/plugins/Plugin.cpp b/libraries/plugins/src/plugins/Plugin.cpp new file mode 100644 index 0000000000..1910b525c2 --- /dev/null +++ b/libraries/plugins/src/plugins/Plugin.cpp @@ -0,0 +1,9 @@ +#include "Plugin.h" + +bool Plugin::isSupported() const { return true; } + +void Plugin::init() {} + +void Plugin::deinit() {} + +void Plugin::idle() {} diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h new file mode 100644 index 0000000000..6f55cb2b1d --- /dev/null +++ b/libraries/plugins/src/plugins/Plugin.h @@ -0,0 +1,29 @@ +#pragma once + +#include <QString> +#include <QObject> + +class PluginContainer; + +class Plugin : public QObject { +public: + virtual const QString& getName() = 0; + virtual bool isSupported() const; + + /// Called when plugin is initially loaded, typically at application start + virtual void init(); + /// Called when application is shutting down + virtual void deinit(); + + /// Called when a plugin is being activated for use. May be called multiple times. + virtual void activate(PluginContainer * container) = 0; + /// Called when a plugin is no longer being used. May be called multiple times. + virtual void deactivate() = 0; + + /** + * Called by the application during it's idle phase. If the plugin needs to do + * CPU intensive work, it should launch a thread for that, rather than trying to + * do long operations in the idle call + */ + virtual void idle(); +}; diff --git a/libraries/plugins/src/PluginContainer.h b/libraries/plugins/src/plugins/PluginContainer.h similarity index 100% rename from libraries/plugins/src/PluginContainer.h rename to libraries/plugins/src/plugins/PluginContainer.h diff --git a/interface/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp similarity index 100% rename from interface/src/plugins/PluginManager.cpp rename to libraries/plugins/src/plugins/PluginManager.cpp diff --git a/interface/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h similarity index 51% rename from interface/src/plugins/PluginManager.h rename to libraries/plugins/src/plugins/PluginManager.h index 2526490eea..653c7a616a 100644 --- a/interface/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -1,12 +1,10 @@ #pragma once -#include "plugins/Plugin.h" -#include "plugins/display/DisplayPlugin.h" +#include "Plugin.h" #include <QList> #include <QSharedPointer> class PluginManager : public QObject { public: static PluginManager * getInstance(); - const QList<QSharedPointer<DisplayPlugin>> getDisplayPlugins(); };