Delen via


Een aangepaste Holographic Remoting Player-app schrijven

Als u geen toegang hebt tot Holographic Remoting, kunt u ons overzicht lezen.

Belangrijk

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

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

Met een Holographic 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 Player-app streamt invoergegevens naar een externe Holographic Remoting-toepassing en ontvangt een meeslepende weergave als video- en audiostream. De verbinding wordt gemaakt met 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 af te handelen 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 het overzicht van DirectX-ontwikkeling voor meer informatie. Als u geen bestaande app hebt en u helemaal opnieuw wilt beginnen met de C++-holografische projectsjabloon , is dit een goed uitgangspunt.

Belangrijk

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

Het NuGet-pakket Holographic Remoting ophalen

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 Bladeren en zoek vervolgens naar Holographic Remoting.
  4. Selecteer Microsoft.Holographic.Remoting, zorg ervoor dat u de nieuwste versie 2.x.x kiest en installeert.
  5. Als het dialoogvenster Voorbeeld wordt weergegeven, selecteert u OK.
  6. Selecteer Ik ga akkoord wanneer het dialoogvenster voor de gebruiksrechtovereenkomst wordt weergegeven.

Belangrijk

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

Wijzig het Package.appxmanifest van de toepassing

Als u de toepassing op de hoogte wilt stellen van de Microsoft.Holographic.AppRemoting.dll die door het NuGet-pakket zijn toegevoegd, moeten de volgende stappen in het project worden uitgevoerd:

  1. Klik in 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 spelercontext 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 tussenliggende laag tussen de speler-app en de Windows Mixed Reality-runtime die wordt geleverd met Windows. Dit gebeurt tijdens het maken van de spelercontext. Daarom kan elke aanroep van een Windows Mixed Reality-API voordat het maken van de spelercontext onverwacht gedrag oplevert. De aanbevolen aanpak is om de context van de speler zo vroeg mogelijk te maken voordat interactie met een Mixed Reality-API plaatsvindt. Meng nooit objecten die zijn gemaakt of opgehaald via een Windows Mixed Reality-API voordat de aanroep naar PlayerContext::Create objecten die daarna zijn gemaakt of opgehaald.

Vervolgens kan de 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 context van de speler die 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 worden veroorzaakt die moet worden verwerkt.

Luisteren naar binnenkomende verbindingen in de speler-app kan worden uitgevoerd door de methode aan te Listen 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 poortnummer 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()
}

Er PlayerContext worden drie gebeurtenissen weergegeven om de status van de verbinding te bewaken

  1. OnConnected: geactiveerd wanneer een verbinding met de externe app tot stand is gebracht.
m_onConnectedEventToken = m_playerContext.OnConnected([]() 
{
    // Handle connection successfully established
});
  1. OnDisconnected: geactiveerd als een tot stand gebrachte verbinding is beëindigd of als er geen verbinding tot stand kon 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 in het Microsoft.Holographic.AppRemoting.idl bestand gedocumenteerd.

  1. OnListening: bij 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 gerenderde frame weergeven

Als u de extern gerenderde inhoud wilt weergeven, roept PlayerContext::BlitRemoteFrame u aan terwijl u een HolographicFrame weergeeft.

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

Wanneer deze wordt aangeroepen, BlitRemoteFrame kopieert u het laatst ontvangen frame van de externe toepassing naar de BackBuffer van het HolographicFrame. Daarnaast wordt de focuspuntset ingesteld als de externe toepassing een focuspunt heeft opgegeven tijdens de rendering 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 het focuspunt voor het huidige frame wordt mogelijk overschreven.

Bij succes, BlitRemoteFrame retourneert BlitResult::Success_Color. Anders wordt de reden van de fout geretourneerd:

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

Belangrijk

Vanaf versie 2.1.0 is het mogelijk met een aangepaste speler 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 wordt de externe diepte in de momenteel gebonden lokale dieptebuffer belicht. Vervolgens kunt u aanvullende lokale inhoud weergeven, die een dieptepunt heeft met de externe gerenderde inhoud. Daarnaast kunt u de lokale dieptebuffer doorvoeren via HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer in uw aangepaste speler om diepteherprojectie te hebben voor externe en lokale gerenderde inhoud.

Projectietransformatiemodus

Een probleem, dat optreedt 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 wordt weergegeven door uw aangepaste speler-app. Een veelvoorkomende use-case is het opgeven van verschillende waarden voor vlak bij en ver (via HolographicCamera::SetNearPlaneDistance en HolographicCamera::SetFarPlaneDistance) aan de spelerzijde en de externe zijde. In dit geval is het niet duidelijk of de projectietransformatie aan de kant van de speler de afstand tussen het vlak of de lokale afstand moet weerspiegelen.

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

  • Local - HolographicCameraPose::P rojectionTransform retourneert een projectietransform , die de afstand van het vlak bijna/ver weerspiegelt die zijn ingesteld door uw aangepaste speler-app op de HolographicCamera.
  • Remote - Projectietransformatie weerspiegelt de afstand tussen het vlak en de afstand die is opgegeven door de externe app.
  • Merged - Vlak-/afstandsafstanden van uw externe app en uw aangepaste speler-app worden samengevoegd. Dit wordt standaard gedaan door de minimale afstand van het vlak in de buurt en het maximum van de verre vlakafstanden te nemen. Als de afstandsbediening of de lokale kant omgekeerd is, bijvoorbeeld ver < dichtbij, worden de afstand van het vlak bij/ver omgedraaid.

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 veelvoorkomende use-case is om de time-out van het BlitRemoteFrame in te schakelen om een leeg scherm weer te geven als er gedurende een bepaalde tijd geen nieuwe frames worden ontvangen. Wanneer het retourtype van de BlitRemoteFrame methode is ingeschakeld, kan ook worden gebruikt om over te schakelen naar een lokaal gerenderde terugvalinhoud.

Als u de time-out wilt inschakelen, stelt u de eigenschapswaarde 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 nulduur. Als de time-out is ingeschakeld en er geen extern frame wordt ontvangen voor de ingestelde duur, mislukt BlitRemoteFrame en keert u terug Failed_RemoteFrameTooOld totdat een nieuw extern frame wordt 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.idl bestand voor meer informatie.

Optioneel: Aangepaste gegevenskanalen

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

Optioneel: Over rendering

Holographic Remoting voorspelt waar het hoofd van de gebruiker zich bevindt op het moment dat de weergegeven afbeeldingen op de schermen worden weergegeven. Deze voorspelling is echter een benadering. Daarom kan de voorspelde viewport op de externe app en de latere werkelijke viewport op de speler-app verschillen. Sterkere afwijkingen (bijvoorbeeld door onvoorspelbare beweging) kunnen zwarte gebieden aan de randen van het weergave frustum veroorzaken. Vanaf versie 2.6.0 kunt u Over-Rendering gebruiken om de zwarte regio's te verminderen en de visuele kwaliteit te verbeteren door de viewport kunstmatig te verhogen buiten het weergave frustum.

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

Hiermee OverRenderingConfig geeft u een breukgrootte op tot de werkelijke viewport, zodat de voorspelde viewport groter wordt en er minder snijbewerkingen optreden. Met een grotere viewportgrootte neemt de pixeldichtheid af, zodat u met OverRenderingConfig ook de resolutie kunt verhogen. Als de viewport-toename gelijk is aan de resolutie, blijft de pixeldichtheid hetzelfde. OverRenderingConfig is 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 systeemsynchronisatie worden gebruikt om ruimtelijke gegevens tussen de speler en de externe app uit te lijnen. Zie Systeemsynchronisatie coördineren met Holographic Remoting Overview voor meer informatie.

Zie ook