Hinzufügen von Holographic Remoting (HoloLens 1. Generation)

Wenn Sie noch nicht mit Holographic Remoting sind, sollten Sie unsere Übersicht lesen.

Wichtig

In diesem Dokument wird die Erstellung einer Hostanwendung für HoloLens 1 beschrieben. Hostanwendung für HoloLens (1. Generation) muss NuGet-Paketversion 1.x.x verwenden. Dies bedeutet, dass für HoloLens 1 geschriebene Hostanwendungen nicht mit HoloLens 2 kompatibel sind und umgekehrt.

HoloLens 2

HoloLens-Entwickler, die Holographic Remoting verwenden, müssen ihre Apps aktualisieren, um sie mit HoloLens 2 kompatibel zu machen. Hierfür ist eine neue Version des Holographic Remoting NuGet-Pakets erforderlich. Achten Sie darauf, version 2.0.0.0 oder höher des Holographic Remoting NuGet-Pakets zu verwenden, wenn Sie eine Verbindung mit dem Holographic Remoting Player auf HoloLens 2 herstellen. Andernfalls wird die Verbindung nicht hergestellt.

Hinweis

Spezifische Anleitungen für HoloLens 2 finden Sie hier.

Hinzufügen von holografischem Remoting zu Ihrer Desktop- oder UWP-App

Auf dieser Seite wird beschrieben, wie Holographic Remoting zu einer Desktop- oder UWP-App hinzugefügt wird.

Holographic Remoting ermöglicht Es Ihrer App, eine HoloLens mit holografischen Inhalten zu verwenden, die auf einem Desktop-PC oder auf einem UWP-Gerät wie der Xbox One gehostet werden. Sie haben auch Zugriff auf mehr Systemressourcen, sodass Sie immersive Remoteansichten in vorhandene Desktop-PC-Software integrieren können. Eine Remotinghost-App empfängt einen Eingabedatenstrom von einer HoloLens, rendert Inhalte in einer virtuellen immersiven Ansicht und streamt Inhaltsframes zurück an HoloLens. Die Verbindung wird über standardmäßiges WLAN hergestellt. Um Remoting zu verwenden, verwenden Sie ein NuGet-Paket, um Ihrer Desktop- oder UWP-App holografisches Remoting hinzuzufügen, und schreiben Sie dann Code, um die Verbindung zu verarbeiten und eine immersive Ansicht zu rendern. Hilfsbibliotheken sind im Codebeispiel enthalten, die die Handhabung der Geräteverbindung vereinfachen.

Eine typische Remotingverbindung weist eine Latenz von nur 50 ms auf. Die Player-App kann die Latenz in Echtzeit melden.

Hinweis

Die Codeausschnitte in diesem Artikel veranschaulichen derzeit die Verwendung von C++/CX anstelle von C++17-kompatiblem C++/WinRT, wie es in der holografischen C++-Projektvorlage verwendet wird. Die Konzepte sind für ein C++/WinRT-Projekt gleichwertig, obwohl Sie den Code übersetzen müssen.

Abrufen der Remoting-NuGet-Pakete

Führen Sie die folgenden Schritte aus, um das NuGet-Paket für holografisches Remoting abzurufen und einen Verweis aus Ihrem Projekt hinzuzufügen:

  1. Wechseln Sie zu Ihrem Projekt in Visual Studio.
  2. Klicken Sie mit der rechten Maustaste auf den Projektknoten, und wählen Sie NuGet-Pakete verwalten... aus.
  3. Wählen Sie im daraufhin angezeigten Bereich Durchsuchen aus, und suchen Sie dann nach "Holographic Remoting".
  4. Wählen Sie Microsoft.Holographic.Remoting und dann Installieren aus.
  5. Wenn das Dialogfeld Vorschau angezeigt wird, wählen Sie OK aus.
  6. Wählen Sie Ich stimme zu , wenn das Dialogfeld für den Lizenzvertrag angezeigt wird.

Erstellen der HolographicStreamerHelpers

Zunächst müssen wir der Klasse, die Remoting behandelt, eine instance von HolographicStreamerHelpers hinzufügen.

#include <HolographicStreamerHelpers.h>

   private:
       Microsoft::Holographic::HolographicStreamerHelpers^ m_streamerHelpers;

Außerdem müssen Sie den Verbindungsstatus nachverfolgen. Wenn Sie die Vorschau rendern möchten, benötigen Sie eine Textur, in die sie kopiert werden kann. Sie benötigen auch einige Dinge wie eine Verbindungszustandssperre, eine Möglichkeit zum Speichern der IP-Adresse von HoloLens usw.

private:
       Microsoft::Holographic::HolographicStreamerHelpers^ m_streamerHelpers;

       Microsoft::WRL::Wrappers::SRWLock                   m_connectionStateLock;

       RemotingHostSample::AppView^                        m_appView;
       Platform::String^                                   m_ipAddress;
       Microsoft::Holographic::HolographicStreamerHelpers^ m_streamerHelpers;

       Microsoft::WRL::Wrappers::CriticalSection           m_deviceLock;
       Microsoft::WRL::ComPtr<IDXGISwapChain1>             m_swapChain;
       Microsoft::WRL::ComPtr<ID3D11Texture2D>             m_spTexture;

Initialisieren von HolographicStreamerHelpers und Herstellen einer Verbindung mit HoloLens

Um eine Verbindung mit einem HoloLens-Gerät herzustellen, erstellen Sie eine instance von HolographicStreamerHelpers, und stellen Sie eine Verbindung mit der Ziel-IP-Adresse her. Sie müssen die Größe des Videoframes so festlegen, dass sie der Breite und Höhe der HoloLens-Anzeige entspricht, da die Holographic Remoting-Bibliothek erwartet, dass die Encoder- und Decoderauflösungen genau übereinstimmen.

m_streamerHelpers = ref new HolographicStreamerHelpers();
       m_streamerHelpers->CreateStreamer(m_d3dDevice);

       // We currently need to stream at 720p because that's the resolution of our remote display.
       // There is a check in the holographic streamer that makes sure the remote and local
       // resolutions match. The default streamer resolution is 1080p.
       m_streamerHelpers->SetVideoFrameSize(1280, 720);

       try
       {
           m_streamerHelpers->Connect(m_ipAddress->Data(), 8001);
       }
       catch (Platform::Exception^ ex)
       {
           DebugLog(L"Connect failed with hr = 0x%08X", ex->HResult);
       }

Die Geräteverbindung ist asynchron. Ihre App muss Ereignishandler für Verbindungs-, Trenn- und Frame send-Ereignisse bereitstellen.

Das OnConnected-Ereignis kann die Benutzeroberfläche aktualisieren, mit dem Rendern beginnen usw. In unserem Desktopcodebeispiel wird der Fenstertitel mit einer Meldung "verbunden" aktualisiert.

m_streamerHelpers->OnConnected += ref new ConnectedEvent(
           [this]()
           {
               UpdateWindowTitle();
           });

Das OnDisconnected-Ereignis kann die erneute Verbindung, Ui-Updates usw. verarbeiten. In diesem Beispiel stellen wir die Verbindung erneut her, wenn ein vorübergehender Fehler auftritt.

Platform::WeakReference streamerHelpersWeakRef = Platform::WeakReference(m_streamerHelpers);
       m_streamerHelpers->OnDisconnected += ref new DisconnectedEvent(
           [this, streamerHelpersWeakRef](_In_ HolographicStreamerConnectionFailureReason failureReason)
           {
               DebugLog(L"Disconnected with reason %d", failureReason);
               UpdateWindowTitle();

               // Reconnect if this is a transient failure.
               if (failureReason == HolographicStreamerConnectionFailureReason::Unreachable ||
                   failureReason == HolographicStreamerConnectionFailureReason::ConnectionLost)
               {
                   DebugLog(L"Reconnecting...");

                   try
                   {
                       auto helpersResolved = streamerHelpersWeakRef.Resolve<HolographicStreamerHelpers>();
                       if (helpersResolved)
                       {
                           helpersResolved->Connect(m_ipAddress->Data(), 8001);
                       }
                       else
                       {
                           DebugLog(L"Failed to reconnect because a disconnect has already occurred.\n");
                       }
                   }
                   catch (Platform::Exception^ ex)
                   {
                       DebugLog(L"Connect failed with hr = 0x%08X", ex->HResult);
                   }
               }
               else
               {
                   DebugLog(L"Disconnected with unrecoverable error, not attempting to reconnect.");
               }
           });

Wenn die Remotingkomponente bereit ist, einen Frame zu senden, erhält Ihre App die Möglichkeit, eine Kopie davon im SendFrameEvent zu erstellen. Hier kopieren wir den Frame in eine Swapchain, damit er in einem Vorschaufenster angezeigt werden kann.

m_streamerHelpers->OnSendFrame += ref new SendFrameEvent(
           [this](_In_ const ComPtr<ID3D11Texture2D>& spTexture, _In_ FrameMetadata metadata)
           {
               if (m_showPreview)
               {
                   ComPtr<ID3D11Device1> spDevice = m_appView->GetDeviceResources()->GetD3DDevice();
                   ComPtr<ID3D11DeviceContext> spContext = m_appView->GetDeviceResources()->GetD3DDeviceContext();

                   ComPtr<ID3D11Texture2D> spBackBuffer;
                   ThrowIfFailed(m_swapChain->GetBuffer(0, IID_PPV_ARGS(&spBackBuffer)));

                   spContext->CopySubresourceRegion(
                       spBackBuffer.Get(), // dest
                       0,                  // dest subresource
                       0, 0, 0,            // dest x, y, z
                       spTexture.Get(),    // source
                       0,                  // source subresource
                       nullptr);           // source box, null means the entire resource

                   DXGI_PRESENT_PARAMETERS parameters = { 0 };
                   ThrowIfFailed(m_swapChain->Present1(1, 0, &parameters));
               }
           });

Rendern holografischer Inhalte

Zum Rendern von Inhalten mithilfe von Remoting richten Sie ein virtuelles IFrameworkView in Ihrer Desktop- oder UWP-App ein und verarbeiten holografische Frames über Remoting. Alle Windows Holographic-APIs werden von dieser Ansicht auf die gleiche Weise verwendet, aber sie ist etwas anders eingerichtet.

Anstatt sie selbst zu erstellen, stammen der holografische Raum und die Sprachkomponenten aus Ihrer HolographicRemotingHelpers-Klasse:

m_appView->Initialize(m_streamerHelpers->HolographicSpace, m_streamerHelpers->RemoteSpeech);

Anstatt eine Updateschleife in einer Run-Methode zu verwenden, stellen Sie Tick-Updates aus der Standard-Schleife Ihrer Desktop- oder UWP-App bereit. Dadurch kann Ihre Desktop- oder UWP-App die Kontrolle über die Nachrichtenverarbeitung behalten.

void DesktopWindow::Tick()
   {
       auto lock = m_deviceLock.Lock();
       m_appView->Tick();

       // display preview, etc.
   }

Die Tick()-Methode der holografischen App-Ansicht schließt eine Iteration der Schleife update, draw, present ab.

void AppView::Tick()
   {
       if (m_main)
       {
           // When running on Windows Holographic, we can use the holographic rendering system.
           HolographicFrame^ holographicFrame = m_main->Update();

           if (holographicFrame && m_main->Render(holographicFrame))
           {
               // The holographic frame has an API that presents the swap chain for each
               // holographic camera.
               m_deviceResources->Present(holographicFrame);
           }
       }
   }

Die Aktualisierungs-, Render- und Gegenwartsschleife der holografischen App ist identisch mit der Ausführung auf HoloLens – mit der Ausnahme, dass Sie Zugriff auf eine viel größere Anzahl von Systemressourcen auf Ihrem Desktop-PC haben. Sie können viel mehr Dreiecke rendern, mehr Zeichendurchläufe haben, mehr Physik ausführen und x64-Prozesse verwenden, um Inhalte zu laden, die mehr als 2 GB RAM erfordern.

Trennen und Beenden der Remotesitzung

Um die Verbindung zu trennen , z. B. wenn der Benutzer auf eine Schaltfläche der Benutzeroberfläche klickt, um die Verbindung zu trennen, rufen Sie Disconnect() für holographicStreamerHelpers auf, und lassen Sie dann das Objekt los.

void DesktopWindow::DisconnectFromRemoteDevice()
   {
       // Disconnecting from the remote device can change the connection state.
       auto exclusiveLock = m_connectionStateLock.LockExclusive();

       if (m_streamerHelpers != nullptr)
       {
           m_streamerHelpers->Disconnect();

           // Reset state
           m_streamerHelpers = nullptr;
       }
   }

Abrufen des Remoting-Players

Der Windows Holographic-Remoting-Player wird im Windows App Store als Endpunkt für Remoting-Host-Apps angeboten, mit denen eine Verbindung hergestellt werden kann. Um den Windows Holographic Remoting Player zu erhalten, besuchen Sie den Windows App Store über Ihre HoloLens, suchen Sie nach Remoting, und laden Sie die App herunter. Der Remotingplayer enthält ein Feature zum Anzeigen von Statistiken auf dem Bildschirm, das beim Debuggen von Remotinghost-Apps nützlich sein kann.

Hinweise und Ressourcen

Die holografische App-Ansicht benötigt eine Möglichkeit, Ihre App mit dem Direct3D-Gerät bereitzustellen, das zum Initialisieren des holografischen Raums verwendet werden muss. Ihre App sollte dieses Direct3D-Gerät verwenden, um den Vorschaurahmen zu kopieren und anzuzeigen.

internal:
       const std::shared_ptr<DX::DeviceResources>& GetDeviceResources()
       {
           return m_deviceResources;
       }

Codebeispiel: Ein vollständiges Holographic Remoting-Codebeispiel ist verfügbar, das eine holografische Anwendungsansicht enthält, die mit Remoting- und Remotinghostprojekten für Desktop-Win32, UWP DirectX und UWP mit XAML kompatibel ist.

Hinweis zum Debuggen: Die Holographic Remoting-Bibliothek kann Ausnahmen für die erste Chance auslösen. Diese Ausnahmen können in Debugsitzungen sichtbar sein, je nachdem, welche Visual Studio-Ausnahmeeinstellungen zu diesem Zeitpunkt aktiv sind. Diese Ausnahmen werden intern von der Holographic Remoting-Bibliothek abgefangen und können ignoriert werden.

Weitere Informationen