OpenXR 超详细spec--Chapter 2 基本原理

本文详细介绍了OpenXR技术中的关键组件,包括运行时的激活、可扩展性(通过extensions)、API分层设计、返回代码的使用以及对象句柄类型,展示了OpenXR如何通过这些特性提供灵活和扩展的功能实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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是唯一的,其格式定义: 
  1. XR_: 前缀来标识它是一OpenXR extension
  2. Vendor tag的字符串标识也是扩展,tag必须是大写字母和十进制数字, eg: KHR, EXT, QCOM, FB
  3. _”下划线
  4. 唯一标识扩展的字符串,它只能使用小写字母和十进制数字,子串之间用“_”连接Eg: XR_QCOM_tracking_optimization_settings

2.7 API Layers

  • OpenXR设计成一个分层的API,用户和application可以在applicationRuntime间插入API Layers,通过intercept(拦截)上层函数进而执行不同的操作来提供额外的功能。例如Validation layerAPI Logging LayerAPI Trace Layer的实现。
  • 命名格式:XR_APILAYER_<VENDOR-TAG>_short_nameeg: 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分配的Objectshandles表示。HandlesObjects的不透明标识,其生命周期由application通过createdestroy function控制。常见的handle TypeXrInstanceXrSessionXrSwapchain
  • 未销毁的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并传递一个XrSeesionhandle,因此XrSwapchain是一个XrSessionchild 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

一些函数涉及到预测,Runtimeforward 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: 用来描述2Ddirection 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是矩形区域的一个角的位置(通常是左上角),其他三个角可以有该offsetXrExtent2Df::widthheight来计算。

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:用来描述定向盒子的poseextent

typedef struct XrBoxf {
    XrPosef        center;
    XrExtent3Df    extents;
} XrBoxf;
  • center: 表示XrSpace中定向边界Box的中心Pose。
  • Extents: 表示以center为中心的沿定向边界盒每个维度的边到边的距离。

XrFrustumf

XrFrustumf描述了frustumpose, 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发给applicationmessage

Event polling

EventRuntime中是放到队列中。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并做为InputResource在该Handle有效期内是不能被释放的。

application不应该释放由Runtime创建的Resource,而且在销毁OpenXR handleapplication应保持与创建该Handle时相同的引用数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值