diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index eb5a389c61..8ddea6a355 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -239,9 +239,9 @@ Hifi.Stats { id: perfText color: root.fontColor font.family: root.monospaceFont - font.pixelSize: 10 - text: "-------------------------------------------------------- Function " + - "------------------------------------------------------- --msecs- -calls--\n" + + font.pixelSize: 12 + text: "------------------------------------------ Function " + + "--------------------------------------- --msecs- -calls--\n" + root.timingStats; } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6b7f42fe0b..dc0eb3d23f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -151,7 +151,6 @@ #include "ui/AddressBarDialog.h" #include "ui/UpdateDialog.h" -static const float MIRROR_FULLSCREEN_DISTANCE = 0.389f; // ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU #if defined(Q_OS_WIN) @@ -325,11 +324,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _viewFrustum(), _lastQueriedViewFrustum(), _lastQueriedTime(usecTimestampNow()), + _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), _firstRun("firstRun", true), _previousScriptLocation("LastScriptLocation"), _scriptsLocationHandle("scriptsLocation"), _fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES), _viewTransform(), + _scaleMirror(1.0f), + _rotateMirror(0.0f), + _raiseMirror(0.0f), _cursorVisible(true), _lastMouseMove(usecTimestampNow()), _lastMouseMoveWasSimulated(false), @@ -821,23 +824,6 @@ void Application::initializeGL() { InfoView::show(INFO_HELP_PATH, true); } -template -void with_stable_stack_check(F f) { - - GLint mvDepth, prDepth; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &mvDepth); - glGetIntegerv(GL_PROJECTION_STACK_DEPTH, &prDepth); - - f(); - - GLint mvDepthFinal, prDepthFinal; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &mvDepthFinal); - glGetIntegerv(GL_PROJECTION_STACK_DEPTH, &prDepthFinal); - Q_ASSERT(mvDepth == mvDepthFinal); - Q_ASSERT(prDepth == prDepthFinal); - -} - void Application::initializeUi() { AddressBarDialog::registerType(); ErrorDialog::registerType(); @@ -875,12 +861,7 @@ void Application::initializeUi() { }); } -void Application::paintGL() { - PROFILE_RANGE(__FUNCTION__); - _glWidget->makeCurrent(); - - auto lodManager = DependencyManager::get(); - +/* { PerformanceTimer perfTimer("renderOverlay"); gpu::Context context(new gpu::GLBackend()); @@ -889,6 +870,13 @@ void Application::paintGL() { RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); _applicationOverlay.renderOverlay(&renderArgs); } +*/ + +void Application::paintGL() { + PROFILE_RANGE(__FUNCTION__); + _glWidget->makeCurrent(); + + auto lodManager = DependencyManager::get(); gpu::Context context(new gpu::GLBackend()); RenderArgs renderArgs(&context, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(), @@ -943,10 +931,6 @@ void Application::paintGL() { } } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - // TODO put the mirror modifiers somewhere both the app and the overlay can access it - float _rotateMirror = 0.0f; - float _raiseMirror = 0.0f; - float _scaleMirror = 1.0f; _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + @@ -986,31 +970,32 @@ void Application::paintGL() { QSize size = DependencyManager::get()->getFrameBufferSize(); glViewport(0, 0, size.width(), size.height()); - with_stable_stack_check([&]{ - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - displaySide(&renderArgs, _myCamera); - _compositor.displayOverlayTexture(&renderArgs); - glPopMatrix(); - }); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + displaySide(&renderArgs, _myCamera); + glPopMatrix(); - //renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; - //if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { - // _rearMirrorTools->render(&renderArgs, true, _glWidget->mapFromGlobal(QCursor::pos())); - //} else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { - // renderRearViewMirror(&renderArgs, _mirrorViewRect); - //} - //renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE; + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; + if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { + _rearMirrorTools->render(&renderArgs, true, _glWidget->mapFromGlobal(QCursor::pos())); + } else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { + renderRearViewMirror(&renderArgs, _mirrorViewRect); + } + + renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE; auto finalFbo = DependencyManager::get()->render(&renderArgs); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo)); glBlitFramebuffer(0, 0, _renderResolution.x, _renderResolution.y, 0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height(), GL_COLOR_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + + _compositor.displayOverlayTexture(&renderArgs); } @@ -1071,21 +1056,24 @@ void Application::resizeGL() { } else { renderSize = _glWidget->getDeviceSize() * getRenderResolutionScale(); } - if (_renderResolution == toGlm(renderSize)) { - return; + + if (_renderResolution != toGlm(renderSize)) { + _renderResolution = toGlm(renderSize); + DependencyManager::get()->setFrameBufferSize(renderSize); + resetCamerasOnResizeGL(_myCamera, _renderResolution); + + glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu??? + + updateProjectionMatrix(); + glLoadIdentity(); } - _renderResolution = toGlm(renderSize); - DependencyManager::get()->setFrameBufferSize(renderSize); - resetCamerasOnResizeGL(_myCamera, _renderResolution); - - glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu??? - - updateProjectionMatrix(); - glLoadIdentity(); - auto offscreenUi = DependencyManager::get(); - offscreenUi->resize(_glWidget->size()); + + auto canvasSize = _glWidget->size(); + if (canvasSize != offscreenUi->getWindow()->size()) { + offscreenUi->resize(canvasSize); + } _glWidget->makeCurrent(); } @@ -1303,37 +1291,37 @@ void Application::keyPressEvent(QKeyEvent* event) { Menu::getInstance()->triggerOption(MenuOption::Chat); break; - //case Qt::Key_Up: - // if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - // if (!isShifted) { - // _scaleMirror *= 0.95f; - // } else { - // _raiseMirror += 0.05f; - // } - // } - // break; + case Qt::Key_Up: + if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + if (!isShifted) { + _scaleMirror *= 0.95f; + } else { + _raiseMirror += 0.05f; + } + } + break; - //case Qt::Key_Down: - // if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - // if (!isShifted) { - // _scaleMirror *= 1.05f; - // } else { - // _raiseMirror -= 0.05f; - // } - // } - // break; + case Qt::Key_Down: + if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + if (!isShifted) { + _scaleMirror *= 1.05f; + } else { + _raiseMirror -= 0.05f; + } + } + break; - //case Qt::Key_Left: - // if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - // _rotateMirror += PI / 20.0f; - // } - // break; + case Qt::Key_Left: + if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + _rotateMirror += PI / 20.0f; + } + break; - //case Qt::Key_Right: - // if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - // _rotateMirror -= PI / 20.0f; - // } - // break; + case Qt::Key_Right: + if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + _rotateMirror -= PI / 20.0f; + } + break; #if 0 case Qt::Key_I: @@ -1598,12 +1586,11 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { // stop propagation return; } -#if 0 + if (_rearMirrorTools->mousePressEvent(getMouseX(), getMouseY())) { // stop propagation return; } -#endif } // nobody handled this - make it an action event on the _window object @@ -1654,15 +1641,6 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { if (event->button() == Qt::LeftButton) { _mousePressed = false; -#if 0 - if (Menu::getInstance()->isOptionChecked(MenuOption::Stats) && mouseOnScreen()) { - // let's set horizontal offset to give stats some margin to mirror - int horizontalOffset = MIRROR_VIEW_WIDTH; - Stats::getInstance()->checkClick(getMouseX(), getMouseY(), - getMouseDragStartedX(), getMouseDragStartedY(), horizontalOffset); - } -#endif - // fire an action end event HFActionEvent actionEvent(HFActionEvent::endType(), computePickRay(event->x(), event->y())); @@ -1847,7 +1825,6 @@ void Application::idle() { targetFramePeriod = 1000.0 / targetFramerate; } double timeSinceLastUpdate = (double)_lastTimeUpdated.nsecsElapsed() / 1000000.0; - //if (true) { if (timeSinceLastUpdate > targetFramePeriod) { _lastTimeUpdated.start(); { @@ -1874,7 +1851,7 @@ void Application::idle() { } // After finishing all of the above work, restart the idle timer, allowing 2ms to process events. - idleTimer->start(0); + idleTimer->start(2); } } @@ -2181,9 +2158,7 @@ void Application::init() { DependencyManager::get()->init(); _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); -#if 0 _mirrorCamera.setMode(CAMERA_MODE_MIRROR); -#endif TV3DManager::connect(); if (TV3DManager::isConnected()) { @@ -2248,13 +2223,12 @@ void Application::init() { _entityClipboardRenderer.setViewFrustum(getViewFrustum()); _entityClipboardRenderer.setTree(&_entityClipboard); -#if 0 _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())); -#endif + // initialize the GlowEffect with our widget bool glow = Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect); @@ -3166,7 +3140,6 @@ PickRay Application::computePickRay(float x, float y) const { return result; } -#if 0 QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) { auto primaryFramebuffer = DependencyManager::get()->getPrimaryFramebuffer(); glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer)); @@ -3192,7 +3165,6 @@ QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) { glBindFramebuffer(GL_FRAMEBUFFER, 0); return image; } -#endif ViewFrustum* Application::getViewFrustum() { #ifdef DEBUG @@ -3410,7 +3382,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se viewTransform.setTranslation(theCamera.getPosition()); viewTransform.setRotation(rotation); if (theCamera.getMode() == CAMERA_MODE_MIRROR) { - //viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f)); +// viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f)); } if (renderArgs->_renderSide != RenderArgs::MONO) { glm::mat4 invView = glm::inverse(_untranslatedViewMatrix); @@ -3677,6 +3649,79 @@ glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) { return screenPoint; } +void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard) { + // Grab current viewport to reset it at the end + int viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + float aspect = (float)region.width() / region.height(); + float fov = MIRROR_FIELD_OF_VIEW; + + // bool eyeRelativeCamera = false; + if (billboard) { + fov = BILLBOARD_FIELD_OF_VIEW; // degees + _mirrorCamera.setPosition(_myAvatar->getPosition() + + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * BILLBOARD_DISTANCE * _myAvatar->getScale()); + + } else if (RearMirrorTools::rearViewZoomLevel.get() == BODY) { + _mirrorCamera.setPosition(_myAvatar->getChestPosition() + + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); + + } else { // HEAD zoom level + // FIXME note that the positioing of the camera relative to the avatar can suffer limited + // precision as the user's position moves further away from the origin. Thus at + // /1e7,1e7,1e7 (well outside the buildable volume) the mirror camera veers and sways + // wildly as you rotate your avatar because the floating point values are becoming + // larger, squeezing out the available digits of precision you have available at the + // human scale for camera positioning. + + // Previously there was a hack to correct this using the mechanism of repositioning + // the avatar at the origin of the world for the purposes of rendering the mirror, + // but it resulted in failing to render the avatar's head model in the mirror view + // when in first person mode. Presumably this was because of some missed culling logic + // that was not accounted for in the hack. + + // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further + // investigated in order to adapt the technique while fixing the head rendering issue, + // but the complexity of the hack suggests that a better approach + _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); + } + _mirrorCamera.setProjection(glm::perspective(glm::radians(fov), aspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); + _mirrorCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); + + // set the bounds of rear mirror view + if (billboard) { + QSize size = DependencyManager::get()->getFrameBufferSize(); + glViewport(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); + glScissor(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); + } else { + // if not rendering the billboard, the region is in device independent coordinates; must convert to device + QSize size = DependencyManager::get()->getFrameBufferSize(); + float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale(); + int x = region.x() * ratio, y = region.y() * ratio, width = region.width() * ratio, height = region.height() * ratio; + glViewport(x, size.height() - y - height, width, height); + glScissor(x, size.height() - y - height, width, height); + } + bool updateViewFrustum = false; + updateProjectionMatrix(_mirrorCamera, updateViewFrustum); + glEnable(GL_SCISSOR_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // render rear mirror view + glPushMatrix(); + displaySide(renderArgs, _mirrorCamera, true, billboard); + glPopMatrix(); + + if (!billboard) { + _rearMirrorTools->render(renderArgs, false, _glWidget->mapFromGlobal(QCursor::pos())); + } + + // reset Viewport and projection matrix + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + glDisable(GL_SCISSOR_TEST); + updateProjectionMatrix(_myCamera, updateViewFrustum); +} + void Application::resetSensors() { DependencyManager::get()->reset(); DependencyManager::get()->reset(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 605c85f7f7..99834a13d2 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -108,6 +108,15 @@ static const QString FST_EXTENSION = ".fst"; static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; // degrees static const float BILLBOARD_DISTANCE = 5.56f; // meters +static const int MIRROR_VIEW_TOP_PADDING = 5; +static const int MIRROR_VIEW_LEFT_PADDING = 10; +static const int MIRROR_VIEW_WIDTH = 265; +static const int MIRROR_VIEW_HEIGHT = 215; +static const float MIRROR_FULLSCREEN_DISTANCE = 0.389f; +static const float MIRROR_REARVIEW_DISTANCE = 0.722f; +static const float MIRROR_REARVIEW_BODY_DISTANCE = 2.56f; +static const float MIRROR_FIELD_OF_VIEW = 30.0f; + static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS_PER_SECOND; static const QString INFO_HELP_PATH = "html/interface-welcome.html"; @@ -469,7 +478,6 @@ private slots: void faceTrackerMuteToggled(); void setCursorVisible(bool visible); - //void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard = false); private: void resetCamerasOnResizeGL(Camera& camera, const glm::uvec2& size); @@ -504,6 +512,7 @@ private: glm::vec3 getSunDirection(); void updateShadowMap(RenderArgs* renderArgs); + void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard = false); void setMenuShortcutsEnabled(bool enabled); static void attachNewHeadToNode(Node *newNode); @@ -555,6 +564,9 @@ private: UserInputMapper _userInputMapper; // User input mapper allowing to mapp different real devices to the action channels that the application has to offer MyAvatar* _myAvatar; // TODO: move this and relevant code to AvatarManager (or MyAvatar as the case may be) Camera _myCamera; // My view onto the world + Camera _mirrorCamera; // Cammera for mirror view + QRect _mirrorViewRect; + RearMirrorTools* _rearMirrorTools; Setting::Handle _firstRun; Setting::Handle _previousScriptLocation; @@ -566,6 +578,10 @@ private: glm::vec3 _viewMatrixTranslation; glm::mat4 _projectionMatrix; + float _scaleMirror; + float _rotateMirror; + float _raiseMirror; + static const int CASCADED_SHADOW_MATRIX_COUNT = 4; glm::mat4 _shadowMatrices[CASCADED_SHADOW_MATRIX_COUNT]; glm::vec3 _shadowDistances; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6b0a398246..16cba72fcb 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1466,7 +1466,6 @@ void MyAvatar::maybeUpdateBillboard() { return; } } - /* gpu::Context context(new gpu::GLBackend()); RenderArgs renderArgs(&context); QImage image = qApp->renderAvatarBillboard(&renderArgs); @@ -1477,7 +1476,6 @@ void MyAvatar::maybeUpdateBillboard() { _billboardValid = true; sendBillboardPacket(); - */ } void MyAvatar::increaseSize() { @@ -1577,7 +1575,7 @@ glm::vec3 MyAvatar::getLaserPointerTipPosition(const PalmData* palm) { glm::vec3 result; - const auto& compositor = Application::getInstance()->getApplicationCompositor(); + const auto& compositor = qApp->getApplicationCompositor(); if (compositor.calculateRayUICollisionPoint(position, direction, result)) { return result; } diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 782d9dadba..53b3702cca 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -646,11 +646,12 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const renderArgs->_renderSide = RenderArgs::MONO; qApp->displaySide(renderArgs, *_camera); - //qApp->getApplicationCompositor().displayOverlayTexture(renderArgs); qApp->getApplicationCompositor().displayOverlayTextureHmd(renderArgs, eye); }); _activeEye = ovrEye_Count; + glPopMatrix(); + gpu::FramebufferPointer finalFbo; //Bind the output texture from the glow shader. If glow effect is disabled, we just grab the texture if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) { @@ -661,7 +662,6 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const finalFbo = DependencyManager::get()->getPrimaryFramebuffer(); glBindFramebuffer(GL_FRAMEBUFFER, 0); } - glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 08de5be0c8..b24054f8a8 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -42,14 +42,6 @@ const int AUDIO_METER_GAP = 5; const int MUTE_ICON_PADDING = 10; const vec4 CONNECTION_STATUS_BORDER_COLOR{ 1.0f, 0.0f, 0.0f, 0.8f }; const float CONNECTION_STATUS_BORDER_LINE_WIDTH = 4.0f; -static const int MIRROR_VIEW_TOP_PADDING = 5; -static const int MIRROR_VIEW_LEFT_PADDING = 10; -static const int MIRROR_VIEW_WIDTH = 265; -static const int MIRROR_VIEW_HEIGHT = 215; -static const int STATS_HORIZONTAL_OFFSET = MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2; -static const float MIRROR_REARVIEW_DISTANCE = 0.722f; -static const float MIRROR_REARVIEW_BODY_DISTANCE = 2.56f; -static const float MIRROR_FIELD_OF_VIEW = 30.0f; static const float ORTHO_NEAR_CLIP = -10000; static const float ORTHO_FAR_CLIP = 10000; @@ -59,8 +51,7 @@ static void fboViewport(QOpenGLFramebufferObject* fbo) { glViewport(0, 0, size.width(), size.height()); } -ApplicationOverlay::ApplicationOverlay() : - _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)) +ApplicationOverlay::ApplicationOverlay() { auto geometryCache = DependencyManager::get(); _audioRedQuad = geometryCache->allocateID(); @@ -295,94 +286,16 @@ void ApplicationOverlay::renderAudioMeter(RenderArgs* renderArgs) { } void ApplicationOverlay::renderRearViewToFbo(RenderArgs* renderArgs) { - // Grab current viewport to reset it at the end - auto mirrorSize = _mirrorFramebuffer->size(); - float aspect = (float)mirrorSize.width() / mirrorSize.height(); - float fov = MIRROR_FIELD_OF_VIEW; - MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); - // bool eyeRelativeCamera = false; - if (RearMirrorTools::rearViewZoomLevel.get() == BODY) { - _mirrorCamera.setPosition(myAvatar->getChestPosition() + - myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * myAvatar->getScale()); - } else { // HEAD zoom level - // FIXME note that the positioing of the camera relative to the avatar can suffer limited - // precision as the user's position moves further away from the origin. Thus at - // /1e7,1e7,1e7 (well outside the buildable volume) the mirror camera veers and sways - // wildly as you rotate your avatar because the floating point values are becoming - // larger, squeezing out the available digits of precision you have available at the - // human scale for camera positioning. - - // Previously there was a hack to correct this using the mechanism of repositioning - // the avatar at the origin of the world for the purposes of rendering the mirror, - // but it resulted in failing to render the avatar's head model in the mirror view - // when in first person mode. Presumably this was because of some missed culling logic - // that was not accounted for in the hack. - - // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further - // investigated in order to adapt the technique while fixing the head rendering issue, - // but the complexity of the hack suggests that a better approach - _mirrorCamera.setPosition(myAvatar->getHead()->getEyePosition() + - myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * myAvatar->getScale()); - } - _mirrorCamera.setProjection(glm::perspective(glm::radians(fov), aspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); - _mirrorCamera.setRotation(myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); - - // set the bounds of rear mirror view - fboViewport(_mirrorFramebuffer); - - _mirrorFramebuffer->bind(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glLoadMatrixf(glm::value_ptr(_mirrorCamera.getProjection())); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glLoadMatrixf(glm::value_ptr(glm::mat4_cast(_mirrorCamera.getOrientation()) * glm::translate(glm::mat4(), _mirrorCamera.getPosition()))); - { - renderArgs->_context->syncCache(); - qApp->displaySide(renderArgs, _mirrorCamera, true, false); - } - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - _mirrorFramebuffer->release(); - fboViewport(_overlayFramebuffer); } void ApplicationOverlay::renderRearView(RenderArgs* renderArgs) { - if (_mirrorFramebuffer && _mirrorFramebuffer->texture()) { - gpu::Batch batch; - auto geometryCache = DependencyManager::get(); - geometryCache->useSimpleDrawPipeline(batch); - batch._glDisable(GL_DEPTH_TEST); - batch._glDisable(GL_LIGHTING); - batch._glEnable(GL_BLEND); - batch.setProjectionTransform(mat4()); - batch.setModelTransform(mat4()); - auto textureCache = DependencyManager::get(); - batch.setUniformTexture(0, textureCache->getBlueTexture()); - geometryCache->renderUnitQuad(batch, glm::vec4(1)); - batch._glBindTexture(GL_TEXTURE_2D, _mirrorFramebuffer->texture()); - geometryCache->renderUnitQuad(batch, glm::vec4(1)); - renderArgs->_context->syncCache(); - auto overlaySize = _overlayFramebuffer->size(); - glViewport(MIRROR_VIEW_LEFT_PADDING, overlaySize.height() - MIRROR_VIEW_TOP_PADDING - MIRROR_VIEW_HEIGHT, - MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT); - renderArgs->_context->render(batch); - fboViewport(_overlayFramebuffer); - } } void ApplicationOverlay::renderStatsAndLogs(RenderArgs* renderArgs) { - // Display stats and log text onscreen // Determine whether to compute timing details - /* // Show on-screen msec timer if (Menu::getInstance()->isOptionChecked(MenuOption::FrameTimer)) { @@ -457,18 +370,6 @@ GLuint ApplicationOverlay::getOverlayTexture() { } void ApplicationOverlay::buildFramebufferObject() { - if (!_mirrorFramebuffer) { - _mirrorFramebuffer = new QOpenGLFramebufferObject(QSize(MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT), QOpenGLFramebufferObject::Depth); - glBindTexture(GL_TEXTURE_2D, _mirrorFramebuffer->texture()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - GLfloat borderColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); - glBindTexture(GL_TEXTURE_2D, 0); - } - auto canvasSize = qApp->getCanvasSize(); QSize fboSize = QSize(canvasSize.x, canvasSize.y); if (_overlayFramebuffer && fboSize == _overlayFramebuffer->size()) { diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index ab242e592b..e50622d122 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -49,15 +49,8 @@ private: int _domainStatusBorder; int _magnifierBorder; - float _scaleMirror{ 1.0f }; - float _rotateMirror{ 0.0f }; - float _raiseMirror{ 0.0f }; - - Camera _mirrorCamera; ivec2 _previousBorderSize{ -1 }; - QRect _mirrorViewRect; QOpenGLFramebufferObject* _overlayFramebuffer{ nullptr }; - QOpenGLFramebufferObject* _mirrorFramebuffer{ nullptr }; }; #endif // hifi_ApplicationOverlay_h diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index c1d77b5fc2..acc9521c72 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -333,7 +333,7 @@ void Stats::updateStats() { QString functionName = j.value(); const PerformanceTimerRecord& record = allRecords.value(functionName); perfLines += QString("%1: %2 [%3]\n"). - arg(QString(qPrintable(functionName)), 120, noBreakingSpace). + arg(QString(qPrintable(functionName)), 90, noBreakingSpace). arg((float)record.getMovingAverage() / (float)USECS_PER_MSEC, 8, 'f', 3, noBreakingSpace). arg((int)record.getCount(), 6, 10, noBreakingSpace); linesDisplayed++; diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 5103633761..cd57d13615 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -689,4 +689,20 @@ void GLBackend::fetchMatrix(GLenum target, glm::mat4 & m) { glGetFloatv(target, glm::value_ptr(m)); } +void GLBackend::checkGLStackStable(std::function f) { +#ifdef DEBUG + GLint mvDepth, prDepth; + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &mvDepth); + glGetIntegerv(GL_PROJECTION_STACK_DEPTH, &prDepth); +#endif + f(); + +#ifdef DEBUG + GLint mvDepthFinal, prDepthFinal; + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &mvDepthFinal); + glGetIntegerv(GL_PROJECTION_STACK_DEPTH, &prDepthFinal); + Q_ASSERT(mvDepth == mvDepthFinal); + Q_ASSERT(prDepth == prDepthFinal); +#endif +} diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index b6a93d1ea3..28236c68c9 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -12,11 +12,13 @@ #define hifi_gpu_GLBackend_h #include +#include +#include + #include "GPUConfig.h" #include "Context.h" #include "Batch.h" -#include namespace gpu { @@ -50,6 +52,8 @@ public: // Only checks in debug builds static bool checkGLErrorDebug(const char* name = nullptr); + static void checkGLStackStable(std::function f); + static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings = Shader::BindingSet()); diff --git a/libraries/gpu/src/gpu/GLBackendShared.h b/libraries/gpu/src/gpu/GLBackendShared.h index 27f58fcbe3..365934379f 100644 --- a/libraries/gpu/src/gpu/GLBackendShared.h +++ b/libraries/gpu/src/gpu/GLBackendShared.h @@ -53,4 +53,6 @@ static const GLenum _elementTypeToGLType[gpu::NUM_TYPES] = { // #define CHECK_GL_ERROR() gpu::GLBackend::checkGLErrorDebug(__FUNCTION__ ":" CHECK_GL_ERROR_HELPER(__LINE__)) #define CHECK_GL_ERROR() gpu::GLBackend::checkGLErrorDebug(__FUNCTION__) +#define CHECK_GL_STACK_STABLE(f) gpu::GLBackend::checkGLStackStable(f) + #endif