mirror of
https://github.com/mii443/rust-openvr.git
synced 2025-08-22 16:25:36 +00:00
Update to 1.0.10, fix travis (#31)
* Update to OpenVR 1.0.10 * Typo fix * Missing doc comment * Delete dead examples, cleanup * Delete dead code * Remove lifetimes from subsystems OpenVR must be shut down manually, which invalidates outstanding subsystem handles regardless of lifetimes, rendering the ergonomic sacrifice pointless. Future work: make shutdown safe by inserting checks before every OpenVR call. * Depend on our own openvr-sys * Update metadata * Update readme * More detailed safety notes * Depend on released openvr-sys
This commit is contained in:
committed by
GitHub
parent
eb1f18a4ea
commit
2098bcc257
@ -1,61 +0,0 @@
|
||||
extern crate openvr;
|
||||
|
||||
pub fn main () {
|
||||
{
|
||||
// init vr system
|
||||
let system = match openvr::init() {
|
||||
Ok(ivr) => ivr,
|
||||
Err(err) => {
|
||||
println!("Failed to create IVRSystem subsystem {:?}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// init camera subsystem
|
||||
let camera = match openvr::subsystems::tracked_camera() {
|
||||
Ok(ivr) => ivr,
|
||||
Err(err) => {
|
||||
println!("Failed to create IVRTrackedCamera subsystem {:?}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// look for tracked devices with a camera
|
||||
let mut camera_device = None;
|
||||
for device in system.tracked_devices(0.0).connected_iter() {
|
||||
if camera.has_camera(&device).unwrap_or(false) {
|
||||
println!("Tracked Device with camera found, ID: {}", device.index);
|
||||
println!("\t{:?}", device.device_class());
|
||||
println!("\t{:?}", camera.frame_size(&device, openvr::tracked_camera::CameraFrameType::MaximumUndistorted));
|
||||
println!("\t{:?}", camera.intrinisics(&device, openvr::tracked_camera::CameraFrameType::MaximumUndistorted));
|
||||
|
||||
camera_device = Some(device.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// make sure camera is available
|
||||
if camera_device.is_none() {
|
||||
println!("No tracked device with camera found. Exiting..");
|
||||
|
||||
openvr::shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
// create stream
|
||||
let stream = camera.stream(&camera_device.unwrap()).unwrap_or_else(|err| {
|
||||
println!("Could not start stream to camera: {}", err.message());
|
||||
openvr::shutdown();
|
||||
panic!("");
|
||||
});
|
||||
|
||||
let frame = stream.read(openvr::tracked_camera::CameraFrameType::MaximumUndistorted).unwrap_or_else(|err| {
|
||||
println!("Could not read from camera stream: {}", err.message());
|
||||
openvr::shutdown();
|
||||
panic!("");
|
||||
});
|
||||
|
||||
println!("Frame Data recieved! {:?}", frame);
|
||||
}
|
||||
|
||||
openvr::shutdown();
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
extern crate openvr;
|
||||
extern crate nalgebra;
|
||||
|
||||
pub fn main () {
|
||||
let system = openvr::init().unwrap();
|
||||
let render_model = openvr::render_models().unwrap();
|
||||
let _ = openvr::compositor().unwrap();
|
||||
|
||||
loop {
|
||||
let _ = openvr::compositor().unwrap().wait_get_poses();
|
||||
let raw = system.projection_matrix(openvr::Eye::Left, 0.1, 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]);
|
||||
|
||||
println!("{:?}", mat);
|
||||
}
|
||||
}
|
@ -1,299 +0,0 @@
|
||||
extern crate openvr;
|
||||
extern crate nalgebra;
|
||||
|
||||
#[macro_use]
|
||||
extern crate glium;
|
||||
|
||||
use std::convert::From;
|
||||
use nalgebra::Inverse;
|
||||
use glium::framebuffer::ToColorAttachment;
|
||||
use glium::framebuffer::ToDepthAttachment;
|
||||
use glium::GlObject;
|
||||
|
||||
#[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 render model subsystem
|
||||
let models = match openvr::render_models() {
|
||||
Ok(ext) => ext,
|
||||
Err(err) => {
|
||||
println!("Failed to create IVRRenderModels subsystem {:?}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
for device in system.tracked_devices(0.0).connected_iter() {
|
||||
println!("device found :) -> {}",
|
||||
device.get_property_string(openvr::tracking::TrackedDeviceStringProperty::RenderModelName).unwrap_or_else(|_| { panic!("No render model")} ));
|
||||
|
||||
println!("\t{:?}", device);
|
||||
println!("\t{:?}", device.device_class());
|
||||
}
|
||||
|
||||
// init compositor subsystem
|
||||
let comp = match openvr::compositor() {
|
||||
Ok(ext) => ext,
|
||||
Err(err) => {
|
||||
println!("Failed to create IVRCompositor 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();
|
||||
|
||||
// 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
|
||||
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("lh_basestation_vive")).unwrap_or_else(|err| {
|
||||
openvr::shutdown(); panic!("controller render model not found: {:?}", err) });
|
||||
|
||||
let mut controller_vertices: Vec<Vertex> = Vec::new();
|
||||
let mut controller_indices: Vec<u16> = 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();
|
||||
|
||||
// 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 {
|
||||
// this is important to make sure frames are synced correctly
|
||||
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::tracking::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::tracking::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;
|
||||
},
|
||||
_ => { }
|
||||
};
|
||||
}
|
||||
|
||||
let mut target = display.draw();
|
||||
target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);
|
||||
|
||||
let left_uniforms = uniform! {
|
||||
matrix: *left_matrix.as_ref(),
|
||||
diffuse: &controller_texture
|
||||
};
|
||||
|
||||
let right_uniforms = uniform! {
|
||||
matrix: *right_matrix.as_ref(),
|
||||
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::CullClockwise,
|
||||
.. Default::default()
|
||||
};
|
||||
|
||||
// render 2d display output
|
||||
target.draw(&controller_vertex_buffer, &controller_index_buffer, &program, &left_uniforms, ¶ms).unwrap();
|
||||
|
||||
// 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, ¶ms).unwrap();
|
||||
right_eye_framebuffer.draw(&controller_vertex_buffer, &controller_index_buffer, &program, &right_uniforms, ¶ms).unwrap();
|
||||
|
||||
// finish all rendering
|
||||
target.finish().unwrap();
|
||||
|
||||
// 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
|
||||
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();
|
||||
}
|
@ -19,7 +19,7 @@ fn main() {
|
||||
let context = match unsafe { openvr::init(openvr::ApplicationType::Other) } {
|
||||
Ok(ivr) => ivr,
|
||||
Err(err) => {
|
||||
println!("Failed to initialize openvr {:?}", err);
|
||||
println!("Failed to initialize openvr: {}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -29,7 +29,7 @@ fn main() {
|
||||
let system = match context.system() {
|
||||
Ok(sys) => sys,
|
||||
Err(err) => {
|
||||
println!("Failed to get system interface {:?}", err);
|
||||
println!("Failed to get system interface: {}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -42,7 +42,7 @@ fn main() {
|
||||
print!("\tProjection matrix right ");
|
||||
print_matrix_4x4(31, system.projection_matrix(openvr::Eye::Right, 0.1, 100.));
|
||||
|
||||
print!("\tEye_to_head ");
|
||||
print!("\tEye to head left ");
|
||||
print_matrix_4x3(8+12, system.eye_to_head_transform(openvr::Eye::Left));
|
||||
|
||||
print!("\tPoses ");
|
||||
@ -65,49 +65,20 @@ fn main() {
|
||||
println!("");
|
||||
}
|
||||
|
||||
/*
|
||||
let ext = match context.extended_display() {
|
||||
Ok(ext) => ext,
|
||||
Err(err) => {
|
||||
println!("Failed to create IVRExtendedDisplay subsystem {:?}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
println!("\nIVRExtendedDisplay was created");
|
||||
|
||||
println!("\tBounds: {:?}", ext.window_bounds());
|
||||
println!("\tEye output: {:?} {:?}", ext.eye_viewport(openvr::Eye::Left), ext.eye_viewport(openvr::Eye::Right));
|
||||
*/
|
||||
|
||||
let comp = match context.compositor() {
|
||||
Ok(ext) => ext,
|
||||
Err(err) => {
|
||||
println!("Failed to create IVRCompositor subsystem {:?}", err);
|
||||
println!("Failed to create IVRCompositor subsystem: {}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
println!("\nIVRCompositor was created");
|
||||
println!("\tIs fullscreen = {}", comp.is_fullscreen());
|
||||
println!("\tInstance Extensions:");
|
||||
println!("\tVulkan Instance Extensions:");
|
||||
for ext in comp.vulkan_instance_extensions_required() {
|
||||
println!("\t\t{:?}", ext);
|
||||
}
|
||||
|
||||
/*
|
||||
let model = match context.render_models() {
|
||||
Ok(ext) => ext,
|
||||
Err(err) => {
|
||||
println!("Failed to create IVRRenderModels subsystem {:?}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
println!("\nIVRRenderModels was created\n Count: {}", model.get_count());
|
||||
for i in 0..model.get_count() {
|
||||
println!("\t{}", model.get_name(i));
|
||||
}
|
||||
*/
|
||||
|
||||
println!("Done! \\o/");
|
||||
}
|
||||
|
Reference in New Issue
Block a user