Aracılığıyla paylaş


HolographicSpace API'sini kullanarak Holographic Remoting Remote uygulaması yazma

Holographic Remoting'i yeni kullanıyorsanız genel bakış bilgilerimizi okumak isteyebilirsiniz.

Önemli

Bu belgede HolographicSpace API'sini kullanarak HoloLens 2 için uzak uygulama oluşturma işlemi açıklanmaktadır. HoloLens (1. nesil) için uzak uygulamalar NuGet paketi sürüm 1.x.x kullanmalıdır. Bu, HoloLens 2 için yazılmış uzak uygulamaların HoloLens 1 ile uyumlu olmadığı anlamına gelir ve bunun tersi de geçerlidir. HoloLens 1 belgelerine buradan ulaşabilirsiniz.

Kullanımdan kaldırma bildirimi: Uygulama geliştirme için Windows Holographic API'lerini destekleyen son sürüm 2.9.x sürüm satırı olacaktır. Gelecek sürümler yalnızca uygulama geliştirme için OpenXR'ı destekleyecektir. Bundan bağımsız olarak, tüm yeni uygulama geliştirme için uygulamanızda OpenXR kullanılmasını öneririz. 2.9 veya daha eski bir sürümünü kullanan mevcut uygulamalar, yaklaşan değişikliklerden etkilenmeden çalışmaya devam eder.

Holografik Uzaktan İletişim uygulamaları, uzaktan işlenen içerikleri HoloLens 2 ve çevreleyici başlıklar Windows Mixed Reality akışla aktarabilir. Ayrıca daha fazla sistem kaynağına erişebilir ve uzak çevreleyici görünümleri mevcut masaüstü bilgisayar yazılımıyla tümleştirebilirsiniz. Uzak uygulama, HoloLens 2 giriş veri akışı alır, içeriği sanal çevreleyici bir görünümde işler ve içerik çerçevelerini HoloLens 2 geri akışla gönderir. Bağlantı, standart Wi-Fi kullanılarak yapılır. Holographic Remoting, nuget paketi aracılığıyla bir masaüstü veya UWP uygulamasına eklenir. Bağlantıyı işleyen ve çevreleyici bir görünümde işleyen ek kod gereklidir. Tipik bir uzaktan iletişim bağlantısının gecikme süresi 50 ms'ye kadar düşer. Oynatıcı uygulaması gecikme süresini gerçek zamanlı olarak bildirebilir.

Bu sayfadaki tüm kodlar ve çalışan projeler Holographic Remoting örnekleri github deposunda bulunabilir.

Önkoşullar

İyi bir başlangıç noktası, Windows Mixed Reality API'sini hedefleyen çalışan bir DirectX tabanlı Masaüstü veya UWP uygulamasıdır. Ayrıntılar için bkz. DirectX geliştirmeye genel bakış. C++ holografik proje şablonu iyi bir başlangıç noktasıdır.

Önemli

Çok iş parçacıklı bir daire kullanmak için Holographic Remoting kullanan tüm uygulamalar yazılmalıdır. Tek iş parçacıklı bir dairenin kullanımı desteklenir, ancak en uygun performansın altında olmasına ve kayıttan yürütme sırasında takılmaya yol açar. C++/WinRT winrt::init_apartment kullanırken, çok iş parçacıklı bir daire varsayılandır.

Holographic Remoting NuGet paketini edinin

NuGet paketini Visual Studio'daki bir projeye eklemek için aşağıdaki adımlar gereklidir.

  1. Projeyi Visual Studio'da açın.
  2. Proje düğümüne sağ tıklayın ve NuGet Paketlerini Yönet... seçeneğini belirleyin.
  3. Görüntülenen panelde Gözat'ı seçin ve ardından "Holographic Remoting" araması yapın.
  4. Microsoft.Holographic.Remoting'i seçin, en son 2.x.x sürümünü seçtiğinizden emin olun ve Yükle'yi seçin.
  5. Önizleme iletişim kutusu görüntülenirse Tamam'ı seçin.
  6. Lisans sözleşmesi iletişim kutusu açıldığında Kabul Ediyorum'a tıklayın.

Not

NuGet paketinin 1.x.x sürümü, HoloLens 1'i hedeflemek isteyen geliştiriciler için hala kullanılabilir. Ayrıntılar için bkz. Holographic Remoting (HoloLens (1. nesil)) ekleme.

Uzak bağlamı oluşturma

İlk adım olarak uygulamanın uzak bağlam oluşturması gerekir.

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

Uyarı

Holographic Remoting, Windows'un parçası olan Windows Mixed Reality çalışma zamanını uzaktan iletişimle belirli bir çalışma zamanıyla değiştirerek çalışır. Bu, uzak bağlam oluşturulurken yapılır. Bu nedenle, uzak bağlamı oluşturmadan önce herhangi bir Windows Mixed Reality API'sindeki herhangi bir çağrı beklenmeyen davranışa neden olabilir. Önerilen yaklaşım, herhangi bir Karma Gerçeklik API'siyle etkileşim kurmadan önce uzak bağlamı mümkün olduğunca erken oluşturmaktır. CreateRemoteContext çağrısından önce hiçbir Windows Mixed Reality API'sinde oluşturulan veya alınan nesneleri daha sonra oluşturulan veya alınan nesnelerle hiçbir zaman karıştırmayın.

Daha sonra holografik alanın oluşturulması gerekir. CoreWindow belirtmek gerekli değildir. CoreWindow'a sahip olmayan masaüstü uygulamaları yalnızca bir nullptrgeçirebilir.

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

Cihaza bağlanma

Uzak uygulama içeriği işlemeye hazır olduğunda oynatıcı cihazla bağlantı kurulabilir.

Bağlantı iki yoldan biriyle yapılabilir.

  1. Uzak uygulama, cihazda çalışan yürütücüye bağlanır.
  2. Cihazda çalışan oynatıcı uzak uygulamaya bağlanır.

Uzak uygulamadan yürütücü cihaza bağlantı kurmak için, uzak bağlamda ana bilgisayar adını ve bağlantı noktasını belirten yöntemini çağırın Connect . Holographic Remoting Player tarafından kullanılan bağlantı noktası 8265'tir.

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

Önemli

Herhangi bir C++/WinRT API'sinde Connect olduğu gibi işlenmesi gereken bir winrt::hresult_error oluşturabilirsiniz.

İpucu

C++/WinRT dil projeksiyonunu kullanmaktan kaçınmak için Holographic Remoting NuGet paketinin içinde bulunan dosya build\native\include\<windows sdk version>\abi\Microsoft.Holographic.AppRemoting.h dahil edilebilir. Temel alınan COM arabirimlerinin bildirimlerini içerir. Ancak C++/WinRT kullanılması önerilir.

Uzak uygulamada gelen bağlantıları dinlemek, yöntemi çağrılarak Listen yapılabilir. Bu çağrı sırasında hem el sıkışma bağlantı noktası hem de aktarım bağlantı noktası belirtilebilir. El sıkışma bağlantı noktası ilk el sıkışma için kullanılır. Veriler daha sonra aktarım bağlantı noktası üzerinden gönderilir. Varsayılan olarak 8265 ve 8266 kullanılır.

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

Önemli

build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl NuGet paketinin içinde Holographic Remoting tarafından kullanıma sunulan API için ayrıntılı belgeler bulunur.

Belirli olayları uzaktan izlemeyi işleme

Uzak bağlam, bir bağlantının durumunu izlemek için önemli olan üç olayı kullanıma sunar.

  1. OnConnected: Cihaza bağlantı başarıyla kurulduğunda tetiklendi.
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: Kurulan bir bağlantı kapatılırsa veya bağlantı kurulamazsa tetikler.
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: Gelen bağlantıları dinlerken başlar.
m_onListeningEventRevoker = m_remoteContext.OnListening(winrt::auto_revoke, [this, remoteContextWeakRef]() {
    if (auto remoteContext = remoteContextWeakRef.get())
    {
        // Update UI state
    }
});

Ayrıca, uzak bağlamdaki ConnectionState özelliği kullanılarak bağlantı durumu sorgulanabilir.

auto connectionState = m_remoteContext.ConnectionState();

Konuşma olaylarını işleme

Uzak konuşma arabirimini kullanarak konuşma tetikleyicilerini HoloLens 2 kaydetmek ve uzak uygulamaya uzaktan erişim sağlamak mümkündür.

Uzak konuşmanın durumunu izlemek için aşağıdaki ek üye gereklidir:

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

İlk olarak, uzak konuşma arabirimini alın.

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

Zaman uyumsuz bir yardımcı yöntemi kullanarak uzak konuşmayı başlatabilirsiniz. Başlatma işlemi çok uzun sürebileceğinden bu işlem zaman uyumsuz olarak yapılmalıdır. C++/WinRT ile eşzamanlılık ve zaman uyumsuz işlemler, C++/WinRT ile zaman uyumsuz işlevlerin nasıl yazacağını açıklar.

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

Tanınacak tümcecikleri belirtmenin iki yolu vardır.

  1. Konuşma dil bilgisi xml dosyasının içindeki belirtim. Ayrıntılar için bkz. Temel XML Dil Bilgisi oluşturma .
  2. Bunları sözlük vektörunun ApplyParametersiçine geçirerek belirtin.

OnRecognizedSpeech geri çağırmasının içinde konuşma olayları işlenebilir:

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")
    {
        ...
    }

    ...
}

Akışı yapılan içeriği yerel olarak önizleme

Cihaza OnSendFrame gönderilen uzak uygulamada aynı içeriği görüntülemek için uzak bağlam olayı kullanılabilir. Olay OnSendFrame , Holographic Remoting kitaplığı geçerli çerçeveyi uzak cihaza her gönderdiğinde tetikleniyor. Bu, içeriği almak ve ayrıca masaüstüne veya UWP penceresine bölmek için ideal zamandır.

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

Derinlik Yeniden Oluşturma

Holographic Remoting, 2.1.0 sürümünden itibaren Derinlik Yeniden Oluşturma'yı destekler. Bunun için hem renk arabelleği hem de derinlik arabelleğinin Uzak uygulamadan HoloLens 2 akışına alınması gerekir. Varsayılan olarak derinlik arabelleği akışı etkinleştirilir ve renk arabelleğinin çözünürlüğünün yarısını kullanacak şekilde yapılandırılır. Bu, aşağıdaki gibi değiştirilebilir:

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

...

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

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

Varsayılan değerlerin kullanılmaması ConfigureDepthVideoStream gerekiyorsa, HoloLens 2 bağlantı kurulmadan önce çağrılmalıdır. En iyi yer, uzak bağlamı oluşturduktan hemen sonradır. DepthBufferStreamResolution için olası değerler şunlardır:

  • Full_Resolution
  • Half_Resolution
  • Quarter_Resolution
  • Devre dışı ( sürüm 2.1.3 ile birlikte eklenir ve ek derinlikli video akışı oluşturulmazsa)

Tam çözünürlük derinliği arabelleği kullanmanın bant genişliği gereksinimlerini de etkilediğini ve için sağladığınız CreateRemoteContexten yüksek bant genişliği değerinde hesaba bağlanması gerektiğini unutmayın.

Çözünürlüğü yapılandırmanın yanı sıra HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer aracılığıyla bir derinlik arabelleği de işlemeniz gerekir.


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

Derinlik yeniden oluşturma işleminin HoloLens 2 üzerinde düzgün çalışıp çalışmadığını doğrulamak için Cihaz Portalı aracılığıyla derinlik görselleştiricisini etkinleştirebilirsiniz. Ayrıntılar için bkz. Derinliğin Doğru Ayarlandığını Doğrulama .

İsteğe bağlı: Özel veri kanalları

Özel veri kanalları, kullanıcı verilerini önceden oluşturulmuş uzaktan iletişim bağlantısı üzerinden göndermek için kullanılabilir. Daha fazla bilgi için bkz. Özel Veri Kanalları.

İsteğe bağlı: Koordinat Sistemi Eşitleme

Sürüm 2.7.0'dan başlayarak, uzamsal verileri yürütücü ve uzak uygulama arasında hizalamak için koordinat sistemi eşitlemesi kullanılabilir. Daha fazla bilgi için bkz. Holografik Uzaktan İletişime Genel Bakış ile Sistem Eşitlemesini Koordine Etme.

Ayrıca Bkz.