Showing the changes to interface/src/Application.cpp (1 of 44 files). Show all
Unified · Split
| @@ -921,6 +921,30 @@ void Application::paintGL() { · 920 unmodified lines | ||
| 921 | 921 | PerformanceWarning warn(showWarnings, "Application::paintGL()"); |
| 922 | 922 | resizeGL(); |
| 923 | 923 | |
| 924 | + // Before anything else, let's sync up the gpuContext with the true glcontext used in case anything happened | |
| 925 | + renderArgs._context->syncCache(); | |
| 926 | + | |
| 927 | + if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { | |
| 928 | + auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor(); | |
| 929 | + | |
| 930 | + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | |
| 931 | + renderRearViewMirror(&renderArgs, _mirrorViewRect); | |
| 932 | + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 933 | + | |
| 934 | + { | |
| 935 | + float ratio = ((float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale()); | |
| 936 | + auto mirrorViewport = glm::ivec4(0, 0, _mirrorViewRect.width() * ratio, _mirrorViewRect.height() * ratio); | |
| 937 | + auto mirrorViewportDest = mirrorViewport; | |
| 938 | + | |
| 939 | + auto selfieFbo = DependencyManager::get<FramebufferCache>()->getSelfieFramebuffer(); | |
| 940 | + gpu::Batch batch; | |
| 941 | + batch.setFramebuffer(selfieFbo); | |
| 942 | + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); | |
| 943 | + batch.blit(primaryFbo, mirrorViewport, selfieFbo, mirrorViewportDest); | |
| 944 | + batch.setFramebuffer(nullptr); | |
| 945 | + renderArgs._context->render(batch); | |
| 946 | + } | |
| 947 | + } | |
| 924 | 948 | |
| 925 | 949 | { |
| 926 | 950 | PerformanceTimer perfTimer("renderOverlay"); |
| @@ -937,10 +961,14 @@ void Application::paintGL() { · 10 unmodified lines | ||
| 937 | 961 | Application::getInstance()->cameraMenuChanged(); |
| 938 | 962 | } |
| 939 | 963 | |
| 964 | + // The render mode is default or mirror if the camera is in mirror mode, assigned further below | |
| 965 | + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 966 | + | |
| 940 | 967 | if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { |
| 941 | 968 | // Always use the default eye position, not the actual head eye position. |
| 942 | 969 | // Using the latter will cause the camera to wobble with idle animations, |
| 943 | 970 | // or with changes from the face tracker |
| 971 | + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 944 | 972 | |
| 945 | 973 | _myCamera.setPosition(_myAvatar->getDefaultEyePosition()); |
| 946 | 974 | if (!getActiveDisplayPlugin()->isHmd()) { |
| @@ -970,6 +998,7 @@ void Application::paintGL() { · 23 unmodified lines | ||
| 970 | 998 | glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + |
| 971 | 999 | (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * |
| 972 | 1000 | glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); |
| 1001 | + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | |
| 973 | 1002 | } |
| 974 | 1003 | |
| 975 | 1004 | // Update camera position |
| @@ -977,17 +1006,15 @@ void Application::paintGL() { · 1 unmodified line | ||
| 977 | 1006 | _myCamera.update(1.0f / _fps); |
| 978 | 1007 | } |
| 979 | 1008 | |
| 980 | − // Sync up the View Furstum with the camera | |
| 981 | − loadViewFrustum(_myCamera, _viewFrustum); | |
| 982 | − | |
| 983 | − | |
| 984 | − renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 985 | 1009 | |
| 986 | 1010 | // Primary rendering pass |
| 987 | 1011 | auto framebufferCache = DependencyManager::get<FramebufferCache>(); |
| 988 | 1012 | QSize size = framebufferCache->getFrameBufferSize(); |
| 989 | 1013 | { |
| 990 | 1014 | PROFILE_RANGE(__FUNCTION__ "/mainRender"); |
| 1015 | + // Viewport is assigned to the size of the framebuffer | |
| 1016 | + QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize(); | |
| 1017 | + renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); | |
| 991 | 1018 | |
| 992 | 1019 | { |
| 993 | 1020 | PROFILE_RANGE(__FUNCTION__ "/clear"); |
| @@ -1019,12 +1046,6 @@ void Application::paintGL() { · 25 unmodified lines | ||
| 1019 | 1046 | batch.setStateScissorRect(renderArgs._viewport); |
| 1020 | 1047 | }); |
| 1021 | 1048 | displaySide(&renderArgs, eyeCamera); |
| 1022 | − if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && | |
| 1023 | − !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { | |
| 1024 | −// renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | |
| 1025 | −// renderRearViewMirror(&renderArgs, _mirrorViewRect); | |
| 1026 | −// renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE; | |
| 1027 | − } | |
| 1028 | 1049 | }, [&] { |
| 1029 | 1050 | r.moveLeft(r.width()); |
| 1030 | 1051 | }); |
| @@ -1038,13 +1059,11 @@ void Application::paintGL() { · 7 unmodified lines | ||
| 1038 | 1059 | batch.setStateScissorRect(renderArgs._viewport); |
| 1039 | 1060 | }); |
| 1040 | 1061 | displaySide(&renderArgs, _myCamera); |
| 1041 | − if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && | |
| 1042 | − !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { | |
| 1043 | − renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | |
| 1044 | − renderRearViewMirror(&renderArgs, _mirrorViewRect); | |
| 1045 | − renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE; | |
| 1046 | − } | |
| 1047 | 1062 | } |
| 1063 | + | |
| 1064 | + doInBatch(&renderArgs, [](gpu::Batch& batch){ | |
| 1065 | + batch.setFramebuffer(nullptr); | |
| 1066 | + }); | |
| 1048 | 1067 | } |
| 1049 | 1068 | |
| 1050 | 1069 | // Overlay Composition, needs to occur after screen space effects have completed |
| @@ -1089,6 +1108,7 @@ void Application::paintGL() { · 38 unmodified lines | ||
| 1089 | 1108 | |
| 1090 | 1109 | // Ensure all operations from the previous context are complete before we try to read the fbo |
| 1091 | 1110 | #ifdef Q_OS_MAC |
| 1111 | + // FIXME once we move to core profile, use fencesync on both platforms | |
| 1092 | 1112 | #else |
| 1093 | 1113 | // FIXME? make the sync a parameter to preDisplay and let the plugin manage this |
| 1094 | 1114 | glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); |
| @@ -1104,11 +1124,11 @@ void Application::paintGL() { · 9 unmodified lines | ||
| 1104 | 1124 | PROFILE_RANGE(__FUNCTION__ "/bufferSwap"); |
| 1105 | 1125 | displayPlugin->finishFrame(); |
| 1106 | 1126 | } |
| 1107 | − | |
| 1108 | − _offscreenContext->makeCurrent(); | |
| 1109 | − _frameCount++; | |
| 1110 | − Stats::getInstance()->setRenderDetails(renderArgs._details); | |
| 1111 | 1127 | } |
| 1128 | + | |
| 1129 | + _offscreenContext->makeCurrent(); | |
| 1130 | + _frameCount++; | |
| 1131 | + Stats::getInstance()->setRenderDetails(renderArgs._details); | |
| 1112 | 1132 | } |
| 1113 | 1133 | |
| 1114 | 1134 | void Application::runTests() { |
| @@ -1151,6 +1171,7 @@ void Application::resizeGL() { · 36 unmodified lines | ||
| 1151 | 1171 | uvec2 framebufferSize = getActiveDisplayPlugin()->getRecommendedRenderSize(); |
| 1152 | 1172 | uvec2 renderSize = uvec2(vec2(framebufferSize) * getRenderResolutionScale()); |
| 1153 | 1173 | if (_renderResolution != renderSize) { |
| 1174 | + _numFramesSinceLastResize = 0; | |
| 1154 | 1175 | _renderResolution = renderSize; |
| 1155 | 1176 | DependencyManager::get<FramebufferCache>()->setFrameBufferSize(fromGlm(renderSize)); |
| 1156 | 1177 | |
| @@ -1933,13 +1954,6 @@ void Application::idle() { · 776 unmodified lines | ||
| 1933 | 1954 | } |
| 1934 | 1955 | double timeSinceLastUpdate = (double)_lastTimeUpdated.nsecsElapsed() / 1000000.0; |
| 1935 | 1956 | if (timeSinceLastUpdate > targetFramePeriod) { |
| 1936 | − | |
| 1937 | − { | |
| 1938 | − static const int IDLE_EVENT_PROCESS_MAX_TIME_MS = 2; | |
| 1939 | − PerformanceTimer perfTimer("processEvents"); | |
| 1940 | − processEvents(QEventLoop::AllEvents, IDLE_EVENT_PROCESS_MAX_TIME_MS); | |
| 1941 | − } | |
| 1942 | − | |
| 1943 | 1957 | _lastTimeUpdated.start(); |
| 1944 | 1958 | { |
| 1945 | 1959 | PerformanceTimer perfTimer("update"); |
| @@ -1978,7 +1992,7 @@ void Application::idle() { · 32 unmodified lines | ||
| 1978 | 1992 | // Once rendering is off on another thread we should be able to have Application::idle run at start(0) in |
| 1979 | 1993 | // perpetuity and not expect events to get backed up. |
| 1980 | 1994 | |
| 1981 | − static const int IDLE_TIMER_DELAY_MS = 0; | |
| 1995 | + static const int IDLE_TIMER_DELAY_MS = 2; | |
| 1982 | 1996 | int desiredInterval = getActiveDisplayPlugin()->isThrottled() ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS; |
| 1983 | 1997 | |
| 1984 | 1998 | if (idleTimer->interval() != desiredInterval) { |
| @@ -2353,23 +2367,21 @@ void Application::updateMyAvatarLookAtPosition() { · 368 unmodified lines | ||
| 2353 | 2367 | lookAtSpot = _myAvatar->getHead()->getEyePosition() + |
| 2354 | 2368 | (_myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); |
| 2355 | 2369 | } |
| 2356 | − } | |
| 2357 | 2370 | |
| 2358 | − // Deflect the eyes a bit to match the detected gaze from Faceshift if active. | |
| 2359 | − // DDE doesn't track eyes. | |
| 2360 | − if (tracker && typeid(*tracker) == typeid(Faceshift) && !tracker->isMuted()) { | |
| 2361 | − float eyePitch = tracker->getEstimatedEyePitch(); | |
| 2362 | − float eyeYaw = tracker->getEstimatedEyeYaw(); | |
| 2363 | − const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f; | |
| 2364 | − glm::vec3 origin = _myAvatar->getHead()->getEyePosition(); | |
| 2365 | − float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f; | |
| 2366 | − float deflection = DependencyManager::get<Faceshift>()->getEyeDeflection(); | |
| 2367 | − if (isLookingAtSomeone) { | |
| 2368 | − deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT; | |
| 2369 | − } | |
| 2370 | − lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( | |
| 2371 | − eyePitch * pitchSign * deflection, eyeYaw * deflection, 0.0f))) * | |
| 2371 | + // Deflect the eyes a bit to match the detected gaze from the face tracker if active. | |
| 2372 | + if (tracker && !tracker->isMuted()) { | |
| 2373 | + float eyePitch = tracker->getEstimatedEyePitch(); | |
| 2374 | + float eyeYaw = tracker->getEstimatedEyeYaw(); | |
| 2375 | + const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f; | |
| 2376 | + glm::vec3 origin = _myAvatar->getHead()->getEyePosition(); | |
| 2377 | + float deflection = tracker->getEyeDeflection(); | |
| 2378 | + if (isLookingAtSomeone) { | |
| 2379 | + deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT; | |
| 2380 | + } | |
| 2381 | + lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( | |
| 2382 | + eyePitch * deflection, eyeYaw * deflection, 0.0f))) * | |
| 2372 | 2383 | glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin); |
| 2384 | + } | |
| 2373 | 2385 | } |
| 2374 | 2386 | |
| 2375 | 2387 | _myAvatar->getHead()->setLookAtPosition(lookAtSpot); |
| @@ -2546,10 +2558,18 @@ void Application::update(float deltaTime) { · 170 unmodified lines | ||
| 2546 | 2558 | _myAvatar->setDriveKeys(DOWN, userInputMapper->getActionState(UserInputMapper::VERTICAL_DOWN)); |
| 2547 | 2559 | _myAvatar->setDriveKeys(LEFT, userInputMapper->getActionState(UserInputMapper::LATERAL_LEFT)); |
| 2548 | 2560 | _myAvatar->setDriveKeys(RIGHT, userInputMapper->getActionState(UserInputMapper::LATERAL_RIGHT)); |
| 2549 | − _myAvatar->setDriveKeys(ROT_UP, userInputMapper->getActionState(UserInputMapper::PITCH_UP)); | |
| 2550 | − _myAvatar->setDriveKeys(ROT_DOWN, userInputMapper->getActionState(UserInputMapper::PITCH_DOWN)); | |
| 2551 | − _myAvatar->setDriveKeys(ROT_LEFT, userInputMapper->getActionState(UserInputMapper::YAW_LEFT)); | |
| 2552 | − _myAvatar->setDriveKeys(ROT_RIGHT, userInputMapper->getActionState(UserInputMapper::YAW_RIGHT)); | |
| 2561 | + if (deltaTime > FLT_EPSILON) { | |
| 2562 | + // For rotations what we really want are meausures of "angles per second" (in order to prevent | |
| 2563 | + // fps-dependent spin rates) so we need to scale the units of the controller contribution. | |
| 2564 | + // (TODO?: maybe we should similarly scale ALL action state info, or change the expected behavior | |
| 2565 | + // controllers to provide a delta_per_second value rather than a raw delta.) | |
| 2566 | + const float EXPECTED_FRAME_RATE = 60.0f; | |
| 2567 | + float timeFactor = EXPECTED_FRAME_RATE * deltaTime; | |
| 2568 | + _myAvatar->setDriveKeys(ROT_UP, userInputMapper->getActionState(UserInputMapper::PITCH_UP) / timeFactor); | |
| 2569 | + _myAvatar->setDriveKeys(ROT_DOWN, userInputMapper->getActionState(UserInputMapper::PITCH_DOWN) / timeFactor); | |
| 2570 | + _myAvatar->setDriveKeys(ROT_LEFT, userInputMapper->getActionState(UserInputMapper::YAW_LEFT) / timeFactor); | |
| 2571 | + _myAvatar->setDriveKeys(ROT_RIGHT, userInputMapper->getActionState(UserInputMapper::YAW_RIGHT) / timeFactor); | |
| 2572 | + } | |
| 2553 | 2573 | } |
| 2554 | 2574 | _myAvatar->setDriveKeys(BOOM_IN, userInputMapper->getActionState(UserInputMapper::BOOM_IN)); |
| 2555 | 2575 | _myAvatar->setDriveKeys(BOOM_OUT, userInputMapper->getActionState(UserInputMapper::BOOM_OUT)); |
| @@ -3190,37 +3210,25 @@ PickRay Application::computePickRay(float x, float y) const { · 634 unmodified lines | ||
| 3190 | 3210 | if (isHMDMode()) { |
| 3191 | 3211 | getApplicationCompositor().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction); |
| 3192 | 3212 | } else { |
| 3193 | − if (QThread::currentThread() == activeRenderingThread) { | |
| 3194 | − getDisplayViewFrustum()->computePickRay(x, y, result.origin, result.direction); | |
| 3195 | − } else { | |
| 3196 | − getViewFrustum()->computePickRay(x, y, result.origin, result.direction); | |
| 3197 | − } | |
| 3213 | + getViewFrustum()->computePickRay(x, y, result.origin, result.direction); | |
| 3198 | 3214 | } |
| 3199 | 3215 | return result; |
| 3200 | 3216 | } |
| 3201 | 3217 | |
| 3202 | 3218 | QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) { |
| 3203 | − auto primaryFramebuffer = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer(); | |
| 3204 | − glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer)); | |
| 3205 | − | |
| 3206 | − // clear the alpha channel so the background is transparent | |
| 3207 | − glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); | |
| 3208 | − glClearColor(0.0, 0.0, 0.0, 0.0); | |
| 3209 | − glClear(GL_COLOR_BUFFER_BIT); | |
| 3210 | − glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); | |
| 3211 | 3219 | |
| 3212 | 3220 | const int BILLBOARD_SIZE = 64; |
| 3213 | −#if 0 | |
| 3214 | − renderRearViewMirror(renderArgs, QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE, | |
| 3215 | − BILLBOARD_SIZE, BILLBOARD_SIZE), | |
| 3216 | − true); | |
| 3217 | −#endif | |
| 3218 | 3221 | |
| 3222 | + // Need to make sure the gl context is current here | |
| 3223 | + _offscreenContext->makeCurrent(); | |
| 3224 | + | |
| 3225 | + renderArgs->_renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 3226 | + renderRearViewMirror(renderArgs, QRect(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), true); | |
| 3227 | + | |
| 3228 | + auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor(); | |
| 3219 | 3229 | QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32); |
| 3220 | − glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits()); | |
| 3221 | − glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
| 3230 | + renderArgs->_context->downloadFramebuffer(primaryFbo, glm::ivec4(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), image); | |
| 3222 | 3231 | |
| 3223 | − glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
| 3224 | 3232 | return image; |
| 3225 | 3233 | } |
| 3226 | 3234 | |
| @@ -3595,16 +3603,20 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi · 368 unmodified lines | ||
| 3595 | 3603 | gpu::Vec4i viewport; |
| 3596 | 3604 | if (billboard) { |
| 3597 | 3605 | QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize(); |
| 3598 | − viewport = gpu::Vec4i(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); | |
| 3606 | + viewport = gpu::Vec4i(0, 0, region.width(), region.height()); | |
| 3599 | 3607 | } else { |
| 3600 | 3608 | // if not rendering the billboard, the region is in device independent coordinates; must convert to device |
| 3601 | 3609 | QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize(); |
| 3602 | 3610 | float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale(); |
| 3603 | − int x = region.x() * ratio, y = region.y() * ratio, width = region.width() * ratio, height = region.height() * ratio; | |
| 3604 | − viewport = gpu::Vec4i(x, size.height() - y - height, width, height); | |
| 3611 | + int x = region.x() * ratio; | |
| 3612 | + int y = region.y() * ratio; | |
| 3613 | + int width = region.width() * ratio; | |
| 3614 | + int height = region.height() * ratio; | |
| 3615 | + viewport = gpu::Vec4i(0, 0, width, height); | |
| 3605 | 3616 | } |
| 3606 | 3617 | renderArgs->_viewport = viewport; |
| 3607 | 3618 | |
| 3619 | +#if 0 | |
| 3608 | 3620 | auto origRenderMode = renderArgs->_renderMode; |
| 3609 | 3621 | renderArgs->_renderMode = RenderArgs::MIRROR_RENDER_MODE; |
| 3610 | 3622 | |
| @@ -3623,14 +3635,12 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi · 12 unmodified lines | ||
| 3623 | 3635 | |
| 3624 | 3636 | bool updateViewFrustum = false; |
| 3625 | 3637 | loadViewFrustum(_mirrorCamera, _viewFrustum); |
| 3626 | − | |
| 3638 | +#endif | |
| 3639 | + | |
| 3627 | 3640 | // render rear mirror view |
| 3628 | 3641 | displaySide(renderArgs, _mirrorCamera, true, billboard); |
| 3629 | 3642 | |
| 3630 | 3643 | renderArgs->_viewport = originalViewport; |
| 3631 | − | |
| 3632 | − // restore renderMode | |
| 3633 | − renderArgs->_renderMode = origRenderMode; | |
| 3634 | 3644 | } |
| 3635 | 3645 | |
| 3636 | 3646 | void Application::resetSensors() { |