Skip to content

Commit f6bd580

Browse files
committed
readme / new feature updates, controls, and a sample log
1 parent cbd71c7 commit f6bd580

File tree

3 files changed

+1314
-29
lines changed

3 files changed

+1314
-29
lines changed

Controls.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
## Note:
2+
3+
The input management code is pretty great™️and cross-platform, but this project was only tested on:
4+
- old Oculus Rift CV1 (the 1.0 from 2016, not the Rift S)
5+
- Valve Index (but on an older version of this project, in 2023)
6+
- aethervr (openxr virtual headset) https://github.com/chnoblouch/aethervr
7+
8+
(Pls comment on this project if you test it on anything else / start an issue.)
9+
10+
## Glossary:
11+
- Grips: the paddle or palm pressure sensor on your controller handle (not the index finger trigger).
12+
- Thumbsticks: whatever joystick you may have on your controller(s). Alternatively a touchpad may work (not tested).
13+
- Tap: (~fully) press and release something. E.g. squeeze a grip and then also let go.
14+
- Press: action triggers when (and possibly also while) the button / trigger is pressed down.
15+
16+
## In-game controls:
17+
18+
### Locomotion:
19+
- Squeeze both Grips to enter the chaperone and locomotion mode: you'll be able to move & rotate the world as if you had grabbed it (as if it was a 3D object you grabbed with both hands). The speed is mildly accelerated with your hand speed.
20+
- If you do the above but while also pushing any Thumbstick, it will act as a boost of up to 4x speed: up to 2x from one hand (via Thumbstick tilt, direction doesn't matter), and up to 2x + 2x from holding both Thumbsticks at the same time.
21+
- press X and A simultaneously (or A and A or Select and Select or Menu and Menu (first button on each controller)) to teleport back to world x: 0, z: 0, (and y: 0) (y is up). This only resets the offset created by the locomotion system, and not also how much you physically walked in your room irl.
22+
23+
### Equipment:
24+
- Tap a Grip (not both grips at the same time) to spawn (toggle) a "beam katana" in your hand: this is a tube light. You can have 2 active at the same time.
25+
26+
### Misc:
27+
- NOTE: because of a known bug with Openxr input and Oculus Rift CV1 specifically, I disabled the trigger input completely, in Input.cpp, and I didn't use triggers for anything.
28+
29+
30+

Readme.md

Lines changed: 105 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,130 @@
11
# TL;DR:
2-
Ready to play performant open source XR with OpenXR / Vulkan / C++.
2+
Performant open-source OpenXR, Vulkan, C++.
3+
A boilerplate / engine to quickly make an actual playable modern royalty-free XR game.
34

4-
\[[my github blog where you can also comment](https://blog.deferredreality.com/openxr-vulkan-c++-gamedev-boilerplate/)\]
5+
Demystifies ECS / Memory Management, Single Pass Rendering, XR Input, and XR gamedev fundamentals, on top of @janhsimon's excellent timesaving khronos setup [openxr-vulkan-example](https://github.com/janhsimon/openxr-vulkan-example).
56

6-
Demystifying Single Pass Rendering, XR Input, and XR gamedev fundamentals, on top of @janhsimon's excellent timesaving openxr-vulkan-example.
7+
\[Note: [you can leave github comments over on my blog post version 😉](https://blog.deferredreality.com/openxr-vulkan-c++-gamedev-boilerplate/)\]
78

8-
A boilerplate / engine starter set. Actually just make an XR game quickly.
9+
<figure class="half">
10+
<video playsinline="" muted="" controls="" autoplay="" loop="" class="" style="">
11+
<source src="https://www.deferredreality.com/images/snowglobe_openxr_vulkan_framework_30crf_800x800_github.webm" type="video/webm">
12+
Your browser does not support the video tag.
13+
</video>
14+
<figcaption>Demo video, summer 2025.</figcaption>
15+
</figure>
916

10-
![Teaser2](teaser2.gif)
17+
There's also a [1600x1600 youtube version](https://www.youtube.com/user/thistudor/featured).
1118

1219
# Abstract:
13-
\*Trey Parker voice\* Vulkan has a rich body of work, and many strengths as a people; but their impaired emotion and empathy makes them hard to understand by hu-mans. I've managed to translate their stack, for hu-mans, whose lifetimes may otherwise be too short to first decipher the khronos lunar manuals for hope of achieving even the most basic useful contact.
20+
\*Trey Parker voice\* Vulkan has a rich body of work, and many strengths as a people; but lack hoo-man compatibility. I've managed to translate their stack, for hoo-mans, whose lifetimes may otherwise be too short to first decipher the khronos lunar manuals for hope of achieving even the most basic useful contact.
1421

15-
(PS: it didn't help that OpenXR Single-Pass rendering (the performant & industry-standard linchpin of rendering) was like the only thing they [didn't want to cover](https://community.khronos.org/t/what-is-the-right-way-to-implement-single-pass-rendering-with-openxr/109157/9).)
22+
It didn't help that [they don't want to touch](https://community.khronos.org/t/what-is-the-right-way-to-implement-single-pass-rendering-with-openxr/109157/9) Single-Pass rendering (the performant & industry-standard linchpin of rendering).
23+
24+
You can now build something pretty good the right way, without worrying about mighty morphing license agreements or wetting the beaks of people with golden parachutes.
1625

1726
## To set up and build:
1827
- See [Build-ProjectSetup.Readme.md](blob/main/Build-ProjectSetup.Readme.md) or just be lazy and run the windows build in `./out/`
1928

29+
## Controls:
30+
31+
- [Controls.md](blob/main/Controls.md)
32+
2033
# My feature stack so far:
2134

35+
(sections ordered from high-level to low-level)
36+
2237
## XR Locomotion
23-
- Mode: Rotating and accelerated Panning the scene by grabbing with both hands, and seeing a "tunnelvision style chaperone".
24-
- Use state machines for movment and for visuals.
38+
- Rotating and (accelerated) Panning of the scene by grabbing with both hands, retreating into a non-euclideanly warped pocket dimension (pushing the world away from you non-linearly) and seeing a "tunnelvision" portal-style chaperone. Highest effectiveness and lowest sickness (carefully tweaked and tested across dozens of different people).
39+
- Uses state machines for movment and for visuals. Supports animated teleportation with targets.
2540

2641
## Base XR gameplay mechanics
27-
- Mechanics system based on a list of `GameBehaviour`'s set up as FSMs.
42+
- Mechanics system based on a list of `GameBehaviour`s set up as FSMs.
2843
- Each behaviour is Created (with its own required references), Updated (with frame & input data etc), and Destroyed.
29-
- Sample mechanics for locomotion, hands, XR Input testing, world objects.
44+
- Mechanics for locomotion, hands, XR Input testing, world objects.
45+
- Any `GameComponent` has one or more `GameEntity` parents and manual or automatic cleanup (and preventing dangling components when all owners are freed). But there's no parenting between different game entities / objects, so manipulate groups of matrixes yourself. `TODO:` add a parenting system that processes the chain of Transform matrixes.
46+
47+
## Physics
48+
- There's support for running jobs on `Bounds` components (generated at model load time), with proper functions for AABB intersection or enclosure tests, plane tests, rectangular selection (even at non-Axis-Aligned angles) / frustum casting, raycasting.
49+
- There's a concept of ground in the locomotion system.
50+
- But `TODO:` no actual Physics library added.
51+
52+
## Animation
53+
- \*crickets\* `TODO:` just add it via full/extended gltf support.
54+
- `TODO:` find something open-source for: IK, gpu-skinning, and LoDs.
55+
56+
## Audio
57+
- \*crickets\* `TODO:` add Audio component, and threaded spatial sound library with audio queueing.
58+
59+
## GUI
60+
- \*crickets\* `TODO:` vector or sdf text, and just textures. Then use previously made ui code.
61+
- `TODO:` main menu, in-game hands inventory
62+
- (I'm certainly not implementing a scene-graph management system (game editor))
63+
64+
## Jobs / Threading
65+
- The objects and memory is set up in a spanned ECS manner but `TODO:` no job system / threading example (there's only sequentially updated `GameBehaviour`s / state machines on the main thread).
66+
- `TODO:` add a simple chunking concept, run jobs in parallel on chunks.
3067

3168
## GameData
32-
- `GameObject`'s{`Material`, `Model`, Properties (e.g. `worldMatrix`, `isVisible`)}.
33-
- `PlayerObject`'s{`GameObject`'s, `PlayerActiveStates`}.
34-
- `Material`'s{`Shader`, Descriptor-set `UniformData`, optional/shared `Pipeline` (for e.g blend ops)}
69+
- Everything is set in generic memory-span pools, by type. You set up a game world with maximum allocated memory for each pool, then during gameplay you can request to use a free object, or mark a used one as free and reusable. There's no need for defragmenting, or swap-and-pop (would be slower in average-case) ("ted talk" in `GameDataPool.h`).
70+
- Enities and components are based on `GameDataId` (serving as a weak reference): `[globalUIDSeed][index][version]` and a top-level `[typeIndex]` for convenience.
71+
- Everything is easy to request and keep track of through various means, even by name in hash maps for light scripting purposes.
72+
- Cleanup is either manual (and cache coherent) or automated via (cache-missing) awareness of component dependencies.
73+
- `GameEntity` and `GameEntityObject`
74+
- `GameComponent`: `Material`, `Model`, `Transform`, `Bounds`, `Light`.
75+
- Properties: `isVisible`, `isEnabled`, `name`, some events etc.
76+
- `PlayerObject`s {`GameEntityObject`s, `PlayerActiveStates`}.
77+
- `Material`s {`Shader`, Descriptor-set `UniformData`, instancing, optional/shared `Pipeline` (for e.g blend ops)}
3578

3679
## Rendering
37-
- Eplained and expanded Khronos' & Janhsimon's Headset & Context classes, and the Renderer/pipeline, the easily confusing & hard to customize khronos vulkan + openxr implementation. Especially regarding multipass vs singlepass & multiview, and what it takes if you want to use your own renderer or a diffrent API like `webgpu`. (look for `"// [tdbe]" `)
38-
- Per-material, per-model, per-pipeline properties. Easily create a material e.g. transparent, doublesided; add uniforms / new `shaders` etc.
39-
- Render pipeline knows if you modified any default properties in materials and in that case creates unique mats/pipelines.
40-
41-
## `Input` class and `InputData`'s in `Inputspace`.
42-
- A 'proper' universal xr input class, supporting (probably) all controllers/headsetss, with customizable binding paths and action sets.
43-
- nicely accessible data through `InputData` and `InputHaptics`, including matrixes and other tracked XR positional data.
44-
- poses for controllers and for head.
45-
- actions (buttons, sticks, triggers, pressure, proximity etc).
46-
- user presence / headset activity state.
47-
- haptic feedback output.
48-
- exposes action state data (e.g. lastChangeTime, isActive, changedSinceLastSync)
80+
- Implemented the most high quality e.g. Disney BRDF lighting equations for diffuse, specular and MRP based (Most Representative Point) shape lights.
81+
- `TODO:` does not include clearcoat.
82+
- `TODO:` does not include subsurface scattering,
83+
- `TODO:` does not include shadows,
84+
- `TODO:` no per-pixel transparent object sorting,
85+
- ^, ^^, ^^^: but, I'll someday add in raytracing into some form of nanite clumps or other semi-volumetric discrete mesh data, instead of going through the legacy shading/sorting timesinks again.
86+
- Per-material, per-model, per-pipeline properties. Easily create a material e.g. transparent, doublesided; add new `shaders` with all the static and dynamic uniform data you need, instance geometry etc.
87+
- Render pipeline knows if you modified any default properties and creates pipelines from unique materials. Tries its best to batch per unique material and per model to minimise GPU-CPU communication, and has instancing, but it's not Indirect Rendering.
88+
- Expanded, added to, and explained Khronos' & JanhSimon's `Headset`, `Context`, `Renderer`/`Pipeline` etc, and the easily misleading & hard to customize khronos vulkan <-> openxr implementation. Especially regarding multipass vs singlepass & multiview, and what it takes if you want to use your own renderer or a diffrent API like `webgpu`. (look for `"// [tdbe]" `)
89+
90+
## `Input` class and `InputData`.
91+
- A 'proper' universal xr input class, supporting (probably) all controllers/headsets, with customizable binding paths and action sets.
92+
- Nicely accessible data through `InputData` and `InputHaptics`, including matrixes and other tracked XR positional data.
93+
- Poses for controllers and for head.
94+
- Actions (buttons, sticks, triggers, pressure, proximity etc).
95+
- User presence / headset activity state.
96+
- Haptic feedback output.
97+
- Exposes action state data (e.g. `lastChangeTime`, `isActive`, c`hangedSinceLastSync`)
4998

5099
## Utils
51-
- Some Utils and math for XR, input, and extra gamedev stuff.
100+
- Utils and math for XR, input, general gamedev.
101+
- Debugging.
102+
- `TODO:` Bring in gizmos, e.g. debug lines, wireframes for lights etc.
103+
104+
105+
## A typical run log:
106+
107+
- Game world load, setup, updates & render loops, unload and exit. [TypicalRunLogSample.md](blob/main/TypicalRunLogSample.md)
108+
109+
# Additional Attributions
110+
111+
| Asset | Title | Author | License |
112+
| --- | --- | --- | --- |
113+
| `models/SuzanneHighQuality20k.obj` | [Suzanne](https://github.com/alecjacobson/common-3d-test-models) | [Blender](https://en.wikipedia.org/wiki/List_of_common_3D_test_models) (but mesh smoothed and subdivided by [tdbe](https://github.com/tdbe/)) | [GNU GPL 2+](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) |
114+
| `models/SudaBeam.obj` | [SudaBeam](https://duckduckgo.com/?q=beam+katana+suda+no+more+heroes&t=ffab&ia=images&iax=images) | [tdbe](https://github.com/tdbe/), a simplified version of Suda 51's parody of a light saber | [GNU GPL 3+](https://www.gnu.org/licenses/gpl-3.0.en.html) |
115+
| `models/Squid_Happy_Grumpy.obj` | Happy Grumpy Squid | [tdbe](https://github.com/tdbe/) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) |
116+
| `models/ground_displaced_*.obj` | demo ground | [tdbe](https://github.com/tdbe/) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) |
117+
| `models/icosphere_*.obj` | utility (ico)spheres | [tdbe](https://github.com/tdbe/) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) |
118+
| `models/quad_*.obj` | utility quad | [tdbe](https://github.com/tdbe/) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) |
119+
| `models/capsule_*.obj` | utility capsule | [tdbe](https://github.com/tdbe/) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) |
120+
| `models/text_*.obj` | various texts | [tdbe](https://github.com/tdbe/) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) |
121+
122+
123+
124+
125+
-------------------------------
126+
127+
52128

53129
-------------------------------
54130

@@ -75,14 +151,14 @@ Integrating both OpenXR and Vulkan yourself can be a daunting and painfully time
75151
2. Reference the code while writing your own implementation from scratch, to help you out if you are stuck with a problem, or simply for inspiration.
76152

77153

78-
# Running the OpenXR Vulkan Example
154+
# Running the OpenXR Vulkan Framework
79155

80156
1. Download the latest [release](https://github.com/janhsimon/openxr-vulkan-example/releases) or build the project yourself with the steps below.
81157
2. Make sure your headset is connected to your computer.
82158
3. Run the program!
83159

84160

85-
# Building the OpenXR Vulkan Example
161+
# Building the OpenXR Vulkan Framework
86162

87163
1. Install the [Vulkan SDK](https://vulkan.lunarg.com) version 1.3 or newer.
88164
2. Install [CMake](https://cmake.org/download) version 3.1 or newer.

0 commit comments

Comments
 (0)