This is an odin script to generate OpenXR bindings from the OpenXR xml registry. The generator
is in a single file generator.odin
, and generates a set of bindings into the directory openxr
.
The style of the bindings is intended to follow that of vendor:vulkan
, since that's taken to be
the canonical example of "Khronos API bindings in Odin".
There were some old OpenXR bindings kicking around but they changed all the procs to snake case,
and didn't handle function pointer loading correctly at all, so I decided to make my own from scratch.
If these prove stable, the goal is eventually to PR these into vendor
.
I have vendored a prebuilt copy of the openxr_loader.lib
for windows. If you want to use these
bindings on windows, it should be enough for you to simply copy that folder into your project and
invoke the appropriate import statement in your odin source file.
import xr "openxr"
The only statically linked symbol is xrGetInstanceProcAddr
, everything else must be dynamically loaded.
I provide two helpers, xr.load_base_procs
which will load:
xrCreateInstance
xrEnumerateApiLayerProperties
xrEnumerateInstanceExtensionProperties
and xr.load_instance_procs
which takes an instance and will attempt to load every other function pointer,
including any from requested extensions. If you do not request an extension and proceed to attempt to call
a procedure from that extension, you will likely dereference a null pointer and crash.
I also provide an odin helper xr.make_string
, which can be used to create inline string buffers that are
used in the API. Example usage is provided below.
Example init code might look like:
package xr_example
import xr "openxr"
main :: proc() {
// Load base procedures
xr.load_base_procs()
// Create OpenXR Instance
application_info := xr.ApplicationInfo {
apiVersion = xr.MAKE_VERSION(1, 0, 25),
applicationName = xr.make_string("Example Application", 128),
applicationVersion = 1,
engineName = xr.make_string("Example Engine", 128),
engineVersion = 1,
}
instance_info := xr.InstanceCreateInfo {
sType = .INSTANCE_CREATE_INFO,
applicationInfo = application_info,
}
instance: xr.Instance
err := xr.CreateInstance(&instance_info, &instance)
if err != .SUCCESS {
panic("failed to create XR instance")
}
defer xr.DestroyInstance(instance)
// Load instance procedures
xr.load_instance_procs(instance)
// Continue setting up OpenXR
// ...
}
These bindings are not complete. Specifically, I do not generate the following structs:
XrGraphicsBindingOpenGLXlibKHR
XrGraphicsBindingOpenGLXcbKHR
XrGraphicsBindingOpenGLWaylandKHR
XrGraphicsBindingOpenGLESAndroidKHR
XrGraphicsBindingEGLMNDX
Because the odin core
packages do not have the required types and I didn't want to be opinionated about these
platforms. D3D11
, D3D12
and Vulkan
graphics bindings structs are generated, so you can still target Linux,
just not on OpenGL (and you'll need to BYO libopenxr_loader.so.1
)
These bindings are not guaranteed correct nor stable. I have just gotten the generator working end to end and have no idea where I've made any errors. I will be using them to write my own OpenXR driver code and will be able to give a more confident estimate of their correctness once I've used them.
You're welcome to use them, but don't expect them to be fully correct.
To ensure xr.xml
(retrieved from https://github.com/KhronosGroup/OpenXR-SDK/blob/main/specification/registry/xr.xml)
can be parsed by core:encoding/xml
, then following hand edits were made:
- Lines 2-4 inclusive were commented out
- Elements with attribute values multiple lines (typically long descriptions) were collapsed onto single lines
The binaries generated by vcpkg
/ OpenXR-SDK
cmake have issues relating to linking of CRT etc. which make
them unsuitable for linking into an odin binary. The one vendored here is loosely based off the vcpkg patch at
https://github.com/LibreVR/Revive/blob/master/fix-vcpkg-openxr-static-loader.patch.