void ApplicationOverlay::renderDomainConnectionStatusBorder(RenderArgs* renderArgs) { auto geometryCache = DependencyManager::get<GeometryCache>(); static std::once_flag once; std::call_once(once, [&] { QVector<vec2> points; static const float B = 0.99f; points.push_back(vec2(-B)); points.push_back(vec2(B, -B)); points.push_back(vec2(B)); points.push_back(vec2(-B, B)); points.push_back(vec2(-B)); geometryCache->updateVertices(_domainStatusBorder, points, CONNECTION_STATUS_BORDER_COLOR); }); auto nodeList = DependencyManager::get<NodeList>(); if (nodeList && !nodeList->getDomainHandler().isConnected()) { gpu::Batch& batch = *renderArgs->_batch; auto geometryCache = DependencyManager::get<GeometryCache>(); geometryCache->useSimpleDrawPipeline(batch); batch.setProjectionTransform(mat4()); batch.setModelTransform(Transform()); batch.setViewTransform(Transform()); batch.setResourceTexture(0, DependencyManager::get<TextureCache>()->getWhiteTexture()); // FIXME: THe line width of CONNECTION_STATUS_BORDER_LINE_WIDTH is not supported anymore, we ll need a workaround // TODO animate the disconnect border for some excitement while not connected? //double usecs = usecTimestampNow(); //double secs = usecs / 1000000.0; //float scaleAmount = 1.0f + (0.01f * sin(secs * 5.0f)); //batch.setModelTransform(glm::scale(mat4(), vec3(scaleAmount))); geometryCache->renderVertices(batch, gpu::LINE_STRIP, _domainStatusBorder); } }
void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) { PROFILE_RANGE(render, __FUNCTION__); if (!_uiTexture) { _uiTexture = gpu::Texture::createExternal(OffscreenQmlSurface::getDiscardLambda()); _uiTexture->setSource(__FUNCTION__); } // Once we move UI rendering and screen rendering to different // threads, we need to use a sync object to deteremine when // the current UI texture is no longer being read from, and only // then release it back to the UI for re-use auto offscreenUi = DependencyManager::get<OffscreenUi>(); OffscreenQmlSurface::TextureAndFence newTextureAndFence; bool newTextureAvailable = offscreenUi->fetchTexture(newTextureAndFence); if (newTextureAvailable) { _uiTexture->setExternalTexture(newTextureAndFence.first, newTextureAndFence.second); } auto geometryCache = DependencyManager::get<GeometryCache>(); gpu::Batch& batch = *renderArgs->_batch; geometryCache->useSimpleDrawPipeline(batch); batch.setProjectionTransform(mat4()); batch.setModelTransform(Transform()); batch.resetViewTransform(); batch.setResourceTexture(0, _uiTexture); geometryCache->renderUnitQuad(batch, glm::vec4(1), _qmlGeometryId); batch.setResourceTexture(0, nullptr); }
// Draws the FBO texture for the screen void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) { if (_alpha == 0.0f) { return; } GLuint texture = qApp->getApplicationOverlay().getOverlayTexture(); if (!texture) { return; } updateTooltips(); auto deviceSize = qApp->getDeviceSize(); glViewport(0, 0, deviceSize.width(), deviceSize.height()); //Handle fading and deactivation/activation of UI gpu::Batch batch; renderArgs->_context->syncCache(); auto geometryCache = DependencyManager::get<GeometryCache>(); geometryCache->useSimpleDrawPipeline(batch); batch.setModelTransform(Transform()); batch.setViewTransform(Transform()); batch.setProjectionTransform(mat4()); batch._glBindTexture(GL_TEXTURE_2D, texture); batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha)); // Doesn't actually render renderPointers(batch); //draw the mouse pointer // Get the mouse coordinates and convert to NDC [-1, 1] vec2 canvasSize = qApp->getCanvasSize(); vec2 mousePosition = toNormalizedDeviceScale(vec2(qApp->getMouse()), canvasSize); // Invert the Y axis mousePosition.y *= -1.0f; Transform model; model.setTranslation(vec3(mousePosition, 0)); vec2 mouseSize = CURSOR_PIXEL_SIZE / canvasSize; model.setScale(vec3(mouseSize, 1.0f)); batch.setModelTransform(model); bindCursorTexture(batch); vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f }; geometryCache->renderUnitQuad(batch, vec4(1)); renderArgs->_context->render(batch); }
void ApplicationOverlay::renderRearView(RenderArgs* renderArgs) { if (!qApp->isHMDMode() && Menu::getInstance()->isOptionChecked(MenuOption::MiniMirror) && !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { gpu::Batch& batch = *renderArgs->_batch; auto geometryCache = DependencyManager::get<GeometryCache>(); auto framebuffer = DependencyManager::get<FramebufferCache>(); auto selfieTexture = framebuffer->getSelfieFramebuffer()->getRenderBuffer(0); int width = renderArgs->_viewport.z; int height = renderArgs->_viewport.w; mat4 legacyProjection = glm::ortho<float>(0, width, height, 0, ORTHO_NEAR_CLIP, ORTHO_FAR_CLIP); batch.setProjectionTransform(legacyProjection); batch.setModelTransform(Transform()); batch.setViewTransform(Transform()); float screenRatio = ((float)qApp->getDevicePixelRatio()); float renderRatio = ((float)qApp->getRenderResolutionScale()); auto viewport = qApp->getMirrorViewRect(); glm::vec2 bottomLeft(viewport.left(), viewport.top() + viewport.height()); glm::vec2 topRight(viewport.left() + viewport.width(), viewport.top()); bottomLeft *= screenRatio; topRight *= screenRatio; glm::vec2 texCoordMinCorner(0.0f, 0.0f); glm::vec2 texCoordMaxCorner(viewport.width() * renderRatio / float(selfieTexture->getWidth()), viewport.height() * renderRatio / float(selfieTexture->getHeight())); geometryCache->useSimpleDrawPipeline(batch, true); batch.setResourceTexture(0, selfieTexture); geometryCache->renderQuad(batch, bottomLeft, topRight, texCoordMinCorner, texCoordMaxCorner, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); batch.setResourceTexture(0, renderArgs->_whiteTexture); geometryCache->useSimpleDrawPipeline(batch, false); } }
void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) { PROFILE_RANGE(__FUNCTION__); if (_uiTexture) { gpu::Batch& batch = *renderArgs->_batch; auto geometryCache = DependencyManager::get<GeometryCache>(); geometryCache->useSimpleDrawPipeline(batch); batch.setProjectionTransform(mat4()); batch.setModelTransform(Transform()); batch.setViewTransform(Transform()); batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _uiTexture); geometryCache->renderUnitQuad(batch, glm::vec4(1)); } }
void ApplicationOverlay::renderAudioScope(RenderArgs* renderArgs) { PROFILE_RANGE(__FUNCTION__); gpu::Batch& batch = *renderArgs->_batch; auto geometryCache = DependencyManager::get<GeometryCache>(); geometryCache->useSimpleDrawPipeline(batch); auto textureCache = DependencyManager::get<TextureCache>(); batch.setResourceTexture(0, textureCache->getWhiteTexture()); int width = renderArgs->_viewport.z; int height = renderArgs->_viewport.w; mat4 legacyProjection = glm::ortho<float>(0, width, height, 0, ORTHO_NEAR_CLIP, ORTHO_FAR_CLIP); batch.setProjectionTransform(legacyProjection); batch.setModelTransform(Transform()); batch.setViewTransform(Transform()); // Render the audio scope DependencyManager::get<AudioScope>()->render(renderArgs, width, height); }
void ApplicationOverlay::renderOverlays(RenderArgs* renderArgs) { PROFILE_RANGE(render, __FUNCTION__); gpu::Batch& batch = *renderArgs->_batch; auto geometryCache = DependencyManager::get<GeometryCache>(); geometryCache->useSimpleDrawPipeline(batch); auto textureCache = DependencyManager::get<TextureCache>(); batch.setResourceTexture(0, textureCache->getWhiteTexture()); int width = renderArgs->_viewport.z; int height = renderArgs->_viewport.w; mat4 legacyProjection = glm::ortho<float>(0, width, height, 0, ORTHO_NEAR_CLIP, ORTHO_FAR_CLIP); batch.setProjectionTransform(legacyProjection); batch.setModelTransform(Transform()); batch.resetViewTransform(); // Render all of the Script based "HUD" aka 2D overlays. qApp->getOverlays().render(renderArgs); }
void ApplicationOverlay::renderOverlays(RenderArgs* renderArgs) { PROFILE_RANGE(__FUNCTION__); gpu::Batch& batch = *renderArgs->_batch; auto geometryCache = DependencyManager::get<GeometryCache>(); geometryCache->useSimpleDrawPipeline(batch); auto textureCache = DependencyManager::get<TextureCache>(); batch.setResourceTexture(0, textureCache->getWhiteTexture()); int width = renderArgs->_viewport.z; int height = renderArgs->_viewport.w; mat4 legacyProjection = glm::ortho<float>(0, width, height, 0, ORTHO_NEAR_CLIP, ORTHO_FAR_CLIP); batch.setProjectionTransform(legacyProjection); batch.setModelTransform(Transform()); batch.setViewTransform(Transform()); // Render all of the Script based "HUD" aka 2D overlays. // note: we call them HUD, as opposed to 2D, only because there are some cases of 3D HUD overlays, like the // cameral controls for the edit.js qApp->getOverlays().renderHUD(renderArgs); }
void AudioScope::render(RenderArgs* renderArgs, int width, int height) { if (!_isEnabled) { return; } static const glm::vec4 backgroundColor = { 0.4f, 0.4f, 0.4f, 0.6f }; static const glm::vec4 gridColor = { 0.7f, 0.7f, 0.7f, 1.0f }; static const glm::vec4 inputColor = { 0.3f, 1.0f, 0.3f, 1.0f }; static const glm::vec4 outputLeftColor = { 1.0f, 0.3f, 0.3f, 1.0f }; static const glm::vec4 outputRightColor = { 0.3f, 0.3f, 1.0f, 1.0f }; static const int gridRows = 2; int gridCols = _framesPerScope; int x = (width - (int)SCOPE_WIDTH) / 2; int y = (height - (int)SCOPE_HEIGHT) / 2; int w = (int)SCOPE_WIDTH; int h = (int)SCOPE_HEIGHT; gpu::Batch& batch = *renderArgs->_batch; auto geometryCache = DependencyManager::get<GeometryCache>(); geometryCache->useSimpleDrawPipeline(batch); auto textureCache = DependencyManager::get<TextureCache>(); batch.setResourceTexture(0, textureCache->getWhiteTexture()); // FIXME - do we really need to reset this here? we know that we're called inside of ApplicationOverlay::renderOverlays // which already set up our batch for us to have these settings mat4 legacyProjection = glm::ortho<float>(0, width, height, 0, -1000, 1000); batch.setProjectionTransform(legacyProjection); batch.setModelTransform(Transform()); batch.setViewTransform(Transform()); geometryCache->renderQuad(batch, x, y, w, h, backgroundColor, _audioScopeBackground); geometryCache->renderGrid(batch, x, y, w, h, gridRows, gridCols, gridColor, _audioScopeGrid); renderLineStrip(batch, _inputID, inputColor, x, y, _samplesPerScope, _scopeInputOffset, _scopeInput); renderLineStrip(batch, _outputLeftID, outputLeftColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputLeft); renderLineStrip(batch, _outputRightD, outputRightColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputRight); }
void AudioScope::render(RenderArgs* renderArgs, int width, int height) { if (!_isEnabled) { return; } static const glm::vec4 backgroundColor = { 0.4f, 0.4f, 0.4f, 0.6f }; static const glm::vec4 gridColor = { 0.7f, 0.7f, 0.7f, 1.0f }; static const glm::vec4 inputColor = { 0.3f, 1.0f, 0.3f, 1.0f }; static const glm::vec4 outputLeftColor = { 1.0f, 0.3f, 0.3f, 1.0f }; static const glm::vec4 outputRightColor = { 0.3f, 0.3f, 1.0f, 1.0f }; static const int gridRows = 2; int gridCols = _framesPerScope; int x = (width - (int)SCOPE_WIDTH) / 2; int y = (height - (int)SCOPE_HEIGHT) / 2; int w = (int)SCOPE_WIDTH; int h = (int)SCOPE_HEIGHT; gpu::Batch batch; auto geometryCache = DependencyManager::get<GeometryCache>(); geometryCache->useSimpleDrawPipeline(batch); auto textureCache = DependencyManager::get<TextureCache>(); batch.setResourceTexture(0, textureCache->getWhiteTexture()); mat4 legacyProjection = glm::ortho<float>(0, width, height, 0, -1000, 1000); batch.setProjectionTransform(legacyProjection); batch.setModelTransform(Transform()); batch.setViewTransform(Transform()); geometryCache->renderQuad(batch, x, y, w, h, backgroundColor); geometryCache->renderGrid(batch, x, y, w, h, gridRows, gridCols, gridColor, _audioScopeGrid); renderLineStrip(batch, _inputID, inputColor, x, y, _samplesPerScope, _scopeInputOffset, _scopeInput); renderLineStrip(batch, _outputLeftID, outputLeftColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputLeft); renderLineStrip(batch, _outputRightD, outputRightColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputRight); renderArgs->_context->syncCache(); renderArgs->_context->render(batch); }
void ViveControllerManager::updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges) { PerformanceTimer perfTimer("ViveControllerManager::updateRendering"); if (_modelLoaded) { //auto controllerPayload = new render::Payload<ViveControllerManager>(this); //auto controllerPayloadPointer = ViveControllerManager::PayloadPointer(controllerPayload); //if (_leftHandRenderID == 0) { // _leftHandRenderID = scene->allocateID(); // pendingChanges.resetItem(_leftHandRenderID, controllerPayloadPointer); //} //pendingChanges.updateItem(_leftHandRenderID, ); UserInputMapper::PoseValue leftHand = _poseStateMap[makeInput(JointChannel::LEFT_HAND).getChannel()]; UserInputMapper::PoseValue rightHand = _poseStateMap[makeInput(JointChannel::RIGHT_HAND).getChannel()]; gpu::Batch batch; auto geometryCache = DependencyManager::get<GeometryCache>(); geometryCache->useSimpleDrawPipeline(batch); DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true); auto mesh = _modelGeometry.getMesh(); batch.setInputFormat(mesh->getVertexFormat()); //batch._glBindTexture(GL_TEXTURE_2D, _uexture); if (leftHand.isValid()) { renderHand(leftHand, batch, LEFT_HAND); } if (rightHand.isValid()) { renderHand(rightHand, batch, RIGHT_HAND); } args->_context->syncCache(); args->_context->render(batch); } }
void ImageOverlay::render(RenderArgs* args) { if (!_isLoaded && _renderImage) { _isLoaded = true; _texture = DependencyManager::get<TextureCache>()->getTexture(_imageURL); } // If we are not visible or loaded, return. If we are trying to render an // image but the texture hasn't loaded, return. if (!_visible || !_isLoaded || (_renderImage && !_texture->isLoaded())) { return; } auto geometryCache = DependencyManager::get<GeometryCache>(); gpu::Batch& batch = *args->_batch; geometryCache->useSimpleDrawPipeline(batch); if (_renderImage) { batch.setResourceTexture(0, _texture->getGPUTexture()); } else { batch.setResourceTexture(0, args->_whiteTexture); } const float MAX_COLOR = 255.0f; xColor color = getColor(); float alpha = getAlpha(); glm::vec4 quadColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); int left = _bounds.left(); int right = _bounds.right() + 1; int top = _bounds.top(); int bottom = _bounds.bottom() + 1; glm::vec2 topLeft(left, top); glm::vec2 bottomRight(right, bottom); batch.setModelTransform(Transform()); // if for some reason our image is not over 0 width or height, don't attempt to render the image if (_renderImage) { float imageWidth = _texture->getWidth(); float imageHeight = _texture->getHeight(); if (imageWidth > 0 && imageHeight > 0) { QRect fromImage; if (_wantClipFromImage) { float scaleX = imageWidth / _texture->getOriginalWidth(); float scaleY = imageHeight / _texture->getOriginalHeight(); fromImage.setX(scaleX * _fromImage.x()); fromImage.setY(scaleY * _fromImage.y()); fromImage.setWidth(scaleX * _fromImage.width()); fromImage.setHeight(scaleY * _fromImage.height()); } else { fromImage.setX(0); fromImage.setY(0); fromImage.setWidth(imageWidth); fromImage.setHeight(imageHeight); } float x = fromImage.x() / imageWidth; float y = fromImage.y() / imageHeight; float w = fromImage.width() / imageWidth; // ?? is this what we want? not sure float h = fromImage.height() / imageHeight; glm::vec2 texCoordTopLeft(x, y); glm::vec2 texCoordBottomRight(x + w, y + h); glm::vec4 texcoordRect(texCoordTopLeft, w, h); DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor); } else { DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor); } } else { DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor); } }
// Draws the FBO texture for Oculus rift. void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int eye) { if (_alpha == 0.0f) { return; } GLuint texture = qApp->getApplicationOverlay().getOverlayTexture(); if (!texture) { return; } updateTooltips(); vec2 canvasSize = qApp->getCanvasSize(); _textureAspectRatio = aspect(canvasSize); renderArgs->_context->syncCache(); auto geometryCache = DependencyManager::get<GeometryCache>(); gpu::Batch batch; geometryCache->useSimpleDrawPipeline(batch); batch._glDisable(GL_DEPTH_TEST); batch._glDisable(GL_CULL_FACE); batch._glBindTexture(GL_TEXTURE_2D, texture); batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); batch.setViewTransform(Transform()); batch.setProjectionTransform(qApp->getEyeProjection(eye)); mat4 eyePose = qApp->getEyePose(eye); glm::mat4 overlayXfm = glm::inverse(eyePose); #ifdef DEBUG_OVERLAY { batch.setModelTransform(glm::translate(mat4(), vec3(0, 0, -2))); geometryCache->renderUnitQuad(batch, glm::vec4(1)); } #else { batch.setModelTransform(overlayXfm); drawSphereSection(batch); } #endif // Doesn't actually render renderPointers(batch); vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize); bindCursorTexture(batch); MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar(); //Controller Pointers for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) { PalmData& palm = myAvatar->getHand()->getPalms()[i]; if (palm.isActive()) { glm::vec2 polar = getPolarCoordinates(palm); // Convert to quaternion mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); mat4 reticleXfm = overlayXfm * pointerXfm; reticleXfm = glm::scale(reticleXfm, reticleScale); batch.setModelTransform(reticleXfm); // Render reticle at location geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); } } //Mouse Pointer if (_reticleActive[MOUSE]) { glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(), _reticlePosition[MOUSE].y())); mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); mat4 reticleXfm = overlayXfm * pointerXfm; reticleXfm = glm::scale(reticleXfm, reticleScale); batch.setModelTransform(reticleXfm); geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); } renderArgs->_context->render(batch); }