Schreiben einer benutzerdefinierten Holographic Remoting Player-App
Wenn Sie noch keine Erfahrung mit Holographic Remoting haben, sollten Sie unsere Übersicht lesen.
Wichtig
In diesem Dokument wird die Erstellung einer benutzerdefinierten Playeranwendung für HoloLens 2 beschrieben. Benutzerdefinierte Player, die für HoloLens 2 geschrieben wurden, sind nicht mit Remoteanwendungen kompatibel, die für HoloLens 1 geschrieben wurden. Dies bedeutet, dass beide Anwendungen die NuGet-Paketversion 2.x.x verwenden müssen.
Durch Erstellen einer benutzerdefinierten Holographic Remoting-Player-App können Sie eine benutzerdefinierte Anwendung erstellen, die immersive Ansichten auf einem Remotecomputer auf Ihrem HoloLens 2 anzeigen kann. Der gesamte Code auf dieser Seite und funktionierende Projekte finden Sie im GitHub-Repository für Holographic Remoting-Beispiele.
Mit einem Holographic Remoting-Player kann Ihre App holografische Inhalte anzeigen, die auf einem Desktop-PC oder UWP-Gerät wie der Xbox One gerendert werden , mit Zugriff auf weitere Systemressourcen. Eine Holographic Remoting-Player-App streamt Eingabedaten an eine Holographic Remoting-Remoteanwendung und empfängt eine immersive Ansicht als Video- und Audiostream. Die Verbindung wird über Standard-WLAN hergestellt. Um eine Player-App zu erstellen, verwenden Sie ein NuGet-Paket, um Holographic Remoting zu Ihrer UWP-App hinzuzufügen. Schreiben Sie dann Code, um die Verbindung zu behandeln und eine immersive Ansicht anzuzeigen.
Voraussetzungen
Ein guter Ausgangspunkt ist eine funktionierende DirectX-basierte UWP-App, die bereits auf die Windows Mixed Reality-API ausgerichtet ist. Weitere Informationen finden Sie unter Übersicht über die DirectX-Entwicklung. Wenn Sie noch keine App haben und von Grund auf neu beginnen möchten, ist die holografische C++-Projektvorlage ein guter Ausgangspunkt.
Wichtig
Jede App, die Holographic Remoting verwendet, sollte für die Verwendung eines Multithread-Apartments erstellt werden. Die Verwendung eines Singlethread-Apartments wird unterstützt, führt jedoch zu einer suboptimalen Leistung und möglicherweise zu Stottern während der Wiedergabe. Bei Verwendung von C++/WinRT winrt::init_apartment ist ein Multithread-Apartment die Standardeinstellung.
Abrufen des Holographic Remoting-NuGet-Pakets
Die folgenden Schritte sind erforderlich, um das NuGet-Paket einem Projekt in Visual Studio hinzuzufügen.
- Öffnen Sie das Projekt in Visual Studio.
- Klicken Sie mit der rechten Maustaste auf den Projektknoten, und wählen Sie NuGet-Pakete verwalten... aus.
- Wählen Sie im daraufhin angezeigten Bereich Durchsuchen aus, und suchen Sie dann nach "Holographic Remoting".
- Wählen Sie Microsoft.Holographic.Remoting aus, stellen Sie sicher, dass Sie die neueste Version 2.x.x und dann Installieren auswählen.
- Wenn das Dialogfeld Vorschau angezeigt wird, wählen Sie OK aus.
- Wählen Sie Ich stimme zu , wenn das Dialogfeld für den Lizenzvertrag angezeigt wird.
Wichtig
Das build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl
im NuGet-Paket enthaltene detaillierte Dokumentation für die API, die von Holographic Remoting verfügbar gemacht wird.
Ändern des Package.appxmanifest der Anwendung
Um die Anwendung auf die vom NuGet-Paket hinzugefügten Microsoft.Holographic.AppRemoting.dll aufmerksam zu machen, müssen die folgenden Schritte für das Projekt ausgeführt werden:
- Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Datei Package.appxmanifest, und wählen Sie Öffnen mit... aus.
- Wählen Sie XML (Text) Editor und dann OK aus.
- Fügen Sie der Datei die folgenden Zeilen hinzu, und speichern Sie
</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>
Erstellen des Playerkontexts
Als ersten Schritt sollte die Anwendung einen Playerkontext erstellen.
// 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();
Warnung
Ein benutzerdefinierter Player fügt eine Zwischenebene zwischen der Player-App und der mit Windows ausgelieferten Windows Mixed Reality Runtime ein. Dies geschieht während der Erstellung des Spielerkontexts. Aus diesem Grund kann jeder Aufruf einer Windows Mixed Reality-API vor dem Erstellen des Playerkontexts zu unerwartetem Verhalten führen. Der empfohlene Ansatz besteht darin, den Playerkontext so früh wie möglich vor der Interaktion mit einer Mixed Reality-API zu erstellen. Mischen Sie niemals Objekte, die vor dem Aufruf PlayerContext::Create
von über eine Windows Mixed Reality-API erstellt oder abgerufen wurden, mit Anschließend erstellten oder abgerufenen Objekten.
Als Nächstes kann holographicSpace erstellt werden, indem HolographicSpace.CreateForCoreWindow aufgerufen wird.
m_holographicSpace = winrt::Windows::Graphics::Holographic::HolographicSpace::CreateForCoreWindow(window);
Herstellen einer Verbindung mit der Remote-App
Sobald die Player-App zum Rendern von Inhalten bereit ist, kann eine Verbindung mit der Remote-App hergestellt werden.
Die Verbindung kann auf eine der folgenden Arten hergestellt werden:
- Die Player-App, die auf HoloLens 2 ausgeführt wird, stellt eine Verbindung mit der Remote-App her.
- Die Remote-App stellt eine Verbindung mit der Player-App her, die auf HoloLens 2 ausgeführt wird.
Um eine Verbindung zwischen der Player-App und der Remote-App herzustellen, rufen Sie die Connect
-Methode im Playerkontext auf, indem Sie hostnamen und port angeben. Der Standardport ist 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()
}
Wichtig
Wie bei jeder C++/WinRT-API Connect
kann ein winrt::hresult_error ausgelöst werden, der behandelt werden muss.
Das Lauschen auf eingehende Verbindungen in der Player-App kann durch Aufrufen der Listen
-Methode erfolgen. Während dieses Aufrufs können sowohl der Handshakeport als auch der Transportport angegeben werden. Der Handshakeport wird für den ersten Handshake verwendet. Die Daten werden dann über den Transportport gesendet. Standardmäßig werden die Portnummern 8265 und 8266 verwendet.
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()
}
Behandeln von verbindungsbezogenen Ereignissen
Macht PlayerContext
drei Ereignisse verfügbar, um den Zustand der Verbindung zu überwachen.
- OnConnected: Wird ausgelöst, wenn eine Verbindung mit der Remote-App erfolgreich hergestellt wurde.
m_onConnectedEventToken = m_playerContext.OnConnected([]()
{
// Handle connection successfully established
});
- OnDisconnected: Wird ausgelöst, wenn eine hergestellte Verbindung beendet wird oder keine Verbindung hergestellt werden konnte.
m_onDisconnectedEventToken = m_playerContext.OnDisconnected([](ConnectionFailureReason failureReason)
{
switch (failureReason)
{
// Handle connection failed or terminated.
// See ConnectionFailureReason for possible reasons.
}
}
Hinweis
Mögliche ConnectionFailureReason
Werte sind in der Microsoft.Holographic.AppRemoting.idl
Datei dokumentiert.
- OnListening: Wenn das Lauschen auf eingehende Verbindungen gestartet wird.
m_onListeningEventToken = m_playerContext.OnListening([]()
{
// Handle start listening for incoming connections
});
Darüber hinaus kann der Verbindungsstatus mithilfe der ConnectionState
-Eigenschaft im Playerkontext abgefragt werden.
winrt::Microsoft::Holographic::AppRemoting::ConnectionState state = m_playerContext.ConnectionState();
Anzeigen des remote gerenderten Frames
Um den remote gerenderten Inhalt anzuzeigen, rufen Sie PlayerContext::BlitRemoteFrame
beim Rendern eines HolographicFrames auf.
BlitRemoteFrame
erfordert, dass der Hintergrundpuffer für den aktuellen HolographicFrame als Renderziel gebunden ist. Der Hintergrundpuffer kann von HolographicCameraRenderingParameters über die Direct3D11BackBuffer-Eigenschaft empfangen werden.
Kopiert beim Aufruf BlitRemoteFrame
den zuletzt empfangenen Frame aus der Remoteanwendung in den BackBuffer des HolographicFrames. Darüber hinaus wird der Fokuspunkt festgelegt, wenn die Remoteanwendung beim Rendern des Remoteframes einen Fokuspunkt angegeben hat.
// Blit the remote frame into the backbuffer for the HolographicFrame.
winrt::Microsoft::Holographic::AppRemoting::BlitResult result = m_playerContext.BlitRemoteFrame();
Hinweis
PlayerContext::BlitRemoteFrame
überschreibt möglicherweise den Fokuspunkt für den aktuellen Frame.
- Um einen Fallbackfokuspunkt anzugeben, rufen Sie HolographicCameraRenderingParameters::SetFocusPoint vor auf
PlayerContext::BlitRemoteFrame
. - Um den Remotefokuspunkt zu überschreiben, rufen Sie HolographicCameraRenderingParameters::SetFocusPoint nach auf
PlayerContext::BlitRemoteFrame
.
Gibt bei Erfolg BlitRemoteFrame
zurück BlitResult::Success_Color
. Andernfalls wird der Fehlergrund zurückgegeben:
-
BlitResult::Failed_NoRemoteFrameAvailable
: Fehler, da kein Remoteframe verfügbar ist. -
BlitResult::Failed_NoCamera
: Fehler, weil keine Kamera vorhanden ist. -
BlitResult::Failed_RemoteFrameTooOld
: Fehler, weil der Remoteframe zu alt ist (siehe PlayerContext::BlitRemoteFrameTimeout-Eigenschaft).
Wichtig
Ab Version 2.1.0 ist es mit einem benutzerdefinierten Player möglich, die Tiefenreprojektion über Holographic Remoting zu verwenden.
BlitResult
kann auch unter den folgenden Bedingungen zurückgegeben BlitResult::Success_Color_Depth
werden:
- Die Remote-App hat über HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer einen Tiefenpuffer committet.
- Die benutzerdefinierte Player-App hat vor dem Aufrufen
BlitRemoteFrame
von einen gültigen Tiefenpuffer gebunden.
Wenn diese Bedingungen erfüllt sind, BlitRemoteFrame
löscht die Remotetiefe in den derzeit gebundenen lokalen Tiefenpuffer. Anschließend können Sie zusätzliche lokale Inhalte rendern, die eine Tiefen schnittmenge mit dem remote gerenderten Inhalt aufweisen. Darüber hinaus können Sie den lokalen Tiefenpuffer über HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer in Ihrem benutzerdefinierten Player committen, um eine Tiefenreprojektion für remote und lokal gerenderte Inhalte zu erhalten.
Projektionstransformationsmodus
Ein Problem, das bei der Verwendung der Tiefenreprojektion über Holographic Remoting auftritt, besteht darin, dass der Remoteinhalt mit einer anderen Projektionstransformation gerendert werden kann als lokale Inhalte, die direkt von Ihrer benutzerdefinierten Player-App gerendert werden. Ein gängiger Anwendungsfall besteht darin, unterschiedliche Werte für die Nah- und Fernebene (über HolographicCamera::SetNearPlaneDistance und HolographicCamera::SetFarPlaneDistance) auf der Spielerseite und auf der Remoteseite anzugeben. In diesem Fall ist nicht klar, ob die Projektionstransformation auf der Spielerseite die entfernungsnahen/entfernten Ebenenabstände oder die lokalen abbilden soll.
Ab Version 2.1.0 können Sie den Projektionstransformationsmodus über PlayerContext::ProjectionTransformConfig
steuern. Unterstützte Werte:
-
Local
- HolographicCameraPose::P rojectionTransform gibt eine Projektionstransformation zurück, die die von Ihrer benutzerdefinierten Player-App auf der HolographicCamera festgelegten Entfernungen auf der Nah-/Fernebene widerspiegelt. -
Remote
– Die Projektionstransformation spiegelt die von der Remote-App angegebenen Entfernungen auf der Nah-/Fernebene wider. -
Merged
– Entfernungen der Nah-/Fernebene von Ihrer Remote-App und Ihrer benutzerdefinierten Player-App werden zusammengeführt. Standardmäßig erfolgt dies, indem der Mindestabstand der nahen Ebene und das Maximum der Entfernungen der entfernten Ebene berücksichtigt werden. Falls entweder die entfernte oder die lokale Seite invertiert ist, z. B. weit < in der Nähe, werden die entfernungsnahen/entfernten Ebenenabstände umgedreht.
Optional: Festlegen von BlitRemoteFrameTimeout
Wichtig
PlayerContext::BlitRemoteFrameTimeout
wird ab Version 2.0.9 unterstützt.
Die PlayerContext::BlitRemoteFrameTimeout
-Eigenschaft gibt an, wie lange ein Remoteframe wiederverwendet wird, wenn kein neuer Remoteframe empfangen wird.
Ein gängiger Anwendungsfall besteht darin, das BlitRemoteFrame-Timeout so zu aktivieren, dass ein leerer Bildschirm angezeigt wird, wenn für einen bestimmten Zeitraum keine neuen Frames empfangen werden. Wenn aktiviert, kann der Rückgabetyp der BlitRemoteFrame
Methode auch verwendet werden, um zu einem lokal gerenderten Fallbackinhalt zu wechseln.
Um das Timeout zu aktivieren, legen Sie den Eigenschaftswert auf eine Dauer von mindestens 100 ms fest. Um das Timeout zu deaktivieren, legen Sie die -Eigenschaft auf null dauer fest. Wenn das Timeout aktiviert ist und kein Remoteframe für die festgelegte Dauer empfangen wird, schlägt BlitRemoteFrame fehl und kehrt zurück, Failed_RemoteFrameTooOld
bis ein neuer Remoteframe empfangen wird.
using namespace std::chrono_literals;
// Set the BlitRemoteFrame timeout to 0.5s
m_playerContext.BlitRemoteFrameTimeout(500ms);
Optional: Abrufen von Statistiken zum letzten Remoteframe
Um Leistungs- oder Netzwerkprobleme zu diagnostizieren, können Statistiken zum letzten Remoteframe über die PlayerContext::LastFrameStatistics
-Eigenschaft abgerufen werden. Statistiken werden während des Aufrufs von HolographicFrame::P resentUsingCurrentPrediction aktualisiert.
// Get statistics for the last presented frame.
winrt::Microsoft::Holographic::AppRemoting::PlayerFrameStatistics statistics = m_playerContext.LastFrameStatistics();
Weitere Informationen finden Sie in der PlayerFrameStatistics
Dokumentation in der Microsoft.Holographic.AppRemoting.idl
Datei.
Optional: Benutzerdefinierte Datenkanäle
Benutzerdefinierte Datenkanäle können verwendet werden, um Benutzerdaten über die bereits hergestellte Remotingverbindung zu senden. Weitere Informationen finden Sie unter Benutzerdefinierte Datenkanäle.
Optional: Over-Rendering
Holographic Remoting sagt vorher, wo sich der Kopf des Benutzers befindet, wenn die gerenderten Bilder auf den Displays angezeigt werden. Diese Vorhersage ist jedoch eine Näherung. Daher können sich der vorhergesagte Viewport für die Remote-App und der spätere tatsächliche Viewport in der Player-App unterscheiden. Stärkere Abweichungen (z. B. aufgrund unvorhersehbarer Bewegung) können schwarze Bereiche an den Rändern des Sicht frustums verursachen. Ab Version 2.6.0 können Sie Over-Rendering verwenden, um die schwarzen Bereiche zu reduzieren und die visuelle Qualität zu verbessern, indem Sie den Viewport über das Ansichts frustum hinaus künstlich erhöhen.
Over-Rendering kann über PlayerContext::ConfigureOverRendering
aktiviert werden.
Gibt OverRenderingConfig
eine Größenbruchteilerhöhung auf den tatsächlichen Viewport an, sodass der vorhergesagte Viewport größer wird und weniger Schnitten auftreten.
Bei einer erhöhten Viewportgröße nimmt die Pixeldichte ab, sodass Sie mit OverRenderingConfig auch die Auflösung erhöhen können.
Wenn die Viewporterhöhung gleich der Auflösungserhöhung ist, bleibt die Pixeldichte unverändert.
OverRenderingConfig
ist definiert 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).
};
Optional: Koordinatensystemsynchronisierung
Ab Version 2.7.0 kann die Koordinatensystemsynchronisierung verwendet werden, um räumliche Daten zwischen dem Player und der Remote-App auszurichten. Weitere Informationen finden Sie unter Übersicht über die Koordinatensystemsynchronisierung mit holographic Remoting.
Siehe auch
- Übersicht über holographic Remoting
- Schreiben einer Holographic Remoting-Remote-App mit Windows Mixed Reality-APIs
- Schreiben einer Holographic Remoting-Remote-App mithilfe von OpenXR-APIs
- Benutzerdefinierte Holographic Remoting-Datenkanäle
- Herstellen einer sicheren Verbindung mit Holographic Remoting
- Holographic Remoting: Problembehandlung und Einschränkungen
- Lizenzbedingungen für Holographic Remoting-Software
- Microsoft-Datenschutzbestimmungen