Skip to content

Commit

Permalink
Messy hacks, but actually working with SteamVR on linux, at least.
Browse files Browse the repository at this point in the history
  • Loading branch information
ixchow committed Nov 8, 2023
1 parent 1459b08 commit 1eedd1b
Show file tree
Hide file tree
Showing 8 changed files with 1,764 additions and 72 deletions.
11 changes: 8 additions & 3 deletions Maekfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const maek = init_maek();
//======================================================================

const NEST_LIBS = `../nest-libs/${maek.OS}`;
const OPENXR_SDK = `../openxr-sdk-source`;
const OPENXR_SDK = `../openxr-sdk`;

//set compile flags (these can also be overridden per-task using the "options" parameter):
if (maek.OS === "windows") {
Expand Down Expand Up @@ -58,7 +58,8 @@ if (maek.OS === "windows") {
//linker flags for nest libraries:
`-L${NEST_LIBS}/SDL2/lib`, `-lSDL2`, `-lm`, `-ldl`, `-lasound`, `-lpthread`, `-lX11`, `-lXext`, `-lpthread`, `-lrt`, `-lGL`, //the output of sdl-config --static-libs
`-L${NEST_LIBS}/libpng/lib`, `-lpng`,
`-L${NEST_LIBS}/zlib/lib`, `-lz`
`-L${NEST_LIBS}/zlib/lib`, `-lz`,
`-L${OPENXR_SDK}/build/linux/src/loader`, `-lopenxr_loader`,
);
} else if (maek.OS === "macos") {
maek.options.CPPFlags.push(
Expand Down Expand Up @@ -87,6 +88,9 @@ let copies = [
if (maek.OS === 'windows') {
copies.push( maek.COPY(`${NEST_LIBS}/SDL2/dist/SDL2.dll`, `dist/SDL2.dll`) );
}
if (maek.OS === 'linux') {
copies.push( maek.COPY(`${OPENXR_SDK}/build/linux/src/loader/libopenxr_loader.so.1`, `dist/libopenxr_loader.so.1`) );
}

//call rules on the maek object to specify tasks.
// rules generally look like:
Expand All @@ -99,8 +103,9 @@ if (maek.OS === 'windows') {
const game_names = [
maek.CPP('PlayMode.cpp'),
maek.CPP('main.cpp'),
maek.CPP('LitColorTextureProgram.cpp')
maek.CPP('LitColorTextureProgram.cpp'),
//, maek.CPP('ColorTextureProgram.cpp') //not used right now, but you might want it
maek.CPP('XR.cpp')
];

const common_names = [
Expand Down
77 changes: 65 additions & 12 deletions PlayMode.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "PlayMode.hpp"
#include "XR.hpp"
#include "xr_linear.h" //for projection matrix building helper

#include "LitColorTextureProgram.hpp"

Expand All @@ -9,6 +11,7 @@
#include "data_path.hpp"

#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/string_cast.hpp>

#include <random>

Expand Down Expand Up @@ -168,9 +171,9 @@ void PlayMode::update(float elapsed) {
}

void PlayMode::draw(glm::uvec2 const &drawable_size) {
//update camera aspect ratio for drawable:
//update window's camera aspect ratio for drawable:
camera->aspect = float(drawable_size.x) / float(drawable_size.y);

//set up light type and position for lit_color_texture_program:
// TODO: consider using the Light(s) in the scene to do this
glUseProgram(lit_color_texture_program->program);
Expand All @@ -179,16 +182,8 @@ void PlayMode::draw(glm::uvec2 const &drawable_size) {
glUniform3fv(lit_color_texture_program->LIGHT_ENERGY_vec3, 1, glm::value_ptr(glm::vec3(1.0f, 1.0f, 0.95f)));
glUseProgram(0);

glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClearDepth(1.0f); //1.0 is actually the default value to clear the depth buffer to, but FYI you can change it.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS); //this is the default depth comparison function, but FYI you can change it.

GL_ERRORS(); //print any errors produced by this setup code

scene.draw(*camera);
//main scene drawing into the window:
draw_helper(camera->make_projection() * glm::mat4(camera->transform->make_world_to_local()));

{ //use DrawLines to overlay some text:
glDisable(GL_DEPTH_TEST);
Expand All @@ -211,4 +206,62 @@ void PlayMode::draw(glm::uvec2 const &drawable_size) {
glm::vec3(H, 0.0f, 0.0f), glm::vec3(0.0f, H, 0.0f),
glm::u8vec4(0xff, 0xff, 0xff, 0x00));
}

//----------------------------------------------

if (xr && xr->next_frame.should_render) {
//set up a transform representing the stage's position in the world:
// NOTE: state's "up" direction is +Y.
Scene::Transform stage;
stage.rotation = glm::quat_cast(glm::mat3(
glm::vec3(1.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 0.0f, 1.0f),
glm::vec3(0.0f,-1.0f, 0.0f)
));
stage.position = glm::vec3(0.0f, 0.0f, 0.0f); //just center up for now
stage.scale = glm::vec3(10.0f); //let's make the player large!

for (auto const &view : xr->views) {
if (!view.current_framebuffer) continue; //weird bug but nothing to do, I guess

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, view.current_framebuffer->fb);
glViewport(0, 0, xr->size.x, xr->size.y);

XrMatrix4x4f xr_proj;
XrMatrix4x4f_CreateProjectionFov(&xr_proj, GRAPHICS_OPENGL, view.fov, 0.1f, 0.0f);

glm::mat4 proj = glm::mat4(
xr_proj.m[0], xr_proj.m[1], xr_proj.m[2], xr_proj.m[3],
xr_proj.m[4], xr_proj.m[5], xr_proj.m[6], xr_proj.m[7],
xr_proj.m[8], xr_proj.m[9], xr_proj.m[10], xr_proj.m[11],
xr_proj.m[12], xr_proj.m[13], xr_proj.m[14], xr_proj.m[15]
);

Scene::Transform at;
at.parent = &stage;
at.position = glm::vec3(view.pose.position.x, view.pose.position.y, view.pose.position.z);
at.rotation = glm::quat(view.pose.orientation.w, view.pose.orientation.x, view.pose.orientation.y, view.pose.orientation.z);

draw_helper(proj * glm::mat4(at.make_world_to_local()));

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glViewport(0, 0, drawable_size.x, drawable_size.y);
}
}


}
void PlayMode::draw_helper(glm::mat4 const &world_to_clip) {

glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClearDepth(1.0f); //1.0 is actually the default value to clear the depth buffer to, but FYI you can change it.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS); //this is the default depth comparison function, but FYI you can change it.

GL_ERRORS(); //print any errors produced by this setup code

scene.draw(world_to_clip);

}
3 changes: 3 additions & 0 deletions PlayMode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ struct PlayMode : Mode {
virtual void update(float elapsed) override;
virtual void draw(glm::uvec2 const &drawable_size) override;

//draw_helper called to draw both into game window and into VR views:
void draw_helper(glm::mat4 const &world_to_clip);

//----- game state -----

//input tracking:
Expand Down
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,40 @@ $ cd ovr-openxr-sdk
$ unzip ../downloads/ovr_openxr_mobile_sdk_57.0.zip #current version as of this writing
```

For **desktop** VR use, grab Khronos's OpenXR loader: (see the README.md for more build info; like non-linux build instructions, required packages to install)
```
$ git clone https://github.com/KhronosGroup/OpenXR-SDK openxr-sdk
$ cd openxr-sdk
$ mkdir -p build/linux
$ cd build/linux
$ cmake -DDYNAMIC_LOADER=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo ../..
```

Once all of that is done you should have these three as siblings:
```
15466-f23-ndk-openxr #this folder
android-sdk #android sdk, tools, etc
ovr-openxr-sdk #Meta's OpenXR SDK stuff
openxr-sdk #Knrono's OpenXR SDK (optional; for desktop use)
```

### SteamVR Linux Notes

Getting "failed to determine active runtime file path for this environment":

```
$ mkdir -p .config/openxr/1
$ ln -sf ~/.steam/steam/steamapps/common/SteamVR/steamxr_linux64.json ~/.config/openxr/1/active_runtime.json
```

Or you can just:
```
$ XR_RUNTIME_JSON=~/.steam/steam/steamapps/common/SteamVR/steamxr_linux64.json ./dist/game
```
(As per https://community.khronos.org/t/openxr-loader-how-to-select-runtime/108524)


I found that opening SteamVR, then closing SteamVR but leaving steam open resulted in OpenXR calls succeeding. But not having steam open at all or having steamvr open both resulted in CreateInstance failing.

### Hardware

Expand All @@ -76,5 +104,9 @@ $ ./platform-tools/adb shell

## Building


...


## OpenXR Notes


Loading

0 comments on commit 1eedd1b

Please sign in to comment.