开发

移动原生 SDK 迁移指南 — 存档(已停用)

更新时间: 2022年9月29日
Mobile SDK Deprecation
自 2022 年 8 月 31 日起,我们不再支持移动 SDK 和 VrApi 资源库。未来的更新将通过 OpenXR 扩展程序和我们的 OpenXR 移动 SDK,而非移动 Meta 或 PC API 的任何新更新提供。
停止支持移动 SDK 后,意味着:
  • 新应用将无法访问 Meta 原生移动 API,但现有应用可继续使用此类 API。
  • 对于使用 Meta 原生 API 创建新应用的,将不提供任何帮助。您可以在开发者指南中找到将现有应用迁移到 OpenXR 的建议。
  • 只有 Meta 原生 API 中的关键安全性、隐私或安全问题才会得到解决。
  • Meta 原生移动应用的任何测试都将仅限于自动化 QA 测试,以确保核心功能正常运作。
如需了解有关此次停用的更多信息,请访问 Meta 全面投入 OpenXR:停用专用 API
本文详细介绍了如何迁移出早期版本的移动 SDK 以进行原生开发。
注意:此存档适用于移动 SDK 1.22.0 及以下版本。之后发布版本,请参阅移动原生迁移

迁移至移动 SDK 1.22.0

本节旨在帮助您从 Oculus 移动 SDK 1.21.0 版升级至 1.22.0 版。

VrApi 变更

  • 新增一个 ovrProperty,即 VRAPI_ACTIVE_INPUT_DEVICE_ID,用于查询主要或最活跃输入设备的设备编号。
  • 为支持 “Bed 模式”的应用程序新增一个 ovrTrackingSpace,即 VRAPI_TRACKING_SPACE_LOCAL_TILTED。该空间定义了用户希望内容显示的倾斜方向。
  • 新增一个 ovrTrackingSpace,即 VRAPI_TRACKING_SPACE_STAGE。该空间的原点在游戏区中央的地板上,它的前进方向指向边界框的某一个边缘。
  • 新增一个 ovrTrackingSpace,即 VRAPI_TRACKING_SPACE_LOCAL_FIXED_YAW。在此空间中,原点与本地空间相同,但偏航角仍固定在实际环境中。此空间可能适用于转椅漫游游戏。
  • 已停用的 ovrFrameParms 参数 ExternalVelocity 已从 API 中删除。

迁移至移动 SDK 1.21.0

本节旨在帮助您从 Oculus 移动 SDK 1.20.0 版迁移至 1.21.0 版。

VrApi 变更

  • 新增由 vrapi_GetTrackingSpacevrapi_SetTrackingSpace 以及 vrapi_LocateTrackingSpace 构成的追踪空间 API。
  • vrapi_GetTrackingTransformvrapi_SetTrackingTransform 被标记为已停用,不应再使用。应用程序应使用新的追踪空间 API。
  • vrapi_RecenterPose 被标记为已停用,不应再使用。
  • 对于使用 VrApi 1.21.0 或更高版本构建的应用程序,所有与防护边界相关的 API 查询(例如 vrapi_GetBoundaryGeometryvrapi_GetBoundaryOrientedBoundingBox 等)现在都会返回边界状态,在没有边界可用时,该状态可以包括 ovrSuccess_BoundaryInvalid

从追踪变换迁移至追踪空间 API:

新的追踪空间 API 为应用提供选择追踪原点位置的办法。以往版本通过提供一种方式来查询应该用于特定原点位置和方向的转换,然后允许应用将 ovrPosef 设置为当前追踪变换来完成该步骤。
以前,要设置追踪原点,您必须输入以下代码:
ovrPosef trackingTransform = vrapi_GetTrackingTransform( ovr, VRAPI_TRACKING_TRANFORM_SYSTEM_CENTER_EYE_LEVEL );
vrapi_SetTrackingTransform( ovr, trackingTransform );
借助新的追踪空间 API,应用只需调用:
vrapi_SetTrackingSpace( ovr, VRAPI_TRACKING_SPACE_LOCAL );
对于地面高度的局部原点,应用将使用:
vrapi_SetTrackingSpace( ovr, VRAPI_TRACKING_SPACE_LOCAL_FLOOR );
系统重新置中操作(由系统发起,往往是响应长按等用户互动)让局部空间定义发生变化。

姿势重新置中

默认追踪空间(称为局部空间)由系统在系统级用户互动的帮助下定义。这是中心位置的实际定义。希望相对于系统中心进行绘制的应用应该使用局部空间,或局部空间的派生词,如“局部地面”(除了原点要转换为地面外,它与局部空间相同)。
应用程序始终控制其虚拟空间和用户追踪空间之间的映射,但它没有用于请求更改系统局部空间定义的 API。

VrAppFramework

VrAppFramework 现在直接链接 gles3 资源库,而不是依赖 OpenGL_Loader 资源库。已从 SDK 包中删除 OpenGL_Loader 资源库。

迁移至移动 SDK 1.20.0

本节旨在帮助您从 Oculus 移动 SDK 1.19.0 版升级至 1.20.0 版。

VrApi 变更

  • vrapi_DefaultLayerEquirect2vrapi_DefaultLayerCube2 帮手功能现默认返回一个身份 TexCoordFromTanAngles 矩阵。
  • 已停用的 Completion Fence 已从 API 中删除。
  • 已停用的 ovrButton_Menu 已从 API 中删除。

完成栅栏

VrApi 不再支持应用程序提供的完成栅栏。使用旧版本 VrApi 构建的应用程序将继续如常运行,但迁移到新版本 VrApi 的应用程序需要停止使用旧版本 VrApi。
需要确保之前提供专属栅栏基元的应用遵守应用要求,不提供完成栅栏。具体来说,它们必须从带有上下文界定的线程调用 vrapi_SubmitFrame,以便将同步基元插入到命令队列中。在不同线程/上下文进行渲染的应用必须确保插入 vrapi_SubmitFrame 上下文命令队列的命令不会在其他上下文完成渲染之前完成。

迁移至 SDK 1.19.0

本节旨在帮助您从 Oculus 移动 SDK 1.18.0 版升级至 1.19.0 版。

概览

  • 此版本中没有面向开发者的变更。

迁移至 SDK 1.18.0

本节旨在帮助您从 Oculus 移动 SDK 1.17.0 版升级至 1.18.0 版。

概览

  • 此版本支持 Samsung Galaxy Note 9 智能手机。

VrApi 变更

  • 将 Samsung Galaxy Note 9 智能手机类型添加到 API。
  • 显式完成栅栏现已标记为已停用,将从未来 SDK 中删除。
  • 已停用的 vrapi_SetTextureSwapchainHandle 已从 API 中删除。
  • 已停用的 ovrTextureSwapChain 类型 VRAPI_TEXTURE_TYPE_2D_EXTERNAL 已从 API 中删除。
  • 已停用的 ovrLayerHeader 参数 SurfaceTextureObject_DEPRECATED 已从 API 中删除。

编译版本变更

由于 gnustl_static 已停用,SDK 示例使用的 Android 编译版本脚本现使用 c++_static 作为 C++ 运行时。更多信息,请参阅 https://developer.android.com/ndk/guides/cpp-support

迁移至移动 SDK 1.17.0

本节旨在帮助您从 Oculus 移动 SDK 1.16.0 版升级至 1.17.0 版。

概览

  • 此版本中没有面向开发者的变更。

迁移至 SDK 1.16.0

本节旨在帮助您从 Oculus 移动 SDK 1.15.0 版升级至 1.16.0 版。

VrApi 变更

  • 由于 Android 游戏手柄事件通过输入 API 公开,因此它们将被较低层系统捕获。将 ovrProperty VRAPI_EAT_NATIVE_GAMEPAD_EVENTS 设置为 false,可更改这种行为。如果原生 Activity 应用将此属性设置为 false,则它们必须处理事件。
  • 对于使用 1.16.0 及更高版本构建的应用程序,重新置中的默认行为是对头戴设备进行另外的重新置中。将 ovrProperty VRAPI_REORIENT_HMD_ON_CONTROLLER_RECENTER 设置为 false,可禁用此行为。
  • VrApi Vulkan 的接入点和结构类型现已公开。参阅新的 VrCubeWorld_Vulkan 示例,了解 API 的使用示例。

迁移至 SDK 1.15.0

本节旨在帮助您从 Oculus 移动 SDK 1.14.0 版升级至 1.15.0 版。

概览

此版本支持 Samsung Galaxy A8 智能手机。

VrApi 变更

  • 将 Samsung A8 Star 设备类型添加到 API。
  • 新增接入点 vrapi_SetTextureSwapChain3,用于传递特定于平台的纹理格式而不是 ovrTextureFormat 类型,从而创建纹理交换链。将 VRAPI_SYS_PROP_SUPPORTED_SWAPCHAIN_FORMATS 传递至 vrapi_GetSystemPropertyInt64Array,即可查询可用格式。
  • vrapi_SetTextureSwapChainHandle 被标记为已停用,不应再使用。
  • 已停用的 ovrFrameLayerFlags 标记、VRAPI_FRAME_LAYER_FLAG_WRITE_ALPHA、相应的 ovrFrameLayerBlend 混合模式、VRAPI_FRAME_LAYER_BLEND_DST_ALPHA 以及 VRAPI_FRAME_LAYER_BLEND_ONE_MINUS_DST_ALPHA 均已 从 API 中删除。
  • 新增接入点,用于创建和获取跨进程友好的 Android 表面交换链 vrapi_CreateAndroidSurfaceSwapChainvrapi_GetTextureSwapChainAndroidSurface
  • ovrTextureTypeVRAPI_TEXTURE_TYPE_2D_EXTERNAL 和相应的 ovrLayerHeader2SurfaceTextureObject 被标记为已停用,不应再使用。应用程序应使用新方法创建跨进程友好的 Android 表面纹理交换链,即 vrapi_CreateAndroidSurfaceSwapChain
  • 使用输入 API 时不再需要 ovrSystemPropertyVRAPI_SYS_PROP_BACK_BUTTON_SHORTPRESS_TIME,因此已将其删除。
  • 对于使用 1.15.0 及更高版本构建的应用程序,将遥控器仿真为头戴设备的默认值现为 false,因为应用程序应使用 输入 API 来查询遥控器和头戴设备输入。要保持旧的行为,请将 false 传递给 vrapi_SetRemoteEmulation
  • 头戴设备仿真关闭后,遥控器将不再发送 Java 输入事件。将 ovrPropertyVRAPI_BLOCK_REMOTE_BUTTONS_WHEN_NOT_EMULATING_HMT 设置为 true,可更改此行为。
  • 现在,检测到按下“返回”按钮后,输入 API 会在整个帧期间将“返回”按钮报告为按下状态,而不仅仅在下一次输入查询时。将 ovrPropertyVRAPI_LATCH_BACK_BUTTON_ENTIRE_FRAME 设置为 false,可更改此行为。

输入 API

从 Android Java 输入迁移至 VrApi 输入

头戴设备遥控器仿真的默认值现在为 false,这意味着遥控器不再发送 Java 输入事件。应用程序应使用 VrApi 输入 API 来查询头戴设备和遥控器的输入状态。
有关输入 API 的详细说明,请参阅 VrApi 输入 API
使用示例见 VrController 原生示例应用。
一般概念
  • VrApi 输入 API 不是基于事件的 Java 输入系统,而是基于 C 的轮询输入系统。
  • 与每帧查询遥控器和头戴设备追踪姿势的方式相似,可以每帧查询输入设备的按钮状态。

迁移至移动 SDK 1.14.0

本节旨在帮助您从 Oculus 移动 SDK 1.12.0 版升级至 1.14.0 版。

概览

该版本支持 Samsung Galaxy s9 智能手机,也支持新的游戏手柄输入 API。

VrApi 变更

  • vrapi_Initialize 现在可以在失败时返回新的错误代码,即 VRAPI_INITIALIZE_ALREADY_INITIALIZED
  • 将 Samsung s9 设备类型添加到 API。
  • VRAPI_FRAME_FLAG_INHIBIT_SRGB_FRAMEBUFFER 已停用,取而代之的是使用每层标记 VRAPI_FRAME_LAYER_FLAG_INHIBIT_SRGB_FRAMEBUFFER
  • 输入 API 现在公开并枚举游戏手柄。
  • 已删除 vrapi_ReturnToHome
  • vrapi_ShowSystemUIWithExtra 被标记为已停用,不应再使用。
  • 提供 VRAPI_REORIENT_HMD_ON_CONTROLLER_RECENTER 属性的目的是让应用能够选择将控制器重新置中操作和调整头戴设备方向相结合的行为。要启用此属性,请使用 vrapi_SetPropertyInt 将属性设置为 1。默认禁用此功能。

游戏手柄输入 API

现在,VrApi 输入 API 除了追踪的遥控器和头戴设备外,还公开游戏手柄。
  • 游戏手柄的新枚举是 ovrControllerType_Gamepad
  • 功能结构是 ovrInputGamepadCapabilities
  • 输入状态结构是 ovrInputStateGamepad
  • 处理查询的方式与追踪遥控器和头戴设备的方式相同,均使用:
    • vrapi_enumerateInputDevices
    • vrapi_GetInputDeviceCapabilities
    • vrapi_GetCurrentInputState
示例:
for ( int i = 0; ; i++ )
{
  ovrInputCapabilityHeader cap;
  ovrResult result = vrapi_EnumerateInputDevices( app->Ovr, i, &cap );
  if ( result < 0 )
  {
    Break;
  }

  if ( cap.Type == ovrControllerType_Gamepad )
  {
    ovrInputStateGamepad gamepadState;
    gamepadState.Header.ControllerType = ovrControllerType_Gamepad;
    result = vrapi_GetCurrentInputState( app->Ovr, i, &gamepadState.Header );
    if ( result == ovrSuccess )
    {
      backButtonDownThisFrame |= gamepadState.Buttons & ovrButton_Back;
      aButtonDownThisFrame |= gamepadState.Buttons & ovrButton_A;
      rightTriggerValueThisFrame = gamepadState.RightTrigger;
      leftJoystickValueThisFrame = gamepadState.LeftJoyStick;
    }
    break;
  }
}

迁移至移动 SDK 1.12.0

本节旨在帮助您从 Oculus 移动 SDK 1.9.0 版升级至 1.12.0 版。

构建系统的变更

以下构建工具版本已更改为:
  • Android NDK r16b
  • Gradle 4.3.1
  • Gradle 3.0.1 专用 Android 插件
  • Android SDK Build-Tools 26.0.2
已根据 Android 操作系统的新版本更新了清单要求,更多信息请参阅 Android 清单要求设置

VrApi 变更

  • 添加了为视觉缓冲区交换链纹理指定注视点级别的机制。
  • 添加了新的 ovrModeFlags 标记,即 VRAPI_MODE_FLAG_CREATE_CONTEXT_NO_ERROR,为想要创建无错误 GL 上下文的应用程序提供支持。
  • 已删除 VRAPI_TEXTURE_SWAPCHAIN_FULL_MIP_CHAIN。应用程序需要在创建交换链时显式传递 mipLevels 的数量。
  • 现在,应用程序指定的追踪变换会影响控制器。
  • VRAPI_DEFAULT_TEXTURE_SWAPCHAIN 表示的交换链现默认为白色,而非黑色。这是为了支持纯色帧,不再局限于黑色帧。应用层的 ColorScale 参数将确定使用的纯色。
  • ovrMobile 结构现在将始终在 vrapi_LeaveVrMode 上释放。
  • 现在要求应用程序向 vrapi_EnterVrMode 显式传递 EGL 对象(DisplayShareContextNativeWindow),否则调用将失败。
  • 已删除 VRAPI_SYS_PROP_BACK_BUTTON_DOUBLETAP_TIME。如果应用程序执行双击逻辑,则仍可通过检查时间是否少于 VRAPI_SYS_PROP_BACK_BUTTON_SHORTPRESS_TIME 来检测它。

注视点

新的注视点 API 支持应用程序调节眼睛纹理交换链的多分辨率级别。
此值可以使用以下 API 调用指定:
vrapi_SetPropertyInt( &Java, VRAPI_FOVEATION_LEVEL, level );
其中:
  • Level = 0 禁用多分辨率
  • Level = 1 低设置(图像质量良好,性能提升不明显)
  • Level = 2 中等设置
  • Level = 3 最大设置
更多信息请观看 High Fidelity OC4 讲座 (https://youtu.be/pjg309WSzlM?t=1677)。

LibOVRKernel 变更

OVR_Geometry 源文件已移动到 VrAppFramework。

VrAppFramework 变更

OVR_Geometry 源文件已添加到 VrAppFramework。
LoadTextureBuffer 现会在加载 png / jpg / bmp 文件后生成 Mipmap。
已删除双击返回按钮逻辑。

迁移至 SDK 1.9.0

本节旨在帮助您从 Oculus 移动 SDK 1.7.0 版升级至 1.9.0 版。

概览

本版本支持新的帧提交路径,能够使用圆柱体、立方体和等距柱状体等新图层类型;该版本还支持指定用户自定义追踪变换,并且支持新的性能 API。

构建系统的变更

  • 我们推荐使用 NDK 版本 r15c。NDK r15 现已弃用 app_dummy,取而代之的是强制导出 ANativeActivity_onCreate
  • 默认情况下,VrAppFramework 和 VrAppSupport 资源库不再提供预构建资源库。如果您的应用程序构建文件依赖于预构建资源库,则需要更改构建文件,将 Projects/Android(而不是 Projects/AndroidPrebuilt)作为资源库的构建路径引用。

VrApi 变更

  • 此版本添加了一个新的入口点 vrapi_SubmitFrame2,它支持灵活图层列表、新图层类型以及单个栅栏表示帧完成。这一新的帧提交 API 不再将性能参数作为输入,因此,在移至此路径时应使用新的性能 API。
  • 添加了新的接入点来指定性能参数:
    • vrapi_SetClockLevels
    • vrapi_SetPerfThread
    • vrapi_SetExtraLatencyMode
  • 已从 API 删除 ovrHeadModelParms 和相应的帮手功能。应用程序不应再使用头部模型来追踪头部姿势,因为 VrApi 运行时已经完成该任务。
  • 添加了新接入点,用于指定用户定义的追踪变换。追踪变换的默认值是视线水平。
  • vrapi_RecenterInputPose 被标记为已停用,不应再使用。
  • API 不再提供 VRAPI_SYS_STATUS_HEADPHONES_PLUGGED_IN。有关如何查询耳机插入状态的示例,请参阅原生 SDK 资源库 VrAppFramework 中的 VrFrameBuilder。
  • VrApi 提供的默认交换链已重命名为 VRAPI_DEFAULT_TEXTURE_SWAPCHAIN。请注意,如果您希望应用程序创建纯黑色的帧,则图层上的 ColorScale 参数必须设置为 { 0.0f, 0.0f, 0.0f, 0.0f },以防止与预期设置 ColorScale 的较新运行时出现任何兼容性问题。

帧提交更新

新的帧提交 API 增加了对灵活图层列表的支持,现在只需要一个完成栅栏即可表示整个帧。性能参数不再通过该 API 指定,而应通过新的性能参数 API 指定(见下文)。
下例介绍如何用新 API 为基本视觉缓冲区渲染的简单情况构建帧提交:
ovrLayerProjection2 & worldLayer = Layers[LayerCount++ ].Projection;
worldLayer = vrapi_DefaultLayerProjection2();

worldLayer.HeadPose = Tracking.HeadPose;
for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ )
{
worldLayer.Textures[eye].ColorSwapChain =ColorTextureSwapChain[eye];
worldLayer.Textures[eye].SwapChainIndex = TextureSwapChainIndex;
worldLayer.Textures[eye].TexCoordsFromTanAngles = TexCoordsFromTanAngles;
}

ovrLayerHeader2 * LayerHeaderList[ovrMaxLayerCount] = {};
for ( int i = 0; i < LayerCount; i++ )
{
LayerHeaderList[i] = &Layers[i].Header;
}

ovrSubmitFrameDescription2 frameDesc = {};
frameDesc.Flags = 0;
frameDesc.SwapInterval = 1;
frameDesc.FrameIndex = FrameIndex;
frameDesc.CompletionFence = (size_t)Fence->Sync;
frameDesc.DisplayTime = PredictedDisplayTime;
frameDesc.LayerCount = LayerCount;
frameDesc.Layers = LayerHeaderList;

vrapi_SubmitFrame2( OvrMobile, &frameDesc );

性能 API

现在,可通过以下性能 API 单独指定时钟级别、应用程序高性能线程以及额外延迟模式等性能参数,不必再与帧提交一起指定:
vrapi_SetClockLevels( ovr, PerformanceParms.CpuLevel, PerformanceParms.GpuLevel );

vrapi_SetPerfThread( ovr, VRAPI_PERF_THREAD_TYPE_MAIN,PerformanceParms.MainThreadTid );

vrapi_SetPerfThread( ovr, VRAPI_PERF_THREAD_TYPE_RENDERER,PerformanceParms.RenderThreadTid );

vrapi_SetExtraLatencyMode( ovr, VRAPI_EXTRA_LATENCY_MODE_OFF );
请注意,这些接入点采用 ovrMobile 指针,因此只应在 VR 模式下调用,即在 vrapi_EnterVrModevrapi_LeaveVrMode 之间。应用程序提供的性能参数将在下一次调用 vrapi_SubmitFrame(2) 时生效。

追踪变换 API

新的追踪变换 API 支持应用程序指定在哪个空间报告追踪姿势。追踪变换的默认值是视线水平。如要更改变换空间,应用程序可以调用以下命令:
vrapi_SetTrackingTransform( ovr, vrapi_GetTrackingTransform( ovr, VRAPI_TRACKING_TRANSFORM_SYSTEM_CENTER_FLOOR_LEVEL ) );

头部模型更新

现在,VrApi 运行时内部已应用头部模型,API 不再使用 ovrHeadModelParms 和相应的帮手功能。
从 SDK 1.7.0 版或更早版本迁移而来的应用程序不再应用自己的头部模型。用于从 ovrTracking2 数据推导出 IPD 和眼睛高度的帮手功能已添加至 VrApi_Helpers.h
如果之前使用 SDK 1.7.0 构建了一个应用程序,并且该应用假设 1) 姿势应用了头部模型,2) Y 轴位置与地面相对,则更新应用程序,以在 vrapi_EnterVrMode() 后立即发出以下调用来获得预期行为:
vrapi_SetTrackingTransform( ovr, vrapi_GetTrackingTransform( ovr, VRAPI_TRACKING_TRANSFORM_SYSTEM_CENTER_FLOOR_LEVEL ) );

VrAppFramework 变更

VrAppFramework 已移植,可与新的提交路径、性能 API 以及用户自定义追踪变换 API 配合使用。

迁移至移动 SDK 1.7.0

本节旨在帮助您从 Oculus 移动 SDK 1.5.0 版升级至 1.7.0 版。

概览

移动 SDK 1.7.0 提供新的 VrApi 界面方法,用于获取预测的追踪信息以及相应的视图和投影矩阵,并通过 externalNativeBuild 提供构建改进和原生调试支持。

构建系统的变更

  • 现在,SDK 为 ndkBuild 使用 externalNativeBuild,而非已停用的 ndkCompile 路径。externalNativeBuild 提供更加强大的原生调试机制,它开箱即用,可以在 Java 和原生代码之间无缝进行单步调试。一定要将 ANDROID_NDK_HOME 环境变量设置为 ndk 路径位置。
  • 已停用 Android KitKat 支持。现在,minSdkVersion 必须为 21 (Lollipop 5.0) 或更高版本。
  • 构建工具已更新为以下版本:
    • Android SDK Build Tools 版本 25.0.1
    • Gradle 2.3.2 专用 Android 插件
    • Gradle 3.3
  • 我们推荐使用 NDK 版本 r14b。

VrApi 变更

  • 添加了新的接入点 vrapi_GetPredictedTracking2(),用于查询预测的追踪信息以及每只眼睛相应的视图和投影矩阵。
  • 现在,对于面向 SDK 1.7.0 及更高版本的应用程序,将在 vrapi_GetPredictedTracking()vrapi_GetPredictedTracking2() 中应用头部模型。应用不再自行应用头部模型。
  • 对于面向 SDK 1.7.0 和更高版本的应用程序,头部姿势 Y 轴变换现在将包括高于地面的视线高度。
  • 已删除 vrapi_GetCenterEye() 帮手功能,取而代之为 vrapi_GetFromPose()* 帮手功能,以删除“中央眼”概念。
  • 已删除 VrApi_LocalPrefs.h。应用程序可以使用 Android 系统属性来满足任何开发调试需求。
  • 已停用 VRAPI_FRAME_LAYER_FLAG_WRITE_ALPHADST_ALPHA 图层混合模式。
  • 现在,在设备上找不到系统驱动程序时,vrapi_Initialize 会返回错误代码,而不是强迫应用程序退出。

LibOVRKernel 变更

已删除已停用的 OVR_Math 常量。有关等效替换,请参阅 OVR_Math.h

VrAppFramework 变更

VrAppFramework 现在使用新的 vrapi_GetPredictedTracking2 方法查询预测的追踪状态,因此,不再显式应用头部模型或管理头部模型参数。
因此,不再提供以下方法:
  • const ovrHeadModelParms & GetHeadModelParms() const;
  • void SetHeadModelParms( const ovrHeadModelParms & parms );

VrModel 变更

  • ModelFile 现在拥有描述完整数据场景的附加数据结构,而不仅仅是含有绘制表面列表的单个 ModelDef
  • 如果系统加载文件失败,现在 LoadModelFile 会返回 nullptr
  • 现在,OvrSceneView.GetWorldModel 会返回一个指针,而不是引用。
  • 现在,ModelState.modelMatrix 是非公开的,必须通过 Get 和 Set 命令访问。
  • 现在,在模型文件中迭代所有绘制表面的正确方式是:
for ( int i = 0; i < modelFile->Models.GetSizeI(); i++ ) { for ( int j = 0; j < modelFile->Models[i].surfaces.GetSizeI(); j++ ) { // work } }

迁移至 SDK 1.5.0

本节旨在帮助您从 Oculus 移动 SDK 1.0.4 版升级至 1.5.0 版。

概览

移动 SDK 1.5.0 提供:
  • Gear VR 控制器和 Gear VR 头戴设备专用 VrApi 输入 API
  • 实验版 64 位 SDK 资源库
  • 删除已停用的 DrawEyeView 渲染路径。
  • 删除已停用的 VrApi 图层类型。
  • 删除已停用的 VrApi 帧标记。

构建系统的变更

我们推荐使用 NDK 版本 r13b。
实验版 64 位 SDK 资源库位于以下资源库路径:Libs/Android/arm64-v8a/

VrApi 变更

VrApi 现在提供新的输入 API,它支持 Gear VR 控制器和头戴设备。请参阅 VrApi 输入 APIVrApi/Include/VrApi_Input.h。使用示例请参阅 VrSamples/Native/VrController/
现已删除已停用的 ovrFrameLayerType 类型。而应使用显式索引来索引图层列表。
现已删除已停用的时间扭曲调试图 ovrFrameFlags 类型。应使用 OvrMonitor 进行性能分析。

LibOVRKernel 变更

OVR_GlUtils 文件已移动到 VrAppFramework。

VrAppFramework 变更

OVR_GlUtils 文件已添加到 VrAppFramework。
VrAppFramework 不再覆盖应用程序指定的帧参数:FrameIndexMinimumVSyncsPerformanceParms
注意:如果应用程序之前依赖于这种行为,请务必在 ovrFrameParms 每帧设置中添加以下内容:
frameParms.FrameIndex = vrFrame.FrameNumber;
frameParms.MinimumVsyncs = app->GetMinimumVsyncs();
frameParms.PerformanceParms = app->GetPerformanceParms();
VrAppFramework 不再提供已停用的 DrawEyeView 渲染路径。请参阅 “1.0.3 SDK 迁移”一节的“重构应用程序渲染实现多视野”,详细了解如何重构应用程序,以使用多视野兼容渲染路径。SDK 随附的 VrSamples 也提供该渲染路径示例。

迁移至 SDK 1.0.4

本节旨在帮助您从 Oculus 移动 SDK 1.0.3 版升级至 1.0.4 版。

概览

移动 SDK 1.0.4 提供:
  • 已删除系统实用程序资源库依赖项,功能直接在 VrApi 中处理。
  • 现在,直接在 VrApi 中检测和处理长按“返回”按钮处理(包括凝视计时器渲染)。应用程序不再执行该逻辑。
  • VrApi Loader 现已不再依赖 Java。
  • 现在,VrApi 实现通过系统驱动程序分发。

构建系统的变更

由于 GCC 不再支持 ndk r13 及更高版本,因此,SDK 现在默认使用 clang 构建。更多信息请参阅 NDK 发布说明第 13 版。
我们推荐使用 NDK 版本 r12b。
SDK 资源库不再提供等效的 jar 文件。而应使用 AAR 文件。
SDK 现在提供 SDK 资源库的调试和发布版本。请注意,这些这些资源库的新路径为:
  • Libs/Android/armeabi-v7a/Release/
  • Libs/Android/aar/Release/

VrApi 变更

VrApi 现在可以处理长按“返回”按钮检测和逻辑,以便在按下“返回”按钮时显示 UM 以及凝视计时器渲染。
现在,VrApi 在场景后面处理系统实用程序功能。提供与系统菜单互动的新 API,详情请参阅 VrApi_SystemUtils.h
现在,vrapi_Initialize 在内部处理致命错误情况的显示。应用程序只需在返回时检查失败情况并进行适当处理,即:
int32_t initResult = vrapi_Initialize( &initParms );
if ( initResult != VRAPI_INITIALIZE_SUCCESS )
{
// As of 1.0.4, vrapi directly triggers the display of Fatal Errors in vrapi_Initialize.
vrapi_Shutdown();
exit( 0 );
}
现已停用 ovrFrameLayerType 类型。而应使用显式索引来索引图层列表。
已删除时间扭曲调试图。而应使用 OvrMonitor 进行性能分析。
VrApi Loader 现已不再依赖 Java。构建文件不应再将 VrApi-Loader.aar 指定为依赖项,或将 VrApi:Projects:AndroidPrebuilt 指定为依赖路径。

VrAppFramework 变更

Input.h 已重命名为 OVR_Input.h
StartSystemActivity( PUI_XXX ) 的调用应替换为 ShowSystemUI( VRAPI_SYS_UI_XXX )
应用应删除返回按钮长按处理,因为现在由 VrApi 直接处理。不再提供以下输入按键事件:KEY_EVENT_LONG_PRESS

VrAppSupport 变更

SystemUtils

已删除 SystemUtils 资源库,所有功能均归入 VrApi。
构建文件不应再将 systemutils.aSystemUtils.aar 指定为构建依赖项。对 SystemActivities.h 的任何引用都应替换为 VrApi_SystemUtils.h
现在,BACK_BUTTON_DOUBLE_TAP_TIME_IN_SECONDSBACK_BUTTON_SHORT_PRESS_TIME_IN_SECONDS 的值均显示在 VrApi 系统属性界面,可通过以下方式查询:
float doubleTapTimeInSeconds = vrapi_GetSystemPropertyFloat( &app->Java, VRAPI_SYS_PROP_BACK_BUTTON_DOUBLETAP_TIME );

float shortPressTimeInSeconds = vrapi_GetSystemPropertyFloat( &app->Java, VRAPI_SYS_PROP_BACK_BUTTON_SHORTPRESS_TIME );
应用程序不再负责管理 SystemUtils 应用事件,因此应删除以下功能调用:
  • SystemActivities_Init
  • SystemActivities_Shutdown
  • SystemActivities_Update
  • SystemActivities_PostUpdate
注意:挂载时重新置中现直接在 VrApi 中处理。应用不再需要执行此逻辑。如果应用程序需要检测已发生的重新置中,现在可以通过 VrApi 检查重新置中计数来实现,例如:
const int currentRecenterCount = vrapi_GetSystemStatusInt( &Java, VRAPI_SYS_STATUS_RECENTER_COUNT );
// Determine if the recenter count has changed since last frame
if ( currentRecenterCount != RecenterCount )
{
// reset menu orientations
RecenterCount = currentRecenterCount;
}
不再提供 SystemActivities_SendIntentSystemActivities_SendLaunchIntent。不过,可以使用 VrAppframework 提供的版本:SendIntentSendLaunchIntent
不再提供 SystemActivities_ReturnToHome,而应使用 vrapi_ReturnToHome

VrGui

已删除凝视计时器,因为现在由 VrApi 直接处理。
现在,ShowInfoTextDebugFont 通过 VrGui 提供。

迁移至 SDK 1.0.3

本节旨在帮助您从 Oculus 移动 SDK 1.0.0 版升级至 1.0.3 版。

概览

移动 SDK 1.0.3 支持多视野渲染。为了让应用程序利用多视野,您需要重构应用程序渲染,以便从帧返回渲染表面列表,而不是依赖 DrawEyeView 路径。请参阅下文“重构应用渲染实现多视野”,了解如何为多视野渲染设置应用程序渲染。
注意:已停用 DrawEyeView 渲染路径,将在未来 SDK 更新中将其删除。
为让 VrApi 更加明确,简化与多线程引擎的集成,VrApi 使用的 EGL 对象和 ANativeWindow 现在可通过 API 进行显式传递。
对 VrAppInterface 进行了重构,实现了界面简化、支持多视野渲染以及强制执行每帧确定性。
构建步骤已从 Python 构建脚本移动到 Gradle。
以下各节提供将原生项目更新至移动 SDK 1.0.3 版的指南。SDK 随附的原生 SDK 示例也是查看所需更改的重要参考(请参阅 VrSamples/Native)。

构建系统的变更

SDK 现使用 gcc 4.9 构建。将个人代码移植到 gcc 4.9 的相关辅助资料,请参阅 https://gcc.gnu.org/gcc-4.9/porting_to.html
SDK 现使用 Android SDK Build Tools 版本 23.0.1 构建。所有 Gradle 文件中,凡指定为 buildToolsVersion 22.0.1 的地方均应修改为 buildToolsVersion 23.0.1
使用 build.py 构建的应用程序(包括 VrSamples/Native 中的所有项目)均需编辑其构建配置,以包括 VrApp.gradle
  1. 在项目级 build.gradle(例如 VrCubeWorld_NativeActivity/Projects/Android/build.gradle)中,将以下行添加到文件顶部:apply from: "${rootProject.projectDir}/VrApp.gradle"
  2. 删除括号内以 project.afterEvaluateandroid.applicationVariants.all 开头的部分。
对所有项目级 build.gradle 文件进行以下更改:
  1. 将以下行添加到括号内标记为 Android 的部分:project.archivesBaseName = "<your project name>"
  2. 确保括号内标记为 Android 的部分也包括:defaultConfig { applicationId "<your project app ID>" }
  3. 在括号内标记为依赖项的部分,将 compile name: 'VrAppFramework', ext: 'aar' 替换为 compile project(':VrAppFramework:Projects:AndroidPrebuilt'),并将以下路径添加到 settings.gradle 包含的列表中:'VrAppFramework:Projects:AndroidPrebuilt'
相关示例,请参阅 VrTemplate/ gradle

VrApi 变更

VrApi 现在自动显示音量调节悬窗。如有必要,可以将 VRAPI_FRAME_FLAG_INHIBIT_VOLUME_LAYER 设为 ovrFrameParm 标记,即可覆盖该行为。
注意:使用 VrApi 音量通知助手时,确保不要渲染您自己的!
VrApi 使用的 ANativeWindow 现在可以通过 API 进行显式传递,方式是指定以下 ovrModeParm 标记:
parms.Flags |= VRAPI_MODE_FLAG_NATIVE_WINDOW;
注意:虽然 VrApi 目前仍支持旧行为,即不显式传递具有线程限制的 EGL 对象,但 VrApi 的未来版本中将删除该功能。
ovrModeParms AllowPowerSave 现指定为 ovrModeParm 标记:
parms.Flags |= VRAPI_MODEL_FLAG_ALLOW_POWER_SAVE
现已显式指定 ovrFrameLayer ProgramParms

LibOVRKernel 变更

ovrPose 成员名称已更改:
Orientation -> Rotation
Position -> Translation
尺寸成员名称已更改:
Width -> w
Height -> h
已停用数学 T 常量,取而代之以新的 MATH_FLOAT_MATH_DOUBLE 定义。

VrAppFramework 变更

VrAppInterface 重构

对 VrAppInterface 进行了重构,以实现界面简化、支持多视野以及强制执行每帧确定性。
已更改 VrAppInterface::Frame() 功能签名。Frame() 现采用 ovrFrameInput 结构,其中包含应用程序需要的所有每帧状态信息。它返回 ovrFrameResult 结构,其中应包含单个应用程序帧生成的所有状态信息。
尤其是,ovrFrameInput 现包含按键状态更改,ovrFrameResult 必须返回要渲染的表面列表。启用多视野渲染后,这份表面列表只提交一次,但要为双眼渲染。在支持多视野之前,每帧都要提交和渲染所有表面两次。
Frame() 必须至少返回含有中心视野矩阵的帧结果,如下所示:
ovrFrameResult res;
res.FrameMatrices.CenterView = Scene.GetCenterEyeViewMatrix();
return res;
由于改而支持多视野,现已停用 DrawEyeView()
已从界面删除 OneTimeInitNewIntent。现在,Android 意图会与 intentType 标记一起传递至 EnteredVrMode()。在创建应用程序主 Activity 后首次进入 EnteredVrMode() 时,intentType 将为 INTENT_LAUNCH。如果重新启动应用程序,而主 Activity 已在运行(通常发生在暂停的应用程序恢复运行时)并且有了新的意图,则 intentType 将为 INTENT_NEW。如果应用程序恢复运行,但没有新意图,则 intentType 将为 INTENT_OLD
现在,实现 OneTimeInit()NewIntent() 的应用程序必须从过载的 EnteredVrMode() 方法显式调用 OneTimeInit()NewIntent()。通常,这意味着:
  • intentTypeINTENT_LAUNCH 时,依次调用 OneTimeInit()NewIntent()
  • intentTypeINTENT_NEW 时,仅调用 NewIntent()
  • intentTypeINTENT_OLD 时,不要调用 OneTimeInit()NewIntent()
已从 VrAppInterface 删除 OneTimeShutdown()。现在,必须从 VrAppInterface 派生类的析构函数调用应用程序关闭代码。
从 VrAppInterface 删除 OnKeyEvent(),让所有输入事件能够通过 ovrFrameInput 结构传递。这可将应用程序代码接收事件的方式减少到仅剩 ovrFrameInput。这要求每个应用程序都执行自己的代码,将按键事件分派到 OnKeyEvent()。应用程序现有的 OnKeyEvent() 可保持不变,并从 Frame() 的开头调用,方式如下:
	// process input events first because this mirrors the behavior when OnKeyEvent was
	// a virtual function on VrAppInterface and was called by VrAppFramework.
	for ( int i = 0; i < vrFrame.Input.NumKeyEvents; i++ )
	{
		const int keyCode = vrFrame.Input.KeyEvents[i].KeyCode;
		const int repeatCount = vrFrame.Input.KeyEvents[i].RepeatCount;
		const KeyEventType eventType = vrFrame.Input.KeyEvents[i].EventType;

		if ( OnKeyEvent( keyCode, repeatCount, eventType ) )
		{
			continue;   // consumed the event
		}
		// If nothing consumed the key and it is a short-press of the back key, then exit the application to Home.
		if ( keyCode == OVR_KEY_BACK & eventType == KEY_EVENT_SHORT_PRESS )
		{
			app->StartSystemActivity( PUI_CONFIRM_QUIT );
			continue;
		}
	}
已添加 LeavingVrMode()。只要应用程序离开 VR 模式(即应用程序暂停、停止运行或崩溃时),就会调用它。

应用

已删除 CreateToast。不过,可使用 App::ShowInfoText 来显示调试文本。

AppLocal

不再提供 DrawScreenMask()OverlayScreenFadeMaskProgram,应由需要它们的应用程序来实现。示例请参阅 VrSamples/Native/CinemaSDK

ovrDrawSurface

ovrDrawSurface 已重构,现包含一个矩阵,而非指向矩阵的指针。已删除关节成员,现在必须在 GlProgram 统一参数中将关节显式指定为统一缓冲区对象。

ovrMaterialDef

ovrMaterialDef 界面已合并到 ovrGraphicsCommand,并标记为停用。
ovrMaterialDef programObject -> ovrGraphicsCommand Program.Program
ovrMaterialDef gpuState -> ovrGraphicsCommand GpuState

ovrSurfaceDef

materialDef 成员已被 graphicsCommand 取代。
cullingBounds 成员已从 ovrSurfaceDef 中删除。GlGeometry 现在计算并存储 localBounds

GlGeometry

GlGeometry 现在计算创建时 localBounds 以保证提交到渲染器的所有几何图形都具有有效的边界。
BuildFadedScreenMask() 功能不再提供,应由需要它的应用程序实现。示例请参阅 VrSamples/Native/CinemaSDK。

GlProgram

GlProgram 已经过重大重构以支持多视野:
内部数据成员已重命名,因此每个成员的首字母均为大写。例如,program 现在为 Program。
GlProgram 现在默认使用 300 版构建着色器程序以支持多视野。但有一种例外情况:如果着色器需要使用 image_external(通常用于视频渲染),则由于驱动程序与 image_external 和 300 版不兼容,因此可能会使用 v100 构建着色器。所有完全支持多视野的驱动程序都将支持 image_external 及 300 版。
使用 image_external 的所有程序都需要进行以下更改,以便与 v100 和 v300 兼容,将以下内容:
#extension GL_OES_EGL_image_external : require
更改为:
#extension GL_OES_EGL_image_external : enable
#extension GL_OES_EGL_image_external_essl3 : enable
如需了解有关 300 版的更多信息,请参阅:https://www.khronos.org/registry/gles/specs/3.0/GLSL_ES_Specification_3.00.3.pdf
着色器指令(如扩展、优化等)现在必须与主着色器源代码分开指定。示例请参阅 VrSamples/Native/CinemaSDK
作为多视野支持的一部分,uniformMvp 不再是 GlProgram 的一部分。为了符合多视野要求,应用必须移除对 Mvpm 的使用,改为使用 TransformVertex() 计算投影位置,即:
gl_Position = TransformVertex( Position );
注意:TransformVertex 函数在默认的系统头文件块中提供,并将添加到每个 GlProgram 中。
GlProgram 现在显式支持统一参数设置。依赖一小部分硬编码系统级统一参数的旧路径现已停用,并将在未来的 SDK 中移除。下面提供了使用新路径设置统一参数的示例。

GlTexture

GlTexture 已更改为要求提供纹理的宽度和高度。为强制执行此要求,GlTexture 构造函数已更改,且 GlTexture 不再支持通过整数隐式构造。

输入

应用程序的输入处理方式已更改,现在通过 ovrFrameInput 结构将输入的数据传递到应用程序的 Frame() 函数中。有关说明和示例代码,请参阅 VrAppInterface 重构部分。
VrAppFramework 现在还可处理 Android 键码 82。短按键码 82 可打开 UM,而长按则直接进入首页。

纹理管理器

VrAppFramework 现在实施纹理管理器。这样 VrGUI 对象便可跨表面共享纹理,从而显著缩短使用 VrGUI 的应用程序的加载时间。目前,纹理不进行引用计数,因此在释放 VrGUI 对象时不会自动释放纹理。在 VrGUI 表面加载大量纹理的项目可能需要使用纹理管理器来显式释放纹理内存。应用程序可以创建 ovrTextureManager 的新实例来管理单独的纹理内存池。

VrAppSupport

VrGUI

VrGUI 组件的各个实例现在可以拥有名称。GetComponentByName() 已更改为 GetComponentByTypeName(),并且存在一个新的模板函数 GetComponentByName(),用于按名称检索 VRMenuObject 的组件。由于新的 GetComponentByName() 的签名不同,调用 GetComponentByName() 的旧代码将无法编译,直到将 GetComponentByName() 更改为 GetComponentByTypeName()
OvrGuiSys::RenderEyeView() 功能接口已从:
GuiSys->RenderEyeView( Scene.GetCenterEyeViewMatrix(), viewMatrix, projectionMatrix
     );
更改为:
GuiSys->RenderEyeView( Scene.GetCenterEyeViewMatrix(), viewMatrix, projectionMatrix, app->GetSurfaceRender() );
注意:此功能特定于 DrawEyeView 渲染路径,并将在未来的 SDK 中移除。
为了支持多视野,VrGUI 现在提供一个接口调用,用于将所有 GUI 表面添加到应用程序的渲染表面列表:
GuiSys->AppendSurfaceList( Scene.GetCenterEyeViewMatrix(), &res.Surfaces );

VrLocale

ovrLocale::Create 功能签名已从:
Locale = ovrLocale::Create( *app, "default" );
更改为:
Locale = ovrLocale::Create( *java->Env, java->ActivityObject, "default" );

VrModel

SceneView::DrawEyeView() 功能签名已从:
Scene.DrawEyeView( eye, fovDegreesX, fovDegreesY );
更改为:
Scene.DrawEyeView( eye, fovDegreesX, fovDegreesY, app->GetSurfaceRender() );

重构多视野应用渲染

如要设置渲染路径以符合多视野标准,应用需要指定返回 AppFrame() 的表面列表和渲染状态列表。应用主渲染通道内的即时 GL 调用不兼容多视野渲染,因此不允许进行此渲染。
下方第一节说明如何将应用从使用 DrawEyeview 进行渲染转换为向应用框架返回表面列表。
下节说明多视野渲染的注意事项以及如何在应用中启用它。

从帧返回表面

设置帧结果:
应用应设置 ovrFrameResult,该代码由帧通过以下步骤返回:
  1. 设置 ovrFrameParms,其存储由应用程序维护。
  2. 设置 FrameMatrices,它包括每只眼睛的 CenterEyeViewProjection 矩阵。
  3. 生成渲染表面列表,并添加到帧结果表面列表。
    1. 注意:表面绘制顺序是列表顺序,从最低索引 (0) 到最高索引。
    2. 注意:在进行帧渲染时,不要释放列表中表面所依赖的任何资源。
  4. 还可以指定是否使用清除颜色来清除颜色或深度缓冲区(可选)。

OvrSceneView 示例

下面是一个使用 OvrSceneView 资源库中的场景矩阵和表面生成的示例:
ovrFrameResult OvrApp::Frame( const ovrFrameInput & vrFrame )
{
...

// fill in the frameresult info for the frame.
ovrFrameResult res;

// Let scene construct the view and projection matrices needed for the frame.
Scene.GetFrameMatrices( vrFrame.FovX, vrFrame.FovY, res.FrameMatrices );

// Let scene generate the surface list for the frame.
Scene.GenerateFrameSurfaceList( res.FrameMatrices, res.Surfaces );

// Initialize the FrameParms.
FrameParms = vrapi_DefaultFrameParms( app->GetJava(), VRAPI_FRAME_INIT_DEFAULT, vrapi_GetTimeInSeconds(), NULL );
for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ )
{
FrameParms.Layers[0].Textures[eye].ColorTextureSwapChain = vrFrame.ColorTextureSwapChain[eye];
	FrameParms.Layers[0].Textures[eye].DepthTextureSwapChain = vrFrame.DepthTextureSwapChain[eye];
	FrameParms.Layers[0].Textures[eye].TextureSwapChainIndex = vrFrame.TextureSwapChainIndex;

	FrameParms.Layers[0].Textures[eye].TexCoordsFromTanAngles = vrFrame.TexCoordsFromTanAngles;
	FrameParms.Layers[0].Textures[eye].HeadPose = vrFrame.Tracking.HeadPose;
}

FrameParms.ExternalVelocity = Scene.GetExternalVelocity();
FrameParms.Layers[0].Flags = VRAPI_FRAME_LAYER_FLAG_CHROMATIC_ABERRATION_CORRECTION;

res.FrameParms = (ovrFrameParmsExtBase *) & FrameParms;
return res;
}

自定义渲染示例

首先,需要确保所有即时 GL 渲染调用均由 ovrSurfaceDef 表示。
DrawEyeView 路径,一般都是通过发出即时 GL 调用来完成自定义表面渲染。
 glActiveTexture( GL_TEXTURE0 );
	glBindTexture( GL_TEXTURE_2D, BackgroundTexId );

	glDisable( GL_DEPTH_TEST );
	glDisable( GL_CULL_FACE );

 GlProgram & prog = BgTexProgram;
	glUseProgram( prog.Program );
	glUniform4f( prog.uColor, 1.0f, 1.0f, 1.0f, 1.0f );
	globeGeometry.Draw();
	glUseProgram( 0 );

	glActiveTexture( GL_TEXTURE0 );
	glBindTexture( GL_TEXTURE_2D, 0 );
而在初次使用符合多视野标准的路径时,将按如下定义 ovrSurfaceDefGlProgram
static ovrProgramParm BgTexProgParms[] =
{
{ "Texm",		ovrProgramParmType::FLOAT_MATRIX4		},
		{ "UniformColor",	ovrProgramParmType::FLOAT_VECTOR4		},
		{ "Texture0",	ovrProgramParmType::TEXTURE_SAMPLED	},
};
BgTexProgram= GlProgram::Build( BgTexVertexShaderSrc, BgTexFragmentShaderSrc, BgTexProgParms, sizeof( BgTexProgParms) / sizeof( ovrProgramParm ) );

	GlobeSurfaceDef.surfaceName = "Globe";
	GlobeSurfaceDef.geo = BuildGlobe();
	GlobeSurfaceDef.graphicsCommand.Program = BgTexProgram;
	GlobeSurfaceDef.graphicsCommand.GpuState.depthEnable = false;
	GlobeSurfaceDef.graphicsCommand.GpuState.cullEnable = false;
	GlobeSurfaceDef.graphicsCommand.UniformData[0].Data = &BackGroundTexture;
	GlobeSurfaceDef.graphicsCommand.UniformData[1].Data = &GlobeProgramColor;

对于帧时间,可以更新统一值,可以更改 gpustate,并且可将表面添加到渲染表面列表。
注意:这种统一参数的设置方式要求应用程序维护统一数据的存储。今后,SDK 将为设置统一参数和材质提供帮手功能。
使用自定义渲染设置 FrameResult 的示例如下:
ovrFrameResult OvrApp::Frame( const ovrFrameInput & vrFrame )
{
...

// fill in the frameresult info for the frame.
ovrFrameResult res;

// calculate the scene matrices for the frame.
res.FrameMatrices.CenterView = vrapi_GetCenterEyeViewMatrix( &app->GetHeadModelParms(), &vrFrame.Tracking, NULL );
for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ )
{
res.FrameMatrices.EyeView[eye] = vrapi_GetEyeViewMatrix( &app->GetHeadModelParms(), &CenterEyeViewMatrix, eye );
	res.FrameMatrices.EyeProjection[eye] = ovrMatrix4f_CreateProjectionFov( vrFrame.FovX, vrFrame.FovY, 0.0f, 0.0f, 1.0f, 0.0f );
}

// Update uniform variables and add needed surfaces to the surface list.
BackGroundTexture = GlTexture( BackgroundTexId, 0, 0 );
GlobeProgramColor = Vector4f( 1.0f, 1.0f, 1.0f, 1.0f );
res.Surfaces.PushBack( ovrDrawSurface( &GlobeSurfaceDef ) );

// Initialize the FrameParms.
FrameParms = vrapi_DefaultFrameParms( app->GetJava(), VRAPI_FRAME_INIT_DEFAULT, vrapi_GetTimeInSeconds(), NULL );
for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ )
{
FrameParms.Layers[0].Textures[eye].ColorTextureSwapChain = vrFrame.ColorTextureSwapChain[eye];
	FrameParms.Layers[0].Textures[eye].DepthTextureSwapChain = vrFrame.DepthTextureSwapChain[eye];
	FrameParms.Layers[0].Textures[eye].TextureSwapChainIndex = vrFrame.TextureSwapChainIndex;

	FrameParms.Layers[0].Textures[eye].TexCoordsFromTanAngles = vrFrame.TexCoordsFromTanAngles;
	FrameParms.Layers[0].Textures[eye].HeadPose = vrFrame.Tracking.HeadPose;
}

FrameParms.ExternalVelocity = Scene.GetExternalVelocity();
FrameParms.Layers[0].Flags = VRAPI_FRAME_LAYER_FLAG_CHROMATIC_ABERRATION_CORRECTION;

res.FrameParms = (ovrFrameParmsExtBase *) & FrameParms;
return res;
}

指定渲染模式:

在应用的 Configure() 中,指定合适的渲染模式。如要将应用配置为使用帧返回的表面进行渲染,请进行以下设置:
settings.RenderMode = RENDERMODE_STEREO;
注意:已提供调试渲染模式选项,该选项可在已停用的 DrawEyeView 路径和从帧返回的渲染表面列表新路径之间交替渲染。这可协助转换过程,因此更容易发现两条路径之间的差异。
settings.RenderMode = RENDERMODE_DEBUG_ALTERNATE_STEREO;

多视野渲染路径**

在启用多视野渲染路径之前,必须确保渲染数据与多视野兼容。这包括:

位置计算

应用渲染程序不应再直接指定 Mvpm,而用使用系统提供的 TransformVertex() 函数来计算 gl_Position,从而将当前 viewID 的正确视野和投影矩阵考虑在内。

每只眼睛的视野计算

应用需要考虑每只眼睛的视野计算。示例如下:

每只眼睛的纹理矩阵

DrawEyeView 路径中,特定眼睛的纹理矩阵绑定在相应眼睛渲染通道的开始处。对于多视野,应该使用以 VIEW_ID 为索引的纹理矩阵阵列。
注意:由于 Adreno 420、KitKat 和 300 版程序的驱动程序问题,统一矩阵阵列应包含在统一缓冲区对象内。

立体图像

DrawEyeView 路径中,特定眼睛的图像绑定在相应眼睛渲染通道的开始处。对于多视野,虽然以 VIEW_ID 为索引的纹理阵列更可取,但 Android KitKat 不支持使用纹理阵列。因此,还可以在片段着色器中指定两个纹理,并由 VIEW_ID 决定选择哪一个。

外部图像使用方法

在构建 image_external 着色器时,必须小心使用 image_external 的应用程序,即视频渲染应用程序。
并非所有驱动程序都像 300 版程序一样支持 image_external。好消息是完全支持多视野的驱动程序将在 300 版路径中支持 image_external,也就是说启用多视野路径时,image_external 程序将正常运行。但是,在不完全支持多视野的驱动程序中,会将这些着色器编译为 100 版。
这些着色器必须继续在两条路径上工作,即不应仅使用 300 版的构造,并且应按照上述规格要求进行扩展。
在某些情况下,最简洁的解决办法可能是,在帧时间范围内只使用 image_external 将外部图像的内容复制到普通 texture2d,然后将其用于应用主渲染通道(这可能会抵消节省的多视野性能)。

启用多视野渲染

最后,如要启用多视野渲染路径,请在应用 Configure() 中对渲染模式进行如下设置:
settings.RenderMode = RENDERMODE_MULTIVIEW;

迁移至移动 SDK 1.0.0

本节旨在帮助您从 0.6.2 SDK 升级至 1.0.0。

VrApi 变更

功能 vrapi_Initialize 现在返回 ovrInitializeStatus。通过检查是否返回 VRAPI_INITIALIZE_SUCCESS 来验证初始化是否成功非常重要。
功能 vrapi_GetHmdInfo 已被 vrapi_GetSystemPropertyIntvrapi_GetSystemPropertyFloat 取代。这些功能使用 ovrSystemProperty 枚举来获取以前在 ovrHmdInfo 结构中返回的各个属性。
功能 ovr_DeviceIsDockedovr_HeadsetIsMountedovr_GetPowerLevelStateThrottledovr_GetPowerLevelStateMinimum 已被 vrapi_GetSystemStatusIntvrapi_GetSystemStatusFloat 取代。这些功能使用 ovrSystemStatus 枚举来选择要查询的各个状态。这些功能现在也可用于查询各种性能指标。
VrApi_Android.h 中的其他功能封装了 Android 功能或处理 System Activities(通用菜单等)的启动或返回。这些功能已从 VrApi 中移除,因为其不被视为 VR 渲染核心最小 API 的一部分。获取/设置亮度、舒适模式和免打扰模式的功能已移除。其他功能现在可通过 VrAppSupport/SystemUtils 资源库获得。有关使用 SystemUtils 资源库的更多详细信息,请参阅 “VrAppsupport 的变更”部分。
图层纹理作为“纹理交换链” (ovrTextureSwapChain) 传递给 vrapi_SubmitFrame()。这些纹理交换链通过 vrapi_CreateTextureSwapChain() 进行分配。通过 VrApi 分配这些纹理以允许在特殊系统内存中进行分配十分重要。当使用静态图层纹理时,纹理交换链不需要缓冲,而且内容链只需要保持单一纹理。当图层纹理动态更新时,纹理交换链需要缓冲。当纹理交换链传递给 vrapi_SubmitFrame() 时,应用程序也会在内容链索引中传递给最近更新的纹理。
异步时间扭曲合成器的行为不再通过选择具有预定合成布局的扭曲程序来指定。现在,执行合成的方式由 ovrFrameParms 中的 ovrFrameLayers 确定。应用程序必须通过设置 ovrFrameParms::LayerCount 来指定要合成的层数,并且应用程序必须初始化 ovrFrameParms::Layers 中的每个 ovrFrameLayer 以实现所需的合成。有关如何设置和配置图层合成的示例,请参阅 SDK 原生示例中的 CinemaSDK。
ovrFrameOption 枚举已重命名为 ovrFrameFlags,而 VRAPI_FRAME_OPTION_* 标记已重命名为 VRAPI_FRAME_FLAG_*
VRAPI_FRAME_OPTION_INHIBIT_CHROMATIC_ABERRATION_CORRECTION 标记已被 VRAPI_FRAME_LAYER_FLAG_CHROMATIC_ABERRATION_CORRECTION 取代,其目前在 ovrFrameLayer::Flags 中设置。请注意,色差校正现在默认为禁用。必须在需要色差校正的每一层上设置 VRAPI_FRAME_LAYER_FLAG_CHROMATIC_ABERRATION_CORRECTION 标记。仅在需要的图层上启用色差校正,以最大限度地提高性能和降低功耗。
ovrFrameLayer::WriteAlphaovrFrameLayer::FixedToView 布尔值已分别被 ovrFrameLayer::FlagsVRAPI_FRAME_LAYER_FLAG_WRITE_ALPHAVRAPI_FRAME_LAYER_FLAG_FIXED_TO_VIEW 取代。
ovrFrameLayerTexture::TextureRect 成员现在会影响合成。有机会在合成器中消除片段着色工作时,可以跳过 TextureRect 以外的区域。但是,即使没有跳过这些区域,渲染仍必须正常工作,因为在某些情况下,TextureRect 以外的区域仍必须进行渲染。
VrApi 现在允许通过 vrapi_EnterVrModevrapi_SubmitFrame 显式传递多个 OpenGL 对象。
结构 ovrModeParms 现在允许将 Display、WindowSurfaceShareContext 显式传递给 vrapi_EnterVrMode。如果在 ovrModeParms 中显式设置了这些 OpenGL 对象,则无需从具有当前活动 Android 窗口表面 OpenGL 上下文的线程调用 vrapi_EnterVrMode。如果没有在 ovrModeParms 上显式设置这些对象(即,这些对象设置为默认值 0),则 vrapi_EnterVrMode 的行为方式将与过去相同,必须从具有当前活动 Android 窗口表面 OpenGL 上下文的线程调用 vrapi_EnterVrMode
作为 ovrFrameParms 的一部分,ovrFrameLayerTexture 结构现在允许将 CompletionFence 显式传递给 vrapi_SubmitFrame。如果在所有图层纹理上都显式设置了此 OpenGL 对象,则无需从当前用于渲染眼睛图像的 OpenGL 上下文的线程调用 vrapi_SubmitFrame。如果未在所有图层纹理上显式设置此对象,则 vrapi_SubmitFrame 的行为将与过去相同,并且必须从当前用于渲染眼睛图像的 OpenGL 上下文的线程调用 vrapi_SubmitFrame

VrAppSupport 变更

VrAppSupport 中的支持模块现在可作为预构建资源库使用。

SystemUtils 资源库

所有 Gear VR 应用程序与 System Activities 应用程序的互动现在都通过 VrAppSupport 下的 SystemUtils 资源库进行管理,其包含 System Activities API。
所有原生应用程序现在都必须链接到 VrAppSupport/SystemUtils 资源库,方法是在 Android.mk 文件中包含以下行并将 SystemUtils.aar(额外提供的 .jar)添加为构建依赖项:
$(call import-module,VrAppSupport/SystemUtils/Projects/AndroidPrebuilt/jni)
为了利用 SystemUtils 资源库,应用程序必须执行以下操作:
  • 在应用程序初始化时调用 SystemActivites_Init()
  • 调用 SystemActivities_Update() 以检索待处理的 System Activities 事件列表。
  • 然后,应用程序可处理该列表中它希望处理的任何事件。应用程序应调用 SystemActivities_RemoveAppEvent() 移除其处理的任何事件。
  • 在应用程序的帧更新期间调用 SystemActivities_PostUpdate()
  • 在销毁应用程序时调用 SystemActivities_Shutdown()
Samsung Gear VR 应用程序可使用此 API 在启动 System Activities 应用程序时发送特殊格式的启动意图。所有应用程序都可以通过使用相应的 PUI_ 命令调用 SystemActivities_StartSystemActivity(),在通用菜单中启动 System Activities 或退出到主菜单。有关更多详细信息以及可用命令列表,请参阅 VrAppSupport/SystemUtils/Include 文件夹中的 SystemActivities.h 头文件。
理论上,Gear VR 应用程序可以随时接收来自 System Activities 的消息,但实际上只有 System Activities 返回到启动它的应用程序时才会发送这些消息。这些消息通过 SystemActivities_Update()SystemActivites_PostUpdate() 进行处理。调用更新时,其返回一个待处理事件的阵列。
应用程序可以处理或消耗此事件阵列中的事件。如果应用程序希望消耗某个事件,则必须使用 SystemActivities_RemoveAppEvent() 从事件阵列中移除该事件。然后,此阵列将通过 PostUpdate 传递,其中将对任何具有默认行为的剩余事件(如调整方向事件)执行默认处理。
此示例序列说明 System Activities 通常如何与应用程序互动:
  1. 用户长按返回按钮。
  2. 应用程序检测到长按,使用 SystemActivities_StartSystemActivityPUI_GLOBAL_MENU 命令启动 System Activities。
  3. 在通用菜单中,用户选择重新调整方向
  4. System Activities 向启动通用菜单的应用程序发送一个启动意图。
  5. System Activities 向启动它的应用程序发送重新调整方向消息。
  6. 应用程序接收该消息并将其添加到 System Activities 事件队列。
  7. 应用程序恢复运行。
  8. 应用程序调用 SystemActivities_Update() 以获取待处理事件的列表。
  9. 如果应用程序有特殊的重新调整方向逻辑(例如,在重新调整方向后将用户界面元素重新对齐到用户前方),其可以调用 vrapi_RecenterPose() 重新定位其用户界面,然后从事件列表中移除该事件。
  10. 应用程序会调用 SystemActivities_PostUpdate()。如果应用程序未处理重新调整方向事件,则会在 PostUpdate 内处理该事件。
如果是 exitToHome 消息,SystemUtils 资源库始终使用默认操作处理消息,即在应用程序的主活动对象上调用 finish(),而不是将其传递到 Update/PostUpdate 队列。这样做是为了允许应用程序在仍在后台运行时退出。
VrAppFramework 资源库已处理 System Activities 事件,因此使用 VrAppFramework 的原生应用程序无需调用任何 System Activities API。VrAppFramework 调用 SystemActivities_Update() 后,会将指向事件阵列的指针放在该帧的 VrFrame 对象中。然后,使用该框架的应用程序可以在其帧循环中处理这些 System Activities 事件,或完全忽略这些事件。在应用程序从其 VrAppInterface::Frame() 方法返回之前,应使用 SystemActivities_RemoveAppEvent() 从事件阵列中移除任何已处理的事件。
Unity 插件(Legacy 0.8+ 和 Utilities 0.1.3+ 中)已包含 SystemUtils 资源库,并根据需要在内部调用 System Activities API 函数。当前,Unity 应用程序无法消耗 System Activities 事件,但可以通过在 OVRManager 类上使用 SetVrApiEventDelegate() 添加事件委托来处理这些事件。

VrGui 资源库

VrGui 资源库包含以场景图形式实现的完全 3D 用户界面。场景图中的每个对象都可以使用组件进行功能扩展。此资源库依赖于 VrAppFramework,必须与之配合使用。有关示例,请参阅 CinemaSDK、Oculus360PhotosSDK 和 Oculus360Videos SDK。

VrLocale 资源库

VrLocale 资源库是一个用于访问本地化字符串表的封装器。该封装器允许将自定义字符串表与 Android 自带的字符串表无缝结合使用。这在本地化内容未嵌入应用程序包本身时非常有用。此资源库依赖于 VrAppFramework。

VrModel 资源库

VrModel 资源库实现了加载 .ovrScene 格式 3D 模型的功能。这些模型可以使用 FbxConverter 实用工具从 .fbx 文件中导出。此资源库依赖于 VrAppFramework 中包含的渲染功能。

VrSound

VrSound 资源库通过 android.media.SoundPool 类实现一个播放声音的简单封装器。此资源库不提供低延迟或 3D 定位音频,仅适用于播放简单的用户界面音效。