3D プログラミングで desktop(glfw), android(OpenXR) で描画を共用にできないか模索している。

言語は zig を使うことは決定していて、先日 0.15.1 が Release された。 なので、 c (のABI) は大いに使うのだが c++ 要素はなるべくさけようとしている( zig cc のクロスビルドでトラブルになりやすい)。

GPU API は vulkan を採用することでいけそうと目途がついていた。 OpenGLと比べてビルドは簡単、ソースコードは大変。 描画を vulkan で GPU との接続を Windows11 上の glfw 、Android の NativeActivity さらに、 Windows11 上の OpenXR と Android 上の OpenXR 、Linux の OpenXR (WiVRn) でビルドと実行ができた。

ついでにWASM にも同じシーンを展開できるようにしたい。 vulkan には web api は無いので WebGpu でできるか試していたのだけど、統合するのは難しそうだった。ラップするのに手間が増えすぎる。

ここで GPU API をラップする sokol を思い出し、 sokol なら WASM が確実にできるので、 OpenXR から sokol を使う路線を検討。 OpenXR の backend に sokol を使って、 sokol の backend は d3d11 や OpenGLES にする。 vulkan を使うことは諦める。

cross platform

どうも platform は OS レベルでは無くて、 OS + WindowSystem + GPU API で切り分けるのがよさそうだ。 ソースレベルの依存性などのビルドの都合を考慮すると以下のように組み合わせの問題になる。

oswindow systemGPUnote
Windows11sokol-appd3d11sokol default
Windows11glfwOpenGL4
Windows11glfwvulkan
Windows11OpenXROpenGL4
Windows11OpenXRd3d11
androidNativeActivitygles3
androidNativeActivityvulkan
androidNativeActivity sokol-appgles3
Quest3NativeActivity OpenXRgles3
Quest3NativeActivity OpenXRvulkan
WASMsokol-appwebgl
Linux waylandOpenXRWiVRn

OpenXR は WindowSystem レイヤーなのだ。 これに真面目に対応しようとすると、window-system と gpu の組み合わせに対応する必要が出てくる。 実際に openxr-sdk-source の hello_xr では、Platform(windows, linux, android, osx) X Graphics(d3d11, d3d12, opengl, opengles, vulkan, metal) という組み合わせに対応する設計になっている。 ビルド時に Platform を分岐して、Runtime に Graphics を分岐する。

https://github.com/KhronosGroup/OpenXR-SDK-Source/tree/main/src/tests/hello_xr

で、以下のように GPU を sokol 一種類にまとめることで、ほどほどの手間でクロスプラットフォームできようというわけです。

oswindow systemGPU APInote
Windows11sokol-appsokol
Windows11glfwsokol
Windows11OpenXRsokol
androidNativeActivitysokol
androidNativeActivity sokol-appsokol
Quest3NativeActivity OpenXRsokol
WASMsokol-appsokol

sokol-xr

hello_xr をベースに WindowsDesktop(quest link) と Android(apk) で、 同じ sokol レンダラーを動かす実験中。

https://github.com/ousttrue/sokol-xr