Share via


使用全像攝影遠端和 OpenXR API 的自訂資料通道

使用自訂資料通道,透過已建立的遠端連線傳送自訂資料。

重要

自訂資料通道需要自訂遠端應用程式和自訂播放機應用程式。 這允許兩個自訂應用程式之間的通訊。

提示

您可以在 Holographic Remoting 範例 github 存放庫內的遠端和播放機範例中找到簡單的 ping-pong 範例。 在 OpenXrProgramm.cpp 和 SamplePlayerMain.h 檔案內取消批註 #define ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE ,以啟用範例程式碼。

建立自訂資料通道

自訂資料通道是由控制碼所 XrRemotingDataChannelMSFT 定義:

XrRemotingDataChannelMSFT m_userDataChannel;

成功建立連線之後,可以透過 xrCreateRemotingDataChannelMSFT 函式建立新的資料通道:

XrRemotingDataChannelCreateInfoMSFT channelInfo{static_cast<XrStructureType>(XR_TYPE_REMOTING_DATA_CHANNEL_CREATE_INFO_MSFT)};
channelInfo.channelId = 0;
channelInfo.channelPriority = XR_REMOTING_DATA_CHANNEL_PRIORITY_LOW_MSFT;
CHECK_XRCMD(m_extensions.xrCreateRemotingDataChannelMSFT(m_instance.Get(), m_systemId, &channelInfo, &m_userDataChannel));

即使執行時間不同,也可以從播放機和遠端應用程式建立自訂資料通道。 如果玩家端建立資料通道,遠端端就會收到 XrEventDataRemotingDataChannelCreatedMSFT 事件結構的通知:

XrEventDataBuffer eventData{};
while (pollEvent(eventData)) 
{
    switch (eventData.type) 
    {
        case XR_TYPE_EVENT_DATA_REMOTING_DATA_CHANNEL_CREATED_MSFT: 
        {
            auto channelCreatedEventData = reinterpret_cast<const XrEventDataRemotingDataChannelCreatedMSFT*>(&eventData);
            m_userDataChannel = channelCreatedEventData->channel;
            break;
        }
    }
}

呼叫 之後的初始 XrRemotingDataChannelStatusMSFT 狀態為 XR_REMOTING_DATA_CHANNEL_STATUS_OPEN_PENDING_MSFTxrCreateRemotingDataChannelMSFT 資料通道完全建立之後,通道的狀態會切換至 XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFT 。 當先前建立的資料通道狀態從 XR_REMOTING_DATA_CHANNEL_STATUS_OPEN_PENDING_MSFT 切換至 XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFT 時,事件 XrEventDataRemotingDataChannelOpenedMSFT 結構會放在事件佇列中。

取得通道狀態

xrGetRemotingDataChannelStateMSFT 式可用來查詢資料通道狀態:

XrRemotingDataChannelStateMSFT channelState{static_cast<XrStructureType>(XR_TYPE_REMOTING_DATA_CHANNEL_STATE_MSFT)};
CHECK_XRCMD(m_extensions.xrGetRemotingDataChannelStateMSFT(m_userDataChannel, &channelState));

傳送資料

如果通道已開啟,函 xrSendRemotingDataMSFT 式會用來將資料傳送至播放機端:

if (channelState.connectionStatus == XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFT) {
    // Only send the packet if the send queue is smaller than 1MiB
    if (channelState.sendQueueSize >= 1 * 1024 * 1024) {
        return;
    }
    uint8_t data[] = {1};

    XrRemotingDataChannelSendDataInfoMSFT sendInfo{
        static_cast<XrStructureType>(XR_TYPE_REMOTING_DATA_CHANNEL_SEND_DATA_INFO_MSFT)};
    sendInfo.data = data;
    sendInfo.size = sizeof(data);
    sendInfo.guaranteedDelivery = true;
    CHECK_XRCMD(m_extensions.xrSendRemotingDataMSFT(m_userDataChannel, &sendInfo));
}

注意

您透過自訂資料通道傳送的資料會與其他資料通道共用全像攝影遠端處理所使用的頻寬。

擷取

每次透過資料通道抵達資料時, XrEventDataRemotingDataChannelDataReceivedMSFT 事件結構都會放入事件佇列中。 接收的封包可以使用 函式來 xrRetrieveRemotingDataMSFT 擷取:

XrEventDataBuffer eventData{};
while (pollEvent(eventData)) 
{
    switch (eventData.type) 
    {
        case XR_TYPE_EVENT_DATA_REMOTING_DATA_CHANNEL_DATA_RECEIVED_MSFT: 
        {
            auto dataReceivedEventData = reinterpret_cast<const XrEventDataRemotingDataChannelDataReceivedMSFT*>(&eventData);
            std::vector<uint8_t> packet(dataReceivedEventData->size);
            uint32_t dataBytesCount;
            CHECK_XRCMD(m_extensions.xrRetrieveRemotingDataMSFT(dataReceivedEventData->channel,
                                                                dataReceivedEventData->packetId,
                                                                static_cast<uint32_t>(packet.size()),
                                                                &dataBytesCount,
                                                                packet.data()));
            break;
        }
    }
}

終結資料通道

您可以使用 終結資料通道 xrDestroyRemotingDataChannelMSFT

CHECK_XRCMD(m_extensions.xrDestroyRemotingDataChannelMSFT(m_userDataChannel));

呼叫之後 xrDestroyRemotingDataChannelMSFT ,句 XrRemotingDataChannelMSFT 柄無效,而且之後不得使用資料通道控制碼。

XrEventDataRemotingDataChannelClosedMSFT如果玩家端關閉或終結資料通道,則會放置在事件佇列中。 資料通道狀態會切換至 XR_REMOTING_DATA_CHANNEL_STATUS_CLOSED_MSFT 。 對於封閉式資料通道,句 XrRemotingDataChannelMSFT 柄會維持有效狀態。

另請參閱