Psaní vzdálené aplikace Holographic Remoting pomocí rozhraní API HolographicSpace
Pokud s Holographic Remotingem začínáte, možná si budete chtít přečíst náš přehled.
Důležité
Tento dokument popisuje vytvoření vzdálené aplikace pro HoloLens 2 pomocí rozhraní HolographicSpace API. Vzdálené aplikace pro HoloLens (1. generace) musí používat balíček NuGet verze 1.x.x. To znamená, že vzdálené aplikace napsané pro HoloLens 2 nejsou kompatibilní s HoloLens 1 a naopak. Dokumentaci k HoloLens 1 najdete tady.
Oznámení o vyřazení: Řádek verze 2.9.x bude poslední, která bude podporovat rozhraní Windows Holographic API pro vývoj aplikací. Nadcházející verze budou podporovat openXR jenom pro vývoj aplikací. Nezávisle na tom doporučujeme používat OpenXR ve vaší aplikaci pro veškerý vývoj nových aplikací. Stávající aplikace používající verze 2.9 nebo starší budou nadále fungovat bez ovlivnění nadcházejících změn.
Holografické aplikace vzdálené komunikace můžou streamovat vzdáleně vykreslený obsah do HoloLens 2 a Windows Mixed Reality imerzivní náhlavní soupravy. Můžete také získat přístup k dalším systémovým prostředkům a integrovat vzdálená imerzivní zobrazení do stávajícího softwaru stolního počítače. Vzdálená aplikace přijímá vstupní datový proud z HoloLens 2, vykresluje obsah ve virtuálním imerzivním zobrazení a streamuje rámce obsahu zpět do HoloLens 2. Připojení se provádí pomocí standardní Wi-Fi. Holografická vzdálená komunikace se přidává do desktopové aplikace nebo aplikace pro UPW prostřednictvím paketu NuGet. Vyžaduje se další kód, který zpracovává připojení a vykresluje se v imerzivním zobrazení. Typické vzdálené připojení bude mít latenci až 50 ms. Aplikace přehrávače může hlásit latenci v reálném čase.
Veškerý kód na této stránce a pracovní projekty najdete v úložišti Holographic Remoting samples github.
Požadavky
Dobrým výchozím bodem je funkční desktopová aplikace nebo aplikace pro UPW založená na Rozhraní DirectX, která cílí na rozhraní API Windows Mixed Reality. Podrobnosti najdete v přehledu vývoje directx. Šablona holografického projektu C++ je dobrým výchozím bodem.
Důležité
Každá aplikace používající Holographic Remoting by měla být ovaná tak, aby používala byt s více vlákny. Použití jednovláknového apartmánu je podporováno , ale povede k neoptimalnímu výkonu a možná i k zadrhávání během přehrávání. Při použití C++/WinRT winrt::init_apartment je výchozí byt s více vlákny.
Získání balíčku NuGet pro Holographic Remoting
Následující kroky jsou potřeba k přidání balíčku NuGet do projektu v sadě Visual Studio.
- Otevřete projekt v sadě Visual Studio.
- Klikněte pravým tlačítkem na uzel projektu a vyberte Spravovat balíčky NuGet...
- Na zobrazeném panelu vyberte Procházet a pak vyhledejte Holographic Remoting(Holographic Remoting).
- Vyberte Microsoft.Holographic.Remoting, vyberte nejnovější verzi 2.x.x a vyberte Nainstalovat.
- Pokud se zobrazí dialogové okno Náhled , vyberte OK.
- Když se zobrazí dialogové okno licenční smlouvy, vyberte Přijmout .
Poznámka
Verze 1.x.x balíčku NuGet je stále dostupná pro vývojáře, kteří chtějí cílit na HoloLens 1. Podrobnosti najdete v tématu Přidání holografické komunikace (HoloLens (1. generace)).
Vytvoření vzdáleného kontextu
Jako první krok by aplikace měla vytvořit vzdálený kontext.
// 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);
Upozornění
Holographic Remoting funguje tak, že nahrazuje modul runtime Windows Mixed Reality, který je součástí Systému Windows, modulem runtime specifickým pro vzdálené komunikace. To se provádí během vytváření vzdáleného kontextu. Z tohoto důvodu může jakékoli volání libovolného rozhraní API Windows Mixed Reality před vytvořením vzdáleného kontextu způsobit neočekávané chování. Doporučeným přístupem je co nejdříve vytvořit vzdálený kontext před interakcí s jakýmkoli rozhraním API Mixed Reality. Nikdy nemíchejte objekty vytvořené nebo načtené prostřednictvím jakéhokoli rozhraní API Windows Mixed Reality před voláním CreateRemoteContext s objekty vytvořenými nebo načtenými později.
Dále je potřeba vytvořit holografický prostor. Zadání CoreWindow se nevyžaduje. Desktopové aplikace, které nemají CoreWindow, můžou jednoduše předat nullptr
.
m_holographicSpace = winrt::Windows::Graphics::Holographic::HolographicSpace::CreateForCoreWindow(nullptr);
Připojení k zařízení
Když je vzdálená aplikace připravená na vykreslování obsahu, je možné navázat připojení k zařízení přehrávače.
Připojení je možné provést jedním ze dvou způsobů.
- Vzdálená aplikace se připojí k přehrávači běžícímu na zařízení.
- Přehrávač spuštěný na zařízení se připojí ke vzdálené aplikaci.
Pokud chcete navázat připojení ze vzdálené aplikace k přehrávači zařízení, zavolejte metodu Connect
ve vzdáleném kontextu a zadejte název hostitele a port. Port používaný nástrojem Holographic Remoting Player je 8265.
try
{
m_remoteContext.Connect(m_hostname, m_port);
}
catch(winrt::hresult_error& e)
{
DebugLog(L"Connect failed with hr = 0x%08X", e.code());
}
Důležité
Stejně jako u jakéhokoli rozhraní API Connect
C++/WinRT může dojít k vyvolání winrt::hresult_error, které je potřeba zpracovat.
Tip
Pokud se chcete vyhnout použití projekce jazyka C++/WinRT , můžete zahrnout soubor build\native\include\<windows sdk version>\abi\Microsoft.Holographic.AppRemoting.h
umístěný v balíčku NuGet Holographic Remoting. Obsahuje deklarace podkladových rozhraní MODELU COM. Doporučuje se ale použít C++/WinRT.
Naslouchání příchozím připojením ve vzdálené aplikaci se dá provést voláním Listen
metody . Během tohoto volání lze zadat port handshake i přenosový port. Port handshake se používá pro počáteční metodu handshake. Data se pak odešlou přes přenosový port. Ve výchozím nastavení se používají 8265 a 8266 .
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());
}
Důležité
Vnitřní build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl
balíček NuGet obsahuje podrobnou dokumentaci k rozhraní API vystavené Holographic Remoting.
Zpracování událostí specifických pro vzdálené komunikace
Vzdálený kontext zveřejňuje tři události, které jsou důležité pro monitorování stavu připojení.
- OnConnected(OnConnected): Aktivuje se, když se úspěšně naváže připojení k zařízení.
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
}
});
- OnDisconnected: Aktivuje se, pokud je navázané připojení ukončeno nebo se nepodařilo navázat připojení.
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.");
}
}
});
- OnListening: Při naslouchání příchozím připojením se spustí.
m_onListeningEventRevoker = m_remoteContext.OnListening(winrt::auto_revoke, [this, remoteContextWeakRef]() {
if (auto remoteContext = remoteContextWeakRef.get())
{
// Update UI state
}
});
Stav připojení je navíc možné dotazovat pomocí ConnectionState
vlastnosti ve vzdáleném kontextu.
auto connectionState = m_remoteContext.ConnectionState();
Zpracování událostí řeči
Pomocí rozhraní pro vzdálenou řeč je možné zaregistrovat triggery řeči s HoloLens 2 a nechat je vzdáleně připojit ke vzdálené aplikaci.
Ke sledování stavu vzdálené řeči se vyžaduje následující další člen:
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech::OnRecognizedSpeech_revoker m_onRecognizedSpeechRevoker;
Nejprve načtěte rozhraní vzdálené řeči.
if (auto remoteSpeech = m_remoteContext.GetRemoteSpeech())
{
InitializeSpeechAsync(remoteSpeech, m_onRecognizedSpeechRevoker, weak_from_this());
}
Pomocí asynchronní pomocné metody pak můžete inicializovat vzdálenou řeč. To by se mělo provádět asynchronně, protože inicializace může trvat poměrně dlouho. Souběžnost a asynchronní operace s C++/WinRT vysvětluje, jak vytvářet asynchronní funkce pomocí C++/WinRT.
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);
}
Existují dva způsoby určení frází, které se mají rozpoznat.
- Specifikace v souboru XML gramatiky řeči. Podrobnosti najdete v tématu Vytvoření základní gramatiky XML .
- Určete je předáním do vektoru slovníku do
ApplyParameters
.
Ve zpětném volání OnRecognizedSpeech se pak dají zpracovat události řeči:
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")
{
...
}
...
}
Místní streamovaný obsah ve verzi Preview
K zobrazení stejného obsahu ve vzdálené aplikaci, který se odesílá do zařízení, OnSendFrame
je možné použít událost vzdáleného kontextu. Událost se OnSendFrame
aktivuje pokaždé, když knihovna Holographic Remoting odešle aktuální snímek do vzdáleného zařízení. Toto je ideální čas na to, abyste obsah převezmou a také ho prosvítá do okna plochy nebo okna UPW.
#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.
});
Hloubková reprojekce
Od verze 2.1.0 podporuje holografická komunikace reprojektování hloubky. To vyžaduje, aby se vyrovnávací paměť barev i hloubková vyrovnávací paměť streamovala ze vzdálené aplikace do HoloLens 2. Ve výchozím nastavení je streamování hloubkové vyrovnávací paměti povolené a nakonfigurované tak, aby používalo polovinu rozlišení vyrovnávací paměti barev. To je možné změnit následujícím způsobem:
// class implementation
#include <HolographicAppRemoting\Streamer.h>
...
CreateRemoteContext(m_remoteContext, 20000, false, PreferredVideoCodec::Default);
// Configure for half-resolution depth.
m_remoteContext.ConfigureDepthVideoStream(DepthBufferStreamResolution::Half_Resolution);
Poznámka: Pokud se nemají použít ConfigureDepthVideoStream
výchozí hodnoty, musí být volána před navázáním připojení k HoloLens 2. Nejlepší místo je hned po vytvoření vzdáleného kontextu. Možné hodnoty pro DepthBufferStreamResolution jsou:
- Full_Resolution
- Half_Resolution
- Quarter_Resolution
- Zakázáno (přidáno ve verzi 2.1.3 , a pokud se použije, nevytvoří se žádný datový proud videa s další hloubkou)
Mějte na paměti, že použití vyrovnávací paměti hloubky plného rozlišení má také vliv na požadavky na šířku pásma a je potřeba vzít v úvahu hodnotu maximální šířky pásma, kterou poskytnete nástroji CreateRemoteContext
.
Kromě konfigurace rozlišení musíte také potvrdit hloubkovou vyrovnávací paměť prostřednictvím HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer.
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);
}
});
}
});
}
Pokud chcete ověřit, jestli na HoloLens 2 správně funguje hloubková reprojekce, můžete povolit vizualizér hloubky prostřednictvím portálu zařízení. Podrobnosti najdete v části Ověření správné hloubky .
Volitelné: Vlastní datové kanály
Vlastní datové kanály je možné použít k odesílání uživatelských dat přes již navázané vzdálené připojení. Další informace najdete v tématu Vlastní datové kanály.
Volitelné: Synchronizace souřadnicového systému
Počínaje verzí 2.7.0 lze synchronizaci souřadnicového systému použít k zarovnání prostorových dat mezi přehrávačem a vzdálenou aplikací. Další informace najdete v tématu Synchronizace souřadnicového systému s holografickým přehledem vzdálené komunikace.
Viz také
- Přehled holografické vzdálené komunikace
- Vytvoření vlastní aplikace přehrávače Holographic Remoting
- Vlastní datové kanály Holographic Remoting
- Vytvoření zabezpečeného připojení pomocí holografické vzdálené komunikace
- Řešení potíží a omezení holografické vzdálené komunikace
- Licenční podmínky pro software Holographic Remoting
- Prohlášení společnosti Microsoft o zásadách ochrany osobních údajů