diff --git a/src/bin/vrtue.rs b/src/bin/vrtue.rs index b0be0ac..b40ae9d 100644 --- a/src/bin/vrtue.rs +++ b/src/bin/vrtue.rs @@ -26,7 +26,7 @@ pub fn main() { 'main: //while let Some(_) = window.next() { loop { - scene.update(); + scene.update(&mut window.encoder); view.draw(&mut window, &mut vr, &scene); // handle window events diff --git a/src/scene.rs b/src/scene.rs index 793ca42..17069e5 100644 --- a/src/scene.rs +++ b/src/scene.rs @@ -8,7 +8,8 @@ extern crate piston_window; pub trait Scene> { fn event(&mut self, event: Event); - fn update(&mut self); + fn update(&mut self, + encoder: &mut gfx::Encoder); fn render(&self, factory: &mut F, encoder: &mut gfx::Encoder, diff --git a/src/scenes/world.rs b/src/scenes/world.rs index 6cafed6..9408d01 100644 --- a/src/scenes/world.rs +++ b/src/scenes/world.rs @@ -8,6 +8,7 @@ extern crate gfx; extern crate piston_window; use std::marker::PhantomData; +use std::time::SystemTime; use gfx::tex; use gfx::traits::FactoryExt; @@ -19,9 +20,15 @@ gfx_defines! { tileidx: u32 = "a_tileidx", } + constant Locals { + millis: u32 = "millis", + anim: u32 = "anim", + } + pipeline pipe { vbuf: gfx::VertexBuffer = (), trans: gfx::ConstantBuffer<::view::Trans> = "b_trans", + locals: gfx::ConstantBuffer = "b_locals", atlas: gfx::TextureSampler<[f32; 4]> = "t_atlas", pixcolor: gfx::RenderTarget<::view::ColorFormat> = "pixcolor", depth: gfx::DepthTarget<::view::DepthFormat> = gfx::preset::depth::LESS_EQUAL_WRITE, @@ -37,13 +44,13 @@ fn get_model(world: &model::World) -> (Vec, Vec) { for (r, row) in world.map().rows().enumerate() { for (c, tile) in row.into_iter().enumerate() { let tileidx = tile.val as u32; - let rf = (((r + 32) % 256) as i16 - 128) as f32; - let cf = (((c + 32) % 256)as i16 - 128) as f32; + let rf = (((r + 26) % 256) as i16 - 128) as f32; + let cf = (((c + 48) % 256) as i16 - 128) as f32; verticies.extend_from_slice( - &[Vertex { pos: [ cf + 0., -rf - 1., -20.0 ], uv: [0., 0.], tileidx: tileidx }, - Vertex { pos: [ cf + 1., -rf - 1., -20.0 ], uv: [1., 0.], tileidx: tileidx }, - Vertex { pos: [ cf + 1., -rf - 0., -20.0 ], uv: [1., 1.], tileidx: tileidx }, - Vertex { pos: [ cf + 0., -rf - 0., -20.0 ], uv: [0., 1.], tileidx: tileidx },]); + &[Vertex { pos: [ cf + 0., 0., -rf - 1. ], uv: [0., 0.], tileidx: tileidx }, + Vertex { pos: [ cf + 1., 0., -rf - 1. ], uv: [1., 0.], tileidx: tileidx }, + Vertex { pos: [ cf + 1., 0., -rf - 0. ], uv: [1., 1.], tileidx: tileidx }, + Vertex { pos: [ cf + 0., 0., -rf - 0. ], uv: [0., 1.], tileidx: tileidx },]); indicies.extend_from_slice( &[ v + 0, v + 1, v + 2, v + 2, v + 3, v + 0 ]); @@ -56,6 +63,7 @@ fn get_model(world: &model::World) -> (Vec, Vec) { pub struct WorldScene> { pso: gfx::PipelineState, + locals: gfx::handle::Buffer, atlas: gfx::handle::ShaderResourceView::View>, sampler: gfx::handle::Sampler, @@ -63,6 +71,8 @@ pub struct WorldScene, slice: gfx::Slice, + + start_time: SystemTime, } impl> WorldScene { @@ -76,6 +86,7 @@ impl> WorldScene { FRAGMENT_SHADER_SRC, pipe::new()) .expect("create pipeline"), + locals: factory.create_constant_buffer(1), atlas: tile::get_tiles::<_, _, view::ColorFormat>(factory), sampler: factory.create_sampler(tex::SamplerInfo::new(tex::FilterMethod::Scale, tex::WrapMode::Clamp)), @@ -83,17 +94,30 @@ impl> WorldScene { vbuf: vertex_buffer, slice: slice, + start_time: SystemTime::now(), } } } +const ANIMDATA: [u32; 4] = + [1 << 0 | 1 << 1 | 1 << 2, + 0, + 1 << (68 % 32) | 1 << (69 % 32) | 1 << (70 % 32) | 1 << (71 % 32) | 1 << (76 % 32), + 0]; + impl> scene::Scene for WorldScene { fn event(&mut self, event: scene::Event) { } - fn update(&mut self) { + fn update(&mut self, + encoder: &mut gfx::Encoder) { + const NANOS_PER_MILLI: u32 = 1_000_000; + const MILLIS_PER_SEC: u64 = 1_000; + let elapsed = self.start_time.elapsed().expect("scene timer"); + let millis = elapsed.subsec_nanos() / NANOS_PER_MILLI + (elapsed.as_secs() * MILLIS_PER_SEC) as u32; + encoder.update_constant_buffer(&self.locals, &Locals { millis: millis, anim: ANIMDATA[0] }); } fn render(&self, @@ -106,6 +130,7 @@ impl { -> ViewRoot { let render_size = vr.recommended_render_target_size(); + + let render_size = vr::Size { width: render_size.width * 220 / 100, + height: render_size.height * 220 / 100 }; + let left = vr::create_eyebuffer(&mut window.factory, render_size) .expect("create left renderbuffer"); let right = vr::create_eyebuffer(&mut window.factory, render_size) @@ -67,7 +71,7 @@ impl ViewRoot { for &(eye, buffers) in [(vr::Eye::Left, &self.left), (vr::Eye::Right, &self.right)].into_iter() { - window.encoder.clear(&buffers.target, [0.05, 0.05, 0.1, 1.0]); + window.encoder.clear(&buffers.target, [0.005, 0.005, 0.01, 1.0]); window.encoder.clear_depth(&buffers.depth, 1.0); @@ -75,9 +79,7 @@ impl ViewRoot { let proj_mat = vr.projection_matrix(eye, NEAR, FAR); let eye_mat = vr.head_to_eye_transform(eye); - let model_mat = na::Matrix4::one(); - - let trans = Trans { matrix: *(proj_mat * eye_mat * hmd_mat * model_mat).as_ref() }; + let trans = Trans { matrix: *(proj_mat * eye_mat * hmd_mat).as_ref() }; window.encoder.update_constant_buffer(&self.trans, &trans); scene.render(&mut window.factory, diff --git a/src/vr.rs b/src/vr.rs index c30b66c..ee4ac1b 100644 --- a/src/vr.rs +++ b/src/vr.rs @@ -6,7 +6,8 @@ extern crate openvr as vr; extern crate openvr_sys; pub use self::vr::Eye; -pub use self::vr::tracking::TrackedDeviceClass; +pub use self::vr::common::Size; +pub use self::vr::tracking::{TrackedDeviceClass, TrackedDevicePoses}; use self::gfx::{tex, Factory, Typed}; use self::gfx_device_gl::Resources as GLResources; @@ -54,7 +55,7 @@ impl VR { vr::common::TextureBounds::new((0.0, 1.0), (0.0, 1.0))); } - pub fn recommended_render_target_size(&self) -> vr::common::Size { + pub fn recommended_render_target_size(&self) -> Size { self.system.recommended_render_target_size() } @@ -149,7 +150,7 @@ pub struct EyeBuffer } pub fn create_eyebuffer(factory: &mut gfx_device_gl::Factory, - size: vr::common::Size) + size: Size) -> Result, gfx::CombinedError> where T: gfx::format::RenderFormat + gfx::format::TextureFormat, D: gfx::format::DepthFormat + gfx::format::TextureFormat {