From 2aa64060b6bb16b5a37cce5aa9e8b1f0467521d3 Mon Sep 17 00:00:00 2001 From: Jared Roberts Date: Fri, 17 Feb 2017 17:02:14 -0800 Subject: [PATCH] wip --- Cargo.toml | 3 ++ src/bin/vrtue.rs | 12 ++++--- src/context.rs | 77 +++++++++++++++++++++++++++++++++++++++++++++ src/engine.rs | 30 ++++++++++++++++++ src/lib.rs | 3 +- src/scenes/world.rs | 34 ++++++++++---------- src/tile.rs | 46 --------------------------- src/view.rs | 24 ++++++++------ 8 files changed, 151 insertions(+), 78 deletions(-) create mode 100644 src/context.rs create mode 100644 src/engine.rs diff --git a/Cargo.toml b/Cargo.toml index f545e11..104c026 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,9 @@ openvr_sys = "*" piston = "*" piston_window = "*" +# for pose-relay +byteorder = "*" + [profile.release] lto = true panic = "abort" diff --git a/src/bin/vrtue.rs b/src/bin/vrtue.rs index ffc7496..8138224 100644 --- a/src/bin/vrtue.rs +++ b/src/bin/vrtue.rs @@ -1,6 +1,6 @@ extern crate vrtue; -use vrtue::{scenes, view, vr}; -use vrtue::scene::{Event, Scene}; +use vrtue::{context, scenes, view, vr}; +use vrtue::engine::{Event, Scene}; extern crate env_logger; extern crate gfx_device_gl; @@ -12,7 +12,6 @@ use self::piston::input::{Button, Input, Key}; use self::piston_window::{PistonWindow, Window, WindowSettings}; use std::env; - pub fn main() { env_logger::init().expect("env logger"); let mut vr = match env::var("NO_VR") { @@ -33,11 +32,14 @@ pub fn main() { let view = view::ViewRoot:: ::create_view(&mut window, &mut vr); + let mut game = context::VrtueRootContext::new(&mut window.device, + &mut window.factory, + &mut aux_command); 'main: //while let Some(_) = window.next() { loop { - scene.update(&mut vr, &mut window.encoder); - view.draw(&mut window, &mut vr, &scene); + scene.update(&mut game, &mut vr, &mut window.encoder); + view.draw(&mut game, &mut window, &mut vr, &scene); // handle window events while let Some(ev) = window.poll_event() { diff --git a/src/context.rs b/src/context.rs new file mode 100644 index 0000000..364800a --- /dev/null +++ b/src/context.rs @@ -0,0 +1,77 @@ +use ega; +use engine; + +use std::io::Read; +use std::marker::PhantomData; +use std::path::Path; + +use gfx::{self, CommandBuffer}; +use gfx::memory::Typed; +use gfx::texture; + +const TILEDIM: u16 = 16; + +pub struct VrtueRootContext + where D: gfx::Device, + F: gfx::Factory, + T: gfx::format::TextureFormat { + + tiles: gfx::handle::ShaderResourceView, + _factory: PhantomData +} + +impl engine::GameContext for VrtueRootContext + where D: gfx::Device, + F: gfx::Factory, + T: gfx::format::TextureFormat {} + +impl VrtueRootContext + where D: gfx::Device, + F: gfx::Factory, + T: gfx::format::TextureFormat, + T::View: Clone { + + pub fn new(device: &mut D, + factory: &mut F, + command: &mut ::CommandBuffer) -> VrtueRootContext { + VrtueRootContext { + tiles: Self::make_tiles(device, factory, command), + _factory: PhantomData + } + } + + pub fn tiles(&self) -> gfx::handle::ShaderResourceView { + self.tiles.clone() + } + + fn make_tiles(device: &mut D, + factory: &mut F, + command: &mut ::CommandBuffer) + -> gfx::handle::ShaderResourceView { + let filename = "data/SHAPES.EGA"; + let mut file = ::std::fs::File::open(Path::new(filename)) + .expect(&format!("failed opening tiles file: {}", filename)); + let mut ega_bytes = Vec::new(); + file.read_to_end(&mut ega_bytes).expect("Read tiles file"); + let ega_page = ega::decode(&ega_bytes, ega::Compression::Uncompressed, ega::Tiling::Tiled(TILEDIM)); + let mipmap = ega_page.mipmap(2); + + let tex = factory.create_texture_immutable_u8::(texture::Kind::D2Array(mipmap.dim as u16, + mipmap.dim as u16, + mipmap.len as u16, + texture::AaMode::Single), + &mipmap.slices()) + .expect("create tile texture"); + + { + let mut manager = gfx::handle::Manager::::new(); + // XXX: Find out if Textures need to be/can be fenced like Buffers, + // Seems like I should mark tex.1 as being read/written, but it's not a Buffer? + let access = gfx::pso::AccessInfo::new(); + let view = manager.ref_srv(tex.1.raw()); + command.generate_mipmap(*view); + device.submit(command, &access); + } + tex.1 + } +} diff --git a/src/engine.rs b/src/engine.rs new file mode 100644 index 0000000..83fe41f --- /dev/null +++ b/src/engine.rs @@ -0,0 +1,30 @@ +use gfx; +use na; +use piston; +use view; +use vr; + +pub trait GameContext {} + +pub trait Scene> { + fn event(&mut self, event: Event); + fn update(&mut self, + game: &mut G, + vr: &mut Option, // TODO: abstract this out + encoder: &mut gfx::Encoder); + fn render(&self, + game: &mut G, + trans: &gfx::handle::Buffer, + target: &gfx::handle::RenderTargetView, + depth: &gfx::handle::DepthStencilView, + factory: &mut F, + encoder: &mut gfx::Encoder); + fn origin(&self) -> na::Matrix4; +} + +pub enum Event { + Vr(vr::Event), + Piston(piston::input::Input), +} diff --git a/src/lib.rs b/src/lib.rs index 7a61868..fd41a15 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,8 +7,9 @@ extern crate num_traits; extern crate piston; pub mod arena; +pub mod context; pub mod ega; -pub mod scene; +pub mod engine; pub mod scenes; pub mod tile; pub mod town; diff --git a/src/scenes/world.rs b/src/scenes/world.rs index faab0b2..b3043df 100644 --- a/src/scenes/world.rs +++ b/src/scenes/world.rs @@ -1,5 +1,5 @@ -use scene; -use tile; +use context::VrtueRootContext; +use engine; use view; use vr; use world as model; @@ -54,7 +54,7 @@ gfx_defines! { trans: gfx::ConstantBuffer<::view::Trans> = "b_trans", constants: gfx::ConstantBuffer = "b_constants", locals: gfx::ConstantBuffer = "b_locals", - atlas: gfx::TextureSampler<[f32; 4]> = "t_tiles", + tiles: gfx::TextureSampler<[f32; 4]> = "t_tiles", pixcolor: gfx::RenderTarget<::view::ColorFormat> = "pixcolor", depth: gfx::DepthTarget<::view::DepthFormat> = gfx::preset::depth::LESS_EQUAL_WRITE, } @@ -125,8 +125,6 @@ pub struct WorldScene, constants_dirty: bool, locals: gfx::handle::Buffer, - atlas: gfx::handle::ShaderResourceView::View>, sampler: gfx::handle::Sampler, f: PhantomData, @@ -142,10 +140,11 @@ pub struct WorldScene> WorldScene { - pub fn new(device: &mut D, +impl> WorldScene { + pub fn new(_device: &mut D, factory: &mut F, - aux_command: &mut ::CommandBuffer) -> WorldScene { + _aux_command: &mut ::CommandBuffer) -> WorldScene { let worldmap = get_data_model(); let (model, model_idx) = get_model(&worldmap); let (vertex_buffer, slice) = @@ -163,7 +162,6 @@ impl> WorldScene { constants_buffer: factory.create_constant_buffer(1), constants_dirty: true, locals: factory.create_constant_buffer(1), - atlas: tile::get_tiles::<_, _, view::ColorFormat>(device, factory, aux_command), sampler: factory.create_sampler(texture::SamplerInfo::new(texture::FilterMethod::Jrd, texture::WrapMode::Tile)), f: PhantomData, @@ -197,10 +195,12 @@ const ANIMDATA: [u32; 4] = 0]; impl> scene::Scene for WorldScene { + F: gfx::Factory> + engine::Scene, D, F> + for WorldScene { - fn event(&mut self, event: scene::Event) { - use scene::Event::*; + fn event(&mut self, event: engine::Event) { + use engine::Event::*; use vr::Event::*; match event { // treadmill / camera movement registration @@ -276,6 +276,7 @@ impl, vr: &mut Option, encoder: &mut gfx::Encoder) { const NANOS_PER_MILLI: u32 = 1_000_000; @@ -334,11 +335,12 @@ impl, + game: &mut VrtueRootContext, trans: &gfx::handle::Buffer, target: &gfx::handle::RenderTargetView, - depth: &gfx::handle::DepthStencilView) { + depth: &gfx::handle::DepthStencilView, + _factory: &mut F, + encoder: &mut gfx::Encoder) { encoder.clear(&target, SKY_COLOR); encoder.clear_depth(&depth, 1.0); @@ -347,7 +349,7 @@ impl(device: &mut D, - factory: &mut F, - command: &mut ::CommandBuffer) - -> gfx::handle::ShaderResourceView - where D: gfx::Device, - F: gfx::Factory, - T: gfx::format::TextureFormat { - let filename = "data/SHAPES.EGA"; - let mut file = std::fs::File::open(Path::new(filename)) - .expect(&format!("failed opening tiles file: {}", filename)); - let mut ega_bytes = Vec::new(); - file.read_to_end(&mut ega_bytes).expect("Read tiles file"); - let ega_page = ega::decode(&ega_bytes, ega::Compression::Uncompressed, ega::Tiling::Tiled(TILEDIM)); - let mipmap = ega_page.mipmap(2); - - let tex = factory.create_texture_immutable_u8::(texture::Kind::D2Array(mipmap.dim as u16, - mipmap.dim as u16, - mipmap.len as u16, - texture::AaMode::Single), - &mipmap.slices()) - .expect("create tile texture"); - - { - let mut manager = gfx::handle::Manager::::new(); - // XXX: Find out if Textures need to be/can be fenced like Buffers, - // Seems like I should mark tex.1 as being read/written, but it's not a Buffer? - let access = gfx::pso::AccessInfo::new(); - let view = manager.ref_srv(tex.1.raw()); - command.generate_mipmap(*view); - device.submit(command, &access); - } - tex.1 -} - - impl Tile { pub fn as_char(&self) -> char { diff --git a/src/view.rs b/src/view.rs index c0547b3..20d31d5 100644 --- a/src/view.rs +++ b/src/view.rs @@ -1,3 +1,4 @@ +use engine::{GameContext, Scene}; use vr::{self, AsMatrix4, VR}; extern crate gfx_device_gl; @@ -64,10 +65,11 @@ impl ViewRoot { } } - pub fn draw(&self, - window: &mut PistonWindow, - vr: &mut Option, - scene: &::scene::Scene) { + pub fn draw(&self, + game: &mut G, + window: &mut PistonWindow, + vr: &mut Option, + scene: &Scene) { if let &mut Some(ref mut vr) = vr { // Get the current sensor state let poses = vr.poses(); @@ -88,11 +90,12 @@ impl ViewRoot { matrix: *(proj_mat * viewmodel_mat).as_ref() }; window.encoder.update_constant_buffer(&self.trans, &trans); - scene.render(&mut window.factory, - &mut window.encoder, + scene.render(game, &self.trans, &target, - &depth); + &depth, + &mut window.factory, + &mut window.encoder); } } else { // If running without VR, just draw from some default projection near the scene origin @@ -107,11 +110,12 @@ impl ViewRoot { window.encoder.update_constant_buffer(&self.trans, &trans); } // draw monitor window - scene.render(&mut window.factory, - &mut window.encoder, + scene.render(game, &self.trans, &window.output_color, - &window.output_stencil); + &window.output_stencil, + &mut window.factory, + &mut window.encoder); window.encoder.flush(&mut window.device); if let (&mut Some(ref mut vr),