Skriva en anpassad Holographic Remoting Player-app

Om du inte har använt Holographic Remoting tidigare kanske du vill läsa vår översikt.

Viktigt

I det här dokumentet beskrivs hur du skapar ett anpassat spelarprogram för HoloLens 2. Anpassade spelare skrivna för HoloLens 2 är inte kompatibla med fjärrprogram som skrivits för HoloLens 1. Detta innebär att båda programmen måste använda NuGet-paketversion 2.x.x.

Genom att skapa en anpassad Holographic Remoting-spelarapp kan du skapa ett anpassat program som kan visa uppslukande vyer från en fjärrdator på din HoloLens 2. All kod på den här sidan och arbetsprojekt finns på github-lagringsplatsen Holographic Remoting Samples.

Med en Holographic Remoting-spelare kan din app visa holografiskt innehåll som återges på en stationär dator eller UWP-enhet som Xbox One med åtkomst till fler systemresurser. En Holographic Remoting Player-app strömmar indata till ett fjärrprogram för Holographic Remoting och tar emot en fördjupande vy som video- och ljudström. Anslutningen görs med wi-fi som standard. Om du vill skapa en spelarapp använder du ett NuGet-paket för att lägga till Holographic Remoting i UWP-appen. Skriv sedan kod för att hantera anslutningen och för att visa en fördjupad vy.

Förutsättningar

En bra startpunkt är en fungerande DirectX-baserad UWP-app som redan är inriktad på Windows Mixed Reality-API:et. Mer information finns i Översikt över DirectX-utveckling. Om du inte har någon befintlig app och vill börja från början är C++-holografiska projektmallen en bra utgångspunkt.

Viktigt

Alla appar som använder Holographic Remoting bör skapas för att använda en flertrådad lägenhet. Användningen av en entrådig lägenhet stöds men leder till underoptimala prestanda och eventuellt stamning under uppspelningen. När du använder C++/WinRT winrt::init_apartment är en flertrådad lägenhet standard.

Hämta NuGet-paketet Holographic Remoting

Följande steg krävs för att lägga till NuGet-paketet i ett projekt i Visual Studio.

  1. Öppna projektet i Visual Studio.
  2. Högerklicka på projektnoden och välj Hantera NuGet-paket...
  3. I panelen som visas väljer du Bläddra och söker sedan efter "Holographic Remoting".
  4. Välj Microsoft.Holographic.Remoting, se till att välja den senaste 2.x.x-versionen och välj Installera.
  5. Om dialogrutan Förhandsgranskning visas väljer du OK.
  6. Välj Jag accepterar när dialogrutan licensavtal visas.

Viktigt

I build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl NuGet-paketet finns detaljerad dokumentation för API:et som exponeras av Holographic Remoting.

Ändra Package.appxmanifest för programmet

För att göra programmet medvetet om Microsoft.Holographic.AppRemoting.dll som lagts till av NuGet-paketet måste följande steg vidtas i projektet:

  1. I Solution Explorer högerklickar du på filen Package.appxmanifest och väljer Öppna med...
  2. Välj XML-redigerare (text) och välj OK
  3. Lägg till följande rader i filen och spara
  </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>

Skapa spelarkontexten

Som ett första steg bör programmet skapa en spelarkontext.

// 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();

Varning

En anpassad spelare matar in ett mellanliggande lager mellan spelarappen och den Windows Mixed Reality körning som levereras med Windows. Detta görs när du skapar spelarkontexten. Därför kan alla anrop på alla Windows Mixed Reality API innan du skapar spelarkontexten resultera i oväntat beteende. Den rekommenderade metoden är att skapa spelarkontexten så tidigt som möjligt innan du interagerar med någon Mixed Reality API. Blanda aldrig objekt som skapats eller hämtats via någon Windows Mixed Reality API innan anropet till PlayerContext::Create med objekt som skapats eller hämtats efteråt.

Därefter kan Du skapa HolographicSpace genom att anropa HolographicSpace.CreateForCoreWindow.

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

Ansluta till fjärrappen

När spelarappen är redo för rendering av innehåll kan en anslutning till fjärrappen upprättas.

Anslutningen kan upprättas på något av följande sätt:

  1. Spelarappen som körs på HoloLens 2 ansluter till fjärrappen.
  2. Fjärrappen ansluter till spelarappen som körs på HoloLens 2.

Om du vill ansluta från spelarappen till fjärrappen Connect anropar du metoden i spelarkontexten som anger värdnamnet och porten. Standardporten är 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()
}

Viktigt

Precis som med alla C++/WinRT-API Connect :ar kan utlösa en winrt::hresult_error som måste hanteras.

Du kan lyssna efter inkommande anslutningar i spelarappen Listen genom att anropa metoden. Både handskakningsporten och transportporten kan anges under det här anropet. Handskakningsporten används för den inledande handskakningen. Data skickas sedan över transportporten. Som standard används portnumret 8265 och 8266 .

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()
}

Exponerar PlayerContext tre händelser för att övervaka anslutningens tillstånd

  1. OnConnected: Utlöses när en anslutning till fjärrappen har upprättats.
m_onConnectedEventToken = m_playerContext.OnConnected([]() 
{
    // Handle connection successfully established
});
  1. OnDisconnected: Utlöses om en upprättad anslutning avslutas eller om det inte gick att upprätta en anslutning.
m_onDisconnectedEventToken = m_playerContext.OnDisconnected([](ConnectionFailureReason failureReason)
{
    switch (failureReason)
    {
        // Handle connection failed or terminated.
        // See ConnectionFailureReason for possible reasons.
    }
}

Anteckning

Möjliga ConnectionFailureReason värden dokumenteras i Microsoft.Holographic.AppRemoting.idlfilen.

  1. OnListening: När du lyssnar efter inkommande anslutningar startar.
m_onListeningEventToken = m_playerContext.OnListening([]()
{
    // Handle start listening for incoming connections
});

Dessutom kan anslutningstillståndet frågas med hjälp av ConnectionState egenskapen i spelarkontexten.

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

Visa den fjärrrederade ramen

Om du vill visa det fjärranslutna innehållet anropar PlayerContext::BlitRemoteFrame du medan du återger en HolographicFrame.

BlitRemoteFrame kräver att den bakre bufferten för den aktuella HolographicFrame är bunden som återgivningsmål. Den bakre bufferten kan tas emot från HolographicCameraRenderingParameters via egenskapen Direct3D11BackBuffer .

När den anropas BlitRemoteFrame kopieras den senaste mottagna ramen från fjärrprogrammet till BackBuffer för HolographicFrame. Dessutom anges fokuspunktuppsättningen om fjärrprogrammet har angett en fokuspunkt under återgivningen av fjärrramen.

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

Anteckning

PlayerContext::BlitRemoteFrame skriver potentiellt över fokuspunkten för den aktuella ramen.

Vid lyckat resultat BlitRemoteFrame returnerar BlitResult::Success_Color. Annars returneras felorsaken:

  • BlitResult::Failed_NoRemoteFrameAvailable: Misslyckades eftersom ingen fjärrram är tillgänglig.
  • BlitResult::Failed_NoCamera: Misslyckades eftersom ingen kamera finns.
  • BlitResult::Failed_RemoteFrameTooOld: Det gick inte eftersom fjärrramen är för gammal (se Egenskapen PlayerContext::BlitRemoteFrameTimeout).

Viktigt

Från och med version 2.1.0 är det möjligt med en anpassad spelare att använda djupåtergivning via Holographic Remoting.

BlitResult kan också returneras BlitResult::Success_Color_Depth under följande villkor:

Om dessa villkor uppfylls blir BlitRemoteFrame fjärrdjupet i den för närvarande bundna lokala djupbufferten. Du kan sedan rendera ytterligare lokalt innehåll, som kommer att ha en djupskärningspunkt med det fjärråtergivna innehållet. Dessutom kan du checka in den lokala djupbufferten via HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer i din anpassade spelare för att ha djupåtergivning för fjärrinnehåll och lokalt renderat innehåll.

Projektionstransformeringsläge

Ett problem som uppstår när du använder djupåtergivning via Holographic Remoting är att fjärrinnehållet kan renderas med en annan projektionstransformering än lokalt innehåll som direkt renderas av din anpassade spelarapp. Ett vanligt användningsfall är att ange olika värden för nära och fjärran plan (via HolographicCamera::SetNearPlaneDistance och HolographicCamera::SetFarPlaneDistance) på spelarsidan och på fjärrsidan. I det här fallet är det inte klart om projektionstransformeringen på spelarsidan ska återspegla fjärravstånden nära/fjärranslutna plan eller de lokala.

Från och med version 2.1.0 kan du styra projektionstransformeringsläget via PlayerContext::ProjectionTransformConfig. Värden som stöds är:

  • Local - HolographicCameraPose::P rojectionTransform returnerar en projektionstransformering som återspeglar de närmast/fjärran planavstånd som angetts av din anpassade spelarapp på HolographicCamera.
  • Remote – Projektionstransformering återspeglar de när/fjärranslutna avstånd som anges av fjärrappen.
  • Merged – Avstånd nära/långt plan från fjärrappen och din anpassade spelarapp slås samman. Detta görs som standard genom att ta det lägsta av de närliggande flygavstånden och det maximala av fjärranslutna avstånden. Om antingen den avlägsna eller lokala sidan är inverterad, till exempel långt < nära, vänds de avlägsna avstånden nära/långt plan.

Valfritt: Ange BlitRemoteFrameTimeout

Viktigt

PlayerContext::BlitRemoteFrameTimeout stöds från och med version 2.0.9.

Egenskapen PlayerContext::BlitRemoteFrameTimeout anger hur lång tid en fjärrram återanvänds om ingen ny fjärrram tas emot.

Ett vanligt användningsfall är att aktivera tidsgränsen för BlitRemoteFrame för att visa en tom skärm om inga nya bildrutor tas emot under en viss tidsperiod. När den är aktiverad kan returtypen BlitRemoteFrame för metoden också användas för att växla till ett lokalt renderat återställningsinnehåll.

Om du vill aktivera tidsgränsen anger du egenskapsvärdet till en varaktighet som är lika med eller större än 100 ms. Om du vill inaktivera tidsgränsen anger du egenskapen till noll varaktighet. Om tidsgränsen är aktiverad och ingen fjärrram tas emot under den angivna varaktigheten misslyckas BlitRemoteFrame och återgår Failed_RemoteFrameTooOld tills en ny fjärrram tas emot.

using namespace std::chrono_literals;

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

Valfritt: Hämta statistik om den senaste fjärrramen

För att diagnostisera prestanda- eller nätverksproblem kan statistik om den senaste fjärrramen PlayerContext::LastFrameStatistics hämtas via egenskapen . Statistiken uppdateras under anropet till HolographicFrame::P resentUsingCurrentPrediction.

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

Mer information finns i dokumentationen PlayerFrameStatisticsMicrosoft.Holographic.AppRemoting.idl i filen .

Valfritt: Anpassade datakanaler

Anpassade datakanaler kan användas för att skicka användardata via den redan etablerade fjärrkommunikationsanslutningen. Mer information finns i anpassade datakanaler.

Valfritt: Over-Rendering

Holographic Remoting förutsäger var användarens huvud kommer att vara när de renderade bilderna visas på displayerna. Den här förutsägelsen är dock en uppskattning. Därför kan det förutsagda visningsområdet för fjärrappen och det senare faktiska visningsområdet i spelarappen skilja sig åt. Starkare avvikelser (till exempel på grund av oförutsägbar rörelse) kan orsaka svarta regioner vid gränserna för visningsfrustumet. Från och med version 2.6.0 kan du använda Over-Rendering för att minska de svarta regionerna och förbättra den visuella kvaliteten genom att artificiellt öka visningsområdet bortom visningsfrustum.

Over-Rendering kan aktiveras via PlayerContext::ConfigureOverRendering.

OverRenderingConfig anger en bråkdels storleksökning till det faktiska visningsområdet, så att det förutsagda visningsområdet blir större och mindre kapning sker. Med en ökad vyportstorlek minskar pixeldensiteten, så med OverRenderingConfig kan du också öka upplösningen. Om viewport-ökningen är lika med upplösningen förblir pixeldensiteten densamma. OverRenderingConfig definieras som:

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).
};

Valfritt: Koordinatsystemsynkronisering

Från och med version 2.7.0 kan koordinatsystemsynkronisering användas för att justera rumsliga data mellan spelaren och fjärrappen. Mer information finns i Koordinatsystemsynkronisering med Holographic Remoting Overview (Översikt över koordinatsystemsynkronisering med Holographic Remoting).

Se även