Een aangepaste Holographic Remoting Player-app schrijven

Als u geen gebruik hebt van Holographic Remoting, kunt u ons overzicht lezen.

Belangrijk

In dit document wordt beschreven hoe u een aangepaste spelertoepassing maakt voor HoloLens 2. Aangepaste spelers die zijn geschreven voor HoloLens 2 zijn niet compatibel met externe toepassingen die zijn geschreven voor HoloLens 1. Dit betekent dat beide toepassingen NuGet-pakketversie 2.x.x moeten gebruiken.

Door een aangepaste Holographic Remoting-speler-app te maken, kunt u een aangepaste toepassing maken die insluitende weergaven kan weergeven op een externe computer op uw HoloLens 2. Alle code op deze pagina en werkprojecten zijn te vinden in de GitHub-opslagplaats holographic Remoting-voorbeelden.

Met een Holoographic Remoting-speler kan uw app holografische inhoud weergeven die wordt weergegeven op een desktop-pc of UWP-apparaat, zoals de Xbox One, met toegang tot meer systeembronnen. Een Holographic Remoting-speler-app streamt invoergegevens naar een externe Holographic Remoting-toepassing en ontvangt een meeslepende weergave als video- en audiostream. De verbinding wordt gemaakt met behulp van standaard Wi-Fi. Als u een speler-app wilt maken, gebruikt u een NuGet-pakket om Holographic Remoting toe te voegen aan uw UWP-app. Schrijf vervolgens code om de verbinding te verwerken en een insluitende weergave weer te geven.

Vereisten

Een goed uitgangspunt is een werkende UWP-app op basis van DirectX die al is gericht op de Windows Mixed Reality-API. Zie Overzicht van DirectX-ontwikkeling voor meer informatie. Als u geen bestaande app hebt en helemaal opnieuw wilt beginnen, is de C++-holografische projectsjabloon een goed uitgangspunt.

Belangrijk

Elke app die gebruikmaakt van Holographic Remoting moet worden geschreven voor het gebruik van een appartement met meerdere threads. Het gebruik van een appartement met één schroefdraad wordt ondersteund, maar leidt tot suboptimale prestaties en mogelijk haperingen tijdens het afspelen. Wanneer u C++/WinRT winrt::init_apartment is een appartement met meerdere threads de standaardinstelling.

Download het Holographic Remoting NuGet-pakket

De volgende stappen zijn vereist om het NuGet-pakket toe te voegen aan een project in Visual Studio.

  1. Open het project in Visual Studio.
  2. Klik met de rechtermuisknop op het projectknooppunt en selecteer NuGet-pakketten beheren...
  3. Selecteer bladeren in het deelvenster dat wordt weergegeven en zoek vervolgens naar 'Holographic Remoting'.
  4. Selecteer Microsoft.Holographic.Remoting, zorg ervoor dat u de meest recente versie 2.x.x kiest en selecteer Installeren.
  5. Als het dialoogvenster Voorbeeld wordt weergegeven, selecteert u OK.
  6. Selecteer Ik ga akkoord wanneer het dialoogvenster met de gebruiksrechtovereenkomst wordt weergegeven.

Belangrijk

De build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl in het NuGet-pakket bevat gedetailleerde documentatie voor de API die wordt weergegeven door Holographic Remoting.

Wijzig het Package.appxmanifest van de toepassing

Om de toepassing bewust te maken van de Microsoft.Holographic.AppRemoting.dll toegevoegd door het NuGet-pakket, moeten de volgende stappen voor het project worden uitgevoerd:

  1. Klik in de Solution Explorer met de rechtermuisknop op het bestand Package.appxmanifest en selecteer Openen met...
  2. Selecteer XML-editor (tekst) en selecteer OK
  3. Voeg de volgende regels toe aan het bestand en sla deze op
  </Capabilities>

  <!--Add lines below -->
  <Extensions>
    <Extension Category="windows.activatableClass.inProcessServer">
      <InProcessServer>
        <Path>Microsoft.Holographic.AppRemoting.dll</Path>
        <ActivatableClass ActivatableClassId="Microsoft.Holographic.AppRemoting.PlayerContext" ThreadingModel="both" />
      </InProcessServer>
    </Extension>
  </Extensions>
  <!--Add lines above -->

</Package>

De context van de speler maken

Als eerste stap moet de toepassing een spelercontext maken.

// class declaration:

#include <winrt/Microsoft.Holographic.AppRemoting.h>

...

private:
// PlayerContext used to connect with a Holographic Remoting remote app and display remotely rendered frames
winrt::Microsoft::Holographic::AppRemoting::PlayerContext m_playerContext = nullptr;
// class implementation:

// Create the player context
// IMPORTANT: This must be done before creating the HolographicSpace (or any other call to the Holographic API).
m_playerContext = winrt::Microsoft::Holographic::AppRemoting::PlayerContext::Create();

Waarschuwing

Een aangepaste speler injecteert een tussenlaag tussen de speler-app en de Windows Mixed Reality runtime die met Windows wordt geleverd. Dit wordt gedaan tijdens het maken van de spelercontext. Daarom kan elke aanroep op een Windows Mixed Reality-API voordat de spelercontext wordt gemaakt, leiden tot onverwacht gedrag. De aanbevolen aanpak is om de spelercontext zo vroeg mogelijk te maken vóór interactie met een Mixed Reality-API. Meng nooit objecten die zijn gemaakt of opgehaald via een Windows Mixed Reality API vóór de aanroep naar PlayerContext::Create met objecten die later zijn gemaakt of opgehaald.

Vervolgens kan holographicSpace worden gemaakt door HolographicSpace.CreateForCoreWindow aan te roepen.

m_holographicSpace = winrt::Windows::Graphics::Holographic::HolographicSpace::CreateForCoreWindow(window);

Verbinding maken met de externe app

Zodra de speler-app klaar is voor het weergeven van inhoud, kan er een verbinding met de externe app tot stand worden gebracht.

De verbinding kan op een van de volgende manieren tot stand worden gebracht:

  1. De speler-app die wordt uitgevoerd op HoloLens 2 maakt verbinding met de externe app.
  2. De externe app maakt verbinding met de speler-app die wordt uitgevoerd op HoloLens 2.

Als u vanuit de speler-app verbinding wilt maken met de externe app, roept u de Connect methode aan in de spelercontext, waarbij u de hostnaam en poort opgeeft. De standaardpoort is 8265.

try
{
    m_playerContext.Connect(m_hostname, m_port);
}
catch(winrt::hresult_error& e)
{
    // Failed to connect. Get an error details via e.code() and e.message()
}

Belangrijk

Net als bij elke C++/WinRT-API Connect kan een winrt::hresult_error genereren die moet worden verwerkt.

Luisteren naar binnenkomende verbindingen in de speler-app kan worden uitgevoerd door de Listen methode aan te roepen. Zowel de handshakepoort als de transportpoort kunnen tijdens deze aanroep worden opgegeven. De handshakepoort wordt gebruikt voor de eerste handshake. De gegevens worden vervolgens verzonden via de transportpoort. Standaard worden poortnummers 8265 en 8266 gebruikt.

try
{
    m_playerContext.Listen(L"0.0.0.0", m_port, m_port + 1);
}
catch(winrt::hresult_error& e)
{
    // Failed to listen. Get an error details via e.code() and e.message()
}

De PlayerContext maakt drie gebeurtenissen beschikbaar om de status van de verbinding te bewaken

  1. OnConnected: wordt geactiveerd wanneer een verbinding met de externe app tot stand is gebracht.
m_onConnectedEventToken = m_playerContext.OnConnected([]() 
{
    // Handle connection successfully established
});
  1. OnDisconnected: wordt geactiveerd als een tot stand gebrachte verbinding wordt beëindigd of als er geen verbinding tot stand kan worden gebracht.
m_onDisconnectedEventToken = m_playerContext.OnDisconnected([](ConnectionFailureReason failureReason)
{
    switch (failureReason)
    {
        // Handle connection failed or terminated.
        // See ConnectionFailureReason for possible reasons.
    }
}

Notitie

Mogelijke ConnectionFailureReason waarden worden gedocumenteerd in het Microsoft.Holographic.AppRemoting.idlbestand.

  1. OnListening: wanneer het luisteren naar binnenkomende verbindingen wordt gestart.
m_onListeningEventToken = m_playerContext.OnListening([]()
{
    // Handle start listening for incoming connections
});

Daarnaast kan de verbindingsstatus worden opgevraagd met behulp van de ConnectionState eigenschap in de context van de speler.

winrt::Microsoft::Holographic::AppRemoting::ConnectionState state = m_playerContext.ConnectionState();

Het extern weergegeven frame weergeven

Als u de extern gegenereerde inhoud wilt weergeven, roept u PlayerContext::BlitRemoteFrame aan tijdens het weergeven van een HolographicFrame.

BlitRemoteFrame vereist dat de achterbuffer voor het huidige HolographicFrame is gebonden als renderdoel. De achterbuffer kan worden ontvangen van de HolographicCameraRenderingParameters via de eigenschap Direct3D11BackBuffer .

Wanneer aangeroepen, BlitRemoteFrame kopieert u het laatst ontvangen frame van de externe toepassing naar de BackBuffer van het HolographicFrame. Daarnaast wordt het focuspunt ingesteld als de externe toepassing een focuspunt heeft opgegeven tijdens het weergeven van het externe frame.

// Blit the remote frame into the backbuffer for the HolographicFrame.
winrt::Microsoft::Holographic::AppRemoting::BlitResult result = m_playerContext.BlitRemoteFrame();

Notitie

PlayerContext::BlitRemoteFrame hiermee wordt mogelijk het focuspunt voor het huidige frame overschreven.

Bij succes BlitRemoteFrame retourneert BlitResult::Success_Color. Anders wordt de foutreden geretourneerd:

  • BlitResult::Failed_NoRemoteFrameAvailable: Mislukt omdat er geen extern frame beschikbaar is.
  • BlitResult::Failed_NoCamera: Is mislukt omdat er geen camera aanwezig is.
  • BlitResult::Failed_RemoteFrameTooOld: Is mislukt omdat het externe frame te oud is (zie eigenschap PlayerContext::BlitRemoteFrameTimeout).

Belangrijk

Vanaf versie 2.1.0 is het met een aangepaste speler mogelijk om diepteherprojectie te gebruiken via Holographic Remoting.

BlitResult kan ook worden geretourneerd BlitResult::Success_Color_Depth onder de volgende voorwaarden:

Als aan deze voorwaarden wordt voldaan, BlitRemoteFrame splitst de externe diepte in de momenteel gebonden lokale dieptebuffer. Vervolgens kunt u aanvullende lokale inhoud weergeven, die diepte-snijpunt heeft met de extern gerenderde inhoud. Daarnaast kunt u de lokale dieptebuffer doorvoeren via HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer in uw aangepaste speler om diepteherprojectie te hebben voor externe en lokale weergegeven inhoud.

Projectietransformatiemodus

Een probleem, dat naar boven komt bij het gebruik van diepteherprojectie via Holographic Remoting, is dat de externe inhoud kan worden weergegeven met een andere projectietransformatie dan lokale inhoud die rechtstreeks door uw aangepaste speler-app wordt weergegeven. Een veelvoorkomend gebruiksvoorbeeld is het opgeven van verschillende waarden voor het vlak dichtbij en veraf (via HolographicCamera::SetNearPlaneDistance en HolographicCamera::SetFarPlaneDistance) aan de spelerzijde en de externe kant. In dit geval is het niet duidelijk of de projectietransformatie aan de zijde van de speler de afstand in de buurt/ver of de lokale vlakafstanden moet weerspiegelen.

Vanaf versie 2.1.0 kunt u de projectietransformatiemodus beheren via PlayerContext::ProjectionTransformConfig. Ondersteunde waarden zijn:

  • Local - HolographicCameraPose::P rojectionTransform retourneert een projectietransformatie, die de vlakafstanden van dichtbij/ver weerspiegelt die zijn ingesteld door uw aangepaste speler-app op de HolographicCamera.
  • Remote - Projectietransformatie weerspiegelt de bijna/verre vlakafstanden die zijn opgegeven door de externe app.
  • Merged - Bijna-/verre vliegtuigafstanden van uw externe app en uw aangepaste speler-app worden samengevoegd. Standaard wordt dit gedaan door het minimum van de dichtstbijzijnde vlakafstanden en het maximum van de verre vlakafstanden te nemen. Als de externe of lokale zijde omgekeerd is, bijvoorbeeld ver < dichtbij, worden de afstandsafstanden in de buurt van het vliegtuig gespiegeld.

Optioneel: BlitRemoteFrameTimeout instellen

Belangrijk

PlayerContext::BlitRemoteFrameTimeout wordt ondersteund vanaf versie 2.0.9.

De PlayerContext::BlitRemoteFrameTimeout eigenschap geeft aan hoe lang een extern frame opnieuw wordt gebruikt als er geen nieuw extern frame wordt ontvangen.

Een veelvoorkomend gebruiksscenario is het inschakelen van de time-out van BlitRemoteFrame om een leeg scherm weer te geven als er gedurende een bepaalde tijd geen nieuwe frames worden ontvangen. Wanneer dit is ingeschakeld, kan het retourtype van de BlitRemoteFrame methode ook worden gebruikt om over te schakelen naar een lokaal gerenderde terugvalinhoud.

Als u de time-out wilt inschakelen, stelt u de waarde van de eigenschap in op een duur die gelijk is aan of groter is dan 100 ms. Als u de time-out wilt uitschakelen, stelt u de eigenschap in op duur nul. Als de time-out is ingeschakeld en er geen extern frame wordt ontvangen voor de ingestelde duur, mislukt BlitRemoteFrame en keert terug Failed_RemoteFrameTooOld totdat een nieuw extern frame is ontvangen.

using namespace std::chrono_literals;

// Set the BlitRemoteFrame timeout to 0.5s
m_playerContext.BlitRemoteFrameTimeout(500ms);

Optioneel: Statistieken over het laatste externe frame ophalen

Om prestatie- of netwerkproblemen vast te stellen, kunnen statistieken over het laatste externe frame worden opgehaald via de PlayerContext::LastFrameStatistics eigenschap. Statistieken worden bijgewerkt tijdens de aanroep van HolographicFrame::P resentUsingCurrentPrediction.

// Get statistics for the last presented frame.
winrt::Microsoft::Holographic::AppRemoting::PlayerFrameStatistics statistics = m_playerContext.LastFrameStatistics();

Zie de PlayerFrameStatistics documentatie in het Microsoft.Holographic.AppRemoting.idlbestand voor meer informatie.

Optioneel: Aangepaste gegevenskanalen

Aangepaste gegevenskanalen kunnen worden gebruikt om gebruikersgegevens te verzenden via de al tot stand gebrachte externe verbinding. Zie Aangepaste gegevenskanalen voor meer informatie.

Optioneel: Over-Rendering

Holographic Remoting voorspelt waar het hoofd van de gebruiker zal zijn op het moment dat de weergegeven afbeeldingen op de schermen verschijnen. Deze voorspelling is echter een benadering. Daarom kunnen de voorspelde viewport op de externe app en de latere werkelijke viewport op de speler-app verschillen. Sterkere afwijkingen (bijvoorbeeld als gevolg van onvoorspelbare beweging) kunnen leiden tot zwarte gebieden aan de rand van het weergaveftum. Vanaf versie 2.6.0 kunt u Over-Rendering gebruiken om de zwarte gebieden te verminderen en de visuele kwaliteit te verbeteren door de viewport kunstmatig te vergroten buiten het weergave frustum.

Over-Rendering kan worden ingeschakeld via PlayerContext::ConfigureOverRendering.

De OverRenderingConfig geeft een toename van de breukgrootte aan tot de werkelijke viewport, zodat de voorspelde viewport groter wordt en er minder knipbewerkingen plaatsvinden. Met een grotere viewportgrootte neemt de pixeldichtheid af, dus met de OverRenderingConfig kunt u ook de resolutie verhogen. Als de viewport-toename gelijk is aan de resolutie, blijft de pixeldichtheid hetzelfde. OverRenderingConfig wordt gedefinieerd als:

struct OverRenderingConfig
{
    float HorizontalViewportIncrease; // The fractional horizontal viewport increase. (e.g. 10% -> 0.1).
    float VerticalViewportIncrease; // The fractional vertical viewport increase. (e.g. 10% -> 0.1).
                
    float HorizontalResolutionIncrease; // The fractional horizontal resolution increase. (e.g. 10% -> 0.1).
    float VerticalResolutionIncrease; // The fractional vertical resolution increase. (e.g. 10% -> 0.1).
};

Optioneel: Systeemsynchronisatie coördineren

Vanaf versie 2.7.0 kan coördinatensysteemsynchronisatie worden gebruikt om ruimtelijke gegevens tussen de speler en de externe app uit te lijnen. Zie Overzicht systeemsynchronisatie coördineren met Holographic Remoting voor meer informatie.

Zie ook