fixed minor bugs, opengl example is rendering now the lighthouse within the hmd

This commit is contained in:
Rene Eichhorn
2016-05-06 14:39:12 +02:00
parent 5801325a54
commit f085d27003
7 changed files with 169 additions and 19 deletions

4
Cargo.lock generated
View File

@ -3,7 +3,7 @@ name = "openvr"
version = "0.2.0" version = "0.2.0"
dependencies = [ dependencies = [
"glium 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "nalgebra 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.32 (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", "openvr_sys 0.1.0",
] ]
@ -301,7 +301,7 @@ dependencies = [
[[package]] [[package]]
name = "nalgebra" name = "nalgebra"
version = "0.6.0" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -18,4 +18,4 @@ path = "src/sys/"
[dev_dependencies] [dev_dependencies]
glium = "0.14.0" glium = "0.14.0"
num = "0.1.31" num = "0.1.31"
nalgebra = "0.6.0" nalgebra = "0.8.2"

View File

@ -4,6 +4,12 @@ extern crate nalgebra;
#[macro_use] #[macro_use]
extern crate glium; extern crate glium;
use std::convert::From;
use nalgebra::Inverse;
use glium::framebuffer::ToColorAttachment;
use glium::framebuffer::ToDepthAttachment;
use glium::GlObject;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct Vertex { struct Vertex {
position: [f32; 3], position: [f32; 3],
@ -35,17 +41,19 @@ pub fn main() {
for device in system.tracked_devices(0.0).connected_iter() { for device in system.tracked_devices(0.0).connected_iter() {
println!("device found :) -> {}", println!("device found :) -> {}",
device.get_property_string(openvr::ETrackedDeviceProperty_Prop_RenderModelName_String).unwrap_or_else(|_| { panic!("No render model")} )); device.get_property_string(openvr::ETrackedDeviceProperty_Prop_RenderModelName_String).unwrap_or_else(|_| { panic!("No render model")} ));
println!("\t{:?}", device);
println!("\t{:?}", device.device_class());
} }
// init compositor subsystem // init compositor subsystem
/*let comp = match openvr::compositor() { let comp = match openvr::compositor() {
Ok(ext) => ext, Ok(ext) => ext,
Err(err) => { Err(err) => {
println!("Failed to create IVRCompositor subsystem {:?}", err); println!("Failed to create IVRCompositor subsystem {:?}", err);
return; return;
} }
};*/ };
// create glium window and context // create glium window and context
use glium::{DisplayBuild, Surface}; use glium::{DisplayBuild, Surface};
@ -54,6 +62,43 @@ pub fn main() {
.build_glium() .build_glium()
.unwrap(); .unwrap();
// create frame buffer for hmd
let texture_size = system.recommended_render_target_size();
let left_eye_depth = glium::framebuffer::DepthRenderBuffer::new(
&display,
glium::texture::DepthFormat::I24,
texture_size.width,
texture_size.height).unwrap();
let left_eye_texture = glium::framebuffer::RenderBuffer::new(
&display,
glium::texture::UncompressedFloatFormat::U8U8U8U8,
texture_size.width,
texture_size.height).unwrap();
let mut left_eye_framebuffer = glium::framebuffer::SimpleFrameBuffer::with_depth_buffer
(
&display, left_eye_texture.to_color_attachment(), left_eye_depth.to_depth_attachment()
).unwrap();
let right_eye_depth = glium::framebuffer::DepthRenderBuffer::new(
&display,
glium::texture::DepthFormat::I24,
texture_size.width,
texture_size.height).unwrap();
let right_eye_texture = glium::framebuffer::RenderBuffer::new(
&display,
glium::texture::UncompressedFloatFormat::U8U8U8U8,
texture_size.width,
texture_size.height).unwrap();
let mut right_eye_framebuffer = glium::framebuffer::SimpleFrameBuffer::with_depth_buffer
(
&display, right_eye_texture.to_color_attachment(), right_eye_depth.to_depth_attachment()
).unwrap();
// prepare shader // prepare shader
let vertex_shader_src = r#" let vertex_shader_src = r#"
#version 140 #version 140
@ -92,7 +137,7 @@ pub fn main() {
let program = glium::Program::from_source(&display, vertex_shader_src, fragment_shader_src, None).unwrap(); let program = glium::Program::from_source(&display, vertex_shader_src, fragment_shader_src, None).unwrap();
// load controller models // load controller models
let controller = models.load(String::from("generic_hmd")).unwrap_or_else(|err| { let controller = models.load(String::from("lh_basestation_vive")).unwrap_or_else(|err| {
openvr::shutdown(); panic!("controller render model not found: {:?}", err) }); openvr::shutdown(); panic!("controller render model not found: {:?}", err) });
let mut controller_vertices: Vec<Vertex> = Vec::new(); let mut controller_vertices: Vec<Vertex> = Vec::new();
@ -115,21 +160,100 @@ pub fn main() {
let image = glium::texture::RawImage2d::from_raw_rgba(controller_texture_response.to_vec(), dimension); let image = glium::texture::RawImage2d::from_raw_rgba(controller_texture_response.to_vec(), dimension);
let controller_texture = glium::texture::Texture2d::new(&display, image).unwrap(); let controller_texture = glium::texture::Texture2d::new(&display, image).unwrap();
// get static jmatrices
let left_projection = {
let raw = system.projection_matrix(openvr::Eye::Left, 0.01, 1000.0);
let mat = nalgebra::Matrix4::new(
raw[0][0], raw[0][1], raw[0][2], raw[0][3],
raw[1][0], raw[1][1], raw[1][2], raw[1][3],
raw[2][0], raw[2][1], raw[2][2], raw[2][3],
raw[3][0], raw[3][1], raw[3][2], raw[3][3]);
mat
};
let left_eye_transform = {
let raw = system.eye_to_head_transform(openvr::Eye::Left);
let mat = nalgebra::Matrix4::new(
raw[0][0], raw[1][0], raw[2][0], 0.0,
raw[0][1], raw[1][1], raw[2][1], 0.0,
raw[0][2], raw[1][2], raw[2][2], 0.0,
raw[0][3], raw[1][3], raw[2][3], 1.0);
mat.inverse().unwrap()
};
let right_projection = {
let raw = system.projection_matrix(openvr::Eye::Right, 0.01, 1000.0);
let mat = nalgebra::Matrix4::new(
raw[0][0], raw[0][1], raw[0][2], raw[0][3],
raw[1][0], raw[1][1], raw[1][2], raw[1][3],
raw[2][0], raw[2][1], raw[2][2], raw[2][3],
raw[3][0], raw[3][1], raw[3][2], raw[3][3]);
mat
};
let right_eye_transform = {
let raw = system.eye_to_head_transform(openvr::Eye::Right);
let mat = nalgebra::Matrix4::new(
raw[0][0], raw[1][0], raw[2][0], 0.0,
raw[0][1], raw[1][1], raw[2][1], 0.0,
raw[0][2], raw[1][2], raw[2][2], 0.0,
raw[0][3], raw[1][3], raw[2][3], 1.0);
mat.inverse().unwrap()
};
'render: loop { 'render: loop {
// this is important to make sure frames are synced correctly // this is important to make sure frames are synced correctly
//let _ = comp.wait_get_poses(); let tracked_devices = comp.wait_get_poses();
let mut left_matrix = left_projection * left_eye_transform;
let mut right_matrix = right_projection * right_eye_transform;
let mut once = false;
for device in tracked_devices.connected_iter() {
match device.device_class() {
openvr::ETrackedDeviceClass_TrackedDeviceClass_HMD => {
let matrix = {
let raw = device.to_device;
let mat = nalgebra::Matrix4::new(
raw[0][0], raw[0][1], raw[0][2], raw[0][3],
raw[1][0], raw[1][1], raw[1][2], raw[1][3],
raw[2][0], raw[2][1], raw[2][2], raw[2][3],
0.0, 0.0, 0.0, 1.0);
mat.inverse().unwrap()
};
left_matrix *= matrix;
right_matrix *= matrix;
},
openvr::ETrackedDeviceClass_TrackedDeviceClass_TrackingReference => {
if once { continue; }
once = true;
let matrix = {
let raw = device.to_device;
let mat = nalgebra::Matrix4::new(
raw[0][0], raw[0][1], raw[0][2], raw[0][3],
raw[1][0], raw[1][1], raw[1][2], raw[1][3],
raw[2][0], raw[2][1], raw[2][2], raw[2][3],
0.0, 0.0, 0.0, 1.0);
mat
};
left_matrix *= matrix;
right_matrix *= matrix;
},
_ => { }
};
}
// render 2d display output
let mut target = display.draw(); let mut target = display.draw();
target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0); target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);
let uniforms = uniform! { let left_uniforms = uniform! {
matrix: [ matrix: *left_matrix.as_ref(),
[5.0, 0.0, 0.0, 0.0], diffuse: &controller_texture
[0.0, 5.0, 0.0, 0.0], };
[0.0, 0.0, 5.0, 0.0],
[0.0 , 0.0, 0.0, 1.0f32], let right_uniforms = uniform! {
], matrix: *right_matrix.as_ref(),
diffuse: &controller_texture diffuse: &controller_texture
}; };
@ -139,18 +263,26 @@ pub fn main() {
write: true, write: true,
.. Default::default() .. Default::default()
}, },
backface_culling: glium::draw_parameters::BackfaceCullingMode::CullCounterClockwise, backface_culling: glium::draw_parameters::BackfaceCullingMode::CullClockwise,
.. Default::default() .. Default::default()
}; };
target.draw(&controller_vertex_buffer, &controller_index_buffer, &program, &uniforms, &params).unwrap(); // render 2d display output
target.draw(&controller_vertex_buffer, &controller_index_buffer, &program, &left_uniforms, &params).unwrap();
// render hmd eye outputs // render hmd eye outputs
left_eye_framebuffer.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);
right_eye_framebuffer.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);
left_eye_framebuffer.draw(&controller_vertex_buffer, &controller_index_buffer, &program, &left_uniforms, &params).unwrap();
right_eye_framebuffer.draw(&controller_vertex_buffer, &controller_index_buffer, &program, &right_uniforms, &params).unwrap();
// finish all rendering // finish all rendering
target.finish().unwrap(); target.finish().unwrap();
// submit to hmd // submit to hmd
comp.submit(openvr::Eye::Left, left_eye_texture.get_id() as usize, openvr::common::TextureBounds::new((0.0, 1.0), (0.0, 1.0)));
comp.submit(openvr::Eye::Right, right_eye_texture.get_id() as usize, openvr::common::TextureBounds::new((0.0, 1.0), (0.0, 1.0)));
// handle window events // handle window events
for ev in display.poll_events() { for ev in display.poll_events() {

View File

@ -50,6 +50,15 @@ pub struct TextureBounds {
} }
impl TextureBounds { impl TextureBounds {
pub fn new(u: (f32, f32), v: (f32, f32)) -> Self {
TextureBounds {
u_min: u.0,
u_max: u.1,
v_min: v.0,
v_max: v.1
}
}
/// Convert a bounds to a openvr_bounds /// Convert a bounds to a openvr_bounds
pub fn to_raw(self) -> openvr_sys::VRTextureBounds_t { pub fn to_raw(self) -> openvr_sys::VRTextureBounds_t {
openvr_sys::VRTextureBounds_t{ openvr_sys::VRTextureBounds_t{

View File

@ -2,6 +2,7 @@ extern crate openvr_sys;
pub use openvr_sys::Enum_EVRInitError::*; pub use openvr_sys::Enum_EVRInitError::*;
pub use openvr_sys::Enum_EVRApplicationType::*; pub use openvr_sys::Enum_EVRApplicationType::*;
pub use openvr_sys::Enum_ETrackedDeviceProperty::*; pub use openvr_sys::Enum_ETrackedDeviceProperty::*;
pub use openvr_sys::Enum_ETrackedDeviceClass::*;
pub mod common; pub mod common;
pub mod tracking; pub mod tracking;

View File

@ -60,7 +60,7 @@ pub enum Enum_ETrackingResult {
ETrackingResult_TrackingResult_Running_OutOfRange = 201, ETrackingResult_TrackingResult_Running_OutOfRange = 201,
} }
pub type ETrackingResult = Enum_ETrackingResult; pub type ETrackingResult = Enum_ETrackingResult;
#[derive(Clone, Copy)] #[derive(Clone, Copy, Debug)]
#[repr(u32)] #[repr(u32)]
pub enum Enum_ETrackedDeviceClass { pub enum Enum_ETrackedDeviceClass {
ETrackedDeviceClass_TrackedDeviceClass_Invalid = 0, ETrackedDeviceClass_TrackedDeviceClass_Invalid = 0,

View File

@ -13,6 +13,14 @@ pub struct TrackedDevicePose {
} }
impl TrackedDevicePose { impl TrackedDevicePose {
// returns the device class of the tracked object
pub fn device_class(&self) -> openvr_sys::Enum_ETrackedDeviceClass {
unsafe {
let system = * { system().unwrap().0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable};
system.GetTrackedDeviceClass.unwrap()(self.index as u32)
}
}
/// gets a propery as a string /// gets a propery as a string
pub fn get_property_string(&self, property: openvr_sys::Enum_ETrackedDeviceProperty) -> Result<String, openvr_sys::Enum_ETrackedPropertyError> { pub fn get_property_string(&self, property: openvr_sys::Enum_ETrackedDeviceProperty) -> Result<String, openvr_sys::Enum_ETrackedPropertyError> {
unsafe { unsafe {