From 95b15050e4e41ec24e515f892d4295b39e6b6cff Mon Sep 17 00:00:00 2001 From: Rene Eichhorn Date: Thu, 5 May 2016 19:01:38 +0200 Subject: [PATCH] fixed some render_model bugs, added opengl/glium sample that renders sample rendermodel --- Cargo.lock | 549 +++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 5 + examples/opengl.rs | 162 ++++++++++++- src/render_models.rs | 120 +++++++++- src/sys/lib.rs | 2 +- 5 files changed, 830 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2197154..0332f33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,10 +2,559 @@ name = "openvr" version = "0.2.0" dependencies = [ + "glium 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nalgebra 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "openvr_sys 0.1.0", ] +[[package]] +name = "android_glue" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "backtrace" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "debug-builders 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cgl" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gleam 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cocoa" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "core-foundation" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "core-foundation-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "core-graphics" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "dbghelp-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "debug-builders" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "dlib" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libloading 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dlib" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libloading 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dwmapi-sys" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dylib" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fs2" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gcc" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "gdi32-sys" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gl_generator" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gleam" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gl_generator 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "glium" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "glutin 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "glutin" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "android_glue 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cgl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cocoa 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "osmesa-sys 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "shared_library 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-client 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-kbd 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-window 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "x11-dl 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "khronos_api" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libloading" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "log" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memmap" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fs2 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nalgebra" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-bigint 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-complex 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-bigint" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-complex" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-iter" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-rational" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-bigint 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "objc" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "openvr_sys" version = "0.1.0" +[[package]] +name = "osmesa-sys" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "shared_library 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-serialize" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc_version" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "shared_library" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "shell32-sys" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "smallvec" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "tempfile" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "user32-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wayland-client" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "dlib 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-scanner 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-sys 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wayland-kbd" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-client 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wayland-scanner" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "xml-rs 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wayland-sys" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wayland-window" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-client 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "x11-dl" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dylib 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "xml-rs" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "xml-rs" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + diff --git a/Cargo.toml b/Cargo.toml index f19262c..93aa325 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,8 @@ path = "src/lib.rs" [dependencies.openvr_sys] path = "src/sys/" + +[dev_dependencies] +glium = "0.14.0" +num = "0.1.31" +nalgebra = "0.6.0" diff --git a/examples/opengl.rs b/examples/opengl.rs index 3786831..9a4f8d2 100644 --- a/examples/opengl.rs +++ b/examples/opengl.rs @@ -1,3 +1,161 @@ -pub fn main() { - // init vr system +extern crate openvr; +extern crate nalgebra; + +#[macro_use] +extern crate glium; + +#[derive(Copy, Clone)] +struct Vertex { + position: [f32; 3], + normal: [f32; 3], + texcoord: [f32; 2] +} +implement_vertex!(Vertex, position, normal, texcoord); + +pub fn main() { + { + // init vr system + let system = match openvr::init() { + Ok(ivr) => ivr, + Err(err) => { + println!("Failed to create IVR subsystem {:?}", err); + return; + } + }; + + // init compositor subsystem + /*let comp = match openvr::compositor() { + Ok(ext) => ext, + Err(err) => { + println!("Failed to create IVRCompositor subsystem {:?}", err); + return; + } + };*/ + + // init render model subsystem + let models = match openvr::render_models() { + Ok(ext) => ext, + Err(err) => { + println!("Failed to create IVRRenderModels subsystem {:?}", err); + return; + } + }; + + // create glium window and context + use glium::{DisplayBuild, Surface}; + let display = glium::glutin::WindowBuilder::new() + .with_depth_buffer(24) + .build_glium() + .unwrap(); + + // prepare shader + let vertex_shader_src = r#" + #version 140 + + in vec3 position; + in vec3 normal; + in vec2 texcoord; + + out vec3 v_normal; + out vec2 v_texcoord; + + uniform mat4 matrix; + + void main() { + v_normal = normal; + v_texcoord = texcoord; + gl_Position = matrix * vec4(position, 1.0); + } + "#; + + let fragment_shader_src = r#" + #version 140 + + uniform sampler2D diffuse; + + in vec3 v_normal; + in vec2 v_texcoord; + + out vec4 color; + + void main() { + color = texture(diffuse, v_texcoord); + } + "#; + + let program = glium::Program::from_source(&display, vertex_shader_src, fragment_shader_src, None).unwrap(); + + // load controller models + let controller = models.load(String::from("vr_controller_vive_1_5")).unwrap_or_else(|err| { + openvr::shutdown(); panic!("controller render model not found: {:?}", err) }); + + let mut controller_vertices: Vec = Vec::new(); + let mut controller_indices: Vec = Vec::new(); + for vertex in controller.vertex_iter() { + controller_vertices.push(Vertex { + position: [vertex.vPosition.v[0] as f32, vertex.vPosition.v[1] as f32, vertex.vPosition.v[2] as f32], + normal: [vertex.vNormal.v[0] as f32, vertex.vNormal.v[1] as f32, vertex.vNormal.v[2] as f32], + texcoord: [vertex.rfTextureCoord[0] as f32, vertex.rfTextureCoord[1] as f32], + }); + } + for index in controller.index_iter() { + controller_indices.push(*index); + } + + let controller_vertex_buffer = glium::VertexBuffer::new(&display, &controller_vertices).unwrap(); + let controller_index_buffer = glium::IndexBuffer::new(&display, glium::index::PrimitiveType::TrianglesList, &controller_indices).unwrap(); + let controller_texture_response = controller.load_texture().unwrap(); + let dimension = (controller_texture_response.dimension().0 as u32, controller_texture_response.dimension().1 as u32); + let image = glium::texture::RawImage2d::from_raw_rgba(controller_texture_response.to_vec(), dimension); + let controller_texture = glium::texture::Texture2d::new(&display, image).unwrap(); + + 'render: loop { + // this is important to make sure frames are synced correctly + //let _ = comp.wait_get_poses(); + + // render 2d display output + let mut target = display.draw(); + target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0); + + let uniforms = uniform! { + matrix: [ + [5.0, 0.0, 0.0, 0.0], + [0.0, 5.0, 0.0, 0.0], + [0.0, 0.0, 5.0, 0.0], + [0.0 , 0.0, 0.0, 1.0f32], + ], + diffuse: &controller_texture + }; + + let params = glium::DrawParameters { + depth: glium::Depth { + test: glium::draw_parameters::DepthTest::IfLess, + write: true, + .. Default::default() + }, + backface_culling: glium::draw_parameters::BackfaceCullingMode::CullCounterClockwise, + .. Default::default() + }; + + target.draw(&controller_vertex_buffer, &controller_index_buffer, &program, &uniforms, ¶ms).unwrap(); + + // render hmd eye outputs + + // finish all rendering + target.finish().unwrap(); + + // submit to hmd + + // handle window events + for ev in display.poll_events() { + match ev { + glium::glutin::Event::Closed => break 'render, // the window has been closed by the user + _ => () + } + } + } + } + + // free openvr + openvr::shutdown(); } diff --git a/src/render_models.rs b/src/render_models.rs index f0441ae..8f4eaff 100644 --- a/src/render_models.rs +++ b/src/render_models.rs @@ -9,6 +9,7 @@ use subsystems::render_models; pub struct IVRRenderModels(*const ()); pub struct RenderModel(*mut openvr_sys::RenderModel_t); +pub struct RenderModelTexture(*mut openvr_sys::RenderModel_TextureMap_t); impl Drop for RenderModel { /// will inform openvr that the memory for the render model is no longer required @@ -22,6 +23,18 @@ impl Drop for RenderModel { } } +impl Drop for RenderModelTexture { + /// will inform openvr that the memory for the render model is no longer required + fn drop (&mut self) { + unsafe { + let models = * { render_models().unwrap().0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable}; + models.FreeTexture.unwrap()( + self.0 + ); + } + } +} + impl RenderModel { /// Returns an iterator that iterates over vertices pub fn vertex_iter(&self) -> slice::Iter { @@ -34,15 +47,77 @@ impl RenderModel { /// Returns an iterator that iterates over indices pub fn index_iter(&self) -> slice::Iter { unsafe { - let slice = slice::from_raw_parts((*self.0).rIndexData, (*self.0).unTriangleCount as usize); + let slice = slice::from_raw_parts((*self.0).rIndexData, (*self.0).unTriangleCount as usize * 3); slice.iter() } } - /// returns the unique identifier for the texture that the models uses - pub fn texture_identifier(&self) -> usize { + /// asynchronosly loads the texture for the current render model + /// see IVRRenderModels::load_async for info how openvr async work + pub fn load_texture_async(&self) -> Result { unsafe { - (*self.0).diffuseTextureId as usize + let models = * { render_models().unwrap().0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable}; + let mut resp: *mut openvr_sys::RenderModel_TextureMap_t = null_mut(); + + let err = models.LoadTexture_Async.unwrap()( + (*self.0).diffuseTextureId, + &mut resp + ); + + match err { + EVRRenderModelError_VRRenderModelError_None => { + Ok(RenderModelTexture (resp)) + }, + _ => { + Err(err) + } + } + + } + } + + /// loads the texture for current model + pub fn load_texture(&self) -> Result { + use std; + + loop { + let result = self.load_texture_async(); + match result { + Ok(texture) => { + return Ok(texture); + }, + Err(err) => { + match err { + EVRRenderModelError_VRRenderModelError_Loading => { + // ask again later + }, + _ => { + return Err(err); + } + } + } + } + std::thread::sleep(std::time::Duration::from_millis(10)); + } + } +} + +impl RenderModelTexture { + /// Returns the dimension from the texture (width, height) + pub fn dimension(&self) -> (usize, usize) { + unsafe { + ((*self.0).unWidth as usize, (*self.0).unHeight as usize) + } + } + + /// Creates a 1 dimensional vector of pixels, format: rgba@32 + pub fn to_vec(&self) -> Vec { + unsafe { + let dimension = self.dimension(); + let slice = slice::from_raw_parts((*self.0).rubTextureMapData, dimension.0 * dimension.1 * 4); + let mut vec = Vec::new(); + vec.extend_from_slice(slice); + vec } } } @@ -82,16 +157,51 @@ impl IVRRenderModels { } /// Loads an render model into local memory + /// blocks the thread and waits until driver responds with model pub fn load(&self, name: String) -> Result { + use std; + + loop { + let result = self.load_async(name.clone()); + match result { + Ok(model) => { + return Ok(model); + }, + Err(err) => { + match err { + EVRRenderModelError_VRRenderModelError_Loading => { + // ask again later + }, + _ => { + return Err(err); + } + } + } + } + std::thread::sleep(std::time::Duration::from_millis(10)); + } + } + + /// Loads an render model into local memory + /// When called for the first time openvr will start to load the model into memory + /// In the mean time this call will respond with EVRRenderModelError_VRRenderModelError_Loading + /// It is designed to be used wihtin the render loop as it won't block the user, for sync usage use load() + pub fn load_async(&self, name: String) -> Result { + use std; + unsafe { let models = * { self.0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable}; let mut resp: *mut openvr_sys::RenderModel_t = null_mut(); + let cname = std::ffi::CString::new(name.as_str()).unwrap(); + let rawname = cname.into_raw(); let err = models.LoadRenderModel_Async.unwrap()( - name.as_ptr() as *mut i8, + rawname, &mut resp ); + let _ = std::ffi::CString::from_raw(rawname); + match err { EVRRenderModelError_VRRenderModelError_None => { Ok(RenderModel ( resp )) diff --git a/src/sys/lib.rs b/src/sys/lib.rs index a602c6b..2f1c22b 100755 --- a/src/sys/lib.rs +++ b/src/sys/lib.rs @@ -635,7 +635,7 @@ pub enum Enum_EOverlayDirection { EOverlayDirection_OverlayDirection_Count = 4, } pub type EOverlayDirection = Enum_EOverlayDirection; -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] #[repr(u32)] pub enum Enum_EVRRenderModelError { EVRRenderModelError_VRRenderModelError_None = 0,