// Renders the overlays either to a texture or to the screen void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) { PROFILE_RANGE(__FUNCTION__); CHECK_GL_ERROR(); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()"); // TODO move to Application::idle()? Stats::getInstance()->updateStats(); AvatarInputs::getInstance()->update(); buildFramebufferObject(); if (!_overlayFramebuffer) { return; // we can't do anything without our frame buffer. } // Execute the batch into our framebuffer gpu::Batch batch; renderArgs->_batch = &batch; int width = _overlayFramebuffer->getWidth(); int height = _overlayFramebuffer->getHeight(); batch.setViewportTransform(glm::ivec4(0, 0, width, height)); batch.setFramebuffer(_overlayFramebuffer); glm::vec4 color { 0.0f, 0.0f, 0.0f, 0.0f }; float depth = 1.0f; int stencil = 0; batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH, color, depth, stencil); // Now render the overlay components together into a single texture renderDomainConnectionStatusBorder(renderArgs); // renders the connected domain line renderAudioScope(renderArgs); // audio scope in the very back renderRearView(renderArgs); // renders the mirror view selfie renderQmlUi(renderArgs); // renders a unit quad with the QML UI texture, and the text overlays from scripts renderOverlays(renderArgs); // renders Scripts Overlay and AudioScope renderStatsAndLogs(renderArgs); // currently renders nothing renderArgs->_context->render(batch); renderArgs->_batch = nullptr; // so future users of renderArgs don't try to use our batch CHECK_GL_ERROR(); }
QImage AbstractAudioScopeWidget::renderScope(uint accelerationFactor) { const int newData = m_newData.fetchAndStoreAcquire(0); return renderAudioScope(accelerationFactor, m_audioFrame, m_freq, m_nChannels, m_nSamples, newData); }