This page contains Windows bias

About This Page

This page is part of the Azure documentation. It contains code examples and configuration instructions for working with Azure services.

Bias Analysis

Bias Types:
⚠️ windows_first
⚠️ missing_linux_example
⚠️ windows_tools
⚠️ powershell_heavy
Summary:
The documentation is heavily biased towards Windows development, specifically targeting Visual Studio, Windows SDK, and UWP. All instructions, tools, and code samples are tailored exclusively for Windows, with no mention of Linux or cross-platform alternatives. There are no Linux equivalents or guidance for non-Windows environments.
Recommendations:
  • Add a section or parallel tutorial for Linux users, outlining how to set up a similar development environment using cross-platform tools (e.g., CMake, GCC/Clang, VS Code).
  • Provide code samples and project setup instructions for Linux, including how to link dependencies and manage project files outside of Visual Studio.
  • Mention and, where possible, support cross-platform graphics APIs or abstractions (e.g., OpenGL, Vulkan) alongside DirectX11.
  • Reference cross-platform package managers (e.g., vcpkg, Conan) for dependency management instead of only NuGet.
  • Clarify early in the documentation that the tutorial is Windows-specific, and provide links or guidance for users on other platforms.
  • If Remote Rendering is not supported on Linux, explicitly state this and provide any available workarounds or roadmap information.
GitHub Create pull request

Scan History

Date Scan ID Status Bias Status
2025-08-17 00:01 #83 in_progress ✅ Clean
2025-07-13 21:37 #48 completed ❌ Biased
2025-07-12 23:44 #41 in_progress ❌ Biased

Flagged Code Snippets

HolographicAppMain::HolographicAppMain(std::shared_ptr<DX::DeviceResources> const& deviceResources) : m_deviceResources(deviceResources) { // 1. One time initialization { RR::RemoteRenderingInitialization clientInit; clientInit.ConnectionType = RR::ConnectionType::General; clientInit.GraphicsApi = RR::GraphicsApiType::WmrD3D11; clientInit.ToolId = "<sample name goes here>"; // <put your sample name here> clientInit.UnitsPerMeter = 1.0f; clientInit.Forward = RR::Axis::NegativeZ; clientInit.Right = RR::Axis::X; clientInit.Up = RR::Axis::Y; if (RR::StartupRemoteRendering(clientInit) != RR::Result::Success) { // something fundamental went wrong with the initialization throw std::exception("Failed to start remote rendering. Invalid client init data."); } } // 2. Create Client { // Users need to fill out the following with their account data and model RR::SessionConfiguration init; init.AccountId = "00000000-0000-0000-0000-000000000000"; init.AccountKey = "<account key>"; init.RemoteRenderingDomain = "westus2.mixedreality.azure.com"; // <change to the region that the rendering session should be created in> init.AccountDomain = "westus2.mixedreality.azure.com"; // <change to the region the account was created in> m_modelURI = "builtin://Engine"; m_sessionOverride = ""; // If there is a valid session ID to re-use, put it here. Otherwise a new one is created m_client = RR::ApiHandle(RR::RemoteRenderingClient(init)); } // 3. Open/create rendering session { auto SessionHandler = [&](RR::Status status, RR::ApiHandle<RR::CreateRenderingSessionResult> result) { if (status == RR::Status::OK) { auto ctx = result->GetContext(); if (ctx.Result == RR::Result::Success) { SetNewSession(result->GetSession()); } else { SetNewState(AppConnectionStatus::ConnectionFailed, ctx.ErrorMessage.c_str()); } } else { SetNewState(AppConnectionStatus::ConnectionFailed, "failed"); } }; // If we had an old (valid) session that we can recycle, we call async function m_client->OpenRenderingSessionAsync if (!m_sessionOverride.empty()) { m_client->OpenRenderingSessionAsync(m_sessionOverride, SessionHandler); SetNewState(AppConnectionStatus::CreatingSession, nullptr); } else { // create a new session RR::RenderingSessionCreationOptions init; init.MaxLeaseInMinutes = 10; // session is leased for 10 minutes init.Size = RR::RenderingSessionVmSize::Standard; m_client->CreateNewRenderingSessionAsync(init, SessionHandler); SetNewState(AppConnectionStatus::CreatingSession, nullptr); } } // Rest of constructor code: ... }
// Updates the application state once per frame. HolographicFrame HolographicAppMain::Update() { if (m_session != nullptr) { // Tick the client to receive messages m_api->Update(); if (!m_sessionStarted) { // Important: To avoid server-side throttling of the requests, we should call GetPropertiesAsync very infrequently: const double delayBetweenRESTCalls = 10.0; // query session status periodically until we reach 'session started' if (m_sessionPropertiesAsync == nullptr && m_timer.GetTotalSeconds() - m_timeAtLastRESTCall > delayBetweenRESTCalls) { m_timeAtLastRESTCall = m_timer.GetTotalSeconds(); m_session->GetPropertiesAsync([this](RR::Status status, RR::ApiHandle<RR::RenderingSessionPropertiesResult> propertiesResult) { if (status == RR::Status::OK) { auto ctx = propertiesResult->GetContext(); if (ctx.Result == RR::Result::Success) { auto res = propertiesResult->GetSessionProperties(); switch (res.Status) { case RR::RenderingSessionStatus::Ready: { // The following ConnectAsync is async, but we'll get notifications via OnConnectionStatusChanged m_sessionStarted = true; SetNewState(AppConnectionStatus::Connecting, nullptr); RR::RendererInitOptions init; init.IgnoreCertificateValidation = false; init.RenderMode = RR::ServiceRenderMode::Default; m_session->ConnectAsync(init, [](RR::Status, RR::ConnectionStatus) {}); } break; case RR::RenderingSessionStatus::Error: SetNewState(AppConnectionStatus::ConnectionFailed, "Session error"); break; case RR::RenderingSessionStatus::Stopped: SetNewState(AppConnectionStatus::ConnectionFailed, "Session stopped"); break; case RR::RenderingSessionStatus::Expired: SetNewState(AppConnectionStatus::ConnectionFailed, "Session expired"); break; } } else { SetNewState(AppConnectionStatus::ConnectionFailed, ctx.ErrorMessage.c_str()); } } else { SetNewState(AppConnectionStatus::ConnectionFailed, "Failed to retrieve session status"); } m_sessionPropertiesQueryInProgress = false; // next try }); } } } if (m_isConnected && !m_modelLoadTriggered) { m_modelLoadTriggered = true; StartModelLoading(); } } if (m_needsCoordinateSystemUpdate && m_stationaryReferenceFrame && m_graphicsBinding) { // Set the coordinate system once. This must be called again whenever the coordinate system changes. winrt::com_ptr<ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem> ptr{ m_stationaryReferenceFrame.CoordinateSystem().as<ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem>() }; m_graphicsBinding->UpdateUserCoordinateSystem(ptr.get()); m_needsCoordinateSystemUpdate = false; } // Rest of the body: ... }
... if (m_isConnected) { // Any near/far plane values of your choosing. constexpr float fNear = 0.1f; constexpr float fFar = 10.0f; for (HolographicCameraPose const& cameraPose : prediction.CameraPoses()) { // Set near and far to the holographic camera as normal cameraPose.HolographicCamera().SetNearPlaneDistance(fNear); cameraPose.HolographicCamera().SetFarPlaneDistance(fFar); } // The API to inform the server always requires near < far. Depth buffer data will be converted locally to match what is set on the HolographicCamera. auto settings = m_api->GetCameraSettings(); settings->SetNearAndFarPlane(std::min(fNear, fFar), std::max(fNear, fFar)); settings->SetEnableDepth(true); } // The holographic frame will be used to get up-to-date view and projection matrices and // to present the swap chain. return holographicFrame; }
#include <AzureRemoteRendering.inl> #include <RemoteRenderingExtensions.h> #include <windows.perception.spatial.h>
class HolographicAppMain { ... // members: std::string m_sessionOverride; // if we have a valid session ID, we specify it here. Otherwise a new one is created RR::ApiHandle<RR::RemoteRenderingClient> m_client; // the client instance RR::ApiHandle<RR::RenderingSession> m_session; // the current remote rendering session RR::ApiHandle<RR::RenderingConnection> m_api; // the API instance, that is used to perform all the actions. This is just a shortcut to m_session->Connection() RR::ApiHandle<RR::GraphicsBindingWmrD3d11> m_graphicsBinding; // the graphics binding instance }
... // Existing clear function: context->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); // ... // Existing check to test for valid camera: bool cameraActive = pCameraResources->AttachViewProjectionBuffer(m_deviceResources); // Inject remote rendering: as soon as we are connected, start blitting the remote frame. // We do the blitting after the Clear, and before cube rendering. if (m_isConnected && cameraActive) { m_graphicsBinding->BlitRemoteFrame(); } ...