Showing the changes to interface/src/Application.cpp (1 of 56 files). Show all
Unified · Split
| @@ -924,6 +924,30 @@ void Application::paintGL() { · 923 unmodified lines | ||
| 924 | 924 | PerformanceWarning warn(showWarnings, "Application::paintGL()"); |
| 925 | 925 | resizeGL(); |
| 926 | 926 | |
| 927 | + // Before anything else, let's sync up the gpuContext with the true glcontext used in case anything happened | |
| 928 | + renderArgs._context->syncCache(); | |
| 929 | + | |
| 930 | + if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { | |
| 931 | + auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor(); | |
| 932 | + | |
| 933 | + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | |
| 934 | + renderRearViewMirror(&renderArgs, _mirrorViewRect); | |
| 935 | + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 936 | + | |
| 937 | + { | |
| 938 | + float ratio = ((float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale()); | |
| 939 | + auto mirrorViewport = glm::ivec4(0, 0, _mirrorViewRect.width() * ratio, _mirrorViewRect.height() * ratio); | |
| 940 | + auto mirrorViewportDest = mirrorViewport; | |
| 941 | + | |
| 942 | + auto selfieFbo = DependencyManager::get<FramebufferCache>()->getSelfieFramebuffer(); | |
| 943 | + gpu::Batch batch; | |
| 944 | + batch.setFramebuffer(selfieFbo); | |
| 945 | + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); | |
| 946 | + batch.blit(primaryFbo, mirrorViewport, selfieFbo, mirrorViewportDest); | |
| 947 | + batch.setFramebuffer(nullptr); | |
| 948 | + renderArgs._context->render(batch); | |
| 949 | + } | |
| 950 | + } | |
| 927 | 951 | |
| 928 | 952 | { |
| 929 | 953 | PerformanceTimer perfTimer("renderOverlay"); |
| @@ -940,18 +964,22 @@ void Application::paintGL() { · 10 unmodified lines | ||
| 940 | 964 | Application::getInstance()->cameraMenuChanged(); |
| 941 | 965 | } |
| 942 | 966 | |
| 967 | + // The render mode is default or mirror if the camera is in mirror mode, assigned further below | |
| 968 | + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 969 | + | |
| 943 | 970 | if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { |
| 944 | 971 | // Always use the default eye position, not the actual head eye position. |
| 945 | 972 | // Using the latter will cause the camera to wobble with idle animations, |
| 946 | 973 | // or with changes from the face tracker |
| 974 | + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 947 | 975 | |
| 948 | − _myCamera.setPosition(_myAvatar->getDefaultEyePosition()); | |
| 949 | 976 | if (!getActiveDisplayPlugin()->isHmd()) { |
| 977 | + _myCamera.setPosition(_myAvatar->getDefaultEyePosition()); | |
| 950 | 978 | _myCamera.setRotation(_myAvatar->getHead()->getCameraOrientation()); |
| 951 | 979 | } else { |
| 952 | − // The plugin getModelview() call below will compose the base | |
| 953 | − // avatar transform with the HMD pose. | |
| 954 | − _myCamera.setRotation(_myAvatar->getOrientation()); | |
| 980 | + mat4 camMat = _myAvatar->getSensorToWorldMatrix() * _myAvatar->getHMDSensorMatrix(); | |
| 981 | + _myCamera.setPosition(extractTranslation(camMat)); | |
| 982 | + _myCamera.setRotation(glm::quat_cast(camMat)); | |
| 955 | 983 | } |
| 956 | 984 | } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { |
| 957 | 985 | if (isHMDMode()) { |
| @@ -973,6 +1001,7 @@ void Application::paintGL() { · 15 unmodified lines | ||
| 973 | 1001 | glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + |
| 974 | 1002 | (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * |
| 975 | 1003 | glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); |
| 1004 | + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | |
| 976 | 1005 | } |
| 977 | 1006 | |
| 978 | 1007 | // Update camera position |
| @@ -980,17 +1009,15 @@ void Application::paintGL() { · 1 unmodified line | ||
| 980 | 1009 | _myCamera.update(1.0f / _fps); |
| 981 | 1010 | } |
| 982 | 1011 | |
| 983 | − // Sync up the View Furstum with the camera | |
| 984 | − loadViewFrustum(_myCamera, _viewFrustum); | |
| 985 | − | |
| 986 | − | |
| 987 | − renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 988 | 1012 | |
| 989 | 1013 | // Primary rendering pass |
| 990 | 1014 | auto framebufferCache = DependencyManager::get<FramebufferCache>(); |
| 991 | 1015 | QSize size = framebufferCache->getFrameBufferSize(); |
| 992 | 1016 | { |
| 993 | 1017 | PROFILE_RANGE(__FUNCTION__ "/mainRender"); |
| 1018 | + // Viewport is assigned to the size of the framebuffer | |
| 1019 | + QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize(); | |
| 1020 | + renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); | |
| 994 | 1021 | |
| 995 | 1022 | { |
| 996 | 1023 | PROFILE_RANGE(__FUNCTION__ "/clear"); |
| @@ -1014,7 +1041,12 @@ void Application::paintGL() { · 17 unmodified lines | ||
| 1014 | 1041 | for_each_eye([&](Eye eye){ |
| 1015 | 1042 | // Load the view frustum, used by meshes |
| 1016 | 1043 | Camera eyeCamera; |
| 1017 | − eyeCamera.setTransform(displayPlugin->getModelview(eye, _myCamera.getTransform())); | |
| 1044 | + if (qApp->isHMDMode()) { | |
| 1045 | + // Allow the displayPlugin to compose the final eye transform, based on the most up-to-date head motion. | |
| 1046 | + eyeCamera.setTransform(displayPlugin->getModelview(eye, _myAvatar->getSensorToWorldMatrix())); | |
| 1047 | + } else { | |
| 1048 | + eyeCamera.setTransform(displayPlugin->getModelview(eye, _myCamera.getTransform())); | |
| 1049 | + } | |
| 1018 | 1050 | eyeCamera.setProjection(displayPlugin->getProjection(eye, _myCamera.getProjection())); |
| 1019 | 1051 | renderArgs._viewport = gpu::Vec4i(r.x(), r.y(), r.width(), r.height()); |
| 1020 | 1052 | doInBatch(&renderArgs, [&](gpu::Batch& batch) { |
| @@ -1022,12 +1054,6 @@ void Application::paintGL() { · 1 unmodified line | ||
| 1022 | 1054 | batch.setStateScissorRect(renderArgs._viewport); |
| 1023 | 1055 | }); |
| 1024 | 1056 | displaySide(&renderArgs, eyeCamera); |
| 1025 | − if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && | |
| 1026 | − !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { | |
| 1027 | −// renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | |
| 1028 | −// renderRearViewMirror(&renderArgs, _mirrorViewRect); | |
| 1029 | −// renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE; | |
| 1030 | − } | |
| 1031 | 1057 | }, [&] { |
| 1032 | 1058 | r.moveLeft(r.width()); |
| 1033 | 1059 | }); |
| @@ -1041,13 +1067,11 @@ void Application::paintGL() { · 7 unmodified lines | ||
| 1041 | 1067 | batch.setStateScissorRect(renderArgs._viewport); |
| 1042 | 1068 | }); |
| 1043 | 1069 | displaySide(&renderArgs, _myCamera); |
| 1044 | − if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && | |
| 1045 | − !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { | |
| 1046 | − renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | |
| 1047 | − renderRearViewMirror(&renderArgs, _mirrorViewRect); | |
| 1048 | − renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE; | |
| 1049 | − } | |
| 1050 | 1070 | } |
| 1071 | + | |
| 1072 | + doInBatch(&renderArgs, [](gpu::Batch& batch){ | |
| 1073 | + batch.setFramebuffer(nullptr); | |
| 1074 | + }); | |
| 1051 | 1075 | } |
| 1052 | 1076 | |
| 1053 | 1077 | // Overlay Composition, needs to occur after screen space effects have completed |
| @@ -1092,6 +1116,7 @@ void Application::paintGL() { · 38 unmodified lines | ||
| 1092 | 1116 | |
| 1093 | 1117 | // Ensure all operations from the previous context are complete before we try to read the fbo |
| 1094 | 1118 | #ifdef Q_OS_MAC |
| 1119 | + // FIXME once we move to core profile, use fencesync on both platforms | |
| 1095 | 1120 | #else |
| 1096 | 1121 | // FIXME? make the sync a parameter to preDisplay and let the plugin manage this |
| 1097 | 1122 | glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); |
| @@ -1107,11 +1132,11 @@ void Application::paintGL() { · 9 unmodified lines | ||
| 1107 | 1132 | PROFILE_RANGE(__FUNCTION__ "/bufferSwap"); |
| 1108 | 1133 | displayPlugin->finishFrame(); |
| 1109 | 1134 | } |
| 1110 | − | |
| 1111 | − _offscreenContext->makeCurrent(); | |
| 1112 | − _frameCount++; | |
| 1113 | − Stats::getInstance()->setRenderDetails(renderArgs._details); | |
| 1114 | 1135 | } |
| 1136 | + | |
| 1137 | + _offscreenContext->makeCurrent(); | |
| 1138 | + _frameCount++; | |
| 1139 | + Stats::getInstance()->setRenderDetails(renderArgs._details); | |
| 1115 | 1140 | } |
| 1116 | 1141 | |
| 1117 | 1142 | void Application::runTests() { |
| @@ -1126,6 +1151,7 @@ void Application::audioMuteToggled() { · 8 unmodified lines | ||
| 1126 | 1151 | } |
| 1127 | 1152 | |
| 1128 | 1153 | void Application::faceTrackerMuteToggled() { |
| 1154 | + | |
| 1129 | 1155 | QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteFaceTracking); |
| 1130 | 1156 | Q_CHECK_PTR(muteAction); |
| 1131 | 1157 | bool isMuted = getSelectedFaceTracker()->isMuted(); |
| @@ -1154,6 +1180,7 @@ void Application::resizeGL() { · 22 unmodified lines | ||
| 1154 | 1180 | uvec2 framebufferSize = getActiveDisplayPlugin()->getRecommendedRenderSize(); |
| 1155 | 1181 | uvec2 renderSize = uvec2(vec2(framebufferSize) * getRenderResolutionScale()); |
| 1156 | 1182 | if (_renderResolution != renderSize) { |
| 1183 | + _numFramesSinceLastResize = 0; | |
| 1157 | 1184 | _renderResolution = renderSize; |
| 1158 | 1185 | DependencyManager::get<FramebufferCache>()->setFrameBufferSize(fromGlm(renderSize)); |
| 1159 | 1186 | |
| @@ -1685,6 +1712,9 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { · 525 unmodified lines | ||
| 1685 | 1712 | |
| 1686 | 1713 | } else if (event->button() == Qt::RightButton) { |
| 1687 | 1714 | // right click items here |
| 1715 | + } else if (event->button() == Qt::MiddleButton) { | |
| 1716 | + // toggle the overlay | |
| 1717 | + _overlayConductor.setEnabled(!_overlayConductor.getEnabled()); | |
| 1688 | 1718 | } |
| 1689 | 1719 | } |
| 1690 | 1720 | } |
| @@ -1936,13 +1966,6 @@ void Application::idle() { · 245 unmodified lines | ||
| 1936 | 1966 | } |
| 1937 | 1967 | double timeSinceLastUpdate = (double)_lastTimeUpdated.nsecsElapsed() / 1000000.0; |
| 1938 | 1968 | if (timeSinceLastUpdate > targetFramePeriod) { |
| 1939 | − | |
| 1940 | − { | |
| 1941 | − static const int IDLE_EVENT_PROCESS_MAX_TIME_MS = 2; | |
| 1942 | − PerformanceTimer perfTimer("processEvents"); | |
| 1943 | − processEvents(QEventLoop::AllEvents, IDLE_EVENT_PROCESS_MAX_TIME_MS); | |
| 1944 | − } | |
| 1945 | − | |
| 1946 | 1969 | _lastTimeUpdated.start(); |
| 1947 | 1970 | { |
| 1948 | 1971 | PerformanceTimer perfTimer("update"); |
| @@ -1977,11 +2000,14 @@ void Application::idle() { · 28 unmodified lines | ||
| 1977 | 2000 | } |
| 1978 | 2001 | } |
| 1979 | 2002 | |
| 2003 | + float secondsSinceLastUpdate = (float)timeSinceLastUpdate / 1000.0f; | |
| 2004 | + _overlayConductor.update(secondsSinceLastUpdate); | |
| 2005 | + | |
| 1980 | 2006 | // depending on whether we're throttling or not. |
| 1981 | 2007 | // Once rendering is off on another thread we should be able to have Application::idle run at start(0) in |
| 1982 | 2008 | // perpetuity and not expect events to get backed up. |
| 1983 | 2009 | |
| 1984 | − static const int IDLE_TIMER_DELAY_MS = 0; | |
| 2010 | + static const int IDLE_TIMER_DELAY_MS = 2; | |
| 1985 | 2011 | int desiredInterval = getActiveDisplayPlugin()->isThrottled() ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS; |
| 1986 | 2012 | |
| 1987 | 2013 | if (idleTimer->interval() != desiredInterval) { |
| @@ -2356,23 +2382,21 @@ void Application::updateMyAvatarLookAtPosition() { · 368 unmodified lines | ||
| 2356 | 2382 | lookAtSpot = _myAvatar->getHead()->getEyePosition() + |
| 2357 | 2383 | (_myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); |
| 2358 | 2384 | } |
| 2359 | − } | |
| 2360 | 2385 | |
| 2361 | − // Deflect the eyes a bit to match the detected gaze from Faceshift if active. | |
| 2362 | − // DDE doesn't track eyes. | |
| 2363 | − if (tracker && typeid(*tracker) == typeid(Faceshift) && !tracker->isMuted()) { | |
| 2364 | − float eyePitch = tracker->getEstimatedEyePitch(); | |
| 2365 | − float eyeYaw = tracker->getEstimatedEyeYaw(); | |
| 2366 | − const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f; | |
| 2367 | − glm::vec3 origin = _myAvatar->getHead()->getEyePosition(); | |
| 2368 | − float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f; | |
| 2369 | − float deflection = DependencyManager::get<Faceshift>()->getEyeDeflection(); | |
| 2370 | − if (isLookingAtSomeone) { | |
| 2371 | − deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT; | |
| 2372 | − } | |
| 2373 | − lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( | |
| 2374 | − eyePitch * pitchSign * deflection, eyeYaw * deflection, 0.0f))) * | |
| 2386 | + // Deflect the eyes a bit to match the detected gaze from the face tracker if active. | |
| 2387 | + if (tracker && !tracker->isMuted()) { | |
| 2388 | + float eyePitch = tracker->getEstimatedEyePitch(); | |
| 2389 | + float eyeYaw = tracker->getEstimatedEyeYaw(); | |
| 2390 | + const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f; | |
| 2391 | + glm::vec3 origin = _myAvatar->getHead()->getEyePosition(); | |
| 2392 | + float deflection = tracker->getEyeDeflection(); | |
| 2393 | + if (isLookingAtSomeone) { | |
| 2394 | + deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT; | |
| 2395 | + } | |
| 2396 | + lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( | |
| 2397 | + eyePitch * deflection, eyeYaw * deflection, 0.0f))) * | |
| 2375 | 2398 | glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin); |
| 2399 | + } | |
| 2376 | 2400 | } |
| 2377 | 2401 | |
| 2378 | 2402 | _myAvatar->getHead()->setLookAtPosition(lookAtSpot); |
| @@ -2549,10 +2573,18 @@ void Application::update(float deltaTime) { · 170 unmodified lines | ||
| 2549 | 2573 | _myAvatar->setDriveKeys(DOWN, userInputMapper->getActionState(UserInputMapper::VERTICAL_DOWN)); |
| 2550 | 2574 | _myAvatar->setDriveKeys(LEFT, userInputMapper->getActionState(UserInputMapper::LATERAL_LEFT)); |
| 2551 | 2575 | _myAvatar->setDriveKeys(RIGHT, userInputMapper->getActionState(UserInputMapper::LATERAL_RIGHT)); |
| 2552 | − _myAvatar->setDriveKeys(ROT_UP, userInputMapper->getActionState(UserInputMapper::PITCH_UP)); | |
| 2553 | − _myAvatar->setDriveKeys(ROT_DOWN, userInputMapper->getActionState(UserInputMapper::PITCH_DOWN)); | |
| 2554 | − _myAvatar->setDriveKeys(ROT_LEFT, userInputMapper->getActionState(UserInputMapper::YAW_LEFT)); | |
| 2555 | − _myAvatar->setDriveKeys(ROT_RIGHT, userInputMapper->getActionState(UserInputMapper::YAW_RIGHT)); | |
| 2576 | + if (deltaTime > FLT_EPSILON) { | |
| 2577 | + // For rotations what we really want are meausures of "angles per second" (in order to prevent | |
| 2578 | + // fps-dependent spin rates) so we need to scale the units of the controller contribution. | |
| 2579 | + // (TODO?: maybe we should similarly scale ALL action state info, or change the expected behavior | |
| 2580 | + // controllers to provide a delta_per_second value rather than a raw delta.) | |
| 2581 | + const float EXPECTED_FRAME_RATE = 60.0f; | |
| 2582 | + float timeFactor = EXPECTED_FRAME_RATE * deltaTime; | |
| 2583 | + _myAvatar->setDriveKeys(ROT_UP, userInputMapper->getActionState(UserInputMapper::PITCH_UP) / timeFactor); | |
| 2584 | + _myAvatar->setDriveKeys(ROT_DOWN, userInputMapper->getActionState(UserInputMapper::PITCH_DOWN) / timeFactor); | |
| 2585 | + _myAvatar->setDriveKeys(ROT_LEFT, userInputMapper->getActionState(UserInputMapper::YAW_LEFT) / timeFactor); | |
| 2586 | + _myAvatar->setDriveKeys(ROT_RIGHT, userInputMapper->getActionState(UserInputMapper::YAW_RIGHT) / timeFactor); | |
| 2587 | + } | |
| 2556 | 2588 | } |
| 2557 | 2589 | _myAvatar->setDriveKeys(BOOM_IN, userInputMapper->getActionState(UserInputMapper::BOOM_IN)); |
| 2558 | 2590 | _myAvatar->setDriveKeys(BOOM_OUT, userInputMapper->getActionState(UserInputMapper::BOOM_OUT)); |
| @@ -3193,37 +3225,25 @@ PickRay Application::computePickRay(float x, float y) const { · 634 unmodified lines | ||
| 3193 | 3225 | if (isHMDMode()) { |
| 3194 | 3226 | getApplicationCompositor().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction); |
| 3195 | 3227 | } else { |
| 3196 | − if (QThread::currentThread() == activeRenderingThread) { | |
| 3197 | − getDisplayViewFrustum()->computePickRay(x, y, result.origin, result.direction); | |
| 3198 | − } else { | |
| 3199 | − getViewFrustum()->computePickRay(x, y, result.origin, result.direction); | |
| 3200 | − } | |
| 3228 | + getViewFrustum()->computePickRay(x, y, result.origin, result.direction); | |
| 3201 | 3229 | } |
| 3202 | 3230 | return result; |
| 3203 | 3231 | } |
| 3204 | 3232 | |
| 3205 | 3233 | QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) { |
| 3206 | − auto primaryFramebuffer = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer(); | |
| 3207 | − glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer)); | |
| 3208 | − | |
| 3209 | − // clear the alpha channel so the background is transparent | |
| 3210 | − glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); | |
| 3211 | − glClearColor(0.0, 0.0, 0.0, 0.0); | |
| 3212 | − glClear(GL_COLOR_BUFFER_BIT); | |
| 3213 | − glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); | |
| 3214 | 3234 | |
| 3215 | 3235 | const int BILLBOARD_SIZE = 64; |
| 3216 | −#if 0 | |
| 3217 | − renderRearViewMirror(renderArgs, QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE, | |
| 3218 | − BILLBOARD_SIZE, BILLBOARD_SIZE), | |
| 3219 | − true); | |
| 3220 | −#endif | |
| 3221 | 3236 | |
| 3237 | + // Need to make sure the gl context is current here | |
| 3238 | + _offscreenContext->makeCurrent(); | |
| 3239 | + | |
| 3240 | + renderArgs->_renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 3241 | + renderRearViewMirror(renderArgs, QRect(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), true); | |
| 3242 | + | |
| 3243 | + auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor(); | |
| 3222 | 3244 | QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32); |
| 3223 | − glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits()); | |
| 3224 | − glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
| 3245 | + renderArgs->_context->downloadFramebuffer(primaryFbo, glm::ivec4(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), image); | |
| 3225 | 3246 | |
| 3226 | − glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
| 3227 | 3247 | return image; |
| 3228 | 3248 | } |
| 3229 | 3249 | |
| @@ -3527,6 +3547,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 297 unmodified lines | ||
| 3527 | 3547 | sceneInterface->setEngineFeedOverlay3DItems(engineRC->_numFeedOverlay3DItems); |
| 3528 | 3548 | sceneInterface->setEngineDrawnOverlay3DItems(engineRC->_numDrawnOverlay3DItems); |
| 3529 | 3549 | } |
| 3550 | + | |
| 3530 | 3551 | //Render the sixense lasers |
| 3531 | 3552 | if (Menu::getInstance()->isOptionChecked(MenuOption::HandLasers)) { |
| 3532 | 3553 | _myAvatar->renderLaserPointers(*renderArgs->_batch); |
| @@ -3598,16 +3619,20 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi · 65 unmodified lines | ||
| 3598 | 3619 | gpu::Vec4i viewport; |
| 3599 | 3620 | if (billboard) { |
| 3600 | 3621 | QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize(); |
| 3601 | − viewport = gpu::Vec4i(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); | |
| 3622 | + viewport = gpu::Vec4i(0, 0, region.width(), region.height()); | |
| 3602 | 3623 | } else { |
| 3603 | 3624 | // if not rendering the billboard, the region is in device independent coordinates; must convert to device |
| 3604 | 3625 | QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize(); |
| 3605 | 3626 | float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale(); |
| 3606 | − int x = region.x() * ratio, y = region.y() * ratio, width = region.width() * ratio, height = region.height() * ratio; | |
| 3607 | − viewport = gpu::Vec4i(x, size.height() - y - height, width, height); | |
| 3627 | + int x = region.x() * ratio; | |
| 3628 | + int y = region.y() * ratio; | |
| 3629 | + int width = region.width() * ratio; | |
| 3630 | + int height = region.height() * ratio; | |
| 3631 | + viewport = gpu::Vec4i(0, 0, width, height); | |
| 3608 | 3632 | } |
| 3609 | 3633 | renderArgs->_viewport = viewport; |
| 3610 | 3634 | |
| 3635 | +#if 0 | |
| 3611 | 3636 | auto origRenderMode = renderArgs->_renderMode; |
| 3612 | 3637 | renderArgs->_renderMode = RenderArgs::MIRROR_RENDER_MODE; |
| 3613 | 3638 | |
| @@ -3626,14 +3651,12 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi · 12 unmodified lines | ||
| 3626 | 3651 | |
| 3627 | 3652 | bool updateViewFrustum = false; |
| 3628 | 3653 | loadViewFrustum(_mirrorCamera, _viewFrustum); |
| 3629 | − | |
| 3654 | +#endif | |
| 3655 | + | |
| 3630 | 3656 | // render rear mirror view |
| 3631 | 3657 | displaySide(renderArgs, _mirrorCamera, true, billboard); |
| 3632 | 3658 | |
| 3633 | 3659 | renderArgs->_viewport = originalViewport; |
| 3634 | − | |
| 3635 | − // restore renderMode | |
| 3636 | − renderArgs->_renderMode = origRenderMode; | |
| 3637 | 3660 | } |
| 3638 | 3661 | |
| 3639 | 3662 | void Application::resetSensors() { |
| @@ -4885,6 +4908,15 @@ mat4 Application::getEyePose(int eye) const { · 1245 unmodified lines | ||
| 4885 | 4908 | return mat4(); |
| 4886 | 4909 | } |
| 4887 | 4910 | |
| 4911 | +mat4 Application::getEyeOffset(int eye) const { | |
| 4912 | + if (isHMDMode()) { | |
| 4913 | + mat4 identity; | |
| 4914 | + return getActiveDisplayPlugin()->getModelview((Eye)eye, identity); | |
| 4915 | + } | |
| 4916 | + | |
| 4917 | + return mat4(); | |
| 4918 | +} | |
| 4919 | + | |
| 4888 | 4920 | mat4 Application::getHMDSensorPose() const { |
| 4889 | 4921 | if (isHMDMode()) { |
| 4890 | 4922 | return getActiveDisplayPlugin()->getHeadPose(); |