Reverting mirror functionality

This commit is contained in:
Brad Davis 2015-06-19 00:03:46 -07:00
parent 0fa6ac175f
commit 9bef5f011b
11 changed files with 196 additions and 221 deletions

View file

@ -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;
}
}

View file

@ -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 <typename F>
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<LODManager>();
/*
{
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<LODManager>();
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<TextureCache>()->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<GlowEffect>()->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<TextureCache>()->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<TextureCache>()->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>();
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<AvatarManager>()->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<TextureCache>()->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<TextureCache>()->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<TextureCache>()->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<Faceshift>()->reset();
DependencyManager::get<DdeFaceTracker>()->reset();

View file

@ -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<bool> _firstRun;
Setting::Handle<QString> _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;

View file

@ -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;
}

View file

@ -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<TextureCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();

View file

@ -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<GeometryCache>();
_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<AvatarManager>()->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>();
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<TextureCache>();
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()) {

View file

@ -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

View file

@ -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++;

View file

@ -689,4 +689,20 @@ void GLBackend::fetchMatrix(GLenum target, glm::mat4 & m) {
glGetFloatv(target, glm::value_ptr(m));
}
void GLBackend::checkGLStackStable(std::function<void()> 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
}

View file

@ -12,11 +12,13 @@
#define hifi_gpu_GLBackend_h
#include <assert.h>
#include <functional>
#include <bitset>
#include "GPUConfig.h"
#include "Context.h"
#include "Batch.h"
#include <bitset>
namespace gpu {
@ -50,6 +52,8 @@ public:
// Only checks in debug builds
static bool checkGLErrorDebug(const char* name = nullptr);
static void checkGLStackStable(std::function<void()> f);
static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings = Shader::BindingSet());

View file

@ -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