WIP: hacky world torus

This commit is contained in:
2016-09-25 00:41:14 -07:00
parent 8a68c1780e
commit 9323380d5c
5 changed files with 76 additions and 19 deletions

View File

@@ -26,7 +26,7 @@ pub fn main() {
'main: 'main:
//while let Some(_) = window.next() { //while let Some(_) = window.next() {
loop { loop {
scene.update(); scene.update(&mut window.encoder);
view.draw(&mut window, &mut vr, &scene); view.draw(&mut window, &mut vr, &scene);
// handle window events // handle window events

View File

@@ -8,7 +8,8 @@ extern crate piston_window;
pub trait Scene<D: gfx::Device, pub trait Scene<D: gfx::Device,
F: gfx::Factory<D::Resources>> { F: gfx::Factory<D::Resources>> {
fn event(&mut self, event: Event); fn event(&mut self, event: Event);
fn update(&mut self); fn update(&mut self,
encoder: &mut gfx::Encoder<D::Resources, D::CommandBuffer>);
fn render(&self, fn render(&self,
factory: &mut F, factory: &mut F,
encoder: &mut gfx::Encoder<D::Resources, D::CommandBuffer>, encoder: &mut gfx::Encoder<D::Resources, D::CommandBuffer>,

View File

@@ -8,6 +8,7 @@ extern crate gfx;
extern crate piston_window; extern crate piston_window;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::time::SystemTime;
use gfx::tex; use gfx::tex;
use gfx::traits::FactoryExt; use gfx::traits::FactoryExt;
@@ -19,9 +20,15 @@ gfx_defines! {
tileidx: u32 = "a_tileidx", tileidx: u32 = "a_tileidx",
} }
constant Locals {
millis: u32 = "millis",
anim: u32 = "anim",
}
pipeline pipe { pipeline pipe {
vbuf: gfx::VertexBuffer<Vertex> = (), vbuf: gfx::VertexBuffer<Vertex> = (),
trans: gfx::ConstantBuffer<::view::Trans> = "b_trans", trans: gfx::ConstantBuffer<::view::Trans> = "b_trans",
locals: gfx::ConstantBuffer<Locals> = "b_locals",
atlas: gfx::TextureSampler<[f32; 4]> = "t_atlas", atlas: gfx::TextureSampler<[f32; 4]> = "t_atlas",
pixcolor: gfx::RenderTarget<::view::ColorFormat> = "pixcolor", pixcolor: gfx::RenderTarget<::view::ColorFormat> = "pixcolor",
depth: gfx::DepthTarget<::view::DepthFormat> = gfx::preset::depth::LESS_EQUAL_WRITE, depth: gfx::DepthTarget<::view::DepthFormat> = gfx::preset::depth::LESS_EQUAL_WRITE,
@@ -37,13 +44,13 @@ fn get_model(world: &model::World) -> (Vec<Vertex>, Vec<u32>) {
for (r, row) in world.map().rows().enumerate() { for (r, row) in world.map().rows().enumerate() {
for (c, tile) in row.into_iter().enumerate() { for (c, tile) in row.into_iter().enumerate() {
let tileidx = tile.val as u32; let tileidx = tile.val as u32;
let rf = (((r + 32) % 256) as i16 - 128) as f32; let rf = (((r + 26) % 256) as i16 - 128) as f32;
let cf = (((c + 32) % 256)as i16 - 128) as f32; let cf = (((c + 48) % 256) as i16 - 128) as f32;
verticies.extend_from_slice( verticies.extend_from_slice(
&[Vertex { pos: [ cf + 0., -rf - 1., -20.0 ], uv: [0., 0.], tileidx: tileidx }, &[Vertex { pos: [ cf + 0., 0., -rf - 1. ], uv: [0., 0.], tileidx: tileidx },
Vertex { pos: [ cf + 1., -rf - 1., -20.0 ], uv: [1., 0.], tileidx: tileidx }, Vertex { pos: [ cf + 1., 0., -rf - 1. ], uv: [1., 0.], tileidx: tileidx },
Vertex { pos: [ cf + 1., -rf - 0., -20.0 ], uv: [1., 1.], tileidx: tileidx }, Vertex { pos: [ cf + 1., 0., -rf - 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 - 0. ], uv: [0., 1.], tileidx: tileidx },]);
indicies.extend_from_slice( indicies.extend_from_slice(
&[ v + 0, v + 1, v + 2, &[ v + 0, v + 1, v + 2,
v + 2, v + 3, v + 0 ]); v + 2, v + 3, v + 0 ]);
@@ -56,6 +63,7 @@ fn get_model(world: &model::World) -> (Vec<Vertex>, Vec<u32>) {
pub struct WorldScene<D: gfx::Device, pub struct WorldScene<D: gfx::Device,
F: gfx::Factory<D::Resources>> { F: gfx::Factory<D::Resources>> {
pso: gfx::PipelineState<D::Resources, pipe::Meta>, pso: gfx::PipelineState<D::Resources, pipe::Meta>,
locals: gfx::handle::Buffer<D::Resources, Locals>,
atlas: gfx::handle::ShaderResourceView<D::Resources, atlas: gfx::handle::ShaderResourceView<D::Resources,
<view::ColorFormat as gfx::format::Formatted>::View>, <view::ColorFormat as gfx::format::Formatted>::View>,
sampler: gfx::handle::Sampler<D::Resources>, sampler: gfx::handle::Sampler<D::Resources>,
@@ -63,6 +71,8 @@ pub struct WorldScene<D: gfx::Device,
vbuf: gfx::handle::Buffer<D::Resources, Vertex>, vbuf: gfx::handle::Buffer<D::Resources, Vertex>,
slice: gfx::Slice<D::Resources>, slice: gfx::Slice<D::Resources>,
start_time: SystemTime,
} }
impl<D: gfx::Device, F: gfx::Factory<D::Resources>> WorldScene<D, F> { impl<D: gfx::Device, F: gfx::Factory<D::Resources>> WorldScene<D, F> {
@@ -76,6 +86,7 @@ impl<D: gfx::Device, F: gfx::Factory<D::Resources>> WorldScene<D, F> {
FRAGMENT_SHADER_SRC, FRAGMENT_SHADER_SRC,
pipe::new()) pipe::new())
.expect("create pipeline"), .expect("create pipeline"),
locals: factory.create_constant_buffer(1),
atlas: tile::get_tiles::<_, _, view::ColorFormat>(factory), atlas: tile::get_tiles::<_, _, view::ColorFormat>(factory),
sampler: factory.create_sampler(tex::SamplerInfo::new(tex::FilterMethod::Scale, sampler: factory.create_sampler(tex::SamplerInfo::new(tex::FilterMethod::Scale,
tex::WrapMode::Clamp)), tex::WrapMode::Clamp)),
@@ -83,17 +94,30 @@ impl<D: gfx::Device, F: gfx::Factory<D::Resources>> WorldScene<D, F> {
vbuf: vertex_buffer, vbuf: vertex_buffer,
slice: slice, 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<D: gfx::Device, impl<D: gfx::Device,
F: gfx::Factory<D::Resources>> scene::Scene<D, F> for WorldScene<D, F> { F: gfx::Factory<D::Resources>> scene::Scene<D, F> for WorldScene<D, F> {
fn event(&mut self, event: scene::Event) { fn event(&mut self, event: scene::Event) {
} }
fn update(&mut self) { fn update(&mut self,
encoder: &mut gfx::Encoder<D::Resources, D::CommandBuffer>) {
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, fn render(&self,
@@ -106,6 +130,7 @@ impl<D: gfx::Device,
let pipe = pipe::Data { let pipe = pipe::Data {
vbuf: self.vbuf.clone(), vbuf: self.vbuf.clone(),
trans: trans.clone(), trans: trans.clone(),
locals: self.locals.clone(),
atlas: (self.atlas.clone(), self.sampler.clone()), atlas: (self.atlas.clone(), self.sampler.clone()),
pixcolor: target.clone(), pixcolor: target.clone(),
depth: depth.clone(), depth: depth.clone(),
@@ -142,11 +167,29 @@ const VERTEX_SHADER_SRC: &'static [u8] = br#"
uniform b_trans { uniform b_trans {
mat4 u_matrix; mat4 u_matrix;
}; };
uniform b_locals {
uint millis;
uint animdata;
};
void main() { void main() {
v_uv = a_uv; v_uv = a_uv;
v_tileidx = a_tileidx; v_tileidx = a_tileidx;
gl_Position = u_matrix * vec4(a_pos, 1.0); float TWO_PI_CIRC = 44.0 / 7.0 / 256.0;
float R = 128.0;
float R2 = 16.0;
gl_Position = u_matrix * vec4(R * -1.0 * sin(TWO_PI_CIRC * a_pos.x), // "z"
(R + R2 * cos(TWO_PI_CIRC * a_pos.x)) * cos(TWO_PI_CIRC * a_pos.z), // "x"
(R + R2 * cos(TWO_PI_CIRC * a_pos.x)) * sin(TWO_PI_CIRC * a_pos.z), // "y"
1.0);
/*
float which = (1.0 + sin(float(millis) / 5000.)) / 2.0;
gl_Position = u_matrix * vec4(a_pos.x,
R * cos(TWO_PI_CIRC * a_pos.z),
which * a_pos.z +
((1.0-which) * R * sin(TWO_PI_CIRC * a_pos.z)),
1.0);
*/
} }
"#; "#;
@@ -157,9 +200,19 @@ const FRAGMENT_SHADER_SRC: &'static [u8] = br#"
flat in uint v_tileidx; flat in uint v_tileidx;
out vec4 pixcolor; out vec4 pixcolor;
uniform sampler2D t_atlas; uniform sampler2D t_atlas;
uniform b_locals {
uint millis;
//uvec4 animdata;
uint animdata;
};
void main() { void main() {
vec2 uv = vec2(v_uv.x, float(v_tileidx) / 256.0 + (1.0 - v_uv.y) / 256.0); vec2 anim_uv = v_uv;
//if (v_tileidx < 128u && bool(animdata[0 /*v_tileidx / 32u*/] & 1u << v_tileidx % 32u)) {
if (v_tileidx < 32u && bool(animdata & 1u << v_tileidx)) {
anim_uv = vec2(v_uv.x, float((uint(v_uv.y * 1000.0) + millis / 4u) % 1000u) / 1000.0);
}
vec2 uv = vec2(anim_uv.x, float(v_tileidx) / 256.0 + (1.0 - anim_uv.y) / 256.0);
pixcolor = texture(t_atlas, uv); pixcolor = texture(t_atlas, uv);
} }
"#; "#;

View File

@@ -17,7 +17,7 @@ pub type ColorFormat = gfx::format::Srgba8;
pub type DepthFormat = gfx::format::DepthStencil; pub type DepthFormat = gfx::format::DepthStencil;
const NEAR: f32 = 0.01; const NEAR: f32 = 0.01;
const FAR: f32 = 1000.0; const FAR: f32 = 1000000.0;
gfx_constant_struct! { gfx_constant_struct! {
Trans { Trans {
@@ -40,6 +40,10 @@ impl ViewRoot<gfx_device_gl::Device, ColorFormat, DepthFormat> {
-> ViewRoot<gfx_device_gl::Device, ColorFormat, DepthFormat> { -> ViewRoot<gfx_device_gl::Device, ColorFormat, DepthFormat> {
let render_size = vr.recommended_render_target_size(); 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) let left = vr::create_eyebuffer(&mut window.factory, render_size)
.expect("create left renderbuffer"); .expect("create left renderbuffer");
let right = vr::create_eyebuffer(&mut window.factory, render_size) let right = vr::create_eyebuffer(&mut window.factory, render_size)
@@ -67,7 +71,7 @@ impl ViewRoot<gfx_device_gl::Device, ColorFormat, DepthFormat> {
for &(eye, buffers) in [(vr::Eye::Left, &self.left), for &(eye, buffers) in [(vr::Eye::Left, &self.left),
(vr::Eye::Right, &self.right)].into_iter() { (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); window.encoder.clear_depth(&buffers.depth, 1.0);
@@ -75,9 +79,7 @@ impl ViewRoot<gfx_device_gl::Device, ColorFormat, DepthFormat> {
let proj_mat = vr.projection_matrix(eye, NEAR, FAR); let proj_mat = vr.projection_matrix(eye, NEAR, FAR);
let eye_mat = vr.head_to_eye_transform(eye); 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).as_ref() };
let trans = Trans { matrix: *(proj_mat * eye_mat * hmd_mat * model_mat).as_ref() };
window.encoder.update_constant_buffer(&self.trans, &trans); window.encoder.update_constant_buffer(&self.trans, &trans);
scene.render(&mut window.factory, scene.render(&mut window.factory,

View File

@@ -6,7 +6,8 @@ extern crate openvr as vr;
extern crate openvr_sys; extern crate openvr_sys;
pub use self::vr::Eye; 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::{tex, Factory, Typed};
use self::gfx_device_gl::Resources as GLResources; 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))); 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() self.system.recommended_render_target_size()
} }
@@ -149,7 +150,7 @@ pub struct EyeBuffer<T, 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: Size)
-> Result<EyeBuffer<T, D>, gfx::CombinedError> -> Result<EyeBuffer<T, 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 {