pixels from headset

This commit is contained in:
2016-09-06 17:15:55 -07:00
parent 8493a12298
commit dacee68d89
2 changed files with 219 additions and 0 deletions

View File

@@ -4,8 +4,17 @@ version = "0.1.0"
authors = ["Jared Roberts <jaredr@gmail.com>"] authors = ["Jared Roberts <jaredr@gmail.com>"]
[dependencies] [dependencies]
env_logger = "0.3"
itertools = ">=0.4" itertools = ">=0.4"
log = "0.3"
memmap = "~0.2" memmap = "~0.2"
gl = "*"
gfx = "*"
gfx_device_gl = "*"
openvr = { git = "https://github.com/rust-openvr/rust-openvr" }
piston = "*"
piston_window = "*"
sdl2 = "0.22" sdl2 = "0.22"
sdl2_image = "0.22" sdl2_image = "0.22"

210
src/bin/gl.rs Normal file
View File

@@ -0,0 +1,210 @@
extern crate gl;
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 piston_window;
use gfx::{tex, CombinedError, Device, Factory, Typed};
use gfx::traits::FactoryExt;
use piston_window::{PistonWindow, Window, WindowSettings};
pub type ColorFormat = gfx::format::Srgba8;
//pub type DepthFormat = gfx::format::DepthStencil;
gfx_defines!{
vertex Vertex {
pos: [f32; 2] = "a_pos",
color: [f32; 3] = "a_color",
}
pipeline pipe {
vbuf: gfx::VertexBuffer<Vertex> = (),
pixcolor: gfx::RenderTarget<ColorFormat> = "pixcolor",
}
}
const TRIANGLE: [Vertex; 3] = [
Vertex { pos: [ -0.5, -0.5 ], color: [1.0, 0.0, 0.0] },
Vertex { pos: [ 0.5, -0.5 ], color: [0.0, 1.0, 0.0] },
Vertex { pos: [ 0.0, 0.5 ], color: [0.0, 0.0, 1.0] }
];
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 window: PistonWindow =
WindowSettings::new("Hello Virtual World!", [512; 2])
.exit_on_esc(true)
.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);
let _eyeleft = system.eye_to_head_transform(vr::Eye::Left);
let _sysright = system.projection_matrix(vr::Eye::Right, 0.01, 1000.0);
let _eyeright = system.eye_to_head_transform(vr::Eye::Right);
*/
let pso = window.factory.create_pipeline_simple(VERTEX_SHADER_SRC,
FRAGMENT_SHADER_SRC,
pipe::new())
.expect("create pipeline");
let (tex_left, tgt_left) = create_renderbuffer_target::<gfx::format::Srgba8>(&mut window.factory,
render_size.width as tex::Size,
render_size.height as tex::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)
.expect("create right renderbuffer");
let (vertex_buffer, slice) = window.factory.create_vertex_buffer_with_slice(&TRIANGLE, ());
let pipe_monitor = pipe::Data {
vbuf: vertex_buffer.clone(),
pixcolor: window.output_color.clone(),
};
let pipe_left = pipe::Data {
vbuf: vertex_buffer.clone(),
pixcolor: tgt_left,
};
let pipe_right = pipe::Data {
vbuf: vertex_buffer.clone(),
pixcolor: tgt_right,
};
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() {
loop {
info!("Frame #{}", frame);
let _now = std::time::SystemTime::now();
// Get the current sensor state
let _poses = compositor.wait_get_poses();
manager.clear();
trace!("\t{:?} got pose", _now.elapsed());
if frame % 90 == 0 {
warn!("\t#{}: poses: {:?}\n", frame, _poses.poses[0]);
}
frame += 1;
for pass in [(Some((vr::Eye::Left, &tex_left)), &pipe_left),
(Some((vr::Eye::Right, &tex_right)), &pipe_right),
(None, &pipe_monitor),]
.into_iter() {
info!("\tpass for eye: {:?}", pass.0);
window.encoder.clear(&pass.1.pixcolor, [0.1, 0.5, 0.1, 1.0]);
window.encoder.draw(&slice, &pso, pass.1);
window.encoder.flush(&mut window.device);
// 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)));
trace!("\t\t{:?} submit {:?}", _now.elapsed(), eye);
gl_debug(&mut window.device, b"after!");
check_err(&mut window.device);
} else {
window.window.swap_buffers();
}
}
window.device.cleanup();
// handle window events
while let Some(ev) = window.poll_event() {
match ev {
piston_window::Input::Text(_) => break 'main,
_ => debug!("\t{:?}", ev)
}
}
}
info!("shutting down");
vr::shutdown()
}
fn create_renderbuffer_target<T>(factory: &mut gfx_device_gl::Factory,
width: tex::Size,
height: tex::Size)
-> Result<(gfx::handle::Texture<gfx_device_gl::Resources,
T::Surface>,
gfx::handle::RenderTargetView<gfx_device_gl::Resources,
T>),
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(<T::Channel as gfx::format::ChannelTyped>::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| {
gl.DebugMessageInsert(gl::DEBUG_SOURCE_APPLICATION,
gl::DEBUG_TYPE_OTHER,
0,
gl::DEBUG_SEVERITY_LOW,
msg.len() as i32,
std::mem::transmute(msg));
});
}
}
fn check_err(device: &mut gfx_device_gl::Device) {
unsafe {
device.with_gl_naked(|gl| {
let err: gl::types::GLenum = gl.GetError();
if err != gl::NO_ERROR {
panic!("GL Error! {:?}", err);
}
});
}
}
const VERTEX_SHADER_SRC: &'static [u8] = br#"
#version 140
in vec2 a_pos;
in vec3 a_color;
out vec3 v_color;
void main() {
v_color = a_color;
gl_Position = vec4(a_pos, 0.0, 1.0);
}
"#;
const FRAGMENT_SHADER_SRC: &'static [u8] = br#"
#version 140
in vec3 v_color;
out vec4 pixcolor;
void main() {
pixcolor = vec4(v_color, 1.0);
}
"#;