feat: ✨ Add Lynx headset support (#1823)
* feat: ✨ Add Lynx headset support
* Disable srgb correction
This commit is contained in:
parent
2e928913b3
commit
057fce4acc
|
@ -15,6 +15,7 @@ This is a fork of [ALVR](https://github.com/polygraphene/ALVR).
|
|||
| Pico 4/Neo 3 | :heavy_check_mark: |
|
||||
| Vive Focus 3/XR Elite | :heavy_check_mark: |
|
||||
| YVR 1/2 | :heavy_check_mark: |
|
||||
| Lynx R1 | :heavy_check_mark: |
|
||||
| Google Cardboard | :heavy_check_mark: ([PhoneVR](https://github.com/PhoneVR-Developers/PhoneVR)) |
|
||||
| Smartphone/Monado | :construction: * |
|
||||
| GearVR | :construction: * (maybe) |
|
||||
|
|
|
@ -22,6 +22,7 @@ struct FfiStreamConfig {
|
|||
float foveationCenterShiftY;
|
||||
float foveationEdgeRatioX;
|
||||
float foveationEdgeRatioY;
|
||||
unsigned int enableSrgbCorrection;
|
||||
};
|
||||
|
||||
// gltf_model.h
|
||||
|
|
|
@ -62,7 +62,7 @@ typedef struct {
|
|||
enum ovrProgramType {
|
||||
STREAMER_PROG,
|
||||
LOBBY_PROG,
|
||||
MAX_PROGS // Not to be used as a type, just a placeholder for len
|
||||
MAX_PROGS // Not to be used as a type, just a placeholder for len
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -95,12 +95,11 @@ typedef struct {
|
|||
} ovrVertexAttribute;
|
||||
|
||||
ovrVertexAttribute ProgramVertexAttributes[] = {
|
||||
{VERTEX_ATTRIBUTE_LOCATION_POSITION, "vertexPosition", {true, true }},
|
||||
{VERTEX_ATTRIBUTE_LOCATION_COLOR, "vertexColor", {true, false}},
|
||||
{VERTEX_ATTRIBUTE_LOCATION_UV, "vertexUv", {true, true }},
|
||||
{VERTEX_ATTRIBUTE_LOCATION_TRANSFORM, "vertexTransform", {false, false}},
|
||||
{VERTEX_ATTRIBUTE_LOCATION_NORMAL, "vertexNormal", {false, true }}
|
||||
};
|
||||
{VERTEX_ATTRIBUTE_LOCATION_POSITION, "vertexPosition", {true, true}},
|
||||
{VERTEX_ATTRIBUTE_LOCATION_COLOR, "vertexColor", {true, false}},
|
||||
{VERTEX_ATTRIBUTE_LOCATION_UV, "vertexUv", {true, true}},
|
||||
{VERTEX_ATTRIBUTE_LOCATION_TRANSFORM, "vertexTransform", {false, false}},
|
||||
{VERTEX_ATTRIBUTE_LOCATION_NORMAL, "vertexNormal", {false, true}}};
|
||||
|
||||
enum E1test {
|
||||
UNIFORM_VIEW_ID,
|
||||
|
@ -428,7 +427,10 @@ void ovrGeometry_DestroyVAO(ovrGeometry *geometry) {
|
|||
|
||||
static const char *programVersion = "#version 300 es\n";
|
||||
|
||||
bool ovrProgram_Create(ovrProgram *program, const char *vertexSource, const char *fragmentSource, ovrProgramType progType) {
|
||||
bool ovrProgram_Create(ovrProgram *program,
|
||||
const char *vertexSource,
|
||||
const char *fragmentSource,
|
||||
ovrProgramType progType) {
|
||||
GLint r;
|
||||
|
||||
LOGI("Compiling shaders.");
|
||||
|
@ -468,12 +470,16 @@ bool ovrProgram_Create(ovrProgram *program, const char *vertexSource, const char
|
|||
// Bind the vertex attribute locations.
|
||||
for (size_t i = 0; i < sizeof(ProgramVertexAttributes) / sizeof(ProgramVertexAttributes[0]);
|
||||
i++) {
|
||||
// Only bind vertex attributes which are used/active in shader else causes uncessary bugs via compiler optimization/aliasing
|
||||
// Only bind vertex attributes which are used/active in shader else causes uncessary bugs
|
||||
// via compiler optimization/aliasing
|
||||
if (ProgramVertexAttributes[i].usedInProg[progType]) {
|
||||
GL(glBindAttribLocation(program->streamProgram,
|
||||
ProgramVertexAttributes[i].location,
|
||||
ProgramVertexAttributes[i].name));
|
||||
LOGD("Binding ProgramVertexAttribute [id.%d] %s to location %d", i, ProgramVertexAttributes[i].name, ProgramVertexAttributes[i].location);
|
||||
ProgramVertexAttributes[i].location,
|
||||
ProgramVertexAttributes[i].name));
|
||||
LOGD("Binding ProgramVertexAttribute [id.%d] %s to location %d",
|
||||
i,
|
||||
ProgramVertexAttributes[i].name,
|
||||
ProgramVertexAttributes[i].location);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -551,19 +557,22 @@ void ovrRenderer_Create(ovrRenderer *renderer,
|
|||
int hudTexture,
|
||||
std::vector<GLuint> textures[2],
|
||||
FFRData ffrData,
|
||||
bool isLobby) {
|
||||
bool isLobby,
|
||||
bool enableSrgbCorrection) {
|
||||
if (!isLobby) {
|
||||
renderer->srgbCorrectionPass = std::make_unique<SrgbCorrectionPass>(streamTexture);
|
||||
renderer->enableFFR = ffrData.enabled;
|
||||
if (renderer->enableFFR) {
|
||||
FoveationVars fv = CalculateFoveationVars(ffrData);
|
||||
renderer->srgbCorrectionPass->Initialize(fv.optimizedEyeWidth, fv.optimizedEyeHeight);
|
||||
renderer->srgbCorrectionPass->Initialize(
|
||||
fv.optimizedEyeWidth, fv.optimizedEyeHeight, !enableSrgbCorrection);
|
||||
renderer->ffr = std::make_unique<FFR>(renderer->srgbCorrectionPass->GetOutputTexture());
|
||||
renderer->ffr->Initialize(fv);
|
||||
renderer->streamRenderTexture = renderer->ffr->GetOutputTexture()->GetGLTexture();
|
||||
} else {
|
||||
renderer->srgbCorrectionPass->Initialize(width, height);
|
||||
renderer->streamRenderTexture = renderer->srgbCorrectionPass->GetOutputTexture()->GetGLTexture();
|
||||
renderer->srgbCorrectionPass->Initialize(width, height, !enableSrgbCorrection);
|
||||
renderer->streamRenderTexture =
|
||||
renderer->srgbCorrectionPass->GetOutputTexture()->GetGLTexture();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -580,7 +589,8 @@ void ovrRenderer_Create(ovrRenderer *renderer,
|
|||
|
||||
ovrProgram_Create(&renderer->streamProgram, VERTEX_SHADER, FRAGMENT_SHADER, STREAMER_PROG);
|
||||
|
||||
ovrProgram_Create(&renderer->lobbyProgram, LOBBY_VERTEX_SHADER, LOBBY_FRAGMENT_SHADER, LOBBY_PROG);
|
||||
ovrProgram_Create(
|
||||
&renderer->lobbyProgram, LOBBY_VERTEX_SHADER, LOBBY_FRAGMENT_SHADER, LOBBY_PROG);
|
||||
|
||||
ovrGeometry_CreatePanel(&renderer->Panel);
|
||||
ovrGeometry_CreateVAO(&renderer->Panel);
|
||||
|
@ -734,7 +744,7 @@ void initGraphicsNative() {
|
|||
g_ctx.streamTexture = std::make_unique<Texture>(false, 0, true);
|
||||
g_ctx.hudTexture = std::make_unique<Texture>(
|
||||
false, 0, false, 1280, 720, GL_RGBA8, GL_RGBA, std::vector<uint8_t>(1280 * 720 * 4, 0));
|
||||
|
||||
|
||||
const GLubyte *sVendor, *sRenderer, *sVersion, *sExts;
|
||||
|
||||
GL(sVendor = glGetString(GL_VENDOR));
|
||||
|
@ -747,10 +757,14 @@ void initGraphicsNative() {
|
|||
}
|
||||
|
||||
void destroyGraphicsNative() {
|
||||
LOGV("Resetting stream texture and hud texture %p, %p", g_ctx.streamTexture.get(), g_ctx.hudTexture.get());
|
||||
LOGV("Resetting stream texture and hud texture %p, %p",
|
||||
g_ctx.streamTexture.get(),
|
||||
g_ctx.hudTexture.get());
|
||||
g_ctx.streamTexture.reset();
|
||||
g_ctx.hudTexture.reset();
|
||||
LOGV("Resetted stream texture and hud texture to %p, %p", g_ctx.streamTexture.get(), g_ctx.hudTexture.get());
|
||||
LOGV("Resetted stream texture and hud texture to %p, %p",
|
||||
g_ctx.streamTexture.get(),
|
||||
g_ctx.hudTexture.get());
|
||||
}
|
||||
|
||||
// on resume
|
||||
|
@ -774,7 +788,8 @@ void prepareLobbyRoom(int viewWidth,
|
|||
g_ctx.hudTexture->GetGLTexture(),
|
||||
g_ctx.lobbySwapchainTextures,
|
||||
{false},
|
||||
true);
|
||||
true,
|
||||
false);
|
||||
}
|
||||
|
||||
// on pause
|
||||
|
@ -819,7 +834,8 @@ void streamStartNative(FfiStreamConfig config) {
|
|||
config.foveationCenterShiftY,
|
||||
config.foveationEdgeRatioX,
|
||||
config.foveationEdgeRatioY},
|
||||
false);
|
||||
false,
|
||||
config.enableSrgbCorrection);
|
||||
}
|
||||
|
||||
void updateLobbyHudTexture(const unsigned char *data) {
|
||||
|
@ -838,14 +854,14 @@ void renderLobbyNative(const FfiViewInput eyeInputs[2]) {
|
|||
if (!g_ctx.hudTextureBitmap.empty()) {
|
||||
GL(glBindTexture(GL_TEXTURE_2D, g_ctx.hudTexture->GetGLTexture()));
|
||||
GL(glTexSubImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
HUD_TEXTURE_WIDTH,
|
||||
HUD_TEXTURE_HEIGHT,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
&g_ctx.hudTextureBitmap[0]));
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
HUD_TEXTURE_WIDTH,
|
||||
HUD_TEXTURE_HEIGHT,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
&g_ctx.hudTextureBitmap[0]));
|
||||
}
|
||||
g_ctx.hudTextureBitmap.clear();
|
||||
}
|
||||
|
|
|
@ -32,15 +32,29 @@ const string SRGB_CORRECTION_FRAGMENT_SHADER = R"glsl(#version 300 es
|
|||
color.rgb = condition * lowValues + (1.0 - condition) * highValues;
|
||||
}
|
||||
)glsl";
|
||||
}
|
||||
const string PASSTHOUGH_FRAGMENT_SHADER = R"glsl(#version 300 es
|
||||
#extension GL_OES_EGL_image_external_essl3 : enable
|
||||
precision mediump float;
|
||||
|
||||
uniform samplerExternalOES tex0;
|
||||
in vec2 uv;
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = texture(tex0, uv);
|
||||
}
|
||||
)glsl";
|
||||
} // namespace
|
||||
|
||||
SrgbCorrectionPass::SrgbCorrectionPass(Texture *inputSurface) : mInputSurface(inputSurface) {}
|
||||
|
||||
void SrgbCorrectionPass::Initialize(uint32_t width, uint32_t height) {
|
||||
void SrgbCorrectionPass::Initialize(uint32_t width, uint32_t height, bool passthrough) {
|
||||
mOutputTexture.reset(new Texture(false, 0, false, width * 2, height));
|
||||
mOutputTextureState = make_unique<RenderState>(mOutputTexture.get());
|
||||
|
||||
auto fragmentShader = SRGB_CORRECTION_FRAGMENT_SHADER;
|
||||
auto fragmentShader =
|
||||
passthrough ? PASSTHOUGH_FRAGMENT_SHADER : SRGB_CORRECTION_FRAGMENT_SHADER;
|
||||
mStagingPipeline = unique_ptr<RenderPipeline>(
|
||||
new RenderPipeline({mInputSurface}, QUAD_2D_VERTEX_SHADER, fragmentShader));
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ class SrgbCorrectionPass {
|
|||
public:
|
||||
SrgbCorrectionPass(gl_render_utils::Texture *inputSurface);
|
||||
|
||||
void Initialize(uint32_t width, uint32_t height);
|
||||
void Initialize(uint32_t width, uint32_t height, bool passthrough);
|
||||
|
||||
void Render() const;
|
||||
|
||||
|
|
|
@ -535,7 +535,12 @@ pub unsafe extern "C" fn alvr_start_stream_opengl(config: AlvrStreamConfig) {
|
|||
edge_ratio_y: config.foveation_edge_ratio_y,
|
||||
});
|
||||
|
||||
opengl::start_stream(view_resolution, swapchain_textures, foveated_rendering);
|
||||
opengl::start_stream(
|
||||
view_resolution,
|
||||
swapchain_textures,
|
||||
foveated_rendering,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
|
@ -71,6 +71,7 @@ pub fn start_stream(
|
|||
view_resolution: UVec2,
|
||||
swapchain_textures: [Vec<u32>; 2],
|
||||
foveated_rendering: Option<FoveatedRenderingConfig>,
|
||||
enable_srgb_correction: bool,
|
||||
) {
|
||||
#[cfg(target_os = "android")]
|
||||
unsafe {
|
||||
|
@ -107,6 +108,7 @@ pub fn start_stream(
|
|||
.as_ref()
|
||||
.map(|f| f.edge_ratio_y)
|
||||
.unwrap_or_default(),
|
||||
enableSrgbCorrection: enable_srgb_correction as u32,
|
||||
};
|
||||
|
||||
streamStartNative(config);
|
||||
|
|
|
@ -155,4 +155,12 @@ value = "1"
|
|||
# Yvr entries
|
||||
[[package.metadata.android.application.meta_data]]
|
||||
name = "com.yvr.intent.category.VR"
|
||||
value = "vr_only"
|
||||
value = "vr_only"
|
||||
|
||||
# Lynx entries
|
||||
[[package.metadata.android.queries.intent]]
|
||||
actions = ["org.khronos.openxr.OpenXRRuntimeService"]
|
||||
[[package.metadata.android.queries.package]]
|
||||
name = "com.ultraleap.tracking.service"
|
||||
[[package.metadata.android.queries.package]]
|
||||
name = "com.ultraleap.openxr.api_layer"
|
||||
|
|
|
@ -45,7 +45,7 @@ pub fn initialize_hands_interaction(
|
|||
Platform::Pico4 => PICO4_CONTROLLER_PROFILE_PATH,
|
||||
Platform::Focus3 => FOCUS3_CONTROLLER_PROFILE_PATH,
|
||||
Platform::Yvr => YVR_CONTROLLER_PROFILE_PATH,
|
||||
Platform::Other => QUEST_CONTROLLER_PROFILE_PATH,
|
||||
_ => QUEST_CONTROLLER_PROFILE_PATH,
|
||||
};
|
||||
let interaction_profile_id = alvr_common::hash_string(interaction_profile_path);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ pub enum Platform {
|
|||
Pico4,
|
||||
Focus3,
|
||||
Yvr,
|
||||
Lynx,
|
||||
Other,
|
||||
}
|
||||
|
||||
|
@ -350,29 +351,30 @@ fn update_streaming_input(ctx: &mut StreamingInputContext) {
|
|||
pub fn entry_point() {
|
||||
alvr_client_core::init_logging();
|
||||
|
||||
let platform = match (
|
||||
alvr_client_core::manufacturer_name().as_str(),
|
||||
alvr_client_core::device_model().as_str(),
|
||||
) {
|
||||
let manufacturer_name = alvr_client_core::manufacturer_name();
|
||||
let device_model = alvr_client_core::device_model();
|
||||
|
||||
info!("Manufacturer: {manufacturer_name}, device model: {device_model}");
|
||||
|
||||
let platform = match (manufacturer_name.as_str(), device_model.as_str()) {
|
||||
("Oculus", _) => Platform::Quest,
|
||||
("Pico", "Pico Neo 3") => Platform::PicoNeo3,
|
||||
("Pico", _) => Platform::Pico4,
|
||||
("HTC", _) => Platform::Focus3,
|
||||
("YVR", _) => Platform::Yvr,
|
||||
("Lynx Mixed Reality", _) => Platform::Lynx,
|
||||
_ => Platform::Other,
|
||||
};
|
||||
|
||||
let xr_entry = match platform {
|
||||
Platform::Quest => unsafe {
|
||||
xr::Entry::load_from(Path::new("libopenxr_loader_quest.so")).unwrap()
|
||||
},
|
||||
Platform::PicoNeo3 | Platform::Pico4 => unsafe {
|
||||
xr::Entry::load_from(Path::new("libopenxr_loader_pico.so")).unwrap()
|
||||
},
|
||||
Platform::Yvr => unsafe {
|
||||
xr::Entry::load_from(Path::new("libopenxr_loader_yvr.so")).unwrap()
|
||||
},
|
||||
_ => unsafe { xr::Entry::load().unwrap() },
|
||||
let loader_suffix = match platform {
|
||||
Platform::Quest => "quest",
|
||||
Platform::PicoNeo3 | Platform::Pico4 => "pico",
|
||||
Platform::Yvr => "yvr",
|
||||
Platform::Lynx => "lynx",
|
||||
_ => "generic",
|
||||
};
|
||||
let xr_entry = unsafe {
|
||||
xr::Entry::load_from(Path::new(&format!("libopenxr_loader_{loader_suffix}.so"))).unwrap()
|
||||
};
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
|
@ -784,6 +786,7 @@ pub fn entry_point() {
|
|||
.collect(),
|
||||
],
|
||||
settings.video.foveated_rendering.into_option(),
|
||||
platform != Platform::Lynx,
|
||||
);
|
||||
|
||||
alvr_client_core::send_playspace(
|
||||
|
|
|
@ -21,19 +21,16 @@ pub fn download(sh: &Shell, url: &str, destination: &Path) -> Result<(), xshell:
|
|||
cmd!(sh, "curl -L -o {destination} --url {url}").run()
|
||||
}
|
||||
|
||||
pub fn download_and_extract_zip(
|
||||
sh: &Shell,
|
||||
url: &str,
|
||||
destination: &Path,
|
||||
) -> Result<(), xshell::Error> {
|
||||
pub fn download_and_extract_zip(url: &str, destination: &Path) -> Result<(), xshell::Error> {
|
||||
let sh = Shell::new().unwrap();
|
||||
let temp_dir_guard = sh.create_temp_dir()?;
|
||||
|
||||
let zip_file = temp_dir_guard.path().join("temp_download.zip");
|
||||
download(sh, url, &zip_file)?;
|
||||
download(&sh, url, &zip_file)?;
|
||||
|
||||
sh.remove_path(destination).ok();
|
||||
sh.create_dir(destination)?;
|
||||
unzip(sh, &zip_file, destination)
|
||||
unzip(&sh, &zip_file, destination)
|
||||
}
|
||||
|
||||
pub fn date_utc_yyyymmdd(sh: &Shell) -> Result<String, xshell::Error> {
|
||||
|
|
|
@ -20,7 +20,6 @@ pub fn prepare_x264_windows() {
|
|||
let deps_dir = afs::deps_dir();
|
||||
|
||||
command::download_and_extract_zip(
|
||||
&sh,
|
||||
&format!(
|
||||
"{}/{VERSION}.r{REVISION}/libx264_{VERSION}.r{REVISION}_msvc16.zip",
|
||||
"https://github.com/ShiftMediaProject/x264/releases/download",
|
||||
|
@ -56,11 +55,8 @@ Cflags: -I${{includedir}}
|
|||
}
|
||||
|
||||
pub fn prepare_ffmpeg_windows() {
|
||||
let sh = Shell::new().unwrap();
|
||||
|
||||
let download_path = afs::deps_dir().join("windows");
|
||||
command::download_and_extract_zip(
|
||||
&sh,
|
||||
&format!(
|
||||
"https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/{}",
|
||||
"ffmpeg-n5.1-latest-win64-gpl-shared-5.1.zip"
|
||||
|
@ -103,7 +99,6 @@ pub fn build_ffmpeg_linux(nvenc_flag: bool) {
|
|||
|
||||
let download_path = afs::deps_dir().join("linux");
|
||||
command::download_and_extract_zip(
|
||||
&sh,
|
||||
"https://codeload.github.com/FFmpeg/FFmpeg/zip/n6.0",
|
||||
&download_path,
|
||||
)
|
||||
|
@ -206,72 +201,52 @@ pub fn build_ffmpeg_linux(nvenc_flag: bool) {
|
|||
}
|
||||
|
||||
fn get_android_openxr_loaders() {
|
||||
let sh = Shell::new().unwrap();
|
||||
fn get_openxr_loader(name: &str, url: &str, source_dir: &str) {
|
||||
let temp_dir = afs::build_dir().join("temp_download");
|
||||
let destination_dir = afs::deps_dir().join("android_openxr/arm64-v8a");
|
||||
fs::create_dir_all(&destination_dir).unwrap();
|
||||
|
||||
let destination_dir = afs::deps_dir().join("android_openxr/arm64-v8a");
|
||||
fs::create_dir_all(&destination_dir).unwrap();
|
||||
command::download_and_extract_zip(url, &temp_dir).unwrap();
|
||||
fs::copy(
|
||||
temp_dir.join(source_dir).join("libopenxr_loader.so"),
|
||||
destination_dir.join(format!("libopenxr_loader_{name}.so")),
|
||||
)
|
||||
.unwrap();
|
||||
fs::remove_dir_all(&temp_dir).ok();
|
||||
}
|
||||
|
||||
let temp_dir = afs::build_dir().join("temp_download");
|
||||
|
||||
// Generic
|
||||
command::download_and_extract_zip(
|
||||
&sh,
|
||||
get_openxr_loader(
|
||||
"generic",
|
||||
&format!(
|
||||
"https://github.com/KhronosGroup/OpenXR-SDK-Source/releases/download/{}",
|
||||
"release-1.0.27/openxr_loader_for_android-1.0.27.aar",
|
||||
),
|
||||
&temp_dir,
|
||||
)
|
||||
.unwrap();
|
||||
fs::copy(
|
||||
temp_dir.join("prefab/modules/openxr_loader/libs/android.arm64-v8a/libopenxr_loader.so"),
|
||||
destination_dir.join("libopenxr_loader.so"),
|
||||
)
|
||||
.unwrap();
|
||||
fs::remove_dir_all(&temp_dir).ok();
|
||||
"prefab/modules/openxr_loader/libs/android.arm64-v8a",
|
||||
);
|
||||
|
||||
// Quest
|
||||
command::download_and_extract_zip(
|
||||
&sh,
|
||||
get_openxr_loader(
|
||||
"quest",
|
||||
"https://securecdn.oculus.com/binaries/download/?id=6316350341736833", // version 53
|
||||
&temp_dir,
|
||||
)
|
||||
.unwrap();
|
||||
fs::copy(
|
||||
temp_dir.join("OpenXR/Libs/Android/arm64-v8a/Release/libopenxr_loader.so"),
|
||||
destination_dir.join("libopenxr_loader_quest.so"),
|
||||
)
|
||||
.unwrap();
|
||||
fs::remove_dir_all(&temp_dir).ok();
|
||||
"OpenXR/Libs/Android/arm64-v8a/Release",
|
||||
);
|
||||
|
||||
// Pico
|
||||
command::download_and_extract_zip(
|
||||
&sh,
|
||||
get_openxr_loader(
|
||||
"pico",
|
||||
"https://sdk.picovr.com/developer-platform/sdk/PICO_OpenXR_SDK_220.zip",
|
||||
&temp_dir,
|
||||
)
|
||||
.unwrap();
|
||||
fs::copy(
|
||||
temp_dir.join("libs/android.arm64-v8a/libopenxr_loader.so"),
|
||||
destination_dir.join("libopenxr_loader_pico.so"),
|
||||
)
|
||||
.unwrap();
|
||||
fs::remove_dir_all(&temp_dir).ok();
|
||||
"libs/android.arm64-v8a",
|
||||
);
|
||||
|
||||
// Yvr
|
||||
command::download_and_extract_zip(
|
||||
&sh,
|
||||
get_openxr_loader(
|
||||
"yvr",
|
||||
"https://developer.yvrdream.com/yvrdoc/sdk/openxr/yvr_openxr_mobile_sdk_1.0.0.zip",
|
||||
&temp_dir,
|
||||
)
|
||||
.unwrap();
|
||||
fs::copy(
|
||||
temp_dir
|
||||
.join("yvr_openxr_mobile_sdk_1.0.0/OpenXR/Libs/Android/arm64-v8a/libopenxr_loader.so"),
|
||||
destination_dir.join("libopenxr_loader_yvr.so"),
|
||||
)
|
||||
.unwrap();
|
||||
fs::remove_dir_all(temp_dir).ok();
|
||||
"yvr_openxr_mobile_sdk_1.0.0/OpenXR/Libs/Android/arm64-v8a",
|
||||
);
|
||||
|
||||
get_openxr_loader(
|
||||
"lynx",
|
||||
"https://portal.lynx-r.com/downloads/download/16", // version 1.0.0
|
||||
"jni/arm64-v8a",
|
||||
);
|
||||
}
|
||||
|
||||
pub fn build_android_deps(skip_admin_priv: bool) {
|
||||
|
|
Loading…
Reference in New Issue