Skriva en Holographic Remoting Remote-app med hjälp av OpenXR-API:et
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 fjärrprogram för HoloLens 2 och Windows Mixed Reality headset med hjälp av OpenXR-API:et. Fjärrprogram för HoloLens (första generationen) måste använda NuGet-paket version 1.x.x. Detta innebär att fjärrprogram som skrivits för HoloLens 2 inte är kompatibla med HoloLens 1 och vice versa. Dokumentationen för HoloLens 1 finns här.
Holographic Remoting-appar kan strömma fjärråtergivet innehåll till HoloLens 2 och Windows Mixed Reality uppslukande headset. Du kan också komma åt fler systemresurser och integrera avancerade fjärrvyer i befintlig programvara för stationära datorer. En fjärrapp tar emot en indataström från HoloLens 2, renderar innehåll i en virtuell uppslukande vy och strömmar tillbaka innehållsramar till HoloLens 2. Anslutningen görs med wi-fi som standard. Holographic Remoting läggs till i en skrivbords- eller UWP-app via ett NuGet-paket. Ytterligare kod krävs som hanterar anslutningen och renderas i en fördjupande vy. En typisk fjärranslutning har så lite som 50 ms svarstid. Spelarappen kan rapportera svarstiden i realtid.
All kod på den här sidan och arbetsprojekt finns på github-lagringsplatsen Holographic Remoting Samples.
Förutsättningar
En bra utgångspunkt är en fungerande OpenXR-baserad skrivbords- eller UWP-app. Mer information finns i Komma igång med OpenXR.
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.
- Öppna projektet i Visual Studio.
- Högerklicka på projektnoden och välj Hantera NuGet-paket...
- I panelen som visas väljer du Bläddra och söker sedan efter "Holographic Remoting".
- Välj Microsoft.Holographic.Remoting.OpenXr och kontrollera sedan att den senaste 2.x.x-versionen är markerad och välj sedan Installera.
- Om dialogrutan Förhandsgranskning visas väljer du OK.
- Välj Jag accepterar när dialogrutan licensavtal öppnas.
- Upprepa steg 3 till 6 för följande NuGet-paket: OpenXR.Headers, OpenXR.Loader
Anteckning
Version 1.x.x av NuGet-paketet är fortfarande tillgänglig för utvecklare som vill rikta in sig på HoloLens 1. Mer information finns i Add Holographic Remoting (HoloLens (1st gen)).
Välj Holographic Remoting OpenXR-körning
Det första steget du behöver göra i fjärrappen är att välja Holographic Remoting OpenXR-körningen, som är en del av NuGet-paketet Microsoft.Holographic.Remoting.OpenXr. Du kan göra detta genom att ange XR_RUNTIME_JSON
miljövariabeln till sökvägen till filen RemotingXR.json i din app. Den här miljövariabeln används av OpenXR-inläsaren för att inte använda systemets standardkörning med OpenXR utan i stället omdirigera till Holographic Remoting OpenXR-körningen. När du använder NuGet-paketet Microsoft.Holographic.Remoting.OpenXr kopieras filen RemotingXR.json automatiskt under kompileringen till utdatamappen. OpenXR-körningsvalet ser vanligtvis ut så här.
bool EnableRemotingXR() {
wchar_t executablePath[MAX_PATH];
if (GetModuleFileNameW(NULL, executablePath, ARRAYSIZE(executablePath)) == 0) {
return false;
}
std::filesystem::path filename(executablePath);
filename = filename.replace_filename("RemotingXR.json");
if (std::filesystem::exists(filename)) {
SetEnvironmentVariableW(L"XR_RUNTIME_JSON", filename.c_str());
return true;
}
return false;
}
Skapa XrInstance med Holographic Remoting Extension
De första åtgärderna som en typisk OpenXR-app ska vidta är att välja OpenXR-tillägg och skapa en XrInstance. OpenXR Core-specifikationen tillhandahåller inte något fjärrkommunikationsspecifikt API. Därför introducerar Holographic Remoting ett eget OpenXR-tillägg med namnet XR_MSFT_holographic_remoting
. Se till att XR_MSFT_HOLOGRAPHIC_REMOTING_EXTENSION_NAME
ingår i XrInstanceCreateInfo för xrCreateInstance-anropet.
Tips
Som standard strömmas det renderade innehållet i din app endast till Holographic Remoting-spelaren som antingen körs på en HoloLens 2 eller på ett Windows Mixed Reality headset. Om du även vill visa det renderade innehållet på fjärrdatorn, via en växlingskedja för ett fönster till exempel, tillhandahåller Holographic Remoting ett andra OpenXR-tillägg med namnet XR_MSFT_holographic_remoting_frame_mirroring
. Se till att även aktivera det här tillägget med om XR_MSFT_HOLOGRAPHIC_REMOTING_FRAME_MIRRORING_EXTENSION_NAME
du vill använda den funktionen.
Viktigt
Om du vill veta mer om Holographic Remoting OpenXR-tilläggs-API:et kan du läsa specifikationen som finns i github-lagringsplatsen Holographic Remoting Samples.
Ansluta till enheten
När fjärrappen har skapat XrInstance och frågat XrSystemId via xrGetSystem kan en anslutning till spelarenheten upprättas.
Varning
Holographic Remoting OpenXR-körningen kan bara tillhandahålla enhetsspecifika data, till exempel visningskonfigurationer eller miljöblandningslägen när en anslutning har upprättats. xrEnumerateViewConfigurations
, xrEnumerateViewConfigurationViews
, xrGetViewConfigurationProperties
, xrEnumerateEnvironmentBlendModes
och xrGetSystemProperties
ger dig standardvärden som matchar vad du normalt får om du ansluter till en spelare som körs på en HoloLens 2 innan du är helt ansluten.
Vi rekommenderar starkt att du inte anropar dessa metoder innan en anslutning har upprättats. Förslaget används dessa metoder när XrSession har skapats och sessionstillståndet är minst XR_SESSION_STATE_READY.
Allmänna egenskaper som maximal bithastighet, ljudaktiverad, video codec eller djupbuffertströmsupplösning kan konfigureras via xrRemotingSetContextPropertiesMSFT
följande.
XrRemotingRemoteContextPropertiesMSFT contextProperties;
contextProperties = XrRemotingRemoteContextPropertiesMSFT{static_cast<XrStructureType>(XR_TYPE_REMOTING_REMOTE_CONTEXT_PROPERTIES_MSFT)};
contextProperties.enableAudio = false;
contextProperties.maxBitrateKbps = 20000;
contextProperties.videoCodec = XR_REMOTING_VIDEO_CODEC_H265_MSFT;
contextProperties.depthBufferStreamResolution = XR_REMOTING_DEPTH_BUFFER_STREAM_RESOLUTION_HALF_MSFT;
xrRemotingSetContextPropertiesMSFT(m_instance.Get(), m_systemId, &contextProperties);
Anslutningen kan göras på ett av två sätt.
- Fjärrappen ansluter till spelaren som körs på enheten.
- Spelaren som körs på enheten ansluter till fjärrappen.
Om du vill upprätta en anslutning från fjärrappen till spelarenheten anropar xrRemotingConnectMSFT
du metoden som anger värdnamnet och porten via XrRemotingConnectInfoMSFT
strukturen. Porten som används av Holographic Remoting Player är 8265.
XrRemotingConnectInfoMSFT connectInfo{static_cast<XrStructureType>(XR_TYPE_REMOTING_CONNECT_INFO_MSFT)};
connectInfo.remoteHostName = "192.168.x.x";
connectInfo.remotePort = 8265;
connectInfo.secureConnection = false;
xrRemotingConnectMSFT(m_instance.Get(), m_systemId, &connectInfo);
Du kan lyssna efter inkommande anslutningar i fjärrappen xrRemotingListenMSFT
genom att anropa metoden. Både handskakningsporten och transportporten XrRemotingListenInfoMSFT
kan anges via strukturen. Handskakningsporten används för den inledande handskakningen. Data skickas sedan över transportporten. Som standard används 8265 och 8266 .
XrRemotingListenInfoMSFT listenInfo{static_cast<XrStructureType>(XR_TYPE_REMOTING_LISTEN_INFO_MSFT)};
listenInfo.listenInterface = "0.0.0.0";
listenInfo.handshakeListenPort = 8265;
listenInfo.transportListenPort = 8266;
listenInfo.secureConnection = false;
xrRemotingListenMSFT(m_instance.Get(), m_systemId, &listenInfo);
Anslutningstillståndet måste vara frånkopplat när du anropar xrRemotingConnectMSFT
eller xrRemotingListenMSFT
. Du kan hämta anslutningstillståndet när som helst när du har skapat en XrInstance och frågat efter XrSystemId via xrRemotingGetConnectionStateMSFT
.
XrRemotingConnectionStateMSFT connectionState;
xrRemotingGetConnectionStateMSFT(m_instance.Get(), m_systemId, &connectionState, nullptr);
Tillgängliga anslutningstillstånd är:
- XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT
- XR_REMOTING_CONNECTION_STATE_CONNECTING_MSFT
- XR_REMOTING_CONNECTION_STATE_CONNECTED_MSFT
Viktigt
xrRemotingConnectMSFT
eller xrRemotingListenMSFT
måste anropas innan du försöker skapa en XrSession via xrCreateSession. Om du försöker skapa en XrSession medan anslutningstillståndet är XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT
kommer sessionsgenereringen att lyckas, men sessionstillståndet övergår omedelbart till XR_SESSION_STATE_LOSS_PENDING.
Holographic Remotings implementering av xrCreateSession
stöder väntan på att en anslutning upprättas. Du kan anropa xrRemotingConnectMSFT
eller xrRemotingListenMSFT
omedelbart följt av ett anrop till xrCreateSession
, som blockerar och väntar på att en anslutning upprättas. Tidsgränsen med xrRemotingConnectMSFT
är fast i 10 sekunder och obegränsad med xrRemotingListenMSFT
. Om en anslutning kan upprättas inom den här tiden lyckas XrSession-skapandet och sessionstillståndet övergår till XR_SESSION_STATE_READY. Om ingen anslutning kan upprättas kan även sessionsskapandet lyckas, men omedelbart övergår till XR_SESSION_STATE_LOSS_PENDING.
I allmänhet är anslutningstillståndet kopplat till XrSession-tillståndet. Eventuella ändringar av anslutningstillståndet påverkar även sessionstillståndet. Om anslutningstillståndet till exempel växlar från XR_REMOTING_CONNECTION_STATE_CONNECTED_MSFT
till XR_REMOTING_CONNECTION_STATE_DISCONNECTED_MSFT
sessionstillståndet övergår det även till XR_SESSION_STATE_LOSS_PENDING.
Hantera fjärrkommunikationsspecifika händelser
Holographic Remoting OpenXR-körningen visar tre händelser, som är viktiga för att övervaka tillståndet för en anslutning.
XR_TYPE_REMOTING_EVENT_DATA_CONNECTED_MSFT
: Utlöses när en anslutning till enheten har upprättats.XR_TYPE_REMOTING_EVENT_DATA_DISCONNECTED_MSFT
: Utlöses om en upprättad anslutning är stängd eller om det inte gick att upprätta en anslutning.XR_TYPE_REMOTING_EVENT_DATA_LISTENING_MSFT
: När du lyssnar efter inkommande anslutningar startar.
Dessa händelser placeras i en kö och fjärrappen måste läsa från kön med regelbundenhet via xrPollEvent
.
auto pollEvent = [&](XrEventDataBuffer& eventData) -> bool {
eventData.type = XR_TYPE_EVENT_DATA_BUFFER;
eventData.next = nullptr;
return CHECK_XRCMD(xrPollEvent(m_instance.Get(), &eventData)) == XR_SUCCESS;
};
XrEventDataBuffer eventData{};
while (pollEvent(eventData)) {
switch (eventData.type) {
...
case XR_TYPE_REMOTING_EVENT_DATA_LISTENING_MSFT: {
DEBUG_PRINT("Holographic Remoting: Listening on port %d",
reinterpret_cast<const XrRemotingEventDataListeningMSFT*>(&eventData)->listeningPort);
break;
}
case XR_TYPE_REMOTING_EVENT_DATA_CONNECTED_MSFT: {
DEBUG_PRINT("Holographic Remoting: Connected.");
break;
}
case XR_TYPE_REMOTING_EVENT_DATA_DISCONNECTED_MSFT: {
DEBUG_PRINT("Holographic Remoting: Disconnected - Reason: %d",
reinterpret_cast<const XrRemotingEventDataDisconnectedMSFT*>(&eventData)->disconnectReason);
break;
}
}
Förhandsgranska strömmat innehåll lokalt
Om du vill visa samma innehåll i fjärrappen som skickas till enheten XR_MSFT_holographic_remoting_frame_mirroring
kan tillägget användas. Med det här tillägget kan du skicka en struktur till xrEndFrame med hjälp XrRemotingFrameMirrorImageInfoMSFT
av som inte är länkad till XrFrameEndInfo på följande sätt.
XrFrameEndInfo frameEndInfo{XR_TYPE_FRAME_END_INFO};
...
XrRemotingFrameMirrorImageD3D11MSFT mirrorImageD3D11{
static_cast<XrStructureType>(XR_TYPE_REMOTING_FRAME_MIRROR_IMAGE_D3D11_MSFT)};
mirrorImageD3D11.texture = m_window->GetNextSwapchainTexture();
XrRemotingFrameMirrorImageInfoMSFT mirrorImageEndInfo{
static_cast<XrStructureType>(XR_TYPE_REMOTING_FRAME_MIRROR_IMAGE_INFO_MSFT)};
mirrorImageEndInfo.image = reinterpret_cast<const XrRemotingFrameMirrorImageBaseHeaderMSFT*>(&mirrorImageD3D11);
frameEndInfo.next = &mirrorImageEndInfo;
xrEndFrame(m_session.Get(), &frameEndInfo);
m_window->PresentSwapchain();
Exemplet ovan använder en DX11-växlingskedja och visar fönstret direkt efter anropet till xrEndFrame. Användningen är inte begränsad till växlingskedjans texturer. Dessutom krävs ingen ytterligare GPU-synkronisering. Mer information om användning och begränsningar finns i tilläggsspecifikationen. Om fjärrappen använder DX12 använder du XrRemotingFrameMirrorImageD3D12MSFT i stället för XrRemotingFrameMirrorImageD3D11MSFT.
Valfritt: Anpassade datakanaler
Från och med version 2.5.0 kan anpassade datakanaler användas med OpenXR API för att skicka användardata via den redan etablerade fjärranslutningen. Mer information finns i Anpassade datakanaler med OpenXR API.
Valfritt: Tal
Från och med version 2.6.0XR_MSFT_holographic_remoting_speech
gör tillägget att fjärrappen kan reagera på talkommandon som identifierats av spelarappen med OpenXR-API:et.
[! VIKTIGT] Den detaljerade specifikationen finns på github-lagringsplatsen Holographic Remoting Samples.
Om du vill initiera en taligenkänning i spelarappen kan fjärrappen anropa xrInitializeRemotingSpeechMSFT
.
Det här anropet överför parametrar för talinitiering, som består av ett språk, en ordlista med fraser och innehållet i en grammatikfil, till spelarappen.
Anteckning
Före version 2.6.1 får taligenkänningen bara initieras en gång per XrSession
.
Om skapandet av taligenkänningen lyckades, vilket anges av XR_TYPE_EVENT_DATA_REMOTING_SPEECH_RECOGNIZER_STATE_CHANGED_MSFT
händelsen, meddelas fjärrappen när ett taligenkänningsresultat genererades i spelarappen.
Händelsestrukturen XrEventDataRemotingSpeechRecognizerStateChangedMSFT
placeras i händelsekön när taligenkänningens tillstånd på spelarsidan ändras.
XrRemotingSpeechRecognizerStateMSFT
definierar alla möjliga tillstånd för taligenkänningen på spelarsidan och XrEventDataRemotingSpeechRecognizedMSFT
händelsestrukturen placeras i händelsekön om taligenkänningen på spelarsidan har en identifierad fras.
När fjärrappen meddelas om en identifierad fras kan den hämta den identifierade frasen genom att anropa xrRetrieveRemotingSpeechRecognizedTextMSFT
.
Anteckning
XrRemotingSpeechRecognitionConfidenceMSFT
är en direkt mappning av SpeechRecognitionConfidence-uppräkningen som returneras med taligenkänningsresultatet från API:et för taligenkänning i Windows.
Valfritt: Samordna systemsynkronisering
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 Översikt över koordinatsystemsynkronisering med holografisk fjärrkommunikation.