mirror of
https://github.com/mii443/rust-openvr.git
synced 2025-08-23 00:35:31 +00:00
fixed some render_model bugs, added opengl/glium sample that renders sample rendermodel
This commit is contained in:
@ -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<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();
|
||||
|
||||
'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();
|
||||
}
|
||||
|
Reference in New Issue
Block a user