From 302aa9db47b4f44da478ab68c06e6587fc2add18 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sat, 2 May 2015 00:49:52 -0700 Subject: [PATCH 1/4] Removing access to the gl widget and display managers --- interface/src/Application.cpp | 125 ++++++++--- interface/src/Application.h | 31 ++- interface/src/Camera.cpp | 50 +---- interface/src/Camera.h | 18 -- interface/src/GLCanvas.cpp | 26 --- interface/src/audio/AudioToolBox.cpp | 31 ++- interface/src/audio/AudioToolBox.h | 7 +- interface/src/avatar/Avatar.cpp | 1 - interface/src/avatar/Head.cpp | 3 +- interface/src/avatar/MyAvatar.cpp | 51 +++-- interface/src/devices/OculusManager.cpp | 21 +- interface/src/devices/OculusManager.h | 3 +- interface/src/devices/SixenseManager.cpp | 1 - interface/src/devices/TV3DManager.cpp | 19 +- interface/src/main.cpp | 7 +- .../ControllerScriptingInterface.cpp | 3 +- .../src/scripting/HMDScriptingInterface.h | 1 - .../scripting/WindowScriptingInterface.cpp | 2 +- interface/src/ui/ApplicationOverlay.cpp | 204 +++++++++--------- interface/src/ui/ApplicationOverlay.h | 43 ++-- interface/src/ui/HMDToolsDialog.cpp | 2 - interface/src/ui/NodeBounds.cpp | 4 +- interface/src/ui/PreferencesDialog.cpp | 9 +- interface/src/ui/RearMirrorTools.cpp | 34 +-- interface/src/ui/RearMirrorTools.h | 19 +- interface/src/ui/Snapshot.cpp | 12 +- interface/src/ui/Snapshot.h | 6 +- interface/src/ui/Stats.cpp | 20 +- .../src/AbstractViewStateInterface.h | 2 +- libraries/render-utils/src/GlowEffect.cpp | 19 +- libraries/render-utils/src/GlowEffect.h | 6 +- libraries/render-utils/src/TextureCache.cpp | 41 ++-- libraries/render-utils/src/TextureCache.h | 9 +- libraries/shared/src/GLMHelpers.cpp | 4 + libraries/shared/src/GLMHelpers.h | 5 + 35 files changed, 400 insertions(+), 439 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d0d01f4534..0acb41c3c5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -801,7 +801,12 @@ void Application::initializeUi() { void Application::paintGL() { PROFILE_RANGE(__FUNCTION__); + _glWidget->makeCurrent(); PerformanceTimer perfTimer("paintGL"); + //Need accurate frame timing for the oculus rift + if (OculusManager::isConnected()) { + OculusManager::beginFrameTiming(); + } PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); @@ -847,11 +852,6 @@ void Application::paintGL() { glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); } - // Update camera position - if (!OculusManager::isConnected()) { - _myCamera.update(1.0f / _fps); - } - if (getShadowsEnabled()) { updateShadowMap(); } @@ -859,12 +859,10 @@ void Application::paintGL() { if (OculusManager::isConnected()) { //When in mirror mode, use camera rotation. Otherwise, use body rotation if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - OculusManager::display(_myCamera.getRotation(), _myCamera.getPosition(), _myCamera); + OculusManager::display(_glWidget, _myCamera.getRotation(), _myCamera.getPosition(), _myCamera); } else { - OculusManager::display(_myAvatar->getWorldAlignedOrientation(), _myAvatar->getDefaultEyePosition(), _myCamera); + OculusManager::display(_glWidget, _myAvatar->getWorldAlignedOrientation(), _myAvatar->getDefaultEyePosition(), _myCamera); } - _myCamera.update(1.0f / _fps); - } else if (TV3DManager::isConnected()) { TV3DManager::display(_myCamera); @@ -883,8 +881,7 @@ void Application::paintGL() { glPopMatrix(); if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { - _rearMirrorTools->render(true); - + _rearMirrorTools->render(true, _glWidget->mapFromGlobal(QCursor::pos())); } else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { renderRearViewMirror(_mirrorViewRect); } @@ -898,6 +895,13 @@ void Application::paintGL() { } } + if (!OculusManager::isConnected() || OculusManager::allowSwap()) { + _glWidget->swapBuffers(); + } + + if (OculusManager::isConnected()) { + OculusManager::endFrameTiming(); + } _frameCount++; } @@ -931,6 +935,7 @@ void Application::resetCamerasOnResizeGL(Camera& camera, int width, int height) } void Application::resizeGL(int width, int height) { + DependencyManager::get()->setFrameBufferSize(QSize(width, height)); resetCamerasOnResizeGL(_myCamera, width, height); glViewport(0, 0, width, height); // shouldn't this account for the menu??? @@ -1298,8 +1303,7 @@ void Application::keyPressEvent(QKeyEvent* event) { if (!event->isAutoRepeat()) { // this starts an HFActionEvent HFActionEvent startActionEvent(HFActionEvent::startType(), - _myCamera.computePickRay(getTrueMouseX(), - getTrueMouseY())); + computePickRay(getTrueMouseX(), getTrueMouseY())); sendEvent(this, &startActionEvent); } @@ -1404,8 +1408,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) { if (!event->isAutoRepeat()) { // this ends the HFActionEvent HFActionEvent endActionEvent(HFActionEvent::endType(), - _myCamera.computePickRay(getTrueMouseX(), - getTrueMouseY())); + computePickRay(getTrueMouseX(), getTrueMouseY())); sendEvent(this, &endActionEvent); } break; @@ -1499,7 +1502,7 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { // nobody handled this - make it an action event on the _window object HFActionEvent actionEvent(HFActionEvent::startType(), - _myCamera.computePickRay(event->x(), event->y())); + computePickRay(event->x(), event->y())); sendEvent(this, &actionEvent); } else if (event->button() == Qt::RightButton) { @@ -1534,7 +1537,7 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { // fire an action end event HFActionEvent actionEvent(HFActionEvent::endType(), - _myCamera.computePickRay(event->x(), event->y())); + computePickRay(event->x(), event->y())); sendEvent(this, &actionEvent); } } @@ -2104,19 +2107,16 @@ void Application::init() { _entityClipboardRenderer.setViewFrustum(getViewFrustum()); _entityClipboardRenderer.setTree(&_entityClipboard); - _rearMirrorTools = new RearMirrorTools(_glWidget, _mirrorViewRect); + _rearMirrorTools = new RearMirrorTools(_mirrorViewRect); connect(_rearMirrorTools, SIGNAL(closeView()), SLOT(closeMirrorView())); connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView())); connect(_rearMirrorTools, SIGNAL(shrinkView()), SLOT(shrinkMirrorView())); connect(_rearMirrorTools, SIGNAL(resetView()), SLOT(resetSensors())); - // make sure our texture cache knows about window size changes - DependencyManager::get()->associateWithWidget(_glWidget); - // initialize the GlowEffect with our widget - DependencyManager::get()->init(_glWidget, - Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)); + bool glow = Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect); + DependencyManager::get()->init(glow); } void Application::closeMirrorView() { @@ -2167,7 +2167,7 @@ void Application::updateMouseRay() { // make sure the frustum is up-to-date loadViewFrustum(_myCamera, _viewFrustum); - PickRay pickRay = _myCamera.computePickRay(getTrueMouseX(), getTrueMouseY()); + PickRay pickRay = computePickRay(getTrueMouseX(), getTrueMouseY()); _mouseRayOrigin = pickRay.origin; _mouseRayDirection = pickRay.direction; @@ -2979,8 +2979,17 @@ int Application::getBoundaryLevelAdjust() const { return DependencyManager::get()->getBoundaryLevelAdjust(); } -PickRay Application::computePickRay(float x, float y) { - return getCamera()->computePickRay(x, y); +PickRay Application::computePickRay(float x, float y) const { + glm::vec2 size = getCanvasSize(); + x /= size.x; + y /= size.y; + PickRay result; + if (isHMDMode()) { + ApplicationOverlay::computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction); + } else { + getViewFrustum()->computePickRay(x, y, result.origin, result.direction); + } + return result; } QImage Application::renderAvatarBillboard() { @@ -3013,6 +3022,16 @@ ViewFrustum* Application::getViewFrustum() { return &_viewFrustum; } +const ViewFrustum* Application::getViewFrustum() const { +#ifdef DEBUG + if (QThread::currentThread() == activeRenderingThread) { + // FIXME, should this be an assert? + qWarning() << "Calling Application::getViewFrustum() from the active rendering thread, did you mean Application::getDisplayViewFrustum()?"; + } +#endif + return &_viewFrustum; +} + ViewFrustum* Application::getDisplayViewFrustum() { #ifdef DEBUG if (QThread::currentThread() != activeRenderingThread) { @@ -3376,7 +3395,6 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { _mirrorCamera.setAspectRatio((float)region.width() / region.height()); _mirrorCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); - _mirrorCamera.update(1.0f/_fps); // set the bounds of rear mirror view if (billboard) { @@ -3402,7 +3420,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { glPopMatrix(); if (!billboard) { - _rearMirrorTools->render(false); + _rearMirrorTools->render(false, _glWidget->mapFromGlobal(QCursor::pos())); } // reset Viewport and projection matrix @@ -4283,7 +4301,7 @@ void Application::takeSnapshot() { player->setMedia(QUrl::fromLocalFile(inf.absoluteFilePath())); player->play(); - QString fileName = Snapshot::saveSnapshot(); + QString fileName = Snapshot::saveSnapshot(_glWidget->grabFrameBuffer()); AccountManager& accountManager = AccountManager::getInstance(); if (!accountManager.isLoggedIn()) { @@ -4471,3 +4489,52 @@ void Application::friendsWindowClosed() { void Application::postLambdaEvent(std::function f) { QCoreApplication::postEvent(this, new LambdaEvent(f)); } + +void Application::initPlugins() { + OculusManager::init(); +} + +void Application::shutdownPlugins() { + OculusManager::deinit(); +} + +glm::vec3 Application::getHeadPosition() const { + return OculusManager::getRelativePosition(); +} + + +glm::quat Application::getHeadOrientation() const { + return OculusManager::getOrientation(); +} + +glm::uvec2 Application::getCanvasSize() const { + return glm::uvec2(_glWidget->width(), _glWidget->height()); +} + +QSize Application::getDeviceSize() const { + return _glWidget->getDeviceSize(); +} + +int Application::getTrueMouseX() const { + return _glWidget->mapFromGlobal(QCursor::pos()).x(); +} + +int Application::getTrueMouseY() const { + return _glWidget->mapFromGlobal(QCursor::pos()).y(); +} + +bool Application::isThrottleRendering() const { + return _glWidget->isThrottleRendering(); +} + +PickRay Application::computePickRay() const { + return computePickRay(getTrueMouseX(), getTrueMouseY()); +} + +bool Application::hasFocus() const { + return _glWidget->hasFocus(); +} + +void Application::resizeGL() { + this->resizeGL(_glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); +} diff --git a/interface/src/Application.h b/interface/src/Application.h index 9f87d05711..027e0e20de 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -144,6 +144,8 @@ public: static glm::quat getOrientationForPath() { return getInstance()->_myAvatar->getOrientation(); } static glm::vec3 getPositionForAudio() { return getInstance()->_myAvatar->getHead()->getPosition(); } static glm::quat getOrientationForAudio() { return getInstance()->_myAvatar->getHead()->getFinalOrientationInWorldFrame(); } + static void initPlugins(); + static void shutdownPlugins(); Application(int& argc, char** argv, QElapsedTimer &startup_time); ~Application(); @@ -159,6 +161,8 @@ public: void paintGL(); void resizeGL(int width, int height); + void resizeEvent(QResizeEvent * size); + void keyPressEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event); @@ -180,12 +184,19 @@ public: bool event(QEvent* event); bool eventFilter(QObject* object, QEvent* event); - GLCanvas* getGLWidget() { return _glWidget; } - bool isThrottleRendering() const { return _glWidget->isThrottleRendering(); } + glm::uvec2 getCanvasSize() const; + QSize getDeviceSize() const; + bool hasFocus() const; + PickRay computePickRay() const; + PickRay computeViewPickRay(float xRatio, float yRatio) const; + void resizeGL(); + + bool isThrottleRendering() const; Camera* getCamera() { return &_myCamera; } // Represents the current view frustum of the avatar. ViewFrustum* getViewFrustum(); + const ViewFrustum* getViewFrustum() const; // Represents the view frustum of the current rendering pass, // which might be different from the viewFrustum, i.e. shadowmap // passes, mirror window passes, etc @@ -207,8 +218,9 @@ public: bool mouseOnScreen() const; int getMouseX() const; int getMouseY() const; - int getTrueMouseX() const { return _glWidget->mapFromGlobal(QCursor::pos()).x(); } - int getTrueMouseY() const { return _glWidget->mapFromGlobal(QCursor::pos()).y(); } + glm::ivec2 getTrueMousePosition() const; + int getTrueMouseX() const; + int getTrueMouseY() const; int getMouseDragStartedX() const; int getMouseDragStartedY() const; int getTrueMouseDragStartedX() const { return _mouseDragStartedX; } @@ -219,6 +231,7 @@ public: QSystemTrayIcon* getTrayIcon() { return _trayIcon; } ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; } + const ApplicationOverlay& getApplicationOverlay() const { return _applicationOverlay; } Overlays& getOverlays() { return _overlays; } float getFps() const { return _fps; } @@ -278,15 +291,15 @@ public: virtual QThread* getMainThread() { return thread(); } virtual float getSizeScale() const; virtual int getBoundaryLevelAdjust() const; - virtual PickRay computePickRay(float x, float y); + virtual PickRay computePickRay(float x, float y) const; virtual const glm::vec3& getAvatarPosition() const { return _myAvatar->getPosition(); } NodeBounds& getNodeBoundsDisplay() { return _nodeBoundsDisplay; } FileLogger* getLogger() { return _logger; } - glm::vec2 getViewportDimensions() const { return glm::vec2(_glWidget->getDeviceWidth(), - _glWidget->getDeviceHeight()); } + glm::vec2 getViewportDimensions() const; + NodeToJurisdictionMap& getEntityServerJurisdictions() { return _entityServerJurisdictions; } void skipVersion(QString latestVersion); @@ -308,7 +321,9 @@ public: // rendering of several elements depend on that // TODO: carry that information on the Camera as a setting bool isHMDMode() const; - + glm::quat getHeadOrientation() const; + glm::vec3 getHeadPosition() const; + QRect getDesirableApplicationGeometry(); RunningScriptsWidget* getRunningScriptsWidget() { return _runningScriptsWidget; } diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 6c6d165e7d..7db598bdfc 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -17,7 +17,6 @@ #include "Camera.h" #include "Menu.h" #include "Util.h" -#include "devices/OculusManager.h" CameraMode stringToMode(const QString& mode) { @@ -54,42 +53,24 @@ Camera::Camera() : _nearClip(DEFAULT_NEAR_CLIP), // default _farClip(DEFAULT_FAR_CLIP), // default _hmdPosition(), - _hmdRotation(), - _isKeepLookingAt(false), - _lookingAt(0.0f, 0.0f, 0.0f) + _hmdRotation() { } -void Camera::update(float deltaTime) { - if (_isKeepLookingAt) { - lookAt(_lookingAt); - } - return; -} - void Camera::setPosition(const glm::vec3& position) { _position = position; } void Camera::setRotation(const glm::quat& rotation) { _rotation = rotation; - if (_isKeepLookingAt) { - lookAt(_lookingAt); - } } void Camera::setHmdPosition(const glm::vec3& hmdPosition) { _hmdPosition = hmdPosition; - if (_isKeepLookingAt) { - lookAt(_lookingAt); - } } void Camera::setHmdRotation(const glm::quat& hmdRotation) { _hmdRotation = hmdRotation; - if (_isKeepLookingAt) { - lookAt(_lookingAt); - } } float Camera::getFarClip() const { @@ -120,21 +101,6 @@ void Camera::setFarClip(float f) { _farClip = f; } -PickRay Camera::computePickRay(float x, float y) { - auto glCanvas = Application::getInstance()->getGLWidget(); - return computeViewPickRay(x / glCanvas->width(), y / glCanvas->height()); -} - -PickRay Camera::computeViewPickRay(float xRatio, float yRatio) { - PickRay result; - if (OculusManager::isConnected()) { - Application::getInstance()->getApplicationOverlay().computeOculusPickRay(xRatio, yRatio, result.origin, result.direction); - } else { - Application::getInstance()->getViewFrustum()->computePickRay(xRatio, yRatio, result.origin, result.direction); - } - return result; -} - void Camera::setModeString(const QString& mode) { CameraMode targetMode = stringToMode(mode); @@ -163,17 +129,3 @@ void Camera::setModeString(const QString& mode) { QString Camera::getModeString() const { return modeToString(_mode); } - -void Camera::lookAt(const glm::vec3& lookAt) { - glm::vec3 up = IDENTITY_UP; - glm::mat4 lookAtMatrix = glm::lookAt(_position, lookAt, up); - glm::quat rotation = glm::quat_cast(lookAtMatrix); - rotation.w = -rotation.w; // Rosedale approved - _rotation = rotation; -} - -void Camera::keepLookingAt(const glm::vec3& point) { - lookAt(point); - _isKeepLookingAt = true; - _lookingAt = point; -} diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 10572d3513..b2eef3a8cb 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -41,8 +41,6 @@ public: void initialize(); // instantly put the camera at the ideal position and rotation. - void update( float deltaTime ); - void setRotation(const glm::quat& rotation); void setHmdPosition(const glm::vec3& hmdPosition); void setHmdRotation(const glm::quat& hmdRotation); @@ -75,20 +73,6 @@ public slots: void setOrientation(const glm::quat& orientation) { setRotation(orientation); } glm::quat getOrientation() const { return getRotation(); } - - PickRay computePickRay(float x, float y); - PickRay computeViewPickRay(float xRatio, float yRatio); - - // These only work on independent cameras - /// one time change to what the camera is looking at - void lookAt(const glm::vec3& value); - - /// fix what the camera is looking at, and keep the camera looking at this even if position changes - void keepLookingAt(const glm::vec3& value); - - /// stops the keep looking at feature, doesn't change what's being looked at, but will stop camera from - /// continuing to update it's orientation to keep looking at the item - void stopLooking() { _isKeepLookingAt = false; } signals: void modeUpdated(const QString& newMode); @@ -105,8 +89,6 @@ private: glm::quat _rotation; glm::vec3 _hmdPosition; glm::quat _hmdRotation; - bool _isKeepLookingAt; - glm::vec3 _lookingAt; }; #endif // hifi_Camera_h diff --git a/interface/src/GLCanvas.cpp b/interface/src/GLCanvas.cpp index 9a9512a0b0..f9dfda77ad 100644 --- a/interface/src/GLCanvas.cpp +++ b/interface/src/GLCanvas.cpp @@ -16,7 +16,6 @@ #include "Application.h" #include "GLCanvas.h" #include "MainWindow.h" -#include "devices/OculusManager.h" const int MSECS_PER_FRAME_WHEN_THROTTLED = 66; @@ -60,21 +59,7 @@ void GLCanvas::initializeGL() { void GLCanvas::paintGL() { if (!_throttleRendering && !Application::getInstance()->getWindow()->isMinimized()) { - //Need accurate frame timing for the oculus rift - if (OculusManager::isConnected()) { - OculusManager::beginFrameTiming(); - } - Application::getInstance()->paintGL(); - - if (!OculusManager::isConnected()) { - swapBuffers(); - } else { - if (OculusManager::allowSwap()) { - swapBuffers(); - } - OculusManager::endFrameTiming(); - } } } @@ -110,18 +95,7 @@ void GLCanvas::activeChanged(Qt::ApplicationState state) { void GLCanvas::throttleRender() { _frameTimer.start(_idleRenderInterval); if (!Application::getInstance()->getWindow()->isMinimized()) { - //Need accurate frame timing for the oculus rift - if (OculusManager::isConnected()) { - OculusManager::beginFrameTiming(); - } - - makeCurrent(); Application::getInstance()->paintGL(); - swapBuffers(); - - if (OculusManager::isConnected()) { - OculusManager::endFrameTiming(); - } } } diff --git a/interface/src/audio/AudioToolBox.cpp b/interface/src/audio/AudioToolBox.cpp index 330e7bc194..4a5c0a7610 100644 --- a/interface/src/audio/AudioToolBox.cpp +++ b/interface/src/audio/AudioToolBox.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "Application.h" #include "AudioToolBox.h" @@ -38,15 +39,14 @@ bool AudioToolBox::mousePressEvent(int x, int y) { void AudioToolBox::render(int x, int y, bool boxed) { glEnable(GL_TEXTURE_2D); - auto glCanvas = Application::getInstance()->getGLWidget(); - if (_micTextureId == 0) { - _micTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/mic.svg")); + if (!_micTexture) { + _micTexture = DependencyManager::get()->getImageTexture(PathUtils::resourcesPath() + "images/mic.svg"); } - if (_muteTextureId == 0) { - _muteTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/mic-mute.svg")); + if (!_muteTexture) { + _muteTexture = DependencyManager::get()->getImageTexture(PathUtils::resourcesPath() + "images/mic-mute.svg"); } - if (_boxTextureId == 0) { - _boxTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/audio-box.svg")); + if (_boxTexture) { + _boxTexture = DependencyManager::get()->getImageTexture(PathUtils::resourcesPath() + "images/audio-box.svg"); } auto audioIO = DependencyManager::get(); @@ -59,11 +59,8 @@ void AudioToolBox::render(int x, int y, bool boxed) { const int BOX_HEIGHT = 44; QRect boxBounds = QRect(x - BOX_LEFT_PADDING, y - BOX_TOP_PADDING, BOX_WIDTH, BOX_HEIGHT); - - glBindTexture(GL_TEXTURE_2D, _boxTextureId); - glm::vec4 quadColor; - + if (isClipping) { quadColor = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f); } else { @@ -71,9 +68,9 @@ void AudioToolBox::render(int x, int y, bool boxed) { } glm::vec2 topLeft(boxBounds.left(), boxBounds.top()); glm::vec2 bottomRight(boxBounds.right(), boxBounds.bottom()); - glm::vec2 texCoordTopLeft(1,1); - glm::vec2 texCoordBottomRight(0,0); - + static const glm::vec2 texCoordTopLeft(1,1); + static const glm::vec2 texCoordBottomRight(0, 0); + glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_boxTexture)); DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor); } @@ -81,10 +78,10 @@ void AudioToolBox::render(int x, int y, bool boxed) { _iconBounds = QRect(x, y, MUTE_ICON_SIZE, MUTE_ICON_SIZE); if (!audioIO->isMuted()) { - glBindTexture(GL_TEXTURE_2D, _micTextureId); + glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_micTexture)); iconColor = 1.0f; } else { - glBindTexture(GL_TEXTURE_2D, _muteTextureId); + glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_muteTexture)); // Make muted icon pulsate static const float PULSE_MIN = 0.4f; @@ -112,6 +109,6 @@ void AudioToolBox::render(int x, int y, bool boxed) { } DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor, _boxQuadID); - + glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); } \ No newline at end of file diff --git a/interface/src/audio/AudioToolBox.h b/interface/src/audio/AudioToolBox.h index 526de89b9c..d209b9930a 100644 --- a/interface/src/audio/AudioToolBox.h +++ b/interface/src/audio/AudioToolBox.h @@ -14,6 +14,7 @@ #include #include +#include class AudioToolBox : public Dependency { SINGLETON_DEPENDENCY @@ -24,9 +25,9 @@ public: protected: AudioToolBox(); private: - GLuint _micTextureId = 0; - GLuint _muteTextureId = 0; - GLuint _boxTextureId = 0; + gpu::TexturePointer _micTexture; + gpu::TexturePointer _muteTexture; + gpu::TexturePointer _boxTexture; int _boxQuadID = GeometryCache::UNKNOWN_ID; QRect _iconBounds; qint64 _iconPulseTimeReference = 0; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 05f834255c..ef21ea918d 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -45,7 +45,6 @@ #include "Recorder.h" #include "Util.h" #include "world.h" -#include "devices/OculusManager.h" #include "InterfaceLogging.h" using namespace std; diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 41c2e9b54c..08e5984d1d 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -22,7 +22,6 @@ #include "Util.h" #include "devices/DdeFaceTracker.h" #include "devices/Faceshift.h" -#include "devices/OculusManager.h" using namespace std; @@ -309,7 +308,7 @@ glm::quat Head::getCameraOrientation() const { // to change the driving direction while in Oculus mode. It is used to support driving toward where you're // head is looking. Note that in oculus mode, your actual camera view and where your head is looking is not // always the same. - if (OculusManager::isConnected()) { + if (qApp->isHMDMode()) { return getOrientation(); } Avatar* owningAvatar = static_cast(_owningAvatar); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 557d630ebf..db59633c4c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -42,7 +42,6 @@ #include "Physics.h" #include "Recorder.h" #include "devices/Faceshift.h" -#include "devices/OculusManager.h" #include "Util.h" #include "InterfaceLogging.h" @@ -230,12 +229,14 @@ void MyAvatar::simulate(float deltaTime) { void MyAvatar::updateFromTrackers(float deltaTime) { glm::vec3 estimatedPosition, estimatedRotation; - if (isPlaying() && !OculusManager::isConnected()) { + bool inHmd = qApp->isHMDMode(); + + if (isPlaying() && inHmd) { return; } - - if (OculusManager::isConnected()) { - estimatedPosition = OculusManager::getRelativePosition(); + + if (inHmd) { + estimatedPosition = qApp->getHeadPosition(); estimatedPosition.x *= -1.0f; _trackedHeadPosition = estimatedPosition; @@ -273,7 +274,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) { Head* head = getHead(); - if (OculusManager::isConnected() || isPlaying()) { + if (inHmd || isPlaying()) { head->setDeltaPitch(estimatedRotation.x); head->setDeltaYaw(estimatedRotation.y); } else { @@ -293,7 +294,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) { // NOTE: this is kinda a hack, it's the same hack we use to make the head tilt. But it's not really a mirror // it just makes you feel like you're looking in a mirror because the body movements of the avatar appear to // match your body movements. - if (OculusManager::isConnected() && Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) { + if (inHmd && Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) { relativePosition.x = -relativePosition.x; } @@ -882,8 +883,10 @@ void MyAvatar::updateLookAtTargetAvatar() { howManyLookingAtMe++; // Have that avatar look directly at my camera // Philip TODO: correct to look at left/right eye - if (OculusManager::isConnected()) { - avatar->getHead()->setCorrectedLookAtPosition(OculusManager::getLeftEyePosition()); + if (qApp->isHMDMode()) { + avatar->getHead()->setCorrectedLookAtPosition(Application::getInstance()->getViewFrustum()->getPosition()); + // FIXME what is the point of this? + // avatar->getHead()->setCorrectedLookAtPosition(OculusManager::getLeftEyePosition()); } else { avatar->getHead()->setCorrectedLookAtPosition(Application::getInstance()->getViewFrustum()->getPosition()); } @@ -1177,7 +1180,7 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode ren renderFrustum->setNearClip(DEFAULT_NEAR_CLIP); } else { float clipDistance = _skeletonModel.getHeadClipDistance(); - if (OculusManager::isConnected()) { + if (qApp->isHMDMode()) { // If avatar is horizontally in front of camera, increase clip distance by the amount it is in front. glm::vec3 cameraToAvatar = _position - cameraPos; cameraToAvatar.y = 0.0f; @@ -1221,7 +1224,7 @@ void MyAvatar::updateOrientation(float deltaTime) { // Gather rotation information from keyboard const float TIME_BETWEEN_HMD_TURNS = 0.5f; const float HMD_TURN_DEGREES = 22.5f; - if (!OculusManager::isConnected()) { + if (!qApp->isHMDMode()) { // Smoothly rotate body with arrow keys if not in HMD _bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_SPEED * deltaTime; _bodyYawDelta += _driveKeys[ROT_LEFT] * YAW_SPEED * deltaTime; @@ -1255,29 +1258,23 @@ void MyAvatar::updateOrientation(float deltaTime) { float MINIMUM_ROTATION_RATE = 2.0f; if (fabs(_bodyYawDelta) < MINIMUM_ROTATION_RATE) { _bodyYawDelta = 0.0f; } - if (OculusManager::isConnected()) { + if (qApp->isHMDMode()) { // these angles will be in radians - float yaw, pitch, roll; - OculusManager::getEulerAngles(yaw, pitch, roll); + glm::quat orientation = qApp->getHeadOrientation(); // ... so they need to be converted to degrees before we do math... - yaw *= DEGREES_PER_RADIAN; - pitch *= DEGREES_PER_RADIAN; - roll *= DEGREES_PER_RADIAN; - + glm::vec3 euler = glm::eulerAngles(orientation) * DEGREES_PER_RADIAN; + //Invert yaw and roll when in mirror mode - Head* head = getHead(); if (Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) { - head->setBaseYaw(-yaw); - head->setBasePitch(pitch); - head->setBaseRoll(-roll); - } else { - head->setBaseYaw(yaw); - head->setBasePitch(pitch); - head->setBaseRoll(roll); + YAW(euler) *= -1.0; + ROLL(euler) *= -1.0; } + Head* head = getHead(); + head->setBaseYaw(YAW(euler)); + head->setBasePitch(PITCH(euler)); + head->setBaseRoll(ROLL(euler)); } - } glm::vec3 MyAvatar::applyKeyboardMotor(float deltaTime, const glm::vec3& localVelocity, bool isHovering) { diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 7d719873f4..2d6141aac9 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -455,8 +455,7 @@ void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenH } //Displays everything for the oculus, frame timing must be active -void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &position, Camera& whichCamera) { - auto glCanvas = Application::getInstance()->getGLWidget(); +void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientation, const glm::vec3 &position, Camera& whichCamera) { #ifdef DEBUG // Ensure the frame counter always increments by exactly 1 @@ -593,7 +592,6 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p glm::vec3(_eyeRenderDesc[eye].HmdToEyeViewOffset.x, _eyeRenderDesc[eye].HmdToEyeViewOffset.y, _eyeRenderDesc[eye].HmdToEyeViewOffset.z)); _eyePositions[eye] = thisEyePosition; - _camera->update(1.0f / Application::getInstance()->getFps()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -617,7 +615,7 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p _camera->setEyeOffsetPosition(glm::vec3(-_eyeRenderDesc[eye].HmdToEyeViewOffset.x, -_eyeRenderDesc[eye].HmdToEyeViewOffset.y, -_eyeRenderDesc[eye].HmdToEyeViewOffset.z)); Application::getInstance()->displaySide(*_camera, false, RenderArgs::MONO); - applicationOverlay.displayOverlayTextureOculus(*_camera); + applicationOverlay.displayOverlayTextureHmd(*_camera); }); _activeEye = ovrEye_Count; @@ -638,7 +636,8 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p glPopMatrix(); // restore our normal viewport - glViewport(0, 0, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight()); + auto deviceSize = qApp->getDeviceSize(); + glViewport(0, 0, deviceSize.width(), deviceSize.height()); #if 0 if (debugFrame && !timerActive) { @@ -707,8 +706,8 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p void OculusManager::renderDistortionMesh(ovrPosef eyeRenderPose[ovrEye_Count]) { glLoadIdentity(); - auto glCanvas = Application::getInstance()->getGLWidget(); - glOrtho(0, glCanvas->getDeviceWidth(), 0, glCanvas->getDeviceHeight(), -1.0, 1.0); + auto deviceSize = qApp->getDeviceSize(); + glOrtho(0, deviceSize.width(), 0, deviceSize.height(), -1.0, 1.0); glDisable(GL_DEPTH_TEST); @@ -795,8 +794,12 @@ void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) { glm::vec3 OculusManager::getRelativePosition() { ovrTrackingState trackingState = ovrHmd_GetTrackingState(_ovrHmd, ovr_GetTimeInSeconds()); ovrVector3f headPosition = trackingState.HeadPose.ThePose.Position; - - return glm::vec3(headPosition.x, headPosition.y, headPosition.z); + return toGlm(trackingState.HeadPose.ThePose.Position); +} + +glm::quat OculusManager::getOrientation() { + ovrTrackingState trackingState = ovrHmd_GetTrackingState(_ovrHmd, ovr_GetTimeInSeconds()); + return toGlm(trackingState.HeadPose.ThePose.Orientation); } //Used to set the size of the glow framebuffers diff --git a/interface/src/devices/OculusManager.h b/interface/src/devices/OculusManager.h index 4b1bc98fb2..e41c6e8f9b 100644 --- a/interface/src/devices/OculusManager.h +++ b/interface/src/devices/OculusManager.h @@ -61,7 +61,7 @@ public: static void endFrameTiming(); static bool allowSwap(); static void configureCamera(Camera& camera, int screenWidth, int screenHeight); - static void display(const glm::quat &bodyOrientation, const glm::vec3 &position, Camera& whichCamera); + static void display(QGLWidget * glCanvas, const glm::quat &bodyOrientation, const glm::vec3 &position, Camera& whichCamera); static void reset(); /// param \yaw[out] yaw in radians @@ -69,6 +69,7 @@ public: /// param \roll[out] roll in radians static void getEulerAngles(float& yaw, float& pitch, float& roll); static glm::vec3 getRelativePosition(); + static glm::quat getOrientation(); static QSize getRenderTargetSize(); static void overrideOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal, diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 2b85a0906f..d74e210642 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -16,7 +16,6 @@ #include "Application.h" #include "SixenseManager.h" -#include "devices/OculusManager.h" #include "UserActivityLogger.h" #include "InterfaceLogging.h" diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index 05d89d5a6d..90030b2f84 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -33,12 +33,9 @@ bool TV3DManager::isConnected() { } void TV3DManager::connect() { - auto glCanvas = Application::getInstance()->getGLWidget(); - int width = glCanvas->getDeviceWidth(); - int height = glCanvas->getDeviceHeight(); Camera& camera = *Application::getInstance()->getCamera(); - - configureCamera(camera, width, height); + auto deviceSize = qApp->getDeviceSize(); + configureCamera(camera, deviceSize.width(), deviceSize.height()); } @@ -91,9 +88,8 @@ void TV3DManager::display(Camera& whichCamera) { // left eye portal int portalX = 0; int portalY = 0; - auto glCanvas = Application::getInstance()->getGLWidget(); - QSize deviceSize = glCanvas->getDeviceSize() * - Application::getInstance()->getRenderResolutionScale(); + QSize deviceSize = qApp->getDeviceSize() * + qApp->getRenderResolutionScale(); int portalW = deviceSize.width() / 2; int portalH = deviceSize.height(); @@ -122,8 +118,9 @@ void TV3DManager::display(Camera& whichCamera) { glLoadIdentity(); // reset projection matrix glFrustum(_leftEye.left, _leftEye.right, _leftEye.bottom, _leftEye.top, nearZ, farZ); // set left view frustum GLfloat p[4][4]; + // Really? glGetFloatv(GL_PROJECTION_MATRIX, &(p[0][0])); - GLfloat cotangent = p[1][1]; + float cotangent = p[1][1]; GLfloat fov = atan(1.0f / cotangent); glTranslatef(_leftEye.modelTranslation, 0.0, 0.0); // translate to cancel parallax @@ -132,7 +129,7 @@ void TV3DManager::display(Camera& whichCamera) { eyeCamera.setEyeOffsetPosition(glm::vec3(-_activeEye->modelTranslation,0,0)); Application::getInstance()->displaySide(eyeCamera, false, RenderArgs::MONO); - applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); + applicationOverlay.displayOverlayTextureStereo(whichCamera, _aspect, fov); _activeEye = NULL; } glPopMatrix(); @@ -161,7 +158,7 @@ void TV3DManager::display(Camera& whichCamera) { eyeCamera.setEyeOffsetPosition(glm::vec3(-_activeEye->modelTranslation,0,0)); Application::getInstance()->displaySide(eyeCamera, false, RenderArgs::MONO); - applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); + applicationOverlay.displayOverlayTextureStereo(whichCamera, _aspect, fov); _activeEye = NULL; } glPopMatrix(); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 7112944375..ae1b93959f 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -18,7 +18,6 @@ #include "AddressManager.h" #include "Application.h" -#include "devices/OculusManager.h" #include "InterfaceLogging.h" #ifdef Q_OS_WIN @@ -97,8 +96,8 @@ int main(int argc, const char* argv[]) { // 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. - OculusManager::init(); - + Application::initPlugins(); + int exitCode; { QSettings::setDefaultFormat(QSettings::IniFormat); @@ -112,7 +111,7 @@ int main(int argc, const char* argv[]) { exitCode = app.exec(); } - OculusManager::deinit(); + Application::shutdownPlugins(); #ifdef Q_OS_WIN ReleaseMutex(mutex); #endif diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 7d6012c880..5f12d73b37 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -286,8 +286,7 @@ void ControllerScriptingInterface::releaseJoystick(int joystickIndex) { } glm::vec2 ControllerScriptingInterface::getViewportDimensions() const { - auto glCanvas = Application::getInstance()->getGLWidget(); - return glm::vec2(glCanvas->width(), glCanvas->height()); + return Application::getInstance()->getCanvasSize(); } AbstractInputController* ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) { diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index bcd458ca5e..9b0f8dc4d1 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -15,7 +15,6 @@ #include #include "Application.h" -#include "devices/OculusManager.h" class HMDScriptingInterface : public QObject { Q_OBJECT diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index bd2903863d..3aae6a4d4a 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -41,7 +41,7 @@ WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& title } QScriptValue WindowScriptingInterface::hasFocus() { - return Application::getInstance()->getGLWidget()->hasFocus(); + return Application::getInstance()->hasFocus(); } void WindowScriptingInterface::setFocus() { diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 8704a61261..7733720a8a 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -12,10 +12,13 @@ #include "InterfaceConfig.h" #include +#include #include #include #include +#include +#include #include #include @@ -25,7 +28,6 @@ #include "audio/AudioToolBox.h" #include "Application.h" #include "ApplicationOverlay.h" -#include "devices/OculusManager.h" #include "Util.h" #include "ui/Stats.h" @@ -45,7 +47,7 @@ const float CONNECTION_STATUS_BORDER_LINE_WIDTH = 4.0f; static const float MOUSE_PITCH_RANGE = 1.0f * PI; static const float MOUSE_YAW_RANGE = 0.5f * TWO_PI; - +static const glm::vec2 MOUSE_RANGE(MOUSE_YAW_RANGE, MOUSE_PITCH_RANGE); // Return a point's cartesian coordinates on a sphere from pitch and yaw glm::vec3 getPoint(float yaw, float pitch) { @@ -133,7 +135,7 @@ void ApplicationOverlay::renderReticle(glm::quat orientation, float alpha) { } ApplicationOverlay::ApplicationOverlay() : - _textureFov(glm::radians(DEFAULT_OCULUS_UI_ANGULAR_SIZE)), + _textureFov(glm::radians(DEFAULT_HMD_UI_ANGULAR_SIZE)), _textureAspectRatio(1.0f), _lastMouseMove(0), _magnifier(true), @@ -185,10 +187,10 @@ ApplicationOverlay::~ApplicationOverlay() { void ApplicationOverlay::renderOverlay() { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()"); Overlays& overlays = qApp->getOverlays(); - auto glCanvas = Application::getInstance()->getGLWidget(); - _textureFov = glm::radians(_oculusUIAngularSize); - _textureAspectRatio = (float)glCanvas->getDeviceWidth() / (float)glCanvas->getDeviceHeight(); + _textureFov = glm::radians(_hmdUIAngularSize); + auto deviceSize = Application::getInstance()->getDeviceSize(); + _textureAspectRatio = (float)deviceSize.width() / (float)deviceSize.height(); //Handle fading and deactivation/activation of UI @@ -201,12 +203,12 @@ void ApplicationOverlay::renderOverlay() { _overlays.buildFramebufferObject(); _overlays.bind(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - + glPushMatrix(); { const float NEAR_CLIP = -10000; const float FAR_CLIP = 10000; glLoadIdentity(); - glOrtho(0, glCanvas->width(), glCanvas->height(), 0, NEAR_CLIP, FAR_CLIP); + glOrtho(0, deviceSize.width(), deviceSize.height(), 0, NEAR_CLIP, FAR_CLIP); glMatrixMode(GL_MODELVIEW); @@ -278,7 +280,7 @@ void ApplicationOverlay::displayOverlayTexture() { } // Draws the FBO texture for Oculus rift. -void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) { +void ApplicationOverlay::displayOverlayTextureHmd(Camera& whichCamera) { if (_alpha == 0.0f) { return; } @@ -356,7 +358,7 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) { } // Draws the FBO texture for 3DTV. -void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float aspectRatio, float fov) { +void ApplicationOverlay::displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov) { if (_alpha == 0.0f) { return; } @@ -411,19 +413,19 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as overlayColor); }); - auto glCanvas = Application::getInstance()->getGLWidget(); - if (_crosshairTexture == 0) { - _crosshairTexture = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/sixense-reticle.png")); + if (!_crosshairTexture) { + _crosshairTexture = DependencyManager::get()-> + getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png"); } //draw the mouse pointer - glBindTexture(GL_TEXTURE_2D, _crosshairTexture); - - const float reticleSize = 40.0f / glCanvas->width() * quadWidth; + glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture)); + glm::vec2 canvasSize = qApp->getCanvasSize(); + const float reticleSize = 40.0f / canvasSize.x * quadWidth; x -= reticleSize / 2.0f; y += reticleSize / 2.0f; - const float mouseX = (qApp->getMouseX() / (float)glCanvas->width()) * quadWidth; - const float mouseY = (1.0 - (qApp->getMouseY() / (float)glCanvas->height())) * quadHeight; + const float mouseX = (qApp->getMouseX() / (float)canvasSize.x) * quadWidth; + const float mouseY = (1.0 - (qApp->getMouseY() / (float)canvasSize.y)) * quadHeight; glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f }; @@ -447,24 +449,23 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as glEnable(GL_LIGHTING); } -void ApplicationOverlay::computeOculusPickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const { +void ApplicationOverlay::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origin, glm::vec3& direction) { const MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); - const float pitch = (0.5f - y) * MOUSE_PITCH_RANGE; - const float yaw = (0.5f - x) * MOUSE_YAW_RANGE; - const glm::quat orientation(glm::vec3(pitch, yaw, 0.0f)); + cursorPos = 0.5f - cursorPos; + cursorPos *= MOUSE_RANGE; + const glm::quat orientation(glm::vec3(cursorPos, 0.0f)); const glm::vec3 localDirection = orientation * IDENTITY_FRONT; // Get cursor position - const glm::vec3 cursorPos = myAvatar->getDefaultEyePosition() + myAvatar->getOrientation() * localDirection; + const glm::vec3 cursorDir = myAvatar->getDefaultEyePosition() + myAvatar->getOrientation() * localDirection; // Ray start where the eye position is and stop where the cursor is origin = myAvatar->getEyePosition(); - direction = cursorPos - origin; + direction = cursorDir - origin; } //Caculate the click location using one of the sixense controllers. Scale is not applied QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const { - auto glCanvas = Application::getInstance()->getGLWidget(); MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); glm::vec3 tip = myAvatar->getLaserPointerTipPosition(palm); @@ -475,8 +476,8 @@ QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const { glm::vec3 tipPos = invOrientation * (tip - eyePos); QPoint rv; - - if (OculusManager::isConnected()) { + auto canvasSize = qApp->getCanvasSize(); + if (qApp->isHMDMode()) { float t; //We back the ray up by dir to ensure that it will not start inside the UI. @@ -495,8 +496,8 @@ QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const { float u = asin(collisionPos.x) / (_textureFov)+0.5f; float v = 1.0 - (asin(collisionPos.y) / (_textureFov)+0.5f); - rv.setX(u * glCanvas->width()); - rv.setY(v * glCanvas->height()); + rv.setX(u * canvasSize.x); + rv.setY(v * canvasSize.y); } } else { //if they did not click on the overlay, just set the coords to INT_MAX @@ -513,8 +514,8 @@ QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const { ndcSpacePos = glm::vec3(clipSpacePos) / clipSpacePos.w; } - rv.setX(((ndcSpacePos.x + 1.0) / 2.0) * glCanvas->width()); - rv.setY((1.0 - ((ndcSpacePos.y + 1.0) / 2.0)) * glCanvas->height()); + rv.setX(((ndcSpacePos.x + 1.0) / 2.0) * canvasSize.x); + rv.setY((1.0 - ((ndcSpacePos.y + 1.0) / 2.0)) * canvasSize.y); } return rv; } @@ -539,18 +540,17 @@ bool ApplicationOverlay::calculateRayUICollisionPoint(const glm::vec3& position, //Renders optional pointers void ApplicationOverlay::renderPointers() { - auto glCanvas = Application::getInstance()->getGLWidget(); - //lazily load crosshair texture if (_crosshairTexture == 0) { - _crosshairTexture = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/sixense-reticle.png")); + _crosshairTexture = DependencyManager::get()-> + getImageTexture(PathUtils::resourcesPath() + "images/sixense-reticle.png"); } glEnable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, _crosshairTexture); - - if (OculusManager::isConnected() && !qApp->getLastMouseMoveWasSimulated() && !qApp->isMouseHidden()) { + glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture)); + + if (qApp->isHMDMode() && !qApp->getLastMouseMoveWasSimulated() && !qApp->isMouseHidden()) { //If we are in oculus, render reticle later if (_lastMouseMove == 0) { _lastMouseMove = usecTimestampNow(); @@ -561,9 +561,9 @@ void ApplicationOverlay::renderPointers() { if (_reticlePosition[MOUSE] != position) { _lastMouseMove = usecTimestampNow(); } else if (usecTimestampNow() - _lastMouseMove > MAX_IDLE_TIME * USECS_PER_SECOND) { - float pitch = 0.0f, yaw = 0.0f, roll = 0.0f; // radians - OculusManager::getEulerAngles(yaw, pitch, roll); - glm::quat orientation(glm::vec3(pitch, yaw, roll)); + //float pitch = 0.0f, yaw = 0.0f, roll = 0.0f; // radians + //OculusManager::getEulerAngles(yaw, pitch, roll); + glm::quat orientation = qApp->getHeadOrientation(); // (glm::vec3(pitch, yaw, roll)); glm::vec3 result; MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); @@ -574,7 +574,8 @@ void ApplicationOverlay::renderPointers() { glm::vec2 spericalPos = directionToSpherical(glm::normalize(lookAtDirection)); glm::vec2 screenPos = sphericalToScreen(spericalPos); position = QPoint(screenPos.x, screenPos.y); - glCanvas->cursor().setPos(glCanvas->mapToGlobal(position)); + // FIXME + //glCanvas->cursor().setPos(glCanvas->mapToGlobal(position)); } else { qDebug() << "No collision point"; } @@ -597,7 +598,6 @@ void ApplicationOverlay::renderPointers() { } void ApplicationOverlay::renderControllerPointers() { - auto glCanvas = Application::getInstance()->getGLWidget(); MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); //Static variables used for storing controller state @@ -646,7 +646,7 @@ void ApplicationOverlay::renderControllerPointers() { //if we have the oculus, we should make the cursor smaller since it will be //magnified - if (OculusManager::isConnected()) { + if (qApp->isHMDMode()) { QPoint point = getPalmClickLocation(palmData); @@ -661,6 +661,7 @@ void ApplicationOverlay::renderControllerPointers() { continue; } + auto canvasSize = qApp->getCanvasSize(); int mouseX, mouseY; if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) { QPoint res = getPalmClickLocation(palmData); @@ -675,14 +676,14 @@ void ApplicationOverlay::renderControllerPointers() { float yAngle = 0.5f - ((atan2(direction.z, direction.y) + M_PI_2)); // Get the pixel range over which the xAngle and yAngle are scaled - float cursorRange = glCanvas->width() * SixenseManager::getInstance().getCursorPixelRangeMult(); + float cursorRange = canvasSize.x * SixenseManager::getInstance().getCursorPixelRangeMult(); - mouseX = (glCanvas->width() / 2.0f + cursorRange * xAngle); - mouseY = (glCanvas->height() / 2.0f + cursorRange * yAngle); + mouseX = (canvasSize.x / 2.0f + cursorRange * xAngle); + mouseY = (canvasSize.y / 2.0f + cursorRange * yAngle); } //If the cursor is out of the screen then don't render it - if (mouseX < 0 || mouseX >= glCanvas->width() || mouseY < 0 || mouseY >= glCanvas->height()) { + if (mouseX < 0 || mouseX >= canvasSize.x || mouseY < 0 || mouseY >= canvasSize.y) { _reticleActive[index] = false; continue; } @@ -707,7 +708,7 @@ void ApplicationOverlay::renderControllerPointers() { } void ApplicationOverlay::renderPointersOculus(const glm::vec3& eyePos) { - glBindTexture(GL_TEXTURE_2D, _crosshairTexture); + glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture)); glDisable(GL_DEPTH_TEST); glMatrixMode(GL_MODELVIEW); @@ -744,10 +745,10 @@ void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool if (!_magnifier) { return; } - auto glCanvas = Application::getInstance()->getGLWidget(); + auto canvasSize = qApp->getCanvasSize(); - const int widgetWidth = glCanvas->width(); - const int widgetHeight = glCanvas->height(); + const int widgetWidth = canvasSize.x; + const int widgetHeight = canvasSize.y; const float halfWidth = (MAGNIFY_WIDTH / _textureAspectRatio) * sizeMult / 2.0f; const float halfHeight = MAGNIFY_HEIGHT * sizeMult / 2.0f; @@ -809,7 +810,6 @@ void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool } void ApplicationOverlay::renderAudioMeter() { - auto glCanvas = Application::getInstance()->getGLWidget(); auto audio = DependencyManager::get(); // Audio VU Meter and Mute Icon @@ -822,7 +822,7 @@ void ApplicationOverlay::renderAudioMeter() { const int AUDIO_METER_X = MIRROR_VIEW_LEFT_PADDING + MUTE_ICON_SIZE + AUDIO_METER_GAP; int audioMeterY; - bool smallMirrorVisible = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && !OculusManager::isConnected(); + bool smallMirrorVisible = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && !qApp->isHMDMode(); bool boxed = smallMirrorVisible && !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror); if (boxed) { @@ -857,16 +857,17 @@ void ApplicationOverlay::renderAudioMeter() { } bool isClipping = ((audio->getTimeSinceLastClip() > 0.0f) && (audio->getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)); + auto canvasSize = qApp->getCanvasSize(); if ((audio->getTimeSinceLastClip() > 0.0f) && (audio->getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)) { const float MAX_MAGNITUDE = 0.7f; float magnitude = MAX_MAGNITUDE * (1 - audio->getTimeSinceLastClip() / CLIPPING_INDICATOR_TIME); - renderCollisionOverlay(glCanvas->width(), glCanvas->height(), magnitude, 1.0f); + renderCollisionOverlay(canvasSize.x, canvasSize.y, magnitude, 1.0f); } DependencyManager::get()->render(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, audioMeterY, boxed); - DependencyManager::get()->render(glCanvas->width(), glCanvas->height()); - DependencyManager::get()->render(WHITE_TEXT, glCanvas->width(), glCanvas->height()); + DependencyManager::get()->render(canvasSize.x, canvasSize.y); + DependencyManager::get()->render(WHITE_TEXT, canvasSize.x, canvasSize.y); audioMeterY += AUDIO_METER_HEIGHT; @@ -927,7 +928,6 @@ void ApplicationOverlay::renderStatsAndLogs() { Application* application = Application::getInstance(); QSharedPointer bandwidthRecorder = DependencyManager::get(); - auto glCanvas = Application::getInstance()->getGLWidget(); const OctreePacketProcessor& octreePacketProcessor = application->getOctreePacketProcessor(); NodeBounds& nodeBoundsDisplay = application->getNodeBoundsDisplay(); @@ -950,12 +950,13 @@ void ApplicationOverlay::renderStatsAndLogs() { // Show on-screen msec timer if (Menu::getInstance()->isOptionChecked(MenuOption::FrameTimer)) { + auto canvasSize = qApp->getCanvasSize(); quint64 mSecsNow = floor(usecTimestampNow() / 1000.0 + 0.5); QString frameTimer = QString("%1\n").arg((int)(mSecsNow % 1000)); int timerBottom = (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) ? 80 : 20; - drawText(glCanvas->width() - 100, glCanvas->height() - timerBottom, + drawText(canvasSize.x - 100, canvasSize.y - timerBottom, 0.30f, 0.0f, 0, frameTimer.toUtf8().constData(), WHITE_TEXT); } nodeBoundsDisplay.drawOverlay(); @@ -965,25 +966,22 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() { auto nodeList = DependencyManager::get(); if (nodeList && !nodeList->getDomainHandler().isConnected()) { - auto glCanvas = Application::getInstance()->getGLWidget(); auto geometryCache = DependencyManager::get(); - int width = glCanvas->width(); - int height = glCanvas->height(); - - if (width != _previousBorderWidth || height != _previousBorderHeight) { + auto canvasSize = qApp->getCanvasSize(); + if (canvasSize.x != _previousBorderWidth || canvasSize.y != _previousBorderHeight) { glm::vec4 color(CONNECTION_STATUS_BORDER_COLOR[0], CONNECTION_STATUS_BORDER_COLOR[1], CONNECTION_STATUS_BORDER_COLOR[2], 1.0f); QVector border; border << glm::vec2(0, 0); - border << glm::vec2(0, height); - border << glm::vec2(width, height); - border << glm::vec2(width, 0); + border << glm::vec2(0, canvasSize.y); + border << glm::vec2(canvasSize.x, canvasSize.y); + border << glm::vec2(canvasSize.x, 0); border << glm::vec2(0, 0); geometryCache->updateVertices(_domainStatusBorder, border, color); - _previousBorderWidth = width; - _previousBorderHeight = height; + _previousBorderWidth = canvasSize.x; + _previousBorderHeight = canvasSize.y; } glLineWidth(CONNECTION_STATUS_BORDER_LINE_WIDTH); @@ -1101,8 +1099,8 @@ void ApplicationOverlay::TexturedHemisphere::cleanupVBO() { } void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() { - QSize size = Application::getInstance()->getGLWidget()->getDeviceSize(); - if (_framebufferObject != NULL && size == _framebufferObject->size()) { + auto deviceSize = qApp->getDeviceSize(); + if (_framebufferObject != NULL && deviceSize == _framebufferObject->size()) { // Already build return; } @@ -1111,7 +1109,7 @@ void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() { delete _framebufferObject; } - _framebufferObject = new QOpenGLFramebufferObject(size, QOpenGLFramebufferObject::Depth); + _framebufferObject = new QOpenGLFramebufferObject(deviceSize, QOpenGLFramebufferObject::Depth); glBindTexture(GL_TEXTURE_2D, getTexture()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -1154,7 +1152,7 @@ GLuint ApplicationOverlay::TexturedHemisphere::getTexture() { return _framebufferObject->texture(); } -glm::vec2 ApplicationOverlay::directionToSpherical(glm::vec3 direction) const { +glm::vec2 ApplicationOverlay::directionToSpherical(const glm::vec3& direction) { glm::vec2 result; // Compute yaw glm::vec3 normalProjection = glm::normalize(glm::vec3(direction.x, 0.0f, direction.z)); @@ -1170,47 +1168,57 @@ glm::vec2 ApplicationOverlay::directionToSpherical(glm::vec3 direction) const { return result; } -glm::vec3 ApplicationOverlay::sphericalToDirection(glm::vec2 sphericalPos) const { +glm::vec3 ApplicationOverlay::sphericalToDirection(const glm::vec2& sphericalPos) { glm::quat rotation(glm::vec3(sphericalPos.y, sphericalPos.x, 0.0f)); return rotation * IDENTITY_FRONT; } -glm::vec2 ApplicationOverlay::screenToSpherical(glm::vec2 screenPos) const { - QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize(); - float yaw = -(screenPos.x / screenSize.width() - 0.5f) * MOUSE_YAW_RANGE; - float pitch = (screenPos.y / screenSize.height() - 0.5f) * MOUSE_PITCH_RANGE; +glm::vec2 ApplicationOverlay::screenToSpherical(const glm::vec2& screenPos) { + auto screenSize = qApp->getCanvasSize(); + glm::vec2 result; + result.x = -(screenPos.x / screenSize.x - 0.5f); + result.y = (screenPos.y / screenSize.y - 0.5f); + result.x *= MOUSE_YAW_RANGE; + result.y *= MOUSE_PITCH_RANGE; - return glm::vec2(yaw, pitch); + return result; } -glm::vec2 ApplicationOverlay::sphericalToScreen(glm::vec2 sphericalPos) const { - QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize(); - float x = (-sphericalPos.x / MOUSE_YAW_RANGE + 0.5f) * screenSize.width(); - float y = (sphericalPos.y / MOUSE_PITCH_RANGE + 0.5f) * screenSize.height(); - - return glm::vec2(x, y); +glm::vec2 ApplicationOverlay::sphericalToScreen(const glm::vec2& sphericalPos) { + glm::vec2 result = sphericalPos; + result.x *= -1.0; + result /= MOUSE_RANGE; + result += 0.5f; + result *= qApp->getCanvasSize(); + return result; } -glm::vec2 ApplicationOverlay::sphericalToOverlay(glm::vec2 sphericalPos) const { - QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize(); - float x = (-sphericalPos.x / (_textureFov * _textureAspectRatio) + 0.5f) * screenSize.width(); - float y = (sphericalPos.y / _textureFov + 0.5f) * screenSize.height(); - - return glm::vec2(x, y); +glm::vec2 ApplicationOverlay::sphericalToOverlay(const glm::vec2& sphericalPos) const { + glm::vec2 result = sphericalPos; + result.x *= -1.0; + result /= _textureFov; + result.x /= _textureAspectRatio; + result += 0.5f; + result.x = (-sphericalPos.x / (_textureFov * _textureAspectRatio) + 0.5f); + result.y = (sphericalPos.y / _textureFov + 0.5f); + result *= qApp->getCanvasSize(); + return result; } -glm::vec2 ApplicationOverlay::overlayToSpherical(glm::vec2 overlayPos) const { - QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize(); - float yaw = -(overlayPos.x / screenSize.width() - 0.5f) * _textureFov * _textureAspectRatio; - float pitch = (overlayPos.y / screenSize.height() - 0.5f) * _textureFov; - - return glm::vec2(yaw, pitch); +glm::vec2 ApplicationOverlay::overlayToSpherical(const glm::vec2& overlayPos) const { + glm::vec2 result = overlayPos; + result.x *= -1.0; + result /= qApp->getCanvasSize(); + result -= 0.5f; + result *= _textureFov; + result.x *= _textureAspectRatio; + return result; } -glm::vec2 ApplicationOverlay::screenToOverlay(glm::vec2 screenPos) const { +glm::vec2 ApplicationOverlay::screenToOverlay(const glm::vec2& screenPos) const { return sphericalToOverlay(screenToSpherical(screenPos)); } -glm::vec2 ApplicationOverlay::overlayToScreen(glm::vec2 overlayPos) const { +glm::vec2 ApplicationOverlay::overlayToScreen(const glm::vec2& overlayPos) const { return sphericalToScreen(overlayToSpherical(overlayPos)); } diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index e6c7526c5d..aa9cae9b3a 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -12,6 +12,7 @@ #ifndef hifi_ApplicationOverlay_h #define hifi_ApplicationOverlay_h +#include class Camera; class Overlays; class QOpenGLFramebufferObject; @@ -20,9 +21,11 @@ const float MAGNIFY_WIDTH = 220.0f; const float MAGNIFY_HEIGHT = 100.0f; const float MAGNIFY_MULT = 2.0f; -const float DEFAULT_OCULUS_UI_ANGULAR_SIZE = 72.0f; +const float DEFAULT_HMD_UI_ANGULAR_SIZE = 72.0f; // Handles the drawing of the overlays to the screen +// TODO, move divide up the rendering, displaying and input handling +// facilities of this class class ApplicationOverlay : public QObject { Q_OBJECT public: @@ -31,19 +34,18 @@ public: void renderOverlay(); void displayOverlayTexture(); - void displayOverlayTextureOculus(Camera& whichCamera); - void displayOverlayTexture3DTV(Camera& whichCamera, float aspectRatio, float fov); - - void computeOculusPickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const; + void displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov); + void displayOverlayTextureHmd(Camera& whichCamera); + QPoint getPalmClickLocation(const PalmData *palm) const; bool calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const; bool hasMagnifier() const { return _magnifier; } void toggleMagnifier() { _magnifier = !_magnifier; } - float getOculusUIAngularSize() const { return _oculusUIAngularSize; } - void setOculusUIAngularSize(float oculusUIAngularSize) { _oculusUIAngularSize = oculusUIAngularSize; } - + float getHmdUIAngularSize() const { return _hmdUIAngularSize; } + void setHmdUIAngularSize(float hmdUIAngularSize) { _hmdUIAngularSize = hmdUIAngularSize; } + // Converter from one frame of reference to another. // Frame of reference: // Direction: Ray that represents the spherical values @@ -52,14 +54,16 @@ public: // Overlay: Position on the overlay (x,y) // (x,y) in Overlay are similar than (x,y) in Screen except they can be outside of the bound of te screen. // This allows for picking outside of the screen projection in 3D. - glm::vec2 directionToSpherical(glm::vec3 direction) const; - glm::vec3 sphericalToDirection(glm::vec2 sphericalPos) const; - glm::vec2 screenToSpherical(glm::vec2 screenPos) const; - glm::vec2 sphericalToScreen(glm::vec2 sphericalPos) const; - glm::vec2 sphericalToOverlay(glm::vec2 sphericalPos) const; - glm::vec2 overlayToSpherical(glm::vec2 overlayPos) const; - glm::vec2 screenToOverlay(glm::vec2 screenPos) const; - glm::vec2 overlayToScreen(glm::vec2 overlayPos) const; + glm::vec2 sphericalToOverlay(const glm::vec2 & sphericalPos) const; + glm::vec2 overlayToSpherical(const glm::vec2 & overlayPos) const; + glm::vec2 screenToOverlay(const glm::vec2 & screenPos) const; + glm::vec2 overlayToScreen(const glm::vec2 & overlayPos) const; + + static glm::vec2 directionToSpherical(const glm::vec3 & direction); + static glm::vec3 sphericalToDirection(const glm::vec2 & sphericalPos); + static glm::vec2 screenToSpherical(const glm::vec2 & screenPos); + static glm::vec2 sphericalToScreen(const glm::vec2 & sphericalPos); + static void computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origin, glm::vec3& direction); private: // Interleaved vertex data @@ -91,7 +95,7 @@ private: VerticesIndices _vbo; }; - float _oculusUIAngularSize = DEFAULT_OCULUS_UI_ANGULAR_SIZE; + float _hmdUIAngularSize = DEFAULT_HMD_UI_ANGULAR_SIZE; void renderReticle(glm::quat orientation, float alpha); void renderPointers();; @@ -121,9 +125,8 @@ private: float _oculusUIRadius; float _trailingAudioLoudness; - GLuint _crosshairTexture; - // TODO, move divide up the rendering, displaying and input handling - // facilities of this class + + gpu::TexturePointer _crosshairTexture; GLuint _newUiTexture{ 0 }; int _reticleQuad; diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index 4a899a641e..231ffa6ed4 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -19,12 +19,10 @@ #include #include - #include "MainWindow.h" #include "Menu.h" #include "ui/DialogsManager.h" #include "ui/HMDToolsDialog.h" - #include "devices/OculusManager.h" HMDToolsDialog::HMDToolsDialog(QWidget* parent) : diff --git a/interface/src/ui/NodeBounds.cpp b/interface/src/ui/NodeBounds.cpp index f0f4d432db..2b1b2f56e1 100644 --- a/interface/src/ui/NodeBounds.cpp +++ b/interface/src/ui/NodeBounds.cpp @@ -38,9 +38,7 @@ void NodeBounds::draw() { // Compute ray to find selected nodes later on. We can't use the pre-computed ray in Application because it centers // itself after the cursor disappears. - Application* application = Application::getInstance(); - PickRay pickRay = application->getCamera()->computePickRay(application->getTrueMouseX(), - application->getTrueMouseY()); + PickRay pickRay = qApp->computePickRay(); // Variables to keep track of the selected node and properties to draw the cube later if needed Node* selectedNode = NULL; diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 98f7382097..ac436cbb10 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -170,7 +170,7 @@ void PreferencesDialog::loadPreferences() { ui.maxOctreePPSSpin->setValue(qApp->getOctreeQuery().getMaxOctreePacketsPerSecond()); - ui.oculusUIAngularSizeSpin->setValue(qApp->getApplicationOverlay().getOculusUIAngularSize()); + ui.oculusUIAngularSizeSpin->setValue(qApp->getApplicationOverlay().getHmdUIAngularSize()); SixenseManager& sixense = SixenseManager::getInstance(); ui.sixenseReticleMoveSpeedSpin->setValue(sixense.getReticleMoveSpeed()); @@ -216,8 +216,7 @@ void PreferencesDialog::savePreferences() { myAvatar->setLeanScale(ui.leanScaleSpin->value()); myAvatar->setClampedTargetScale(ui.avatarScaleSpin->value()); - auto glCanvas = Application::getInstance()->getGLWidget(); - Application::getInstance()->resizeGL(glCanvas->width(), glCanvas->height()); + Application::getInstance()->resizeGL(); DependencyManager::get()->getMyAvatar()->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value()); @@ -231,7 +230,7 @@ void PreferencesDialog::savePreferences() { qApp->getOctreeQuery().setMaxOctreePacketsPerSecond(ui.maxOctreePPSSpin->value()); - qApp->getApplicationOverlay().setOculusUIAngularSize(ui.oculusUIAngularSizeSpin->value()); + qApp->getApplicationOverlay().setHmdUIAngularSize(ui.oculusUIAngularSizeSpin->value()); SixenseManager& sixense = SixenseManager::getInstance(); sixense.setReticleMoveSpeed(ui.sixenseReticleMoveSpeedSpin->value()); @@ -255,7 +254,7 @@ void PreferencesDialog::savePreferences() { audio->setOutputStarveDetectionThreshold(ui.outputStarveDetectionThresholdSpinner->value()); audio->setOutputStarveDetectionPeriod(ui.outputStarveDetectionPeriodSpinner->value()); - Application::getInstance()->resizeGL(glCanvas->width(), glCanvas->height()); + Application::getInstance()->resizeGL(); // LOD items auto lodManager = DependencyManager::get(); diff --git a/interface/src/ui/RearMirrorTools.cpp b/interface/src/ui/RearMirrorTools.cpp index a215d20148..ec73668d9e 100644 --- a/interface/src/ui/RearMirrorTools.cpp +++ b/interface/src/ui/RearMirrorTools.cpp @@ -15,6 +15,7 @@ #include #include +#include #include "Application.h" #include "RearMirrorTools.h" @@ -28,16 +29,16 @@ const char ZOOM_LEVEL_SETTINGS[] = "ZoomLevel"; Setting::Handle RearMirrorTools::rearViewZoomLevel(QStringList() << SETTINGS_GROUP_NAME << ZOOM_LEVEL_SETTINGS, ZoomLevel::HEAD); -RearMirrorTools::RearMirrorTools(QGLWidget* parent, QRect& bounds) : - _parent(parent), +RearMirrorTools::RearMirrorTools(QRect& bounds) : _bounds(bounds), _windowed(false), _fullScreen(false) { - _closeTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/close.svg")); + auto textureCache = DependencyManager::get(); + _closeTexture = textureCache->getImageTexture(PathUtils::resourcesPath() + "images/close.svg"); - _zoomHeadTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/plus.svg")); - _zoomBodyTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/minus.svg")); + _zoomHeadTexture = textureCache->getImageTexture(PathUtils::resourcesPath() + "images/plus.svg"); + _zoomBodyTexture = textureCache->getImageTexture(PathUtils::resourcesPath() + "images/minus.svg"); _shrinkIconRect = QRect(ICON_PADDING, ICON_PADDING, ICON_SIZE, ICON_SIZE); _closeIconRect = QRect(_bounds.left() + ICON_PADDING, _bounds.top() + ICON_PADDING, ICON_SIZE, ICON_SIZE); @@ -46,20 +47,19 @@ RearMirrorTools::RearMirrorTools(QGLWidget* parent, QRect& bounds) : _headZoomIconRect = QRect(_bounds.left() + ICON_PADDING, _bounds.bottom() - ICON_PADDING - ICON_SIZE, ICON_SIZE, ICON_SIZE); } -void RearMirrorTools::render(bool fullScreen) { +void RearMirrorTools::render(bool fullScreen, const QPoint & mousePosition) { if (fullScreen) { _fullScreen = true; - displayIcon(_parent->geometry(), _shrinkIconRect, _closeTextureId); + displayIcon(QRect(QPoint(), qApp->getDeviceSize()), _shrinkIconRect, _closeTexture); } else { // render rear view tools if mouse is in the bounds - QPoint mousePosition = _parent->mapFromGlobal(QCursor::pos()); - _windowed = _bounds.contains(mousePosition.x(), mousePosition.y()); + _windowed = _bounds.contains(mousePosition); if (_windowed) { - displayIcon(_bounds, _closeIconRect, _closeTextureId); + displayIcon(_bounds, _closeIconRect, _closeTexture); ZoomLevel zoomLevel = (ZoomLevel)rearViewZoomLevel.get(); - displayIcon(_bounds, _headZoomIconRect, _zoomHeadTextureId, zoomLevel == HEAD); - displayIcon(_bounds, _bodyZoomIconRect, _zoomBodyTextureId, zoomLevel == BODY); + displayIcon(_bounds, _headZoomIconRect, _zoomHeadTexture, zoomLevel == HEAD); + displayIcon(_bounds, _bodyZoomIconRect, _zoomBodyTexture, zoomLevel == BODY); } } } @@ -99,7 +99,7 @@ bool RearMirrorTools::mousePressEvent(int x, int y) { return false; } -void RearMirrorTools::displayIcon(QRect bounds, QRect iconBounds, GLuint textureId, bool selected) { +void RearMirrorTools::displayIcon(QRect bounds, QRect iconBounds, const gpu::TexturePointer& texture, bool selected) { glMatrixMode(GL_PROJECTION); glPushMatrix(); @@ -116,13 +116,13 @@ void RearMirrorTools::displayIcon(QRect bounds, QRect iconBounds, GLuint texture } else { quadColor = glm::vec4(1, 1, 1, 1); } - - glBindTexture(GL_TEXTURE_2D, textureId); + + glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(texture)); glm::vec2 topLeft(iconBounds.left(), iconBounds.top()); glm::vec2 bottomRight(iconBounds.right(), iconBounds.bottom()); - glm::vec2 texCoordTopLeft(0.0f, 1.0f); - glm::vec2 texCoordBottomRight(1.0f, 0.0f); + static const glm::vec2 texCoordTopLeft(0.0f, 1.0f); + static const glm::vec2 texCoordBottomRight(1.0f, 0.0f); DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor); diff --git a/interface/src/ui/RearMirrorTools.h b/interface/src/ui/RearMirrorTools.h index 8a76134627..2b359c2d07 100644 --- a/interface/src/ui/RearMirrorTools.h +++ b/interface/src/ui/RearMirrorTools.h @@ -12,10 +12,7 @@ #ifndef hifi_RearMirrorTools_h #define hifi_RearMirrorTools_h -#include "InterfaceConfig.h" - -#include - +#include #include enum ZoomLevel { @@ -26,8 +23,8 @@ enum ZoomLevel { class RearMirrorTools : public QObject { Q_OBJECT public: - RearMirrorTools(QGLWidget* parent, QRect& bounds); - void render(bool fullScreen); + RearMirrorTools(QRect& bounds); + void render(bool fullScreen, const QPoint & mousePos); bool mousePressEvent(int x, int y); static Setting::Handle rearViewZoomLevel; @@ -39,12 +36,10 @@ signals: void restoreView(); private: - QGLWidget* _parent; QRect _bounds; - GLuint _closeTextureId; - GLuint _resetTextureId; - GLuint _zoomBodyTextureId; - GLuint _zoomHeadTextureId; + gpu::TexturePointer _closeTexture; + gpu::TexturePointer _zoomBodyTexture; + gpu::TexturePointer _zoomHeadTexture; QRect _closeIconRect; QRect _resetIconRect; @@ -55,7 +50,7 @@ private: bool _windowed; bool _fullScreen; - void displayIcon(QRect bounds, QRect iconBounds, GLuint textureId, bool selected = false); + void displayIcon(QRect bounds, QRect iconBounds, const gpu::TexturePointer& texture, bool selected = false); }; #endif // hifi_RearMirrorTools_h diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index 5a3109ff64..0d91f4e7ba 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -75,8 +75,8 @@ SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) { return data; } -QString Snapshot::saveSnapshot() { - QFile* snapshotFile = savedFileForSnapshot(false); +QString Snapshot::saveSnapshot(QImage image) { + QFile* snapshotFile = savedFileForSnapshot(image, false); // we don't need the snapshot file, so close it, grab its filename and delete it snapshotFile->close(); @@ -88,14 +88,12 @@ QString Snapshot::saveSnapshot() { return snapshotPath; } -QTemporaryFile* Snapshot::saveTempSnapshot() { +QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) { // return whatever we get back from saved file for snapshot - return static_cast(savedFileForSnapshot(true));; + return static_cast(savedFileForSnapshot(image, true));; } -QFile* Snapshot::savedFileForSnapshot(bool isTemporary) { - auto glCanvas = Application::getInstance()->getGLWidget(); - QImage shot = glCanvas->grabFrameBuffer(); +QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary) { Avatar* avatar = DependencyManager::get()->getMyAvatar(); diff --git a/interface/src/ui/Snapshot.h b/interface/src/ui/Snapshot.h index 2a40ee183b..e83f8b3ec4 100644 --- a/interface/src/ui/Snapshot.h +++ b/interface/src/ui/Snapshot.h @@ -42,13 +42,13 @@ private: class Snapshot { public: - static QString saveSnapshot(); - static QTemporaryFile* saveTempSnapshot(); + static QString saveSnapshot(QImage image); + static QTemporaryFile* saveTempSnapshot(QImage image); static SnapshotMetaData* parseSnapshotData(QString snapshotPath); static Setting::Handle snapshotsLocation; private: - static QFile* savedFileForSnapshot(bool isTemporary); + static QFile* savedFileForSnapshot(QImage & image, bool isTemporary); }; #endif // hifi_Snapshot_h diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index ec225dde72..161eb06f5f 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -57,8 +57,8 @@ Stats::Stats(): _octreeStatsWidth(STATS_OCTREE_MIN_WIDTH), _lastHorizontalOffset(0) { - auto glCanvas = Application::getInstance()->getGLWidget(); - resetWidth(glCanvas->width(), 0); + auto canvasSize = Application::getInstance()->getCanvasSize(); + resetWidth(canvasSize.x, 0); } void Stats::toggleExpanded() { @@ -68,7 +68,7 @@ void Stats::toggleExpanded() { // called on mouse click release // check for clicks over stats in order to expand or contract them void Stats::checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseDragStartedY, int horizontalOffset) { - auto glCanvas = Application::getInstance()->getGLWidget(); + auto canvasSize = Application::getInstance()->getCanvasSize(); if (0 != glm::compMax(glm::abs(glm::ivec2(mouseX - mouseDragStartedX, mouseY - mouseDragStartedY)))) { // not worried about dragging on stats @@ -115,7 +115,7 @@ void Stats::checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseD // top-right stats click lines = _expanded ? 11 : 3; statsHeight = lines * STATS_PELS_PER_LINE + 10; - statsWidth = glCanvas->width() - statsX; + statsWidth = canvasSize.x - statsX; if (mouseX > statsX && mouseX < statsX + statsWidth && mouseY > statsY && mouseY < statsY + statsHeight) { toggleExpanded(); return; @@ -123,8 +123,8 @@ void Stats::checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseD } void Stats::resetWidth(int width, int horizontalOffset) { - auto glCanvas = Application::getInstance()->getGLWidget(); - int extraSpace = glCanvas->width() - horizontalOffset -2 + auto canvasSize = Application::getInstance()->getCanvasSize(); + int extraSpace = canvasSize.x - horizontalOffset - 2 - STATS_GENERAL_MIN_WIDTH - (Menu::getInstance()->isOptionChecked(MenuOption::TestPing) ? STATS_PING_MIN_WIDTH -1 : 0) - STATS_GEO_MIN_WIDTH @@ -148,7 +148,7 @@ void Stats::resetWidth(int width, int horizontalOffset) { _pingStatsWidth += (int) extraSpace / panels; } _geoStatsWidth += (int) extraSpace / panels; - _octreeStatsWidth += glCanvas->width() - + _octreeStatsWidth += canvasSize.x - (_generalStatsWidth + _pingStatsWidth + _geoStatsWidth + 3); } } @@ -197,7 +197,7 @@ void Stats::display( int outKbitsPerSecond, int voxelPacketsToProcess) { - auto glCanvas = Application::getInstance()->getGLWidget(); + auto canvasSize = Application::getInstance()->getCanvasSize(); unsigned int backgroundColor = 0x33333399; int verticalOffset = 0, lines = 0; @@ -211,7 +211,7 @@ void Stats::display( QSharedPointer bandwidthRecorder = DependencyManager::get(); if (_lastHorizontalOffset != horizontalOffset) { - resetWidth(glCanvas->width(), horizontalOffset); + resetWidth(canvasSize.x, horizontalOffset); _lastHorizontalOffset = horizontalOffset; } @@ -461,7 +461,7 @@ void Stats::display( lines = _expanded ? 10 : 2; - drawBackground(backgroundColor, horizontalOffset, 0, glCanvas->width() - horizontalOffset, + drawBackground(backgroundColor, horizontalOffset, 0, canvasSize.x - horizontalOffset, (lines + 1) * STATS_PELS_PER_LINE); horizontalOffset += 5; diff --git a/libraries/render-utils/src/AbstractViewStateInterface.h b/libraries/render-utils/src/AbstractViewStateInterface.h index 0d73614e7c..9f7042d325 100644 --- a/libraries/render-utils/src/AbstractViewStateInterface.h +++ b/libraries/render-utils/src/AbstractViewStateInterface.h @@ -45,7 +45,7 @@ public: virtual bool shouldRenderMesh(float largestDimension, float distanceToCamera) = 0; virtual float getSizeScale() const = 0; virtual int getBoundaryLevelAdjust() const = 0; - virtual PickRay computePickRay(float x, float y) = 0; + virtual PickRay computePickRay(float x, float y) const = 0; virtual const glm::vec3& getAvatarPosition() const = 0; }; diff --git a/libraries/render-utils/src/GlowEffect.cpp b/libraries/render-utils/src/GlowEffect.cpp index 6addd84da6..3040088ce5 100644 --- a/libraries/render-utils/src/GlowEffect.cpp +++ b/libraries/render-utils/src/GlowEffect.cpp @@ -31,7 +31,6 @@ GlowEffect::GlowEffect() _isOddFrame(false), _isFirstFrame(true), _intensity(0.0f), - _widget(NULL), _enabled(false) { } @@ -64,7 +63,7 @@ static ProgramObject* createProgram(const QString& name) { return program; } -void GlowEffect::init(QGLWidget* widget, bool enabled) { +void GlowEffect::init(bool enabled) { if (_initialized) { qCDebug(renderutils, "[ERROR] GlowEffeect is already initialized."); return; @@ -92,19 +91,9 @@ void GlowEffect::init(QGLWidget* widget, bool enabled) { _diffusionScaleLocation = _diffuseProgram->uniformLocation("diffusionScale"); _initialized = true; - _widget = widget; _enabled = enabled; } -int GlowEffect::getDeviceWidth() const { - return _widget->width() * (_widget->windowHandle() ? _widget->windowHandle()->devicePixelRatio() : 1.0f); -} - -int GlowEffect::getDeviceHeight() const { - return _widget->height() * (_widget->windowHandle() ? _widget->windowHandle()->devicePixelRatio() : 1.0f); -} - - void GlowEffect::prepare() { auto primaryFBO = DependencyManager::get()->getPrimaryFramebuffer(); GLuint fbo = gpu::GLBackend::getFramebufferID(primaryFBO); @@ -173,7 +162,8 @@ gpu::FramebufferPointer GlowEffect::render(bool toTexture) { } else { maybeBind(destFBO); if (!destFBO) { - glViewport(0, 0, getDeviceWidth(), getDeviceHeight()); + //destFBO->getSize(); + glViewport(0, 0, framebufferSize.width(), framebufferSize.height()); } glEnable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); @@ -219,7 +209,7 @@ gpu::FramebufferPointer GlowEffect::render(bool toTexture) { } maybeBind(destFBO); if (!destFBO) { - glViewport(0, 0, getDeviceWidth(), getDeviceHeight()); + glViewport(0, 0, framebufferSize.width(), framebufferSize.height()); } _addSeparateProgram->bind(); renderFullscreenQuad(); @@ -228,7 +218,6 @@ gpu::FramebufferPointer GlowEffect::render(bool toTexture) { glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); - } glPopMatrix(); diff --git a/libraries/render-utils/src/GlowEffect.h b/libraries/render-utils/src/GlowEffect.h index 6b7bad7689..1cee7b2e9d 100644 --- a/libraries/render-utils/src/GlowEffect.h +++ b/libraries/render-utils/src/GlowEffect.h @@ -34,7 +34,7 @@ public: /// (either the secondary or the tertiary). gpu::FramebufferPointer getFreeFramebuffer() const; - void init(QGLWidget* widget, bool enabled); + void init(bool enabled); /// Prepares the glow effect for rendering the current frame. To be called before rendering the scene. void prepare(); @@ -61,9 +61,6 @@ private: GlowEffect(); virtual ~GlowEffect(); - int getDeviceWidth() const; - int getDeviceHeight() const; - bool _initialized; ProgramObject* _addProgram; @@ -80,7 +77,6 @@ private: float _intensity; QStack _intensityStack; - QGLWidget* _widget; bool _enabled; }; diff --git a/libraries/render-utils/src/TextureCache.cpp b/libraries/render-utils/src/TextureCache.cpp index 63ca43725b..aa796ec48f 100644 --- a/libraries/render-utils/src/TextureCache.cpp +++ b/libraries/render-utils/src/TextureCache.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -32,8 +33,7 @@ TextureCache::TextureCache() : _permutationNormalTexture(0), _whiteTexture(0), _blueTexture(0), - _frameBufferSize(100, 100), - _associatedWidget(NULL) + _frameBufferSize(100, 100) { const qint64 TEXTURE_DEFAULT_UNUSED_MAX_SIZE = DEFAULT_UNUSED_MAX_SIZE; setUnusedResourceCacheSize(TEXTURE_DEFAULT_UNUSED_MAX_SIZE); @@ -290,22 +290,21 @@ GLuint TextureCache::getShadowDepthTextureID() { return gpu::GLBackend::getTextureID(_shadowTexture); } -bool TextureCache::eventFilter(QObject* watched, QEvent* event) { - if (event->type() == QEvent::Resize) { - QSize size = static_cast(event)->size(); - if (_frameBufferSize != size) { - _primaryFramebuffer.reset(); - _primaryColorTexture.reset(); - _primaryDepthTexture.reset(); - _primaryNormalTexture.reset(); - _primarySpecularTexture.reset(); - - _secondaryFramebuffer.reset(); - - _tertiaryFramebuffer.reset(); - } +/// Returns a texture version of an image file +gpu::TexturePointer TextureCache::getImageTexture(const QString & path) { + QImage image(path); + gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB); + gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB); + if (image.hasAlphaChannel()) { + formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA); + formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, gpu::BGRA); } - return false; + gpu::TexturePointer texture = gpu::TexturePointer( + gpu::Texture::create2D(formatGPU, image.width(), image.height(), + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); + texture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); + texture->autoGenerateMips(-1); + return texture; } QSharedPointer TextureCache::createResource(const QUrl& url, @@ -315,14 +314,6 @@ QSharedPointer TextureCache::createResource(const QUrl& url, &Resource::allReferencesCleared); } -void TextureCache::associateWithWidget(QGLWidget* widget) { - if (_associatedWidget) { - _associatedWidget->removeEventFilter(this); - } - _associatedWidget = widget; - _associatedWidget->installEventFilter(this); -} - Texture::Texture() { } diff --git a/libraries/render-utils/src/TextureCache.h b/libraries/render-utils/src/TextureCache.h index 42c1cecde3..e25a640ae7 100644 --- a/libraries/render-utils/src/TextureCache.h +++ b/libraries/render-utils/src/TextureCache.h @@ -35,9 +35,6 @@ class TextureCache : public ResourceCache, public Dependency { SINGLETON_DEPENDENCY public: - - void associateWithWidget(QGLWidget* widget); - /// Sets the desired texture resolution for the framebuffer objects. void setFrameBufferSize(QSize frameBufferSize); const QSize& getFrameBufferSize() const { return _frameBufferSize; } @@ -53,6 +50,9 @@ public: /// Returns the a pale blue texture (useful for a normal map). const gpu::TexturePointer& getBlueTexture(); + /// Returns a texture version of an image file + gpu::TexturePointer getImageTexture(const QString & path); + /// Loads a texture from the specified URL. NetworkTexturePointer getTexture(const QUrl& url, TextureType type = DEFAULT_TEXTURE, bool dilatable = false, const QByteArray& content = QByteArray()); @@ -94,8 +94,6 @@ public: /// Returns the ID of the shadow framebuffer object's depth texture. GLuint getShadowDepthTextureID(); - virtual bool eventFilter(QObject* watched, QEvent* event); - protected: virtual QSharedPointer createResource(const QUrl& url, @@ -127,7 +125,6 @@ private: gpu::TexturePointer _shadowTexture; QSize _frameBufferSize; - QGLWidget* _associatedWidget; }; /// A simple object wrapper for an OpenGL texture. diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 5d1b70275c..89fd15e179 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -336,6 +336,10 @@ QMatrix4x4 fromGlm(const glm::mat4 & m) { return QMatrix4x4(&m[0][0]).transposed(); } +QSize fromGlm(const glm::ivec2 & v) { + return QSize(v.x, v.y); +} + QRectF glmToRect(const glm::vec2 & pos, const glm::vec2 & size) { QRectF result(pos.x, pos.y, size.x, size.y); return result; diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index dda57a9cd9..a06f6f26cf 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -112,8 +112,13 @@ glm::vec2 toGlm(const QPointF & pt); glm::vec3 toGlm(const xColor & color); glm::vec4 toGlm(const QColor & color); +QSize fromGlm(const glm::ivec2 & v); QMatrix4x4 fromGlm(const glm::mat4 & m); QRectF glmToRect(const glm::vec2 & pos, const glm::vec2 & size); +#define YAW(euler) euler.y +#define PITCH(euler) euler.x +#define ROLL(euler) euler.z + #endif // hifi_GLMHelpers_h From 098a9bd70e87481fe1cfbe754a423bbfe75dca63 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Mon, 4 May 2015 13:10:16 -0700 Subject: [PATCH 2/4] Fixing sixense and restoring lookat --- interface/src/Application.cpp | 5 ++++ interface/src/Camera.cpp | 38 +++++++++++++++++++++++- interface/src/Camera.h | 17 +++++++++++ interface/src/devices/OculusManager.cpp | 1 + interface/src/devices/SixenseManager.cpp | 9 +++--- interface/src/devices/TV3DManager.cpp | 3 +- 6 files changed, 65 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f5d0e3b01a..0b3df7540f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -852,6 +852,11 @@ void Application::paintGL() { glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); } + // Update camera position + if (!OculusManager::isConnected()) { + _myCamera.update(1.0f / _fps); + } + if (getShadowsEnabled()) { updateShadowMap(); } diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 7db598bdfc..1016d60ccf 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -53,24 +53,42 @@ Camera::Camera() : _nearClip(DEFAULT_NEAR_CLIP), // default _farClip(DEFAULT_FAR_CLIP), // default _hmdPosition(), - _hmdRotation() + _hmdRotation(), + _isKeepLookingAt(false), + _lookingAt(0.0f, 0.0f, 0.0f) { } +void Camera::update(float deltaTime) { + if (_isKeepLookingAt) { + lookAt(_lookingAt); + } + return; +} + void Camera::setPosition(const glm::vec3& position) { _position = position; } void Camera::setRotation(const glm::quat& rotation) { _rotation = rotation; + if (_isKeepLookingAt) { + lookAt(_lookingAt); + } } void Camera::setHmdPosition(const glm::vec3& hmdPosition) { _hmdPosition = hmdPosition; + if (_isKeepLookingAt) { + lookAt(_lookingAt); + } } void Camera::setHmdRotation(const glm::quat& hmdRotation) { _hmdRotation = hmdRotation; + if (_isKeepLookingAt) { + lookAt(_lookingAt); + } } float Camera::getFarClip() const { @@ -101,6 +119,10 @@ void Camera::setFarClip(float f) { _farClip = f; } +PickRay Camera::computePickRay(float x, float y) { + return qApp->computePickRay(x, y); +} + void Camera::setModeString(const QString& mode) { CameraMode targetMode = stringToMode(mode); @@ -129,3 +151,17 @@ void Camera::setModeString(const QString& mode) { QString Camera::getModeString() const { return modeToString(_mode); } + +void Camera::lookAt(const glm::vec3& lookAt) { + glm::vec3 up = IDENTITY_UP; + glm::mat4 lookAtMatrix = glm::lookAt(_position, lookAt, up); + glm::quat rotation = glm::quat_cast(lookAtMatrix); + rotation.w = -rotation.w; // Rosedale approved + _rotation = rotation; +} + +void Camera::keepLookingAt(const glm::vec3& point) { + lookAt(point); + _isKeepLookingAt = true; + _lookingAt = point; +} diff --git a/interface/src/Camera.h b/interface/src/Camera.h index b2eef3a8cb..e06e12f7dc 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -41,6 +41,8 @@ public: void initialize(); // instantly put the camera at the ideal position and rotation. + void update( float deltaTime ); + void setRotation(const glm::quat& rotation); void setHmdPosition(const glm::vec3& hmdPosition); void setHmdRotation(const glm::quat& hmdRotation); @@ -73,6 +75,19 @@ public slots: void setOrientation(const glm::quat& orientation) { setRotation(orientation); } glm::quat getOrientation() const { return getRotation(); } + + PickRay computePickRay(float x, float y); + + // These only work on independent cameras + /// one time change to what the camera is looking at + void lookAt(const glm::vec3& value); + + /// fix what the camera is looking at, and keep the camera looking at this even if position changes + void keepLookingAt(const glm::vec3& value); + + /// stops the keep looking at feature, doesn't change what's being looked at, but will stop camera from + /// continuing to update it's orientation to keep looking at the item + void stopLooking() { _isKeepLookingAt = false; } signals: void modeUpdated(const QString& newMode); @@ -89,6 +104,8 @@ private: glm::quat _rotation; glm::vec3 _hmdPosition; glm::quat _hmdRotation; + bool _isKeepLookingAt; + glm::vec3 _lookingAt; }; #endif // hifi_Camera_h diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 2d6141aac9..872cb62e4b 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -592,6 +592,7 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati glm::vec3(_eyeRenderDesc[eye].HmdToEyeViewOffset.x, _eyeRenderDesc[eye].HmdToEyeViewOffset.y, _eyeRenderDesc[eye].HmdToEyeViewOffset.z)); _eyePositions[eye] = thisEyePosition; + _camera->update(1.0f / Application::getInstance()->getFps()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index d74e210642..f1a762e64f 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -472,7 +472,6 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers) //Injecting mouse movements and clicks void SixenseManager::emulateMouse(PalmData* palm, int index) { MyAvatar* avatar = DependencyManager::get()->getMyAvatar(); - auto glCanvas = Application::getInstance()->getGLWidget(); QPoint pos; Qt::MouseButton bumperButton; @@ -498,12 +497,12 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) { // Get the angles, scaled between (-0.5,0.5) float xAngle = (atan2(direction.z, direction.x) + M_PI_2); float yAngle = 0.5f - ((atan2(direction.z, direction.y) + M_PI_2)); - + auto canvasSize = qApp->getCanvasSize(); // Get the pixel range over which the xAngle and yAngle are scaled - float cursorRange = glCanvas->width() * getCursorPixelRangeMult(); + float cursorRange = canvasSize.x * getCursorPixelRangeMult(); - pos.setX(glCanvas->width() / 2.0f + cursorRange * xAngle); - pos.setY(glCanvas->height() / 2.0f + cursorRange * yAngle); + pos.setX(canvasSize.x / 2.0f + cursorRange * xAngle); + pos.setY(canvasSize.y / 2.0f + cursorRange * yAngle); } diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index 90030b2f84..9d5dd2faae 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -33,9 +33,8 @@ bool TV3DManager::isConnected() { } void TV3DManager::connect() { - Camera& camera = *Application::getInstance()->getCamera(); auto deviceSize = qApp->getDeviceSize(); - configureCamera(camera, deviceSize.width(), deviceSize.height()); + configureCamera(*(qApp->getCamera()), deviceSize.width(), deviceSize.height()); } From 351246fac11de6243d10cb5fcd6d64ec2b0affcc Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Wed, 6 May 2015 12:50:20 -0700 Subject: [PATCH 3/4] Fixing new image texture use from last upstream merge --- interface/src/devices/CameraToolBox.cpp | 14 +++++++------- interface/src/devices/CameraToolBox.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/interface/src/devices/CameraToolBox.cpp b/interface/src/devices/CameraToolBox.cpp index 26aff4bf9a..a1e00d7052 100644 --- a/interface/src/devices/CameraToolBox.cpp +++ b/interface/src/devices/CameraToolBox.cpp @@ -14,6 +14,7 @@ #include #include +#include "gpu/GLBackend.h" #include "Application.h" #include "CameraToolBox.h" #include "FaceTracker.h" @@ -74,21 +75,20 @@ void CameraToolBox::toggleMute() { void CameraToolBox::render(int x, int y, bool boxed) { glEnable(GL_TEXTURE_2D); - auto glCanvas = Application::getInstance()->getGLWidget(); - if (_enabledTextureId == 0) { - _enabledTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/face.svg")); + if (!_enabledTexture) { + _enabledTexture = DependencyManager::get()->getImageTexture(PathUtils::resourcesPath() + "images/face.svg"); } - if (_mutedTextureId == 0) { - _mutedTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/face-mute.svg")); + if (!_mutedTexture) { + _mutedTexture = DependencyManager::get()->getImageTexture(PathUtils::resourcesPath() + "images/face-mute.svg"); } const int MUTE_ICON_SIZE = 24; _iconBounds = QRect(x, y, MUTE_ICON_SIZE, MUTE_ICON_SIZE); float iconColor = 1.0f; if (!Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking)) { - glBindTexture(GL_TEXTURE_2D, _enabledTextureId); + glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_enabledTexture)); } else { - glBindTexture(GL_TEXTURE_2D, _mutedTextureId); + glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_mutedTexture)); // Make muted icon pulsate static const float PULSE_MIN = 0.4f; diff --git a/interface/src/devices/CameraToolBox.h b/interface/src/devices/CameraToolBox.h index 5f9241c81d..89e0c6a8dc 100644 --- a/interface/src/devices/CameraToolBox.h +++ b/interface/src/devices/CameraToolBox.h @@ -34,8 +34,8 @@ private slots: void toggleMute(); private: - GLuint _enabledTextureId = 0; - GLuint _mutedTextureId = 0; + gpu::TexturePointer _enabledTexture; + gpu::TexturePointer _mutedTexture; int _boxQuadID = GeometryCache::UNKNOWN_ID; QRect _iconBounds; qint64 _iconPulseTimeReference = 0; From 3c10d29d5384fad890f15d21a66b599b3e34d107 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Wed, 6 May 2015 14:09:43 -0700 Subject: [PATCH 4/4] Removing another reference to oculus manager --- interface/src/ui/ApplicationOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 21b10566d2..c410b992c4 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -820,7 +820,7 @@ void ApplicationOverlay::renderCameraToggle() { } int audioMeterY; - bool smallMirrorVisible = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && !OculusManager::isConnected(); + bool smallMirrorVisible = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && !qApp->isHMDMode(); bool boxed = smallMirrorVisible && !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror); if (boxed) {