В этом разделе рассказывается о панели управления Oculus для PC-SDK.
На панели управления Oculus все меню и пользовательский интерфейс Rift собраны в центральный узел, всегда доступный откуда бы то ни было в VR-приложении. Панель управления работает как оверлей внутри текущего VR-приложения, так что вы можете быстро переключаться с одного приложения на другое, открывать библиотеку, общаться с друзьями и даже просто пользоваться своим ПК без каких-либо дополнительных действий. Это не только делает VR более интуитивной и удобной, но и обеспечивает непревзойденную многозадачность. Это огромный плюс для авторов и разработчиков, которые используют VR во время работы.
Подробнее о панели управления см. в анонсе панели управления: Introducing Rift Core 2.0—Our Biggest Software Update Yet! (Представляем Rift Core 2.0 — наше самое серьезное обновление программного обеспечения за всё время!). Также посмотрите видео Introducing Oculus Dash (Представляем панель управления Oculus) в нашем блоге Welcome to Rift Core 2.0 (Вас приветствует Rift Core 2.0), чтобы понять, как работает панель управления.
Подготовка к работе с панелью управления
Убедитесь, что ваш компьютер (системный блок или ноутбук) подготовлен для обеспечения наилучшего опыта взаимодействия. Вот несколько советов, которые помогут вам начать работу:
Рекомендуется использовать Windows 10. Платформа Rift Core 2.0, на которой основана панель управления, выводит VR-вычисления на новый уровень. Мы внедрили в нее ресурсоемкие системные задачи, такие как многозадачность, прикрепление окон и функции Oculus Desktop, сохранив при этом текущие стандарты производительности. Для Oculus Desktop требуется Windows 10. Основными функциями Rift Core 2.0, в том числе новым системным меню панели управления и Oculus Home, можно пользоваться в Windows 7 и Windows 8. Однако в этом случае вы не сможете использовать такие функции, как Oculus Desktop, для виртуальных вычислений, а панель управления не сможет работать как оверлей поверх текущего VR-приложения.
Обновите драйверы графического процессора. Мы интегрировали поддержку панели управления на уровне драйверов в сотрудничестве с AMD и NVIDIA. Для работы панели управления вам понадобятся последние версии драйверов NVIDIA и AMD. Подробнее о характеристиках графического процессора см. в этой статье.
Дизайн, ориентированный на Touch. Мы переработали основной интерфейс Rift, сделав его по-настоящему нативным для Touch, и предлагаем вам все преимущества присутствия рук в интуитивно понятном и простом в использовании интерфейсе. Хотя многие функции будут по-прежнему работать с контроллером Xbox, некоторые новые функции, например настройка Дома, требуют Touch. Проще говоря, если вы хотите в полной мере использовать все возможности Rift Core 2.0, выбирайте Touch.
Работа с панелью управления
Мы рекомендуем добавить в ваше приложение поддержку панели управления, чтобы обеспечить наилучший пользовательский опыт. В зависимости от того, поддерживает ли ваше приложение панель управления, впечатления будут разными:
если приложение поддерживает панель управления, то при приостановке приложения пользовательский интерфейс меню панели управления будет накладываться на приостановленное приложение;
если приложение не поддерживает панель управления, то при приостановке приложения пользовательский интерфейс меню панели управления будет представлен в пустой комнате, подобно тому, как отображалось универсальное меню в предыдущих версиях Oculus.
Когда пользовательский интерфейс панели управления активен, среда выполнения отображает в сцене отслеживаемые контроллеры для взаимодействия с меню. Ваше приложение должно приостанавливать, переключать в немой режим и скрывать все отслеживаемые контроллеры, которые оно отображает в сцене, чтобы не возникало дублирующей пары рук.
При реализации поддержки панели управления необходимо учитывать три аспекта:
обработка фокуса ввода;
поддержка буфера глубины;
объявление о том, что в приложении учитывается фокус ввода.
Обработка фокуса ввода
Обработка фокуса Oculus CAPI
Когда пользовательский интерфейс панели управления активен, запущенное приложение теряет фокус ввода, и флаг ovrSessionStatus::HasInputFocus возвращает значение false. В этом состоянии среда выполнения отображает отслеживаемые контроллеры в сцене для взаимодействия с меню.
Когда HasInputFocus имеет значение false, ваше приложение должно приостановить все действия, отключить воспроизведение звука, скрыть все отслеживаемые контроллеры в сцене, чтобы не возникало дублирующей пары рук, и скрыть все объекты ближнего поля (в радиусе одного метра от пользователя). Для некоторых приложений при потере фокуса ввода могут потребоваться дополнительные действия. Например, во время многопользовательской боевой игры вы можете указать, что игрок недоступен, и предпринять любые другие соответствующие действия.
Для компоновки VR может потребоваться до 3 мс дополнительного времени рендеринга в каждом цикле кадров, пока HasInputFocus имеет значение False. В связи с этим, пока HasInputFocusis имеет значение false, имеет смысл переключить приложение в режим пониженной производительности, если это возможно. Отменяйте этот режим, когда значение HasInputFocus вновь станет равным true. Такой подход не обязателен, и требования VRC к производительности не применяются, когда пользовательский интерфейс панели управления активен.
Обратите внимание: HasInputFocus возвращает false при любых других условиях, при которых приложение теряет фокус ввода, например когда пользователь снимает гарнитуру с головы.
Чтобы проверить флаг HasInputFocus, используйте следующий код:
ovrSessionStatus sessionStatus = {};
ovr_GetSessionStatus(Session, &sessionStatus);
if (!sessionStatus.HasInputFocus) {/*Handle situation where your app has lost input focus*/}
Этот код должен выполняться один раз в течение каждого цикла рендеринга кадра.
Обработка фокуса OpenXR
Когда пользовательский интерфейс панели управления активен, запущенное приложение теряет фокус ввода и сеанс переходит из состояния XR_SESSION_STATE_FOCUSED в состояние XR_SESSION_STATE_VISIBLE. В этом состоянии среда выполнения отображает отслеживаемые контроллеры в сцене для взаимодействия с меню. Обратите внимание: состояние XR_SESSION_STATE_FOCUSED также подразумевает состояние видимости.
Когда сеанс переходит из состояния XR_SESSION_STATE_FOCUSED в состояние XR_SESSION_STATE_VISIBLE, ваше приложение должно приостановить все действия, отключить воспроизведение звука, скрыть все отслеживаемые контроллеры в сцене, чтобы не возникало дублирующей пары рук, и скрыть все объекты ближнего поля (в радиусе примерно одного метра от пользователя). Для некоторых приложений при потере фокуса ввода могут потребоваться дополнительные действия. Например, во время многопользовательской боевой игры вы можете указать, что игрок недоступен, и предпринять любые другие соответствующие действия.
Для компоновки VR может потребоваться до 3 мс дополнительного времени рендеринга в каждом цикле кадров, пока панель управления остается видимой. В связи с этим, пока приложение не находится в фокусе, имеет смысл переключить его в режим пониженной производительности, если это возможно. Отменяйте этот режим, когда получите результат XR_SESSION_STATE_VISIBLE. Такой подход не обязателен, и требования VRC к производительности не применяются, когда пользовательский интерфейс панели управления активен.
Обратите внимание: фокус ввода будет потерян при любых других условиях, при которых приложение теряет его, например когда пользователь снимает гарнитуру с головы.
Изменения статуса сеанса определяются следующим кодом:
do {
XrEventDataBuffer event{XR_TYPE_EVENT_DATA_BUFFER};
XrResult result = xrPollEvent(instance, &event);
if (result == XR_SUCCESS) {
switch (event.type) {
case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: {
const XrEventDataSessionStateChanged& sessionStateChanged =
*reinterpret_cast<XrEventDataSessionStateChanged*>(&event);
switch(sessionStateChanged.state){
case XR_SESSION_STATE_FOCUSED:
// Application is now focused (and visible)...
break;
case XR_SESSION_STATE_VISIBLE:
// Application is now merely visible and not focused...
break;
...
}
break;
}
}
}
} while(result == XR_SUCCESS)
xrPollEvent необходимо вызывать повторно в каждом цикле кадра аналогично описанному выше, пока сообщения не прекратятся.
Поддержка буфера глубины
Поддержка буфера глубины CAPI
Если вы отрисовываете много геометрии рядом с пользователем, это может вызвать неудобные визуальные диспропорции, когда панель управления представляется поверх геометрии, которая находится ближе к игроку, чем сама панель. Чтобы избежать этих диспропорций, вы можете отправлять глубину с помощью глазных буферов. Так панель управления сможет использовать рентгеновский эффект, который предотвратит этот дискомфорт. По этой причине, а также для будущих улучшений, мы рекомендуем отправлять данные о глубине с помощью глазных буферов. Если это невозможно, мы всё равно рекомендуем поддерживать работу панели управления (и смириться с диспропорциями) и не отказываться от нее.
Для отправки данных о глубине используйте ovrLayerType_EyeFovDepth, как показано в примере ниже. Этот код взят из примера кода OculusRoomTiny DX11 (находится в {sdk_folder}\OculusSDK\Samples\OculusRoomTiny\OculusRoomTiny (DX11)\Projects\Windows\VS2015):
// Initialize our single full screen Fov layer.
ovrLayerEyeFovDepth ld = {};
ld.Header.Type = ovrLayerType_EyeFovDepth;
ld.Header.Flags = 0;
for (int eye = 0; eye < 2; ++eye)
{
ld.ColorTexture[eye] = pEyeRenderTexture[eye]->TextureChain;
ld.DepthTexture[eye] = pEyeRenderTexture[eye]->DepthTextureChain;
ld.Viewport[eye] = eyeRenderViewport[eye];
ld.Fov[eye] = hmdDesc.DefaultEyeFov[eye];
ld.RenderPose[eye] = EyeRenderPose[eye];
ld.SensorSampleTime = sensorSampleTime;
ld.ProjectionDesc = posTimewarpProjectionDesc[eye];
}
ovrLayerHeader* layers = &ld.Header;
result = ovr_SubmitFrame(session, frameIndex, nullptr, &layers, 1);
// exit the rendering loop if submit returns an error, will retry on ovrError_DisplayLost
if (!OVR_SUCCESS(result))
goto Done;
frameIndex++;
Поддержка буфера глубины OpenXR
Чтобы включить отправку данных о глубине, включите расширение XR_KHR_composition_layer_depth. Чтобы передать данные о глубине, добавьте экземпляр XrCompositionLayerDepthInfoKHR в следующую цепочку для каждой отправляемой структуры XrCompositionLayerProjectionView в xrEndFrame. Буферы глубины создаются с помощью xrCreateSwapchain, как и буферы цвета.
Объявление о том, что приложение на базе CAPI учитывает фокус ввода
Ваше приложение на базе CAPI должно указывать, готово ли оно реагировать на состояния фокуса ovrSessionStatus, в том числе HasInputFocus. Если приложение готово обрабатывать потерю фокуса, как описано в разделе Обработка фокуса ввода (см. выше), установите для флага ovrInit_FocusAware значение true. В противном случае установите для флага ovrInit_FocusAware значение false.
Приложения на базе OpenXR изначально всегда учитывают фокус ввода и не требуют специальной обработки.
Объявление о том, что приложение учитывает фокус ввода
Ваше приложение должно указывать, готово ли оно реагировать на состояния фокуса ovrSessionStatus, в том числе HasInputFocus. Если приложение готово обрабатывать потерю фокуса, как описано в разделе Обработка фокуса ввода (см. выше), установите для флага ovrInit_FocusAware значение true. В противном случае установите для флага ovrInit_FocusAware значение false.
В следующем примере кода показано, как установить флаг ovrInit_FocusAware. Этот код взят из примера кода OculusRoomTiny DX11 (находится в {sdk_folder}\OculusSDK\Samples\OculusRoomTiny\OculusRoomTiny (DX11)\Projects\Windows\VS2015):
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int)
{
// Initializes LibOVR and the Rift
ovrInitParams initParams = { ovrInit_RequestVersion | ovrInit_FocusAware, OVR_MINOR_VERSION, NULL, 0, 0 };
ovrResult result = ovr_Initialize(&initParams);
VALIDATE(OVR_SUCCESS(result), "Failed to initialize libOVR.");
VALIDATE(DIRECTX.InitWindow(hinst, L"Oculus Room Tiny (DX11)"), "Failed to open window.");
DIRECTX.Run(MainLoop);
ovr_Shutdown();
return(0);
}