diff --git a/Cargo.toml b/Cargo.toml index e00c0be..6125e68 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ gl = "*" gfx = "*" gfx_device_gl = "*" openvr = { git = "https://github.com/rust-openvr/rust-openvr" } +openvr_sys = "*" piston = "*" piston_window = "*" diff --git a/src/bin/gl.rs b/src/bin/gl.rs index 11e048e..783a1e8 100644 --- a/src/bin/gl.rs +++ b/src/bin/gl.rs @@ -1,13 +1,13 @@ -extern crate gl; +extern crate vrtue; +use vrtue::*; extern crate env_logger; -#[macro_use] extern crate log; #[macro_use] extern crate gfx; -extern crate gfx_device_gl; -extern crate openvr as vr; +extern crate gl; +#[macro_use] extern crate log; extern crate piston_window; -use gfx::{tex, CombinedError, Device, Factory, Typed}; +use gfx::Device; use gfx::traits::FactoryExt; use piston_window::{PistonWindow, Window, WindowSettings}; @@ -34,9 +34,8 @@ const TRIANGLE: [Vertex; 3] = [ fn main() { env_logger::init().expect("env logger"); - let system = vr::init().expect("OpenVR init"); - let compositor = vr::compositor().expect("OpenVR Compositor"); - let render_size = system.recommended_render_target_size(); + let mut vr = vr::VR::new().expect("VR init"); + let render_size = vr.recommended_render_target_size(); let mut window: PistonWindow = WindowSettings::new("Hello Virtual World!", [512; 2]) @@ -44,7 +43,6 @@ fn main() { .vsync(false) //.vsync(true) .build().expect("Building Window"); - info!("monitor target: {:?}", window.output_color.raw()); /* let _sysleft = system.projection_matrix(vr::Eye::Left, 0.01, 1000.0); @@ -57,13 +55,9 @@ fn main() { pipe::new()) .expect("create pipeline"); - let (tex_left, tgt_left) = create_renderbuffer_target::(&mut window.factory, - render_size.width as tex::Size, - render_size.height as tex::Size) + let (tex_left, tgt_left) = vr::create_eyebuffer(&mut window.factory, render_size) .expect("create left renderbuffer"); - let (tex_right, tgt_right) = create_renderbuffer_target(&mut window.factory, - render_size.width as tex::Size, - render_size.height as tex::Size) + let (tex_right, tgt_right) = vr::create_eyebuffer(&mut window.factory, render_size) .expect("create right renderbuffer"); let (vertex_buffer, slice) = window.factory.create_vertex_buffer_with_slice(&TRIANGLE, ()); @@ -81,7 +75,6 @@ fn main() { }; let mut frame = 0; - let mut manager = gfx::handle::Manager::new(); window.window.swap_buffers(); frame += 1; // To contain setup calls to Frame 0 in apitrace 'main: //while let Some(_) = window.next() { @@ -90,8 +83,7 @@ fn main() { let _now = std::time::SystemTime::now(); // Get the current sensor state - let _poses = compositor.wait_get_poses(); - manager.clear(); + let _poses = vr.poses(); trace!("\t{:?} got pose", _now.elapsed()); if frame % 90 == 0 { warn!("\t#{}: poses: {:?}\n", frame, _poses.poses[0]); @@ -109,20 +101,8 @@ fn main() { // Submit eye textures if let Some((eye, tex)) = pass.0 { - let tex_id = match manager.ref_texture(tex.raw()) { - &gfx_device_gl::NewTexture::Surface(id) => id, - _ => panic!("Not a surface") - }; - info!("\t\tUsing texture id #{} for target {:?}", tex_id, pass.1.pixcolor.raw()); - check_err(&mut window.device); - - gl_debug(&mut window.device, b"before"); - compositor.submit(eye, - tex_id as usize, - vr::common::TextureBounds::new((0.0, 1.0), (0.0, 1.0))); + vr.submit(eye, tex); trace!("\t\t{:?} submit {:?}", _now.elapsed(), eye); - gl_debug(&mut window.device, b"after!"); - check_err(&mut window.device); } else { window.window.swap_buffers(); } @@ -139,28 +119,9 @@ fn main() { } info!("shutting down"); - vr::shutdown() -} - -fn create_renderbuffer_target(factory: &mut gfx_device_gl::Factory, - width: tex::Size, - height: tex::Size) - -> Result<(gfx::handle::Texture, - gfx::handle::RenderTargetView), - gfx::CombinedError> - where T: gfx::format::RenderFormat + gfx::format::TextureFormat { - let tex = try!(factory.create_texture( - tex::Kind::D2(width, height, tex::AaMode::Single), - 1, // levels - gfx::RENDER_TARGET, // bind - gfx::Usage::GpuOnly, // Usage - Some(::get_channel_type()))); // hint: format::ChannelType? - let tgt = try!(factory.view_texture_as_render_target(&tex, 0, None)); - Ok((tex, tgt)) } +/* fn gl_debug(device: &mut gfx_device_gl::Device, msg: &'static [u8; 6]) { unsafe { device.with_gl_naked(|gl| { @@ -169,7 +130,7 @@ fn gl_debug(device: &mut gfx_device_gl::Device, msg: &'static [u8; 6]) { 0, gl::DEBUG_SEVERITY_LOW, msg.len() as i32, - std::mem::transmute(msg)); + ::std::mem::transmute(msg)); }); } } @@ -184,6 +145,7 @@ fn check_err(device: &mut gfx_device_gl::Device) { }); } } +*/ const VERTEX_SHADER_SRC: &'static [u8] = br#" #version 140 diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..a4dd473 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,3 @@ +#[macro_use] extern crate log; + +pub mod vr; diff --git a/src/vr.rs b/src/vr.rs new file mode 100644 index 0000000..7b80d7e --- /dev/null +++ b/src/vr.rs @@ -0,0 +1,67 @@ +extern crate gfx; +extern crate gfx_device_gl; +extern crate openvr as vr; +extern crate openvr_sys; + +use self::gfx::{tex, Factory, Typed}; + +pub use self::vr::Eye; + +pub struct VR { + system: vr::IVRSystem, + compositor: vr::IVRCompositor, + gfx_handles: gfx::handle::Manager, +} + +impl VR { + pub fn new() -> Result> { + Ok(VR { + system: try!(vr::init()), + compositor: try!(vr::compositor()), + gfx_handles: gfx::handle::Manager::new(), + }) + } + + pub fn poses(&mut self) -> vr::tracking::TrackedDevicePoses { + self.gfx_handles.clear(); + self.compositor.wait_get_poses() + } + + pub fn submit(&mut self, eye: Eye, tex: &gfx::handle::Texture) { + let tex_id = match self.gfx_handles.ref_texture(tex.raw()) { + &gfx_device_gl::NewTexture::Surface(id) => id, + _ => panic!("Not a surface") + }; + self.compositor.submit(eye, + tex_id as usize, + vr::common::TextureBounds::new((0.0, 1.0), (0.0, 1.0))); + } + + pub fn recommended_render_target_size(&self) -> vr::common::Size { + self.system.recommended_render_target_size() + } +} + +impl Drop for VR { + fn drop(&mut self) { + vr::shutdown() + } +} + +pub fn create_eyebuffer(factory: &mut gfx_device_gl::Factory, + size: vr::common::Size) + -> Result<(gfx::handle::Texture, + gfx::handle::RenderTargetView), + gfx::CombinedError> + where T: gfx::format::RenderFormat + gfx::format::TextureFormat { + let tex = try!(factory.create_texture( + tex::Kind::D2(size.width as tex::Size, size.height as tex::Size, tex::AaMode::Single), + 1, // levels + gfx::RENDER_TARGET, // bind + gfx::Usage::GpuOnly, // Usage + Some(::get_channel_type()))); // hint: format::ChannelType? + let tgt = try!(factory.view_texture_as_render_target(&tex, 0, None)); + Ok((tex, tgt)) +}