You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _posts/2025-01-20-OpenXrCustomEngine.md
+76-9Lines changed: 76 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,19 +2,18 @@
2
2
title: How I implemented OpenXR rendering into a custom engine in C++
3
3
date: 2025-01-20 18:33:00 +/-0100
4
4
categories:
5
-
- Vr
6
-
- Gamedev
5
+
- Programming
6
+
- Virtual-Reality
7
7
tags:
8
8
- cpp
9
9
- openxr
10
10
- opengl
11
-
- programming
12
11
- entt
13
12
description: A blog about how to implement OpenXR rendering into a custom C++ engine.
14
13
toc: true
15
14
---
16
15
# This blog post is unfinished and still a work in progress!
17
-
####Intro
16
+
## Intro
18
17
19
18
I am Justin, a second year student at BUAS and for the past 7 weeks, I have been working on implementing OpenXR into a custom engine made by the lecturers here called "Bee".
20
19
During the process of implementing OpenXR I have learned a lot about not only OpenXR, but also OpenGL, which is the rendering library that Bee uses. Of course, none of this hasn't been without running into many obstacles. In this blog post I will explain how I implemented OpenXR and combined it with the pre-existing Bee library. I will go over what my original plans were, how I got the required scripts to run, how I made the rendering using the OpenXR swapchains combined with OpenGL and much more!
@@ -24,12 +23,12 @@ It is worth keeping in mind that I used my Rift S to test any code that I wrote.
24
23
For those wishing to skip straight to the end and/or take a look at my code, I below will be the entire class. Do keep in mind that there are some variables and functions for OpenXR's input that do not work as of writing this! The files are unfiltered and will likely contain things your project might not.
- Visual Studio (or another environment for programming)
29
-
- VR headset compatible with OpenXR (I used a Rift S for this)
30
-
- An engine in C++ (At the very least, it should be able to open a window and render graphics to a framebuffer, with a rendering function that we can call manually in our script. The framebuffer will also have to be accessible. It also will need to use Entt or you will have to modify the code to remove the Entt parts)
28
+
- VR headset compatible with OpenXR
29
+
- An engine in C++ (At the very least, it should be able to open a window and render graphics to a framebuffer, with a rendering function that we can call manually in our script. The framebuffer will also have to be accessible and the size needs to be able to be set before creation)
31
30
32
-
####First steps
31
+
## First steps
33
32
34
33
So the first step to any project, deciding on what you want to make and setting up some milestones for yourself. These don't always have to be time-bound, but in my case, since this is for school, I have 1 milestone every 2 weeks excluding the first week, so week 3, 5 and 7 all had milestones attached to them.
35
34
For me, the end result was that I wanted to be able to render a scene to my VR headset and be able to move around some physics objects with my hands. I also wanted to add some basic movement, which at the time I hadn't exactly decided on yet, but I did know that simple walking around when moving the thumbstick would be the easiest and thus most likely to be implemented. For being able to use physics, I was going to use the Jolt library, which is a library can deal with the physics calculations.
@@ -58,7 +57,7 @@ Week 7 milestone: Implement controller input and then implement Jolt physics for
58
57
As one might be able to tell, I got stuck on the rendering part for a good while before finally getting it to work properly and I will go into more detail when we get to the rendering step.
59
58
As one can also see, the milestones had changed a lot since when I first started compared to when the project was over. Plans change, stuff like this happens, mostly when researching subjects that one does not have any knowledge of. New things will most likely take a lot of time to do properly and thus, the milestones should evolve over time to better and more accurately reflect one's progress.
60
59
61
-
####Implementing OpenXR
60
+
## Implementing OpenXR
62
61
So, the goals have been set, now to implement the library and get to work!
63
62
Personally, I downloaded the NuGet package with all the libraries. The package is called "OpenXR.Headers" by Khronos Group. I used version 1.0.10.2. Installing this package should also download OpenXR.Loader automatically.
64
63
@@ -93,6 +92,8 @@ Now onto the actual interesting subjects.
93
92
94
93
The header will be explained first.
95
94
95
+
### Includes
96
+
96
97
First the includes. In my header I include the following:
97
98
```cpp
98
99
#pragma once
@@ -118,6 +119,8 @@ First the includes. In my header I include the following:
118
119
119
120
As shown here, I include some basic C++ things like strings and vectors, but also OpenXR and some Glad for math, you are free to use whatever math library you'd like, though you might have to create your own conversion functions to accommodate for this.
120
121
122
+
### Variables
123
+
121
124
After that, we will need a couple of variables, so it should look something like this:
122
125
```cpp
123
126
structDimensions
@@ -231,3 +234,67 @@ private:
231
234
}
232
235
```
233
236
Now we've got some functions to properly set up and use the variables we just created. What these functions do is relatively self-explanatory based on the names of the variables, but we'll get to that soon enough.
237
+
238
+
### Creating the functions
239
+
I will start from the top and work my way through each function, one at a time.
240
+
First, the constructor, it's very short and simple. I call the Initialize() function that will set up everything for OpenXR, after that I create the pointer to my renderer but I also give the renderer the dimensions of my swapchain, this is because the framebuffer that the renderer creates should have the same size as the swapchainImages, since those are the ones that will be displayed to the user. I also use the first element in the array which is the left eye, it does not matter whether element 0 or 1 is used since both will have the same dimensions.
First, the essentials. We create the instance and get the system details, as you can see here, I also have a boolean for result, if at any point, result returns false, something went wrong, we log it, and quit the setup. If your program would require some specific actions to happen if this setup fails, you can modify the constructor to do something if Initialize() returns false.
0 commit comments