注:Oculus使用的是开源的hello_xr示例,但要使用自家的loader;在hello_xr上篇侧重分析了入口和图形的基本流程,此篇将侧重分析XR相关的流程
一,Setup and Build hello_xr
1,下载hello_xr官方示例、Oculus的sdk,获取loader
The OpenXR™ Software Development Kit (SDK) Sources Project contains the hello_xr
Oculus不支持标准的openxr的loader,需要下载ovr_openxr_mobile_sdk,取出对应的loader,/OpenXR/Libs/Android/ in SDK package;
修改hello_xr的cmake,将loader替换为Oculus提供的。
download the Oculus OpenXR Mobile SDK Downloads page.
2,修改配置文件,直接引用已下载的loader
replace this line:
option(BUILD_LOADER "Build loader" ON)
with these:
option(BUILD_LOADER "Build loader" OFF)
add_library(openxr_loader SHARED IMPORTED)
set_property(
TARGET
openxr_loader
PROPERTY
IMPORTED_LOCATION
C:/<path_to_Oculus_SDK_folder>/OpenXRMobileSDK/OpenXR/Libs/Android/${
ANDROID_ABI}/${
CMAKE_BUILD_TYPE}/libopenxr_loader.so
)
修改externalNativeBuild
externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_shared',
'-DBUILD_API_LAYERS=OFF',
'-DBUILD_TESTS=ON',
'-DBUILD_LOADER=ON',
'-DBUILD_CONFORMANCE_TESTS=OFF',
'-DBUILD_ALL_EXTENSIONS=ON'
targets "openxr_loader", "hello_xr"
}
}
更新
externalNativeBuild {
ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a'
}
cmake {
cppFlags ''
}
}
- Manifest增加Oculus项
src\tests\hello_xr\AndroidManifest.xml两处
<application>
<meta-data android:name="com.oculus.intent.category.VR" android:value="vr_only"/>
<meta-data android:name="com.oculus.supportedDevices" android:value="quest|quest2"/>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.oculus.intent.category.VR" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
二,重要概念
OpenXR 核心概念和openXR官方文档:
study the OpenXR 1.0 Specification at the Khronos Group site.
更多核心概念参考:spec1.0中Fundamentals部分
The site offers API reference documentation and a PDF reference guide that provides a detailed overview of the API.
Important: To get started with OpenXR core concepts, review Core Concepts and the rest of the topics under this doc set. These cover concepts and examples for:
在此面向应用开发,基于sample和框架的分析,review一些重要概念和流程
1 系统System
XR系统中定义了各种子系统,提供特定领域的功能,并有设备和硬件各子模块来实现,比如我们可以通过各个独立的设备获取不同的input输入、display frames显示等等;
——参考unity的XR plugin systems架构,即可理解unity的这一设计背景。
这些设备和模块在XR系统加载起来后,由运行时runtime来控制其激活和响应;
——参考unity新input action system,可理解这一软硬件解耦的框架。
2 对象概念和原子定义Handles and Atoms
Handles概念
代表运行时中的各object,有相应的创建销毁声明周期行为,应用可以调用对应的方法进行控制;这些对象在创建后,形成 父子管理 结构(也可以理解为 容器管理 结构),父级Handle往往管理子级的声明周期;
比如
要创建XrActionSet (handle),调用xrCreateActionSet 方法,传入XrInstance (handle)参数,那么XrInstance 就是 XrActionSet 的父级句柄,持有着ActionSet对象;
要销毁 XrSession, XrSpace and XrSwapchain各子级对象都会被一同销毁;
应用中几个重要的句柄类型如下:
Handle type |
Description |
XrInstance |
Enables apps to use the OpenXR runtime. These handles are the only ones without a parent. |
XrSession |
Enables interaction with a specific XR device, allows for user input, rendering, managing events, and more. Generally, it is a graphics interaction with a particular XrSystem using a particular graphics binding. |
XrAction |
Refers to individual actions when retrieving input data or sending haptic events. Apps receive input action states without directly receiving input from the hardware. |
XrActionSet |
Refers to groups of actions that are valid in a certain context (for example, all actions to interact with a menu UI). Action sets can be enabled or disabled. |
XrSwapchain |
Manages display of rendered images as a series of frame buffers. Images can be organized in multiple swapchains (queues of images to be displayed to the user). |
XrSpace |
Represents spaces that the app can reason about through xrLocateSpace. |
OpenXR extensions通过创建新的handle对象,及其struct和functions来定义和扩展更多的api。
atoms 概念
定义为静态常量,在运行时中预定义了相关的数值,代表了对象无关的特征,比如XrPath and XrSystemID;
XrPath (atom)本质上是一个固定的数值,指向一个string,即语义化的设备路径如“/interaction_profiles/oculus/touch_controller”;XrSystemID制定了支持OpenXR的子系统的id;
3 传参封装structs和struct-chaining extension
openXR方法大量使用struct的结构传参,有更好的封装和扩展性,使得新的extension扩展可以增加新的参数而不影响原来的api;
另一个特性就是对extension扩展使用的struct成员构建了参数指针链,要求是扩展的这部分extension必须在创建instance时使能enable:
In order to use a structure type defined by an extension in a next chain, the proper extension must have been previously enabled during xrCreateInstance
Read-only的 struct pointer chain常常定义为
typedef struct XrBaseInStructure {
XrStructureType type;
const struct XrBaseInStructure* next;
} XrBaseInStructure;
例如:xrCreateInstance 调用时,传入的参数结构体:
typedef struct XrInstanc