Working on overlays still, mirror rendering and overlay order

This commit is contained in:
Brad Davis 2015-06-17 11:35:30 -07:00
parent 5ded9e7eb9
commit 1e90aaf9c3
6 changed files with 112 additions and 70 deletions

View file

@ -230,6 +230,7 @@ Hifi.Stats {
Rectangle { Rectangle {
y: 250 y: 250
visible: root.timingExpanded
width: perfText.width + 8 width: perfText.width + 8
height: perfText.height + 8 height: perfText.height + 8
color: root.bgColor; color: root.bgColor;

View file

@ -874,6 +874,11 @@ void Application::paintGL() {
OculusManager::beginFrameTiming(); OculusManager::beginFrameTiming();
} }
{
PerformanceTimer perfTimer("renderOverlay");
_applicationOverlay.renderOverlay(&renderArgs);
}
PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::paintGL()"); PerformanceWarning warn(showWarnings, "Application::paintGL()");
@ -974,10 +979,6 @@ void Application::paintGL() {
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
} }
{
PerformanceTimer perfTimer("renderOverlay");
_applicationOverlay.renderOverlay(&renderArgs);
}
if (!OculusManager::isConnected() || OculusManager::allowSwap()) { if (!OculusManager::isConnected() || OculusManager::allowSwap()) {

View file

@ -87,16 +87,16 @@ ApplicationOverlay::~ApplicationOverlay() {
void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) { void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
glm::vec2 size = qApp->getCanvasSize(); buildFramebufferObject();
// TODO Handle fading and deactivation/activation of UI
// TODO First render the mirror to the mirror FBO // First render the mirror to the mirror FBO
renderRearViewToFbo(renderArgs);
// Execute the batch into our framebuffer // Execute the batch into our framebuffer
buildFramebufferObject();
_overlayFramebuffer->bind(); _overlayFramebuffer->bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::vec2 size = qApp->getCanvasSize();
glViewport(0, 0, size.x, size.y); glViewport(0, 0, size.x, size.y);
// Now render the overlay components together into a single texture // Now render the overlay components together into a single texture
@ -104,6 +104,7 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
//renderAudioMeter(renderArgs); //renderAudioMeter(renderArgs);
//renderCameraToggle(renderArgs); //renderCameraToggle(renderArgs);
renderStatsAndLogs(renderArgs); renderStatsAndLogs(renderArgs);
renderRearView(renderArgs);
renderDomainConnectionStatusBorder(renderArgs); renderDomainConnectionStatusBorder(renderArgs);
renderQmlUi(renderArgs); renderQmlUi(renderArgs);
@ -284,73 +285,77 @@ void ApplicationOverlay::renderAudioMeter(RenderArgs* renderArgs) {
} }
} }
void ApplicationOverlay::renderRearView(RenderArgs* renderArgs) { void fboViewport(QOpenGLFramebufferObject* fbo) {
// // Grab current viewport to reset it at the end auto size = fbo->size();
// int viewport[4]; glViewport(0, 0, size.width(), size.height());
// glGetIntegerv(GL_VIEWPORT, viewport); }
// float aspect = (float)region.width() / region.height();
// float fov = MIRROR_FIELD_OF_VIEW;
// // bool eyeRelativeCamera = false; void ApplicationOverlay::renderRearViewToFbo(RenderArgs* renderArgs) {
// if (billboard) { // Grab current viewport to reset it at the end
// fov = BILLBOARD_FIELD_OF_VIEW; // degees auto mirrorSize = _mirrorFramebuffer->size();
// _mirrorCamera.setPosition(_myAvatar->getPosition() + float aspect = (float)mirrorSize.width() / mirrorSize.height();
// _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * BILLBOARD_DISTANCE * _myAvatar->getScale()); float fov = MIRROR_FIELD_OF_VIEW;
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
// bool eyeRelativeCamera = false;
bool billboard = 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) { } else if (RearMirrorTools::rearViewZoomLevel.get() == BODY) {
// _mirrorCamera.setPosition(_myAvatar->getChestPosition() + _mirrorCamera.setPosition(myAvatar->getChestPosition() +
// _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * myAvatar->getScale());
// } else { // HEAD zoom level } else { // HEAD zoom level
// // FIXME note that the positioing of the camera relative to the avatar can suffer limited // 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 // 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 // /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 // 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 // larger, squeezing out the available digits of precision you have available at the
// // human scale for camera positioning. // human scale for camera positioning.
// // Previously there was a hack to correct this using the mechanism of repositioning // 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, // 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 // 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 // when in first person mode. Presumably this was because of some missed culling logic
// // that was not accounted for in the hack. // that was not accounted for in the hack.
// // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further
// // investigated in order to adapt the technique while fixing the head rendering issue, // investigated in order to adapt the technique while fixing the head rendering issue,
// // but the complexity of the hack suggests that a better approach // but the complexity of the hack suggests that a better approach
// _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + _mirrorCamera.setPosition(myAvatar->getHead()->getEyePosition() +
// _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); 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.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))); _mirrorCamera.setRotation(myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f)));
// // set the bounds of rear mirror view // set the bounds of rear mirror view
// if (billboard) { if (billboard) {
// QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize(); //QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
// glViewport(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); //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()); //glScissor(region.x(), size.height() - region.y() - region.height(), region.width(), region.height());
// } else { } else {
// // if not rendering the billboard, the region is in device independent coordinates; must convert to device auto mirrorSize = _mirrorFramebuffer->size();
// QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize(); fboViewport(_mirrorFramebuffer);
// float ratio = 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 _mirrorFramebuffer->bind();
// glMatrixMode(GL_MODELVIEW); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glPushMatrix(); {
// glLoadIdentity(); auto projection = _mirrorCamera.getProjection();
// glLoadMatrixf(glm::value_ptr(glm::mat4_cast(_mirrorCamera.getOrientation()) * glm::translate(glm::mat4(), _mirrorCamera.getPosition()))); glMatrixMode(GL_PROJECTION);
// renderArgs->_context->syncCache(); glLoadMatrixf(glm::value_ptr(projection));
// displaySide(renderArgs, _mirrorCamera, true, billboard); glMatrixMode(GL_MODELVIEW);
// glMatrixMode(GL_MODELVIEW); glPushMatrix();
// glPopMatrix(); glLoadIdentity();
glLoadMatrixf(glm::value_ptr(glm::mat4_cast(_mirrorCamera.getOrientation()) * glm::translate(glm::mat4(), _mirrorCamera.getPosition())));
renderArgs->_context->syncCache();
qApp->displaySide(renderArgs, _mirrorCamera, true, billboard);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
_mirrorFramebuffer->release();
// if (!billboard) { // if (!billboard) {
// _rearMirrorTools->render(renderArgs, false, _glWidget->mapFromGlobal(QCursor::pos())); // _rearMirrorTools->render(renderArgs, false, _glWidget->mapFromGlobal(QCursor::pos()));
@ -363,6 +368,30 @@ void ApplicationOverlay::renderRearView(RenderArgs* renderArgs) {
//} //}
} }
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) { void ApplicationOverlay::renderStatsAndLogs(RenderArgs* renderArgs) {
// Display stats and log text onscreen // Display stats and log text onscreen

View file

@ -33,6 +33,7 @@ private:
void renderCameraToggle(RenderArgs* renderArgs); void renderCameraToggle(RenderArgs* renderArgs);
void renderStatsAndLogs(RenderArgs* renderArgs); void renderStatsAndLogs(RenderArgs* renderArgs);
void renderDomainConnectionStatusBorder(RenderArgs* renderArgs); void renderDomainConnectionStatusBorder(RenderArgs* renderArgs);
void renderRearViewToFbo(RenderArgs* renderArgs);
void renderRearView(RenderArgs* renderArgs); void renderRearView(RenderArgs* renderArgs);
void renderQmlUi(RenderArgs* renderArgs); void renderQmlUi(RenderArgs* renderArgs);
void renderOverlays(RenderArgs* renderArgs); void renderOverlays(RenderArgs* renderArgs);
@ -52,7 +53,7 @@ private:
float _rotateMirror{ 0.0f }; float _rotateMirror{ 0.0f };
float _raiseMirror{ 0.0f }; float _raiseMirror{ 0.0f };
Camera _mirrorCamera;
ivec2 _previousBorderSize{ -1 }; ivec2 _previousBorderSize{ -1 };
QRect _mirrorViewRect; QRect _mirrorViewRect;
QOpenGLFramebufferObject* _overlayFramebuffer{ nullptr }; QOpenGLFramebufferObject* _overlayFramebuffer{ nullptr };

View file

@ -296,6 +296,10 @@ void Stats::updateStats() {
bool performanceTimerIsActive = PerformanceTimer::isActive(); bool performanceTimerIsActive = PerformanceTimer::isActive();
bool displayPerf = _expanded && Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails); bool displayPerf = _expanded && Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails);
if (displayPerf && performanceTimerIsActive) { if (displayPerf && performanceTimerIsActive) {
if (!_timingExpanded) {
_timingExpanded = true;
emit timingExpandedChanged();
}
PerformanceTimer::tallyAllTimerRecords(); // do this even if we're not displaying them, so they don't stack up PerformanceTimer::tallyAllTimerRecords(); // do this even if we're not displaying them, so they don't stack up
// we will also include room for 1 line per timing record and a header of 4 lines // we will also include room for 1 line per timing record and a header of 4 lines
@ -336,8 +340,10 @@ void Stats::updateStats() {
} }
_timingStats = perfLines; _timingStats = perfLines;
emit timingStatsChanged(); emit timingStatsChanged();
} else if (_timingExpanded) {
_timingExpanded = false;
emit timingExpandedChanged();
} }
} }
void Stats::setRenderDetails(const RenderDetails& details) { void Stats::setRenderDetails(const RenderDetails& details) {

View file

@ -31,6 +31,7 @@ class Stats : public QQuickItem {
Q_OBJECT Q_OBJECT
HIFI_QML_DECL HIFI_QML_DECL
Q_PROPERTY(bool expanded READ isExpanded WRITE setExpanded NOTIFY expandedChanged) Q_PROPERTY(bool expanded READ isExpanded WRITE setExpanded NOTIFY expandedChanged)
Q_PROPERTY(bool timingExpanded READ isTimingExpanded NOTIFY timingExpandedChanged)
STATS_PROPERTY(int, serverCount, 0) STATS_PROPERTY(int, serverCount, 0)
STATS_PROPERTY(int, framerate, 0) STATS_PROPERTY(int, framerate, 0)
STATS_PROPERTY(int, avatarCount, 0) STATS_PROPERTY(int, avatarCount, 0)
@ -82,6 +83,7 @@ public:
void updateStats(); void updateStats();
bool isExpanded() { return _expanded; } bool isExpanded() { return _expanded; }
bool isTimingExpanded() { return _timingExpanded; }
void setExpanded(bool expanded) { void setExpanded(bool expanded) {
if (_expanded != expanded) { if (_expanded != expanded) {
@ -92,6 +94,7 @@ public:
signals: signals:
void expandedChanged(); void expandedChanged();
void timingExpandedChanged();
void serverCountChanged(); void serverCountChanged();
void framerateChanged(); void framerateChanged();
void avatarCountChanged(); void avatarCountChanged();
@ -137,6 +140,7 @@ private:
int _recentMaxPackets{ 0 } ; // recent max incoming voxel packets to process int _recentMaxPackets{ 0 } ; // recent max incoming voxel packets to process
bool _resetRecentMaxPacketsSoon{ true }; bool _resetRecentMaxPacketsSoon{ true };
bool _expanded{ false }; bool _expanded{ false };
bool _timingExpanded{ false };
}; };
#endif // hifi_Stats_h #endif // hifi_Stats_h