Share via


Holographic Remoting Remote alkalmazás írása a HolographicSpace API használatával

Ha még nem ismerkedik a Holographic Remoting használatával, érdemes elolvasnia az áttekintést.

Fontos

Ez a dokumentum egy távoli alkalmazás létrehozását ismerteti HoloLens 2 a HolographicSpace API használatával. A HoloLens távoli alkalmazásainak (1. generációs)NuGet-csomag 1.x.x-es verzióját kell használniuk. Ez azt jelenti, hogy a HoloLens 2 írt távoli alkalmazások nem kompatibilisek a HoloLens 1-zel, és fordítva. A HoloLens 1 dokumentációja itt található.

Elavulási értesítés: A 2.9.x kiadási sor lesz az utolsó, amely támogatja a Windows Holographic API-kat az alkalmazásfejlesztéshez. A közelgő verziók csak az OpenXR-t támogatják az alkalmazásfejlesztéshez. Ebbôl függetlenül javasoljuk, hogy minden új alkalmazásfejlesztéshez használja az OpenXR-t az alkalmazásban. A 2.9-es vagy újabb verziót használó meglévő alkalmazások továbbra is működni fognak a közelgő változásoktól függetlenül.

A Holographic Remoting-alkalmazások távolról renderelt tartalmakat streamelhetnek HoloLens 2 és Windows Mixed Reality magával ragadó fejhallgatókba. Emellett több rendszererőforrást is elérhet, és távoli , modern nézeteket integrálhat a meglévő asztali pc-szoftverekbe. A távoli alkalmazások bemeneti adatstreamet kapnak HoloLens 2, virtuális, modern nézetben renderelik a tartalmat, és a tartalomkereteket visszaküldik HoloLens 2. A kapcsolat standard Wi-Fi-vel jön létre. A holografikus remoting nuGet-csomagon keresztül kerül egy asztali vagy UWP-alkalmazásba. További kódra van szükség, amely kezeli a kapcsolatot, és magával ragadó nézetben jelenik meg. Egy tipikus újraegyenlítési kapcsolat 50 ms késéssel fog rendelkezni. A lejátszóalkalmazás valós időben jelentheti a késést.

Ezen a lapon és a munkaprojektekben található összes kód megtalálható a Holographic Remoting samples github-adattárban.

Előfeltételek

Jó kiindulópont egy működő DirectX-alapú asztali vagy UWP-alkalmazás, amely a Windows Mixed Reality API-t célozza meg. Részletekért lásd: DirectX-fejlesztés áttekintése. A C++ holografikus projektsablon jó kiindulópont.

Fontos

A Holographic Remotingot használó alkalmazásokat többszálú lakás használatához kell létrehozni. Az egyszálas lakás használata támogatott, de a lejátszás során az optimálisnál rosszabb teljesítményhez és esetleg akadozáshoz vezet. A C++/WinRT winrt::init_apartment használata esetén a többszálas apartman az alapértelmezett.

A Holographic Remoting NuGet-csomag lekérése

A NuGet-csomag Visual Studióban való hozzáadásához a következő lépések szükségesek.

  1. Nyissa meg a projektet a Visual Studióban.
  2. Kattintson a jobb gombbal a projektcsomópontra, és válassza a NuGet-csomagok kezelése... lehetőséget.
  3. A megjelenő panelen válassza a Tallózás lehetőséget, majd keressen rá a "Holographic Remoting" kifejezésre.
  4. Válassza a Microsoft.Holographic.Remoting lehetőséget, válassza ki a legújabb 2.x.x verziót, és válassza a Telepítés lehetőséget.
  5. Ha megjelenik az Előnézet párbeszédpanel, válassza az OK gombot.
  6. Válassza az Elfogadom lehetőséget, amikor megjelenik a licencszerződés párbeszédpanel.

Megjegyzés

A NuGet-csomag 1.x.x-es verziója továbbra is elérhető a HoloLens 1-et megcélzó fejlesztők számára. További információ: HoloLens hozzáadása (1. generációs).

A távoli környezet létrehozása

Első lépésként az alkalmazásnak létre kell hoznia egy távoli környezetet.

// class declaration
#include <winrt/Microsoft.Holographic.AppRemoting.h>

...

private:
    // RemoteContext used to connect with a Holographic Remoting player and display rendered frames
    winrt::Microsoft::Holographic::AppRemoting::RemoteContext m_remoteContext = nullptr;
// class implementation
#include <HolographicAppRemoting\Streamer.h>

...

CreateRemoteContext(m_remoteContext, 20000, false, PreferredVideoCodec::Default);

Figyelmeztetés

A Holographic Remoting úgy működik, hogy lecseréli a Windows részét képező Windows Mixed Reality futtatókörnyezetet egy adott futtatókörnyezetre. Ez a távoli környezet létrehozásakor történik. Ezért a távoli környezet létrehozása előtt bármely Windows Mixed Reality API-n történő hívás váratlan viselkedést eredményezhet. Az ajánlott módszer a távoli környezet lehető legkorábbi létrehozása, mielőtt bármilyen Mixed Reality API-val kommunikál. Soha ne keverje össze az Windows Mixed Reality API-val létrehozott vagy lekért objektumokat, mielőtt a CreateRemoteContext metódust meghívja a később létrehozott vagy lekért objektumokkal.

Ezután létre kell hozni a holografikus helyet. A CoreWindow megadása nem kötelező. Azok az asztali alkalmazások, amelyek nem rendelkeznek CoreWindowval, egyszerűen átadhatnak egy parancsot nullptr.

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

Csatlakozás az eszközhöz

Ha a távoli alkalmazás készen áll a tartalom renderelésére, létre lehet hozni egy kapcsolatot a lejátszóeszközrel.

A kapcsolat kétféleképpen végezhető el.

  1. A távoli alkalmazás csatlakozik az eszközön futó lejátszóhoz.
  2. Az eszközön futó lejátszó csatlakozik a távoli alkalmazáshoz.

Ha kapcsolatot szeretne létesíteni a távoli alkalmazás és a lejátszóeszköz között, hívja meg a Connect metódust a távoli környezetben, megadva a gazdagépnevet és a portot. A Holographic Remoting Player által használt port 8265.

try
{
    m_remoteContext.Connect(m_hostname, m_port);
}
catch(winrt::hresult_error& e)
{
    DebugLog(L"Connect failed with hr = 0x%08X", e.code());
}

Fontos

A C++/WinRT API-hoz Connect hasonlóan a winrt::hresult_error is, amelyet kezelni kell.

Tipp

A C++/WinRT nyelvi kivetítés használatának elkerülése érdekében a Holographic Remoting NuGet-csomagban található fájl build\native\include\<windows sdk version>\abi\Microsoft.Holographic.AppRemoting.h belefoglalható. A mögöttes COM-felületek deklarációit tartalmazza. A C++/WinRT használata azonban ajánlott.

A távoli alkalmazás bejövő kapcsolatainak figyelése a metódus meghívásával Listen végezhető el. A hívás során a kézfogási port és az átviteli port is megadható. A kézfogási port a kezdeti kézfogáshoz használatos. Az adatok ezután az átviteli porton keresztül lesznek elküldve. Alapértelmezés szerint a 8265 és a 8266 van használatban.

try
{
    m_remoteContext.Listen(L"0.0.0.0", m_port, m_port + 1);
}
catch(winrt::hresult_error& e)
{
    DebugLog(L"Listen failed with hr = 0x%08X", e.code());
}

Fontos

A build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl NuGet-csomagon belül részletes dokumentáció található a Holographic Remoting által közzétett API-hoz.

Adott események újraegyenlítésének kezelése

A távoli környezet három eseményt tesz elérhetővé, amelyek fontosak a kapcsolat állapotának monitorozásához.

  1. OnConnected: Akkor aktiválódik, ha sikerült kapcsolatot létesíteni az eszközzel.
winrt::weak_ref<winrt::Microsoft::Holographic::AppRemoting::IRemoteContext> remoteContextWeakRef = m_remoteContext;

m_onConnectedEventRevoker = m_remoteContext.OnConnected(winrt::auto_revoke, [this, remoteContextWeakRef]() {
    if (auto remoteContext = remoteContextWeakRef.get())
    {
        // Update UI state
    }
});
  1. OnDisconnected: Akkor aktiválódik, ha egy létrehozott kapcsolat lezárult, vagy nem sikerült kapcsolatot létesíteni.
m_onDisconnectedEventRevoker =
    m_remoteContext.OnDisconnected(winrt::auto_revoke, [this, remoteContextWeakRef](ConnectionFailureReason failureReason) {
        if (auto remoteContext = remoteContextWeakRef.get())
        {
            DebugLog(L"Disconnected with reason %d", failureReason);
            // Update UI

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

                ConnectOrListen();
            }
            // Failure reason None indicates a normal disconnect.
            else if (failureReason != ConnectionFailureReason::None)
            {
                DebugLog(L"Disconnected with unrecoverable error, not attempting to reconnect.");
            }
        }
    });
  1. OnListening: A bejövő kapcsolatok figyelésekor elindul.
m_onListeningEventRevoker = m_remoteContext.OnListening(winrt::auto_revoke, [this, remoteContextWeakRef]() {
    if (auto remoteContext = remoteContextWeakRef.get())
    {
        // Update UI state
    }
});

Emellett a kapcsolati állapot lekérdezhető a ConnectionState távoli környezet tulajdonságával.

auto connectionState = m_remoteContext.ConnectionState();

Beszédesemények kezelése

A távoli beszédfelület használatával regisztrálhatja a beszédindítókat a HoloLens 2, és távolról is el lehet őket távolíteni a távoli alkalmazáshoz.

A távoli beszéd állapotának nyomon követéséhez a következő további tagra van szükség:

winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech::OnRecognizedSpeech_revoker m_onRecognizedSpeechRevoker;

Először kérje le a távoli beszédfelületet.

if (auto remoteSpeech = m_remoteContext.GetRemoteSpeech())
{
    InitializeSpeechAsync(remoteSpeech, m_onRecognizedSpeechRevoker, weak_from_this());
}

Aszinkron segédmetódussal inicializálhatja a távoli beszédet. Ezt aszinkron módon kell elvégezni, mivel az inicializálás jelentős időt vehet igénybe. Az egyidejűség és aszinkron műveletek a C++/WinRT használatával ismerteti, hogyan lehet aszinkron függvényeket létrehozni a C++/WinRT használatával.

winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> LoadGrammarFileAsync()
{
    const wchar_t* speechGrammarFile = L"SpeechGrammar.xml";
    auto rootFolder = winrt::Windows::ApplicationModel::Package::Current().InstalledLocation();
    return rootFolder.GetFileAsync(speechGrammarFile);
}

winrt::fire_and_forget InitializeSpeechAsync(
    winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech remoteSpeech,
    winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech::OnRecognizedSpeech_revoker& onRecognizedSpeechRevoker,
    std::weak_ptr<SampleRemoteMain> sampleRemoteMainWeak)
{
    onRecognizedSpeechRevoker = remoteSpeech.OnRecognizedSpeech(
        winrt::auto_revoke, [sampleRemoteMainWeak](const winrt::Microsoft::Holographic::AppRemoting::RecognizedSpeech& recognizedSpeech) {
            if (auto sampleRemoteMain = sampleRemoteMainWeak.lock())
            {
                sampleRemoteMain->OnRecognizedSpeech(recognizedSpeech.RecognizedText);
            }
        });

    auto grammarFile = co_await LoadGrammarFileAsync();

    std::vector<winrt::hstring> dictionary;
    dictionary.push_back(L"Red");
    dictionary.push_back(L"Blue");
    dictionary.push_back(L"Green");
    dictionary.push_back(L"Default");
    dictionary.push_back(L"Aquamarine");

    remoteSpeech.ApplyParameters(L"", grammarFile, dictionary);
}

A felismerendő kifejezések megadásának két módja van.

  1. Specifikáció egy beszédhelyességi XML-fájlban. A részletekért lásd: Alapszintű XML-nyelvhelyesség létrehozása .
  2. Adja meg őket a szótárvektoron belül a következőnek ApplyParameters: .

Az OnRecognizedSpeech visszahíváson belül a beszédesemények ezután feldolgozhatók:

void SampleRemoteMain::OnRecognizedSpeech(const winrt::hstring& recognizedText)
{
    bool changedColor = false;
    DirectX::XMFLOAT4 color = {1, 1, 1, 1};

    if (recognizedText == L"Red")
    {
        color = {1, 0, 0, 1};
        changedColor = true;
    }
    else if (recognizedText == L"Blue")
    {
        color = {0, 0, 1, 1};
        changedColor = true;
    }
    else if (recognizedText == L"Green")
    {
        ...
    }

    ...
}

Streamelt tartalom előzetes verziója helyileg

Ha ugyanazt a tartalmat szeretné megjeleníteni a távoli alkalmazásban, amelyet a rendszer az eszközre OnSendFrame küld, a távoli környezet eseménye használható. Az OnSendFrame esemény minden alkalommal aktiválódik, amikor a Holographic Remoting kódtár elküldi az aktuális keretet a távoli eszköznek. Ez az ideális alkalom arra, hogy a tartalmat az asztalra vagy az UWP-ablakba is becsomagolja.

#include <windows.graphics.directx.direct3d11.interop.h>

...

m_onSendFrameEventRevoker = m_remoteContext.OnSendFrame(
    winrt::auto_revoke, [this](const winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface& texture) {
        winrt::com_ptr<ID3D11Texture2D> texturePtr;
        {
            winrt::com_ptr<ID3D11Resource> resource;
            winrt::com_ptr<::IInspectable> inspectable = texture.as<::IInspectable>();
            winrt::com_ptr<Windows::Graphics::DirectX::Direct3D11::IDirect3DDxgiInterfaceAccess> dxgiInterfaceAccess;
            winrt::check_hresult(inspectable->QueryInterface(__uuidof(dxgiInterfaceAccess), dxgiInterfaceAccess.put_void()));
            winrt::check_hresult(dxgiInterfaceAccess->GetInterface(__uuidof(resource), resource.put_void()));
            resource.as(texturePtr);
        }

        // Copy / blit texturePtr into the back buffer here.
    });

Mélységi újraprojection

A 2.1.0-s verziótól kezdve a Holographic Remoting támogatja a mélységi újraprojektezést. Ehhez a színpuffert és a mélységi puffert is streamelni kell a távoli alkalmazásból a HoloLens 2. Alapértelmezés szerint a mélységi puffer streamelése engedélyezve van, és úgy van konfigurálva, hogy a színpuffer felbontásának felét használja. Ez a következőképpen módosítható:

// class implementation
#include <HolographicAppRemoting\Streamer.h>

...

CreateRemoteContext(m_remoteContext, 20000, false, PreferredVideoCodec::Default);

// Configure for half-resolution depth.
m_remoteContext.ConfigureDepthVideoStream(DepthBufferStreamResolution::Half_Resolution);

Vegye figyelembe, hogy ha az alapértelmezett értékeket nem érdemes használniConfigureDepthVideoStream, a HoloLens 2 való kapcsolat létrehozása előtt meg kell hívni. A legjobb hely közvetlenül a távoli környezet létrehozása után található. A DepthBufferStreamResolution lehetséges értékei a következők:

  • Full_Resolution
  • Half_Resolution
  • Quarter_Resolution
  • Letiltva ( a 2.1.3-es verzióval lett hozzáadva, és ha nincs használatban további mélységi videóstream)

Ne feledje, hogy a teljes felbontású mélységi puffer használata hatással van a sávszélesség-követelményekre is, és figyelembe kell venni a számára megadott CreateRemoteContextmaximális sávszélesség-értéket.

A felbontás konfigurálása mellett mélységi puffert is véglegesítenie kell a HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer használatával.


void SampleRemoteMain::Render(HolographicFrame holographicFrame)
{
    ...

    m_deviceResources->UseHolographicCameraResources([this, holographicFrame](auto& cameraResourceMap) {
        
        ...

        for (auto cameraPose : prediction.CameraPoses())
        {
            DXHelper::CameraResources* pCameraResources = cameraResourceMap[cameraPose.HolographicCamera().Id()].get();

            ...

            m_deviceResources->UseD3DDeviceContext([&](ID3D11DeviceContext3* context) {
                
                ...

                // Commit depth buffer if available and enabled.
                if (m_canCommitDirect3D11DepthBuffer && m_commitDirect3D11DepthBuffer)
                {
                    auto interopSurface = pCameraResources->GetDepthStencilTextureInteropObject();
                    HolographicCameraRenderingParameters renderingParameters = holographicFrame.GetRenderingParameters(cameraPose);
                    renderingParameters.CommitDirect3D11DepthBuffer(interopSurface);
                }
            });
        }
    });
}

Annak ellenőrzéséhez, hogy a mélységi újraprojection megfelelően működik-e HoloLens 2, engedélyezheti a mélységi vizualizációt az eszközportálon. A részletekért lásd: A mélység helyesen van beállítva .

Nem kötelező: Egyéni adatcsatornák

Az egyéni adatcsatornák segítségével felhasználói adatokat küldhet a már létrehozott újrakapcsolódási kapcsolaton keresztül. További információ: Egyéni adatcsatornák.

Nem kötelező: A rendszerszinkronizálás koordinálása

A 2.7.0-s verziótól kezdve a koordinátarendszer-szinkronizálás használható a térbeli adatok a lejátszó és a távoli alkalmazás közötti igazítására. További információ: A rendszerszinkronizálás koordinálása holografikus újraegyenlítéssel – áttekintés.

Lásd még: