History

Merge remote-tracking branch 'upstream/plugins' into macPluginsFix

Sam Gondelman committed 11 years ago

Commit 0e4d0652 parents 7c9189c dc4ef8e56 files · +892 −238Browse files

Showing the changes to interface/src/Application.cpp (1 of 56 files). Show all

Unified · Split

interface/src/Application.cpp+113−81
@@ -924,6 +924,30 @@ void Application::paintGL() { · 923 unmodified lines
924 PerformanceWarning warn(showWarnings, "Application::paintGL()");924 PerformanceWarning warn(showWarnings, "Application::paintGL()");
925 resizeGL();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 PerformanceTimer perfTimer("renderOverlay");953 PerformanceTimer perfTimer("renderOverlay");
@@ -940,18 +964,22 @@ void Application::paintGL() { · 10 unmodified lines
940 Application::getInstance()->cameraMenuChanged();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 if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {970 if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
944 // Always use the default eye position, not the actual head eye position.971 // Always use the default eye position, not the actual head eye position.
945 // Using the latter will cause the camera to wobble with idle animations,972 // Using the latter will cause the camera to wobble with idle animations,
946 // or with changes from the face tracker973 // or with changes from the face tracker
974 renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
947 975
948 _myCamera.setPosition(_myAvatar->getDefaultEyePosition());
949 if (!getActiveDisplayPlugin()->isHmd()) {976 if (!getActiveDisplayPlugin()->isHmd()) {
977 _myCamera.setPosition(_myAvatar->getDefaultEyePosition());
950 _myCamera.setRotation(_myAvatar->getHead()->getCameraOrientation());978 _myCamera.setRotation(_myAvatar->getHead()->getCameraOrientation());
951 } else {979 } else {
952 // The plugin getModelview() call below will compose the base980 mat4 camMat = _myAvatar->getSensorToWorldMatrix() * _myAvatar->getHMDSensorMatrix();
953 // avatar transform with the HMD pose.981 _myCamera.setPosition(extractTranslation(camMat));
954 _myCamera.setRotation(_myAvatar->getOrientation());982 _myCamera.setRotation(glm::quat_cast(camMat));
955 }983 }
956 } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {984 } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
957 if (isHMDMode()) {985 if (isHMDMode()) {
@@ -973,6 +1001,7 @@ void Application::paintGL() { · 15 unmodified lines
973 glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) +1001 glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) +
974 (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *1002 (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
975 glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);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 // Update camera position1007 // Update camera position
@@ -980,17 +1009,15 @@ void Application::paintGL() { · 1 unmodified line
980 _myCamera.update(1.0f / _fps);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 // Primary rendering pass1013 // Primary rendering pass
990 auto framebufferCache = DependencyManager::get<FramebufferCache>();1014 auto framebufferCache = DependencyManager::get<FramebufferCache>();
991 QSize size = framebufferCache->getFrameBufferSize();1015 QSize size = framebufferCache->getFrameBufferSize();
992 {1016 {
993 PROFILE_RANGE(__FUNCTION__ "/mainRender");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 PROFILE_RANGE(__FUNCTION__ "/clear");1023 PROFILE_RANGE(__FUNCTION__ "/clear");
@@ -1014,7 +1041,12 @@ void Application::paintGL() { · 17 unmodified lines
1014 for_each_eye([&](Eye eye){1041 for_each_eye([&](Eye eye){
1015 // Load the view frustum, used by meshes1042 // Load the view frustum, used by meshes
1016 Camera eyeCamera;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 eyeCamera.setProjection(displayPlugin->getProjection(eye, _myCamera.getProjection()));1050 eyeCamera.setProjection(displayPlugin->getProjection(eye, _myCamera.getProjection()));
1019 renderArgs._viewport = gpu::Vec4i(r.x(), r.y(), r.width(), r.height());1051 renderArgs._viewport = gpu::Vec4i(r.x(), r.y(), r.width(), r.height());
1020 doInBatch(&renderArgs, [&](gpu::Batch& batch) {1052 doInBatch(&renderArgs, [&](gpu::Batch& batch) {
@@ -1022,12 +1054,6 @@ void Application::paintGL() { · 1 unmodified line
1022 batch.setStateScissorRect(renderArgs._viewport);1054 batch.setStateScissorRect(renderArgs._viewport);
1023 });1055 });
1024 displaySide(&renderArgs, eyeCamera);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 r.moveLeft(r.width());1058 r.moveLeft(r.width());
1033 });1059 });
@@ -1041,13 +1067,11 @@ void Application::paintGL() { · 7 unmodified lines
1041 batch.setStateScissorRect(renderArgs._viewport);1067 batch.setStateScissorRect(renderArgs._viewport);
1042 });1068 });
1043 displaySide(&renderArgs, _myCamera);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 // Overlay Composition, needs to occur after screen space effects have completed1077 // Overlay Composition, needs to occur after screen space effects have completed
@@ -1092,6 +1116,7 @@ void Application::paintGL() { · 38 unmodified lines
1092 1116
1093 // Ensure all operations from the previous context are complete before we try to read the fbo1117 // Ensure all operations from the previous context are complete before we try to read the fbo
1094#ifdef Q_OS_MAC1118#ifdef Q_OS_MAC
1119 // FIXME once we move to core profile, use fencesync on both platforms
1095#else1120#else
1096 // FIXME? make the sync a parameter to preDisplay and let the plugin manage this1121 // FIXME? make the sync a parameter to preDisplay and let the plugin manage this
1097 glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);1122 glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
@@ -1107,11 +1132,11 @@ void Application::paintGL() { · 9 unmodified lines
1107 PROFILE_RANGE(__FUNCTION__ "/bufferSwap");1132 PROFILE_RANGE(__FUNCTION__ "/bufferSwap");
1108 displayPlugin->finishFrame();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
1117void Application::runTests() {1142void Application::runTests() {
@@ -1126,6 +1151,7 @@ void Application::audioMuteToggled() { · 8 unmodified lines
1126}1151}
1127 1152
1128void Application::faceTrackerMuteToggled() {1153void Application::faceTrackerMuteToggled() {
1154
1129 QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteFaceTracking);1155 QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteFaceTracking);
1130 Q_CHECK_PTR(muteAction);1156 Q_CHECK_PTR(muteAction);
1131 bool isMuted = getSelectedFaceTracker()->isMuted();1157 bool isMuted = getSelectedFaceTracker()->isMuted();
@@ -1154,6 +1180,7 @@ void Application::resizeGL() { · 22 unmodified lines
1154 uvec2 framebufferSize = getActiveDisplayPlugin()->getRecommendedRenderSize();1180 uvec2 framebufferSize = getActiveDisplayPlugin()->getRecommendedRenderSize();
1155 uvec2 renderSize = uvec2(vec2(framebufferSize) * getRenderResolutionScale());1181 uvec2 renderSize = uvec2(vec2(framebufferSize) * getRenderResolutionScale());
1156 if (_renderResolution != renderSize) {1182 if (_renderResolution != renderSize) {
1183 _numFramesSinceLastResize = 0;
1157 _renderResolution = renderSize;1184 _renderResolution = renderSize;
1158 DependencyManager::get<FramebufferCache>()->setFrameBufferSize(fromGlm(renderSize));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 } else if (event->button() == Qt::RightButton) {1713 } else if (event->button() == Qt::RightButton) {
1687 // right click items here1714 // 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 double timeSinceLastUpdate = (double)_lastTimeUpdated.nsecsElapsed() / 1000000.0;1967 double timeSinceLastUpdate = (double)_lastTimeUpdated.nsecsElapsed() / 1000000.0;
1938 if (timeSinceLastUpdate > targetFramePeriod) {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 _lastTimeUpdated.start();1969 _lastTimeUpdated.start();
1947 {1970 {
1948 PerformanceTimer perfTimer("update");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 // depending on whether we're throttling or not.2006 // depending on whether we're throttling or not.
1981 // Once rendering is off on another thread we should be able to have Application::idle run at start(0) in2007 // Once rendering is off on another thread we should be able to have Application::idle run at start(0) in
1982 // perpetuity and not expect events to get backed up.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 int desiredInterval = getActiveDisplayPlugin()->isThrottled() ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS;2011 int desiredInterval = getActiveDisplayPlugin()->isThrottled() ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS;
1986 2012
1987 if (idleTimer->interval() != desiredInterval) {2013 if (idleTimer->interval() != desiredInterval) {
@@ -2356,23 +2382,21 @@ void Application::updateMyAvatarLookAtPosition() { · 368 unmodified lines
2356 lookAtSpot = _myAvatar->getHead()->getEyePosition() +2382 lookAtSpot = _myAvatar->getHead()->getEyePosition() +
2357 (_myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE));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.2386 // Deflect the eyes a bit to match the detected gaze from the face tracker if active.
2362 // DDE doesn't track eyes.2387 if (tracker && !tracker->isMuted()) {
2363 if (tracker && typeid(*tracker) == typeid(Faceshift) && !tracker->isMuted()) {2388 float eyePitch = tracker->getEstimatedEyePitch();
2364 float eyePitch = tracker->getEstimatedEyePitch();2389 float eyeYaw = tracker->getEstimatedEyeYaw();
2365 float eyeYaw = tracker->getEstimatedEyeYaw();2390 const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f;
2366 const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f;2391 glm::vec3 origin = _myAvatar->getHead()->getEyePosition();
2367 glm::vec3 origin = _myAvatar->getHead()->getEyePosition();2392 float deflection = tracker->getEyeDeflection();
2368 float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f;2393 if (isLookingAtSomeone) {
2369 float deflection = DependencyManager::get<Faceshift>()->getEyeDeflection();2394 deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT;
2370 if (isLookingAtSomeone) {2395 }
2371 deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT;2396 lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3(
2372 }2397 eyePitch * deflection, eyeYaw * deflection, 0.0f))) *
2373 lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3(
2374 eyePitch * pitchSign * deflection, eyeYaw * deflection, 0.0f))) *
2375 glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin);2398 glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin);
2399 }
2376 }2400 }
2377 2401
2378 _myAvatar->getHead()->setLookAtPosition(lookAtSpot);2402 _myAvatar->getHead()->setLookAtPosition(lookAtSpot);
@@ -2549,10 +2573,18 @@ void Application::update(float deltaTime) { · 170 unmodified lines
2549 _myAvatar->setDriveKeys(DOWN, userInputMapper->getActionState(UserInputMapper::VERTICAL_DOWN));2573 _myAvatar->setDriveKeys(DOWN, userInputMapper->getActionState(UserInputMapper::VERTICAL_DOWN));
2550 _myAvatar->setDriveKeys(LEFT, userInputMapper->getActionState(UserInputMapper::LATERAL_LEFT));2574 _myAvatar->setDriveKeys(LEFT, userInputMapper->getActionState(UserInputMapper::LATERAL_LEFT));
2551 _myAvatar->setDriveKeys(RIGHT, userInputMapper->getActionState(UserInputMapper::LATERAL_RIGHT));2575 _myAvatar->setDriveKeys(RIGHT, userInputMapper->getActionState(UserInputMapper::LATERAL_RIGHT));
2552 _myAvatar->setDriveKeys(ROT_UP, userInputMapper->getActionState(UserInputMapper::PITCH_UP));2576 if (deltaTime > FLT_EPSILON) {
2553 _myAvatar->setDriveKeys(ROT_DOWN, userInputMapper->getActionState(UserInputMapper::PITCH_DOWN));2577 // For rotations what we really want are meausures of "angles per second" (in order to prevent
2554 _myAvatar->setDriveKeys(ROT_LEFT, userInputMapper->getActionState(UserInputMapper::YAW_LEFT));2578 // fps-dependent spin rates) so we need to scale the units of the controller contribution.
2555 _myAvatar->setDriveKeys(ROT_RIGHT, userInputMapper->getActionState(UserInputMapper::YAW_RIGHT));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 _myAvatar->setDriveKeys(BOOM_IN, userInputMapper->getActionState(UserInputMapper::BOOM_IN));2589 _myAvatar->setDriveKeys(BOOM_IN, userInputMapper->getActionState(UserInputMapper::BOOM_IN));
2558 _myAvatar->setDriveKeys(BOOM_OUT, userInputMapper->getActionState(UserInputMapper::BOOM_OUT));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 if (isHMDMode()) {3225 if (isHMDMode()) {
3194 getApplicationCompositor().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction);3226 getApplicationCompositor().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction);
3195 } else {3227 } else {
3196 if (QThread::currentThread() == activeRenderingThread) {3228 getViewFrustum()->computePickRay(x, y, result.origin, result.direction);
3197 getDisplayViewFrustum()->computePickRay(x, y, result.origin, result.direction);
3198 } else {
3199 getViewFrustum()->computePickRay(x, y, result.origin, result.direction);
3200 }
3201 }3229 }
3202 return result;3230 return result;
3203}3231}
3204 3232
3205QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) {3233QImage 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 const int BILLBOARD_SIZE = 64;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 QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);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());3245 renderArgs->_context->downloadFramebuffer(primaryFbo, glm::ivec4(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), image);
3224 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3225 3246
3226 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3227 return image;3247 return image;
3228}3248}
3229 3249
@@ -3527,6 +3547,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 297 unmodified lines
3527 sceneInterface->setEngineFeedOverlay3DItems(engineRC->_numFeedOverlay3DItems);3547 sceneInterface->setEngineFeedOverlay3DItems(engineRC->_numFeedOverlay3DItems);
3528 sceneInterface->setEngineDrawnOverlay3DItems(engineRC->_numDrawnOverlay3DItems);3548 sceneInterface->setEngineDrawnOverlay3DItems(engineRC->_numDrawnOverlay3DItems);
3529 }3549 }
3550
3530 //Render the sixense lasers3551 //Render the sixense lasers
3531 if (Menu::getInstance()->isOptionChecked(MenuOption::HandLasers)) {3552 if (Menu::getInstance()->isOptionChecked(MenuOption::HandLasers)) {
3532 _myAvatar->renderLaserPointers(*renderArgs->_batch);3553 _myAvatar->renderLaserPointers(*renderArgs->_batch);
@@ -3598,16 +3619,20 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi · 65 unmodified lines
3598 gpu::Vec4i viewport;3619 gpu::Vec4i viewport;
3599 if (billboard) {3620 if (billboard) {
3600 QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();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 } else {3623 } else {
3603 // if not rendering the billboard, the region is in device independent coordinates; must convert to device3624 // if not rendering the billboard, the region is in device independent coordinates; must convert to device
3604 QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();3625 QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();
3605 float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale();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;3627 int x = region.x() * ratio;
3607 viewport = gpu::Vec4i(x, size.height() - y - height, width, height);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 renderArgs->_viewport = viewport;3633 renderArgs->_viewport = viewport;
3610 3634
3635#if 0
3611 auto origRenderMode = renderArgs->_renderMode;3636 auto origRenderMode = renderArgs->_renderMode;
3612 renderArgs->_renderMode = RenderArgs::MIRROR_RENDER_MODE;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 bool updateViewFrustum = false;3652 bool updateViewFrustum = false;
3628 loadViewFrustum(_mirrorCamera, _viewFrustum);3653 loadViewFrustum(_mirrorCamera, _viewFrustum);
3629 3654#endif
3655
3630 // render rear mirror view3656 // render rear mirror view
3631 displaySide(renderArgs, _mirrorCamera, true, billboard);3657 displaySide(renderArgs, _mirrorCamera, true, billboard);
3632 3658
3633 renderArgs->_viewport = originalViewport;3659 renderArgs->_viewport = originalViewport;
3634
3635 // restore renderMode
3636 renderArgs->_renderMode = origRenderMode;
3637}3660}
3638 3661
3639void Application::resetSensors() {3662void Application::resetSensors() {
@@ -4885,6 +4908,15 @@ mat4 Application::getEyePose(int eye) const { · 1245 unmodified lines
4885 return mat4();4908 return mat4();
4886}4909}
4887 4910
4911mat4 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
4888mat4 Application::getHMDSensorPose() const {4920mat4 Application::getHMDSensorPose() const {
4889 if (isHMDMode()) {4921 if (isHMDMode()) {
4890 return getActiveDisplayPlugin()->getHeadPose();4922 return getActiveDisplayPlugin()->getHeadPose();