Добавление голографического удаленного взаимодействия (HoloLens 1-го поколения)

Если вы не знакомы с голографическим удаленным взаимодействием, ознакомьтесь с нашим обзором.

Важно!

В этом документе описывается создание ведущего приложения для HoloLens 1. Ведущее приложение для HoloLens (1-го поколения) должно использовать пакет NuGet версии 1.x.x. Это означает, что ведущее приложение, написанное для HoloLens 1, несовместимо с HoloLens 2 и наоборот.

HoloLens 2

Разработчикам HoloLens, использующим голографическое удаленное взаимодействие, потребуется обновить свои приложения, чтобы сделать их совместимыми с HoloLens 2. Для этого требуется новая версия пакета NuGet для голографического удаленного взаимодействия. При подключении к проигрывателю голографического удаленного взаимодействия на HoloLens 2 обязательно используйте версию 2.0.0.0 или более позднюю. В противном случае подключение завершится ошибкой.

Примечание

Инструкции по HoloLens 2 можно найти здесь.

Добавление голографического удаленного взаимодействия в классическое приложение или приложение UWP

На этой странице описывается добавление голографического удаленного взаимодействия в классическое приложение или приложение UWP.

Голографическое удаленное взаимодействие позволяет приложению нацеливаться на HoloLens с голографическим содержимым, размещенным на настольном компьютере или на устройстве UWP, таком как Xbox One. У вас также есть доступ к дополнительным системным ресурсам, что позволяет интегрировать удаленные иммерсивные представления в существующее программное обеспечение для настольных компьютеров. Ведущее приложение удаленного взаимодействия получает поток входных данных из HoloLens, отрисовывает содержимое в виртуальном иммерсивном представлении и передает кадры содержимого обратно в HoloLens. Подключение осуществляется по стандартной сети Wi-Fi. Чтобы использовать удаленное взаимодействие, используйте пакет NuGet для добавления голографического удаленного взаимодействия в классическое приложение или приложение UWP, а затем напишите код для обработки подключения и отрисовки иммерсивного представления. В пример кода включены вспомогательные библиотеки, упрощающие обработку подключения устройства.

Обычное подключение удаленного взаимодействия будет иметь задержку в 50 мс. Приложение проигрывателя может сообщать о задержке в режиме реального времени.

Примечание

Фрагменты кода в этой статье в настоящее время демонстрируют использование C++/CX, а не C++17-совместимого C++/WinRT, как используется в шаблоне голографического проекта C++. Эти понятия эквивалентны для проекта C++/WinRT, хотя вам потребуется перевести код.

Получение пакетов NuGet для удаленного взаимодействия

Выполните следующие действия, чтобы получить пакет NuGet для голографического удаленного взаимодействия и добавить ссылку из проекта:

  1. Перейдите к проекту в Visual Studio.
  2. Щелкните правой кнопкой мыши узел проекта и выберите Управление пакетами NuGet...
  3. На появившемся экране нажмите кнопку Обзор и выполните поиск по запросу "Голографическое удаленное взаимодействие".
  4. Выберите Microsoft.Holographic.Remoting и нажмите кнопку Установить.
  5. Если откроется диалоговое окно Предварительный просмотр , нажмите кнопку ОК.
  6. Выберите Принимаю , когда откроется диалоговое окно лицензионного соглашения.

Создание HolographicStreamerHelpers

Сначала необходимо добавить экземпляр HolographicStreamerHelpers в класс, который будет обрабатывать удаленное взаимодействие.

#include <HolographicStreamerHelpers.h>

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

Кроме того, необходимо отслеживать состояние подключения. Если требуется отрисовка предварительного просмотра, вам потребуется текстура для ее копирования. Вам также потребуется несколько вещей, таких как блокировка состояния подключения, какой-то способ хранения IP-адреса HoloLens и т. д.

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;

Инициализация HolographicStreamerHelpers и подключение к HoloLens

Чтобы подключиться к устройству HoloLens, создайте экземпляр HolographicStreamerHelpers и подключитесь к целевому IP-адресу. Необходимо задать размер видеокадра в соответствии с шириной и высотой дисплея HoloLens, так как библиотека голографического удаленного взаимодействия ожидает точного соответствия разрешений кодировщика и декодера.

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

Подключение устройства является асинхронным. Приложение должно предоставлять обработчики событий для событий подключения, отключения и отправки кадров.

Событие OnConnected может обновить пользовательский интерфейс, начать отрисовку и т. д. В нашем примере кода на рабочем столе мы обновим заголовок окна сообщением "подключено".

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

Событие OnDisconnected может обрабатывать повторное подключение, обновления пользовательского интерфейса и т. д. В этом примере мы повторно подключаемся при временном сбое.

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

Когда компонент удаленного взаимодействия будет готов к отправке кадра, приложению предоставляется возможность создать его копию в SendFrameEvent. Здесь мы копируем кадр в цепочку буферов, чтобы отобразить его в окне предварительного просмотра.

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

Отрисовка голографического содержимого

Для отрисовки содержимого с помощью удаленного взаимодействия необходимо настроить виртуальный IFrameworkView в классическом приложении или приложении UWP и обработать голографические кадры из удаленного взаимодействия. Все интерфейсы API Windows Holographic используются в этом представлении одинаково, но оно настроено немного по-другому.

Вместо того чтобы создавать их самостоятельно, голографическое пространство и компоненты речи поступают из класса HolographicRemotingHelpers:

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

Вместо использования цикла обновления в методе Run вы предоставляете такт обновления из цикла main классического приложения или приложения UWP. Это позволяет классическому приложению или приложению UWP оставаться под контролем обработки сообщений.

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

       // display preview, etc.
   }

Метод Tick() представления голографического приложения завершает одну итерацию цикла update, draw, present.

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

Цикл обновления, отрисовки и представления голографического приложения точно такой же, как и при выполнении на HoloLens, за исключением того, что у вас есть доступ к гораздо большему количеству системных ресурсов на настольном компьютере. Вы можете визуализировать гораздо больше треугольников, иметь больше проходов рисования, выполнять больше физики и использовать процессы x64 для загрузки содержимого, требующего более 2 ГБ ОЗУ.

Отключение и завершение удаленного сеанса

Чтобы отключиться ( например, когда пользователь нажимает кнопку пользовательского интерфейса для отключения), вызовите Disconnect() в HolographicStreamerHelpers, а затем отпустите объект .

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

Получение проигрывателя удаленного взаимодействия

Проигрыватель удаленного взаимодействия Windows Holographic предлагается в магазине приложений Windows в качестве конечной точки для удаленного взаимодействия ведущих приложений для подключения. Чтобы получить проигрыватель удаленного взаимодействия Windows Holographic, посетите магазин приложений Windows из HoloLens, выполните поиск по запросу Удаленное взаимодействие и скачайте приложение. Проигрыватель удаленного взаимодействия включает функцию для отображения статистики на экране, что может быть полезно при отладке ведущих приложений удаленного взаимодействия.

Заметки и ресурсы

В представлении голографического приложения потребуется способ предоставить приложению устройство Direct3D, которое должно использоваться для инициализации голографического пространства. Приложение должно использовать это устройство Direct3D для копирования и отображения кадра предварительного просмотра.

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

Пример кода: Доступен полный пример кода голографического удаленного взаимодействия , который включает представление голографического приложения, совместимое с удаленным взаимодействием и удаленным взаимодействием хост-проектов для классических приложений Win32, UWP DirectX и UWP с ПОМОЩЬЮ XAML.

Примечание об отладке: Библиотека голографического удаленного взаимодействия может создавать исключения первого случая. Эти исключения могут быть видны в сеансах отладки в зависимости от параметров исключений Visual Studio, которые были активны в то время. Эти исключения перехватываются внутренне библиотекой голографического удаленного взаимодействия и могут быть проигнорированы.

См. также: