refactor view/scene to separate modules
This commit is contained in:
218
src/bin/gl.rs
218
src/bin/gl.rs
@@ -1,218 +0,0 @@
|
|||||||
extern crate vrtue;
|
|
||||||
use vrtue::{tile, vr};
|
|
||||||
use vrtue::vr::AsMatrix4;
|
|
||||||
|
|
||||||
extern crate env_logger;
|
|
||||||
#[macro_use] extern crate gfx;
|
|
||||||
extern crate gl;
|
|
||||||
#[macro_use] extern crate log;
|
|
||||||
extern crate nalgebra as na;
|
|
||||||
extern crate num_traits;
|
|
||||||
extern crate piston_window;
|
|
||||||
|
|
||||||
use gfx::{tex, Device, Factory};
|
|
||||||
use gfx::traits::FactoryExt;
|
|
||||||
use na::Inverse;
|
|
||||||
use num_traits::identities::One;
|
|
||||||
use piston_window::{PistonWindow, Window, WindowSettings};
|
|
||||||
|
|
||||||
pub type ColorFormat = gfx::format::Srgba8;
|
|
||||||
pub type DepthFormat = gfx::format::DepthStencil;
|
|
||||||
|
|
||||||
const NEAR: f32 = 0.01;
|
|
||||||
const FAR: f32 = 1000.0;
|
|
||||||
|
|
||||||
gfx_defines!{
|
|
||||||
vertex Vertex {
|
|
||||||
pos: [f32; 3] = "a_pos",
|
|
||||||
uv: [f32; 2] = "a_uv",
|
|
||||||
}
|
|
||||||
|
|
||||||
constant Trans {
|
|
||||||
matrix: [[f32; 4]; 4] = "u_matrix",
|
|
||||||
}
|
|
||||||
|
|
||||||
pipeline pipe {
|
|
||||||
vbuf: gfx::VertexBuffer<Vertex> = (),
|
|
||||||
trans: gfx::ConstantBuffer<Trans> = "b_trans",
|
|
||||||
tiles: gfx::TextureSampler<[f32; 4]> = "t_tiles",
|
|
||||||
pixcolor: gfx::RenderTarget<ColorFormat> = "pixcolor",
|
|
||||||
depth: gfx::DepthTarget<DepthFormat> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const POLYGON: [Vertex; 4] = [
|
|
||||||
Vertex { pos: [ -0.25, -0.25, 0. ], uv: [0., 0.] },
|
|
||||||
Vertex { pos: [ 0.25, -0.25, 0. ], uv: [1., 0.] },
|
|
||||||
Vertex { pos: [ 0.25, 0.25, 0. ], uv: [1., 1.] },
|
|
||||||
Vertex { pos: [ -0.25, 0.25, 0. ], uv: [0., 1.] }
|
|
||||||
];
|
|
||||||
const POLYGON_IDX: &'static [u16] = &[ 0, 1, 2,
|
|
||||||
2, 3, 0 ];
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
env_logger::init().expect("env logger");
|
|
||||||
let mut vr = vr::VR::new().expect("VR init");
|
|
||||||
let render_size = vr.recommended_render_target_size();
|
|
||||||
|
|
||||||
let mut window: PistonWindow =
|
|
||||||
WindowSettings::new("Hello Virtual World!", [512; 2])
|
|
||||||
.exit_on_esc(true)
|
|
||||||
.vsync(false)
|
|
||||||
.build().expect("Building Window");
|
|
||||||
|
|
||||||
let pso = window.factory.create_pipeline_simple(VERTEX_SHADER_SRC,
|
|
||||||
FRAGMENT_SHADER_SRC,
|
|
||||||
pipe::new())
|
|
||||||
.expect("create pipeline");
|
|
||||||
|
|
||||||
let (tex_left, tgt_left, depth_left) = vr::create_eyebuffer(&mut window.factory, render_size)
|
|
||||||
.expect("create left renderbuffer");
|
|
||||||
let (tex_right, tgt_right, depth_right) = vr::create_eyebuffer(&mut window.factory, render_size)
|
|
||||||
.expect("create right renderbuffer");
|
|
||||||
let (vertex_buffer, slice) = window.factory.create_vertex_buffer_with_slice(&POLYGON, POLYGON_IDX);
|
|
||||||
|
|
||||||
let tiles = tile::get_tiles::<_, _, ColorFormat>(&mut window.factory);
|
|
||||||
let nn_sampler = window.factory.create_sampler(
|
|
||||||
tex::SamplerInfo::new(tex::FilterMethod::Scale,
|
|
||||||
tex::WrapMode::Clamp));
|
|
||||||
|
|
||||||
let pipe_monitor = pipe::Data {
|
|
||||||
vbuf: vertex_buffer.clone(),
|
|
||||||
trans: window.factory.create_constant_buffer(1),
|
|
||||||
tiles: (tiles.clone(), nn_sampler.clone()),
|
|
||||||
pixcolor: window.output_color.clone(),
|
|
||||||
depth: window.output_stencil.clone(),
|
|
||||||
};
|
|
||||||
let pipe_left = pipe::Data {
|
|
||||||
vbuf: vertex_buffer.clone(),
|
|
||||||
trans: window.factory.create_constant_buffer(1),
|
|
||||||
tiles: (tiles.clone(), nn_sampler.clone()),
|
|
||||||
pixcolor: tgt_left,
|
|
||||||
depth: depth_left,
|
|
||||||
};
|
|
||||||
let pipe_right = pipe::Data {
|
|
||||||
vbuf: vertex_buffer.clone(),
|
|
||||||
trans: window.factory.create_constant_buffer(1),
|
|
||||||
tiles: (tiles.clone(), nn_sampler.clone()),
|
|
||||||
pixcolor: tgt_right,
|
|
||||||
depth: depth_right,
|
|
||||||
};
|
|
||||||
window.encoder.update_constant_buffer(
|
|
||||||
&pipe_monitor.trans,
|
|
||||||
&Trans { matrix: *na::Matrix4::one().as_ref() });
|
|
||||||
|
|
||||||
let mut frame = 0u32;
|
|
||||||
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 = vr.poses();
|
|
||||||
trace!("\t{:?} got pose", _now.elapsed());
|
|
||||||
if frame % 90 == 0 {
|
|
||||||
debug!("\t#{}: poses:", frame);
|
|
||||||
let mut devnum = 0;
|
|
||||||
for track in (0..poses.count).map(|pose| poses.poses[pose]) {
|
|
||||||
match track.device_class() {
|
|
||||||
vr::TrackedDeviceClass::Invalid => (),
|
|
||||||
_ => debug!("\t\t#{}: {:?} = valid? {}, connected? {}\n\t\t\t{:?}\n\t\t\t{:?}",
|
|
||||||
devnum,
|
|
||||||
track.device_class(),
|
|
||||||
track.is_valid,
|
|
||||||
track.is_connected,
|
|
||||||
track.to_device,
|
|
||||||
track.velocity)
|
|
||||||
}
|
|
||||||
devnum += 1;
|
|
||||||
}
|
|
||||||
debug!("");
|
|
||||||
}
|
|
||||||
frame += 1;
|
|
||||||
|
|
||||||
let mut hmd_mat = poses.poses[0].to_device.as_matrix4();
|
|
||||||
hmd_mat.inverse_mut();
|
|
||||||
|
|
||||||
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.2, 0.3, 1.0]);
|
|
||||||
window.encoder.clear_depth(&pass.1.depth, 1.0);
|
|
||||||
|
|
||||||
// Submit eye textures
|
|
||||||
if let Some((eye, tex)) = pass.0 {
|
|
||||||
let proj_mat = vr.projection_matrix(eye, NEAR, FAR);
|
|
||||||
let eye_mat = vr.head_to_eye_transform(eye);
|
|
||||||
for track in (0..poses.count).map(|pose| poses.poses[pose]) {
|
|
||||||
match track.device_class() {
|
|
||||||
vr::TrackedDeviceClass::Controller |
|
|
||||||
vr::TrackedDeviceClass::TrackingReference => {
|
|
||||||
let model_mat = track.to_device.as_matrix4();
|
|
||||||
|
|
||||||
let trans = Trans { matrix: *(proj_mat * eye_mat * hmd_mat * model_mat).as_ref() };
|
|
||||||
window.encoder.update_constant_buffer(&pass.1.trans, &trans);
|
|
||||||
|
|
||||||
window.encoder.draw(&slice, &pso, pass.1);
|
|
||||||
window.encoder.flush(&mut window.device);
|
|
||||||
},
|
|
||||||
_ => ()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vr.submit(eye, tex);
|
|
||||||
trace!("\t\t{:?} submit {:?}", _now.elapsed(), eye);
|
|
||||||
} else {
|
|
||||||
window.encoder.draw(&slice, &pso, pass.1);
|
|
||||||
window.encoder.flush(&mut window.device);
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("shutting down");
|
|
||||||
}
|
|
||||||
|
|
||||||
const VERTEX_SHADER_SRC: &'static [u8] = br#"
|
|
||||||
#version 140
|
|
||||||
|
|
||||||
in vec3 a_pos;
|
|
||||||
in vec2 a_uv;
|
|
||||||
out vec3 v_color;
|
|
||||||
out vec2 v_uv;
|
|
||||||
uniform b_trans {
|
|
||||||
mat4 u_matrix;
|
|
||||||
};
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
v_uv = a_uv;
|
|
||||||
gl_Position = u_matrix * vec4(a_pos, 1.0);
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
|
|
||||||
const FRAGMENT_SHADER_SRC: &'static [u8] = br#"
|
|
||||||
#version 140
|
|
||||||
|
|
||||||
in vec3 v_color;
|
|
||||||
in vec2 v_uv;
|
|
||||||
out vec4 pixcolor;
|
|
||||||
uniform sampler2D t_tiles;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec2 uv = vec2(v_uv.x, 31.0 / 256 + (1.0 - v_uv.y) / 256.0);
|
|
||||||
pixcolor = texture(t_tiles, uv);
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
40
src/bin/vrtue.rs
Normal file
40
src/bin/vrtue.rs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
extern crate vrtue;
|
||||||
|
use vrtue::{view, vr};
|
||||||
|
|
||||||
|
extern crate env_logger;
|
||||||
|
extern crate gfx_device_gl;
|
||||||
|
#[macro_use] extern crate log;
|
||||||
|
extern crate piston_window;
|
||||||
|
|
||||||
|
use self::piston_window::{PistonWindow, Window, WindowSettings};
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
env_logger::init().expect("env logger");
|
||||||
|
let mut vr = vr::VR::new().expect("VR init");
|
||||||
|
|
||||||
|
let mut window: PistonWindow =
|
||||||
|
WindowSettings::new("Hello Virtual World!", [512; 2])
|
||||||
|
.exit_on_esc(true)
|
||||||
|
.vsync(false)
|
||||||
|
.build().expect("Building Window");
|
||||||
|
|
||||||
|
let view = view::ViewRoot::<gfx_device_gl::Device,
|
||||||
|
view::ColorFormat,
|
||||||
|
view::DepthFormat>::create_view(&mut window, &mut vr);
|
||||||
|
|
||||||
|
'main:
|
||||||
|
//while let Some(_) = window.next() {
|
||||||
|
loop {
|
||||||
|
view.draw(&mut window, &mut vr);
|
||||||
|
|
||||||
|
// handle window events
|
||||||
|
while let Some(ev) = window.poll_event() {
|
||||||
|
match ev {
|
||||||
|
piston_window::Input::Text(_) => break 'main,
|
||||||
|
_ => debug!("\t{:?}", ev)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!("shutting down");
|
||||||
|
}
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
#![feature(conservative_impl_trait)]
|
#![feature(conservative_impl_trait)]
|
||||||
|
|
||||||
|
#[macro_use] extern crate gfx;
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
|
|
||||||
pub mod arena;
|
pub mod arena;
|
||||||
pub mod ega;
|
pub mod ega;
|
||||||
|
pub mod scene;
|
||||||
|
pub mod scenes;
|
||||||
pub mod tile;
|
pub mod tile;
|
||||||
pub mod town;
|
pub mod town;
|
||||||
|
pub mod view;
|
||||||
pub mod vr;
|
pub mod vr;
|
||||||
pub mod world;
|
pub mod world;
|
||||||
|
|
||||||
|
|||||||
15
src/scene.rs
Normal file
15
src/scene.rs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
use view;
|
||||||
|
|
||||||
|
extern crate gfx;
|
||||||
|
extern crate gfx_device_gl;
|
||||||
|
extern crate piston_window;
|
||||||
|
|
||||||
|
pub trait Scene<D: gfx::Device,
|
||||||
|
F: gfx::Factory<D::Resources>> {
|
||||||
|
fn update(&mut self);
|
||||||
|
fn render(&self,
|
||||||
|
factory: &mut F,
|
||||||
|
encoder: &mut gfx::Encoder<D::Resources, D::CommandBuffer>,
|
||||||
|
target: &gfx::handle::RenderTargetView<D::Resources, view::ColorFormat>,
|
||||||
|
depth: &gfx::handle::DepthStencilView<D::Resources, view::DepthFormat>);
|
||||||
|
}
|
||||||
1
src/scenes/mod.rs
Normal file
1
src/scenes/mod.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub mod world;
|
||||||
123
src/scenes/world.rs
Normal file
123
src/scenes/world.rs
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
use scene;
|
||||||
|
use tile;
|
||||||
|
use view;
|
||||||
|
|
||||||
|
extern crate gfx;
|
||||||
|
extern crate piston_window;
|
||||||
|
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use gfx::tex;
|
||||||
|
use gfx::traits::FactoryExt;
|
||||||
|
|
||||||
|
gfx_defines! {
|
||||||
|
vertex Vertex {
|
||||||
|
pos: [f32; 3] = "a_pos",
|
||||||
|
uv: [f32; 2] = "a_uv",
|
||||||
|
tileidx: u32 = "a_tileidx",
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeline pipe {
|
||||||
|
vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||||
|
trans: gfx::ConstantBuffer<::view::Trans> = "b_trans",
|
||||||
|
atlas: gfx::TextureSampler<[f32; 4]> = "t_atlas",
|
||||||
|
pixcolor: gfx::RenderTarget<::view::ColorFormat> = "pixcolor",
|
||||||
|
depth: gfx::DepthTarget<::view::DepthFormat> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn get_model(/*x: u16, y: u16,*/ tile: &tile::Tile) -> ([Vertex; 4], [u16; 6]) {
|
||||||
|
let tileidx = tile.val as u32;
|
||||||
|
([Vertex { pos: [ 0., 0., 0. ], uv: [0., 0.], tileidx: tileidx },
|
||||||
|
Vertex { pos: [ 1., 0., 0. ], uv: [1., 0.], tileidx: tileidx },
|
||||||
|
Vertex { pos: [ 1., 0., 1. ], uv: [1., 1.], tileidx: tileidx },
|
||||||
|
Vertex { pos: [ 0., 0., 1. ], uv: [0., 1.], tileidx: tileidx },],
|
||||||
|
[ 0, 1, 2,
|
||||||
|
2, 3, 0 ])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WorldScene<D: gfx::Device,
|
||||||
|
F: gfx::Factory<D::Resources>> {
|
||||||
|
pso: gfx::PipelineState<D::Resources, pipe::Meta>,
|
||||||
|
trans: gfx::handle::Buffer<D::Resources, view::Trans>,
|
||||||
|
atlas: gfx::handle::ShaderResourceView<D::Resources,
|
||||||
|
<view::ColorFormat as gfx::format::Formatted>::View>,
|
||||||
|
sampler: gfx::handle::Sampler<D::Resources>,
|
||||||
|
f: PhantomData<F>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: gfx::Device, F: gfx::Factory<D::Resources>> WorldScene<D, F> {
|
||||||
|
pub fn new(factory: &mut F, trans: &gfx::handle::Buffer<D::Resources, view::Trans>) -> WorldScene<D, F> {
|
||||||
|
WorldScene {
|
||||||
|
pso: factory.create_pipeline_simple(VERTEX_SHADER_SRC,
|
||||||
|
FRAGMENT_SHADER_SRC,
|
||||||
|
pipe::new())
|
||||||
|
.expect("create pipeline"),
|
||||||
|
trans: trans.clone(),
|
||||||
|
atlas: tile::get_tiles::<_, _, view::ColorFormat>(factory),
|
||||||
|
sampler: factory.create_sampler(tex::SamplerInfo::new(tex::FilterMethod::Scale,
|
||||||
|
tex::WrapMode::Clamp)),
|
||||||
|
f: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: gfx::Device,
|
||||||
|
F: gfx::Factory<D::Resources>> scene::Scene<D, F> for WorldScene<D, F> {
|
||||||
|
|
||||||
|
fn update(&mut self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&self,
|
||||||
|
factory: &mut F,
|
||||||
|
encoder: &mut gfx::Encoder<D::Resources, D::CommandBuffer>,
|
||||||
|
target: &gfx::handle::RenderTargetView<D::Resources, view::ColorFormat>,
|
||||||
|
depth: &gfx::handle::DepthStencilView<D::Resources, view::DepthFormat>) {
|
||||||
|
let (model, model_idx) = get_model(&tile::Tile { val: 31 });
|
||||||
|
let (vertex_buffer, slice) =
|
||||||
|
factory.create_vertex_buffer_with_slice(&model, &model_idx[..]);
|
||||||
|
|
||||||
|
let pipe = pipe::Data {
|
||||||
|
vbuf: vertex_buffer.clone(),
|
||||||
|
trans: self.trans.clone(),
|
||||||
|
atlas: (self.atlas.clone(), self.sampler.clone()),
|
||||||
|
pixcolor: target.clone(),
|
||||||
|
depth: depth.clone(),
|
||||||
|
};
|
||||||
|
encoder.draw(&slice, &self.pso, &pipe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const VERTEX_SHADER_SRC: &'static [u8] = br#"
|
||||||
|
#version 150
|
||||||
|
|
||||||
|
in vec3 a_pos;
|
||||||
|
in vec2 a_uv;
|
||||||
|
in uint a_tileidx;
|
||||||
|
out vec2 v_uv;
|
||||||
|
flat out uint v_tileidx;
|
||||||
|
uniform b_trans {
|
||||||
|
mat4 u_matrix;
|
||||||
|
};
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
v_uv = a_uv;
|
||||||
|
v_tileidx = a_tileidx;
|
||||||
|
gl_Position = u_matrix * vec4(a_pos, 1.0);
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const FRAGMENT_SHADER_SRC: &'static [u8] = br#"
|
||||||
|
#version 150
|
||||||
|
|
||||||
|
in vec2 v_uv;
|
||||||
|
flat in uint v_tileidx;
|
||||||
|
out vec4 pixcolor;
|
||||||
|
uniform sampler2D t_atlas;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = vec2(v_uv.x, float(v_tileidx) / 256.0 + (1.0 - v_uv.y) / 256.0);
|
||||||
|
pixcolor = texture(t_atlas, uv);
|
||||||
|
}
|
||||||
|
"#;
|
||||||
@@ -8,9 +8,10 @@ use std::path::Path;
|
|||||||
|
|
||||||
use self::gfx::tex;
|
use self::gfx::tex;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Tile {
|
pub struct Tile {
|
||||||
val: u8,
|
pub val: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tiles<R, F, T>(factory: &mut F) -> (//gfx::handle::Texture<R, T::Surface>,
|
pub fn get_tiles<R, F, T>(factory: &mut F) -> (//gfx::handle::Texture<R, T::Surface>,
|
||||||
@@ -31,6 +32,8 @@ pub fn get_tiles<R, F, T>(factory: &mut F) -> (//gfx::handle::Texture<R, T::Surf
|
|||||||
tex.1
|
tex.1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl Tile {
|
impl Tile {
|
||||||
pub fn as_char(&self) -> char {
|
pub fn as_char(&self) -> char {
|
||||||
match self.val {
|
match self.val {
|
||||||
|
|||||||
111
src/view.rs
Normal file
111
src/view.rs
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
use scenes;
|
||||||
|
use vr;
|
||||||
|
use vr::{AsMatrix4, VR};
|
||||||
|
|
||||||
|
extern crate gfx_device_gl;
|
||||||
|
extern crate nalgebra as na;
|
||||||
|
extern crate num_traits;
|
||||||
|
extern crate piston_window;
|
||||||
|
|
||||||
|
use gfx;
|
||||||
|
use gfx::Device;
|
||||||
|
use gfx::traits::FactoryExt;
|
||||||
|
use self::na::Inverse;
|
||||||
|
use self::num_traits::identities::One;
|
||||||
|
use self::piston_window::{PistonWindow, Window};
|
||||||
|
|
||||||
|
pub type ColorFormat = gfx::format::Srgba8;
|
||||||
|
pub type DepthFormat = gfx::format::DepthStencil;
|
||||||
|
|
||||||
|
const NEAR: f32 = 0.01;
|
||||||
|
const FAR: f32 = 1000.0;
|
||||||
|
|
||||||
|
gfx_constant_struct! {
|
||||||
|
Trans {
|
||||||
|
matrix: [[f32; 4]; 4] = "u_matrix",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ViewRoot<Dev, T, D>
|
||||||
|
where Dev: gfx::Device,
|
||||||
|
T: gfx::format::RenderFormat + gfx::format::TextureFormat,
|
||||||
|
D: gfx::format::DepthFormat + gfx::format::TextureFormat {
|
||||||
|
|
||||||
|
left: vr::EyeBuffer<T, D>,
|
||||||
|
right: vr::EyeBuffer<T, D>,
|
||||||
|
trans: gfx::handle::Buffer<Dev::Resources, Trans>,
|
||||||
|
scene: Box<::scene::Scene<Dev, gfx_device_gl::Factory>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ViewRoot<gfx_device_gl::Device, ColorFormat, DepthFormat> {
|
||||||
|
pub fn create_view(window: &mut PistonWindow, vr: &VR)
|
||||||
|
-> ViewRoot<gfx_device_gl::Device, ColorFormat, DepthFormat> {
|
||||||
|
|
||||||
|
let render_size = vr.recommended_render_target_size();
|
||||||
|
let left = vr::create_eyebuffer(&mut window.factory, render_size)
|
||||||
|
.expect("create left renderbuffer");
|
||||||
|
let right = vr::create_eyebuffer(&mut window.factory, render_size)
|
||||||
|
.expect("create right renderbuffer");
|
||||||
|
let trans = window.factory.create_constant_buffer(1);
|
||||||
|
|
||||||
|
window.window.swap_buffers(); // To contain setup calls to Frame 0 in apitrace
|
||||||
|
|
||||||
|
ViewRoot::<gfx_device_gl::Device, ColorFormat, DepthFormat> {
|
||||||
|
left: left,
|
||||||
|
right: right,
|
||||||
|
trans: trans.clone(),
|
||||||
|
scene: Box::new(scenes::world::WorldScene::new(&mut window.factory, &trans)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(&self,
|
||||||
|
window: &mut PistonWindow,
|
||||||
|
vr: &mut vr::VR) {
|
||||||
|
// Get the current sensor state
|
||||||
|
let poses = vr.poses();
|
||||||
|
|
||||||
|
let mut hmd_mat = poses.poses[0].to_device.as_matrix4();
|
||||||
|
hmd_mat.inverse_mut();
|
||||||
|
|
||||||
|
for &(eye, buffers) in [(vr::Eye::Left, &self.left),
|
||||||
|
(vr::Eye::Right, &self.right)].into_iter() {
|
||||||
|
window.encoder.clear(&buffers.target, [0.1, 0.2, 0.3, 1.0]);
|
||||||
|
|
||||||
|
window.encoder.clear_depth(&buffers.depth, 1.0);
|
||||||
|
|
||||||
|
// Submit eye textures
|
||||||
|
let proj_mat = vr.projection_matrix(eye, NEAR, FAR);
|
||||||
|
let eye_mat = vr.head_to_eye_transform(eye);
|
||||||
|
for track in (0..poses.count).map(|pose| poses.poses[pose]) {
|
||||||
|
match track.device_class() {
|
||||||
|
vr::TrackedDeviceClass::Controller |
|
||||||
|
vr::TrackedDeviceClass::TrackingReference => {
|
||||||
|
let model_mat = track.to_device.as_matrix4();
|
||||||
|
|
||||||
|
let trans = Trans { matrix: *(proj_mat * eye_mat * hmd_mat * model_mat).as_ref() };
|
||||||
|
window.encoder.update_constant_buffer(&self.trans, &trans);
|
||||||
|
|
||||||
|
self.scene.render(&mut window.factory,
|
||||||
|
&mut window.encoder,
|
||||||
|
&buffers.target,
|
||||||
|
&buffers.depth);
|
||||||
|
},
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// draw monitor window
|
||||||
|
window.encoder.update_constant_buffer(&self.trans,
|
||||||
|
&Trans { matrix: *na::Matrix4::one().as_ref() });
|
||||||
|
window.encoder.clear(&window.output_color, [0.1, 0.2, 0.3, 1.0]);
|
||||||
|
window.encoder.clear_depth(&window.output_stencil, 1.0);
|
||||||
|
self.scene.render(&mut window.factory, &mut window.encoder, &window.output_color, &window.output_stencil);
|
||||||
|
|
||||||
|
window.encoder.flush(&mut window.device);
|
||||||
|
vr.submit(vr::Eye::Left, &self.left.tex);
|
||||||
|
vr.submit(vr::Eye::Right, &self.right.tex);
|
||||||
|
window.window.swap_buffers();
|
||||||
|
window.device.cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/vr.rs
16
src/vr.rs
@@ -87,12 +87,18 @@ impl<N: Copy> AsMatrix4<N> for [[N; 4]; 4] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct EyeBuffer<T, D>
|
||||||
|
where T: gfx::format::RenderFormat + gfx::format::TextureFormat,
|
||||||
|
D: gfx::format::DepthFormat + gfx::format::TextureFormat {
|
||||||
|
|
||||||
|
pub tex: gfx::handle::Texture<GLResources, T::Surface>,
|
||||||
|
pub target: gfx::handle::RenderTargetView<GLResources, T>,
|
||||||
|
pub depth: gfx::handle::DepthStencilView<GLResources, D>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_eyebuffer<T, D>(factory: &mut gfx_device_gl::Factory,
|
pub fn create_eyebuffer<T, D>(factory: &mut gfx_device_gl::Factory,
|
||||||
size: vr::common::Size)
|
size: vr::common::Size)
|
||||||
-> Result<(gfx::handle::Texture<GLResources, T::Surface>,
|
-> Result<EyeBuffer<T, D>, gfx::CombinedError>
|
||||||
gfx::handle::RenderTargetView<GLResources, T>,
|
|
||||||
gfx::handle::DepthStencilView<GLResources, D>),
|
|
||||||
gfx::CombinedError>
|
|
||||||
where T: gfx::format::RenderFormat + gfx::format::TextureFormat,
|
where T: gfx::format::RenderFormat + gfx::format::TextureFormat,
|
||||||
D: gfx::format::DepthFormat + gfx::format::TextureFormat {
|
D: gfx::format::DepthFormat + gfx::format::TextureFormat {
|
||||||
let tex = try!(factory.create_texture(
|
let tex = try!(factory.create_texture(
|
||||||
@@ -104,5 +110,5 @@ pub fn create_eyebuffer<T, D>(factory: &mut gfx_device_gl::Factory,
|
|||||||
let tgt = try!(factory.view_texture_as_render_target(&tex, 0, None));
|
let tgt = try!(factory.view_texture_as_render_target(&tex, 0, None));
|
||||||
let depth = try!(factory.create_depth_stencil_view_only(size.width as tex::Size,
|
let depth = try!(factory.create_depth_stencil_view_only(size.width as tex::Size,
|
||||||
size.height as tex::Size));
|
size.height as tex::Size));
|
||||||
Ok((tex, tgt, depth))
|
Ok(EyeBuffer { tex: tex, target: tgt, depth: depth })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ pub trait HasMap {
|
|||||||
const CHUNKDIM: usize = 32;
|
const CHUNKDIM: usize = 32;
|
||||||
pub type ChunkRow = [Tile; CHUNKDIM];
|
pub type ChunkRow = [Tile; CHUNKDIM];
|
||||||
pub type ChunkRect = [ChunkRow; CHUNKDIM];
|
pub type ChunkRect = [ChunkRow; CHUNKDIM];
|
||||||
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Chunk {
|
pub struct Chunk {
|
||||||
pub rect: ChunkRect,
|
pub rect: ChunkRect,
|
||||||
@@ -53,6 +54,7 @@ impl<'a> IntoIterator for &'a Chunk {
|
|||||||
const WORLDDIM: usize = 8;
|
const WORLDDIM: usize = 8;
|
||||||
pub type WorldRow = [Chunk; WORLDDIM];
|
pub type WorldRow = [Chunk; WORLDDIM];
|
||||||
pub type WorldRect = [WorldRow; WORLDDIM];
|
pub type WorldRect = [WorldRow; WORLDDIM];
|
||||||
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct World {
|
pub struct World {
|
||||||
pub rect: WorldRect,
|
pub rect: WorldRect,
|
||||||
|
|||||||
Reference in New Issue
Block a user