2.1 API Version
typedef uint64_t XrVersion;
2.2 String Encoding
所有String字符串都是以NULL终止的UTF-8编码,区分大小写的char arrays.
2.3. Threading Behavior
OpenXR API function必须支持多线程并发调用,要确保多线程下数据的一致性和正确性。
对于所有destroy an object handle的函数,application必须对外同步该object handle参数and any child handles. Eg: xrDestroyInstance
2.4 Multiprocessing Behavior
OpenXR API没有明确说Runtime不能同时支持多进程,也不禁止多进程的支持。
2.5. Runtime
OpenXR runtime是实现OpenXR API的程序。一个系统中可能安装不止一个openXR runtime,但是在任何时间只有一个Runtime处于active。
2.6. Extensions
- OpenXR是一个可扩展的API,可以通过添加new features进行扩展。和其他Khronos APIs类似,extension可以用来expose new OpenXR functions or modify 现有的openXR functions的功能。
- Extensions是可选的,所以必须在扩展功能available之前先由application enabled,而application应该在enable extensions之前调用xrEnumerateInstanceExtensionProperties()查询available list of extensions, 然后在调用xrCreateInstance()时enable指定的extensions。
- OpenXR Extensions Name是唯一的,其格式定义:
- XR_: 前缀来标识它是一个OpenXR extension。
- Vendor tag的字符串标识也是扩展,tag必须是大写字母和十进制数字, eg: KHR, EXT, QCOM, FB
- “_”下划线
- 唯一标识扩展的字符串,它只能使用小写字母和十进制数字,子串之间用“_”连接。Eg: XR_QCOM_tracking_optimization_settings
2.7 API Layers
- OpenXR设计成一个分层的API,用户和application可以在application和Runtime间插入API Layers,通过intercept(拦截)上层函数进而执行不同的操作来提供额外的功能。例如Validation layer,API Logging Layer,API Trace Layer的实现。
- 命名格式:XR_APILAYER_<VENDOR-TAG>_short_name,eg: XR_APILAYER_ACME_check_best_practices
- Enable时序:application应该在enable API layers之前调用 xrEnumerateApiLayerProperties ()查询available list of API Layers, 然后在调用xrCreateInstance()时enable指定的API layers。
2.10. Return Codes
虽然核心API没设计去捕获不正确的使用,但一些情况仍需要return codes。API中的函数通过return code返回他们的状态。
Return code有两类:
- Suceessful completion codes:非负值
- Runtime error code:负值。
typedef enum XrResult {
XR_SUCCESS = 0,
XR_TIMEOUT_EXPIRED = 1,
XR_ERROR_VALIDATION_FAILURE = -1,
XR_ERROR_RUNTIME_FAILURE = -2,
......
}
2.11. Handles
- 由Runtime代表application分配的Objects用handles表示。Handles是Objects的不透明标识,其生命周期由application通过create和destroy function控制。常见的handle Type有XrInstance、XrSession和XrSwapchain。
- 未销毁的handles对于给定的application process是唯一的,但可以在销毁后重新使用。
- 除非特殊说明,一个成功的handle creation function return a new unique handle, 当其父类handle被销毁时,handles会被隐式销毁。如果不再需要该handle, Application可以父handle销毁前显式地destroy the handle,这样可以节约资源。
- 当需要a valid handle时,Runtime检测到XR_NULL_HANDLE和其他无效handle后返回XR_ERROR_HANDLE_INVALID。当一个函数有个可选的handle参数时,如果不能传入a valid handle, 则必须传入XR_NULL_HANDLE。
- Child handle必须在parent handle的有效性和生命周期内。例如要创建一个XrSwapchain handle时,application必须调用xrCreateSwapchain并传递一个XrSeesion的handle,因此XrSwapchain是一个XrSession的child handle。
2.12. Object Handle Types
- 函数中使用的object handle类型通常由函数的规则说明来决定,但是有一些函数的参数或者返回的object handle参数在执行时是未知的,也没有在函数说明中指定类型,对于这些函数,需用XrObjectType来显性指定handle类型。
typedef enum XrObjectType {
XR_OBJECT_TYPE_UNKNOWN = 0,
XR_OBJECT_TYPE_INSTANCE = 1, //对于XrInstance
XR_OBJECT_TYPE_SESSION = 2, //对应XrSession
XR_OBJECT_TYPE_SWAPCHAIN = 3, //对应XrSwapchain
XR_OBJECT_TYPE_SPACE = 4, //对应XrSpace
XR_OBJECT_TYPE_ACTION_SET = 5, //对应XrActionSer
XR_OBJECT_TYPE_ACTION = 6,
XR_OBJECT_TYPE_SPATIAL_ANCHOR_MSFT = 1000039000,
……
}
2.13 Buffer Size Parameters
有输入输出 buffer参数的函数采用参数形式或者结构体形式。
//Parameter form:
XrResult xrFunction(uint32_t elementCapacityInput, uint32_t* elementCountOutput, float* elements);
//Struct form:
XrResult xrFunction(XrBuffer * buffer);
struct XrBuffer {
uint32_t elementCapacityInput;
uint32_t elementCountOutput;
float* elements;
};
2.14 Time
Time不是system clock time,两者不能混为一谈。
typedef int64_t XrTime;
2.15 Duration
Duration是指经过的一段时间,而不是一个绝对的timepoint。两个XrTime间的时间差值是XrDuration,是一个有符号的纳秒(nanoseconds)值。
typedef int64_t XrDuration;
#define XR_NO_DURATION 0 //timeout is immediate
#define XR_INFINITE_DURATION 0x7fffffffffffffffLL //never timeout
2.16 Prediction Time Limits
一些函数涉及到预测,Runtime对forward or backward prediction有不同的限制,对于backward prediction(例如可以插入历史数据),application传入的prediction time相当于最近收到pose timestamp加上最多50ms。
2.17 Color
typedef struct XrColor3f {
float r;
float g;
float b;
} XrColor3f;
typedef struct XrColor4f {
float r;
float g;
float b;
float a;
} XrColor4f;
- 除非特殊说明,每个颜色通道分量的值在0.0~1.0之间。
- XrColor4f::a 表示透明度。
- 对于包含alpha通道的Color,其余r/g/b通道的值都是原值,不是经过alpha分量预乘处理。
2.18 Coordinate System
2D vector定义为XrVector2f struct
typedef struct XrVector2f {
float x;
float y;
} XrVector2f;
XrVector3f
3D vector定位XrVector3f struct
typedef struct XrVector3f {
float x;
float y;
float z;
} XrVector3f;
4D vector定义为XrVector4f struct
typedef struct XrVector4f {
float x;
float y;
float z;
float w;
} XrVector4f;
XrQuaternionf
旋转的单位四元数定义为XrQuaternionf struct
typedef struct XrQuaternionf {
float x;
float y;
float z;
float w;
} XrQuaternionf;
Pose
Pose定义为XrPosef struct
typedef struct XrPosef {
XrQuaternionf orientation;
XrVector3f position;
} XrPosef;
2.19 Common Data Types
Offset
Offset: 用来描述2D中direction and distance
typedef struct XrOffset2Df {
float x;
float y;
} XrOffset2Df;
typedef struct XrOffset2Di {
int32_t x;
int32_t y;
} XrOffset2Di;
- x:x方向上的offset
- 如果表示physical distance,则value的单位必须是米(meter),使用XrOffset2Df。
- 如果表示离散数值,例如texel(texture pixel),使用XrOffset2Di。
Extents
Extents:用来描述2D或者3D中矩形区域的大小。如果表示physical distance,则value的单位必须是米(meter),width, height, depth必须是非负。
-
typedef struct XrExtent2Df { float width; float height; } XrExtent2Df;
typedef struct XrExtent2Di{ int32_t width; int32_t height; } XrExtent2Di;
typedef struct XrExtent3Df { float width; float height; float depth; } XrExtent3Df;
Rectangles
-
Rectangles:用来描述2D中特定的矩形区域,必须包含一个offset和一个extent,两者单位相同。Offset是矩形区域的一个角的位置(通常是左上角),其他三个角可以有该offset和XrExtent2Df::width和height来计算。
typedef struct XrRect2Df {
XrOffset2Df offset;
XrExtent2Df extent;
} XrRect2Df;
typedef struct XrRect2Di {
XrOffset2Di offset;
XrExtent2Di extent;
} XrRect2Di;
Spheref
Spheref:用来描述球体边界的中心和半径。
-
typedef struct XrSpheref { XrPosef center; float radius; } XrSpheref;
center: 表示XrSpace中球体的中心的pose。
-
Radius: 表示球体的半径。如果radius不是valid,Runtime必须返回XR_ERROR_VALIDATION_FAILURE。
XrBox
XrBox:用来描述定向盒子的pose和extent。
typedef struct XrBoxf {
XrPosef center;
XrExtent3Df extents;
} XrBoxf;
- center: 表示XrSpace中定向边界Box的中心Pose。
- Extents: 表示以center为中心的沿定向边界盒每个维度的边到边的距离。
XrFrustumf
XrFrustumf:描述了frustum的pose, FOV和远截面(决定了视椎体的有效深度)。
typedef struct XrFrustumf {
XrPosef pose;
XrFovf fov;
float nearZ;
float farZ;
} XrFrustumf;
- Fov: 表示视椎体的四个侧面的视野角度,angleLeft 和 angleRight 沿着视锥体空间的 X 轴,而 angleUp 和 angleDown 沿着视锥体空间的 Y 轴。
- nearZ: 表示-z轴方向上近截面到视点的距离。
- farZ: 表示-z轴方向上远截面到视点的距离。
2.20 Angles
typedef struct XrFovf {
float angleLeft;
float angleRight;
float angleUp;
float angleDown;
} XrFovf;
- angleLeft: FOV左侧角度,如果是对称的FOV,则该值为负。
- angleRight: FOV右侧角度,如果是对称的FOV,则该值为正。
- angleLeft: FOV上侧角度,如果是对称的FOV,则该值为正。
- angleUp: FOV下侧角度,如果是对称的FOV,则该值为负。
- Angle必须以弧度表示,并且必须完全在-π/2和π/2之间。
- When angleLeft > angleRight, the content of the view must be flipped horizontally.
- When angleDown > angleUp, the content of the view must be flipped vertically.
2.21 Boolean Values
XrBool32的值只能是XR_TRUE或者XR_FALSE
typedef uint32_t XrBool32;
#define XR_TRUE 1
#define XR_FALSE 0
2.22 Event
Event是从Runtime发给application的message。
Event polling
Event在Runtime中是放到队列中。Application必须定期从队列中读取Event,使用xrPollEvent()一次读取一个event。
每种event都由独立的结构体标识,每个结构体都以XrEventDataBaseHeader开头。
typedef struct XrEventDataBaseHeader {
XrStructureType type;
const void* next;
} XrEventDataBaseHeader;
常见的Event
- XrEventDataEventsLost:Event queue溢出或者丢失
- XrEventDataInstanceLossPending:Application即将loss Instance
- XrEventDataInteractionProfileChanged:一个或者多个top level的user path的interaction profile发生变化
- XrEventDataReferenceSpaceChangePending:Runtime更新Space的定义或边界
- XrEventDataSessionStateChanged:application的session的lifecycle state changed
XrEventDataEventsLost结构体定义
typedef struct XrEventDataEventsLost {
XrStructureType type;
const void* next;
uint32_t lostEventCount;
} XrEventDataEventsLost;
- lostEventCount:自上次调用xrPollEvent()后溢出的Event数量
- 收到该结构体的event表明Event队列溢出,队列中该位置的一些events被删除。
xrPollEvent
XrResult xrPollEvent(
XrInstance instance,
XrEventDataBuffer* eventData);
- Event查询:该函数用来查询下一个event,无论是否有可用的event,xrPollEvent都会立即返回。
- Event出队:当xrInstance有效时,event会从队列中出队。
- Event Data填充:返回时eventData会被填充上event’s data和event’s event。
- Event清理(discard):Runtime必须丢弃被destroyed或者invalid的Handles。
- 有效性check:当call xrPollEvent()时Runtime禁止返回包含被destroyed或者invalid的Events。
XrEventDataBuffer结构体定义
typedef struct XrEventDataBuffer {
XrStructureType type;
const void* next;
uint8_t varying[4000];
} XrEventDataBuffer;
2.23 System resource lifetime
在创建openXR handle时,从application传递给Runtime并做为Input的Resource在该Handle有效期内是不能被释放的。
application不应该释放由Runtime创建的Resource,而且在销毁OpenXR handle时application应保持与创建该Handle时相同的引用数。