WIP: hacky world torus
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -8,7 +8,8 @@ extern crate piston_window;
|
||||
pub trait Scene<D: gfx::Device,
|
||||
F: gfx::Factory<D::Resources>> {
|
||||
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,
|
||||
factory: &mut F,
|
||||
encoder: &mut gfx::Encoder<D::Resources, D::CommandBuffer>,
|
||||
|
||||
@@ -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<Vertex> = (),
|
||||
trans: gfx::ConstantBuffer<::view::Trans> = "b_trans",
|
||||
locals: gfx::ConstantBuffer<Locals> = "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<Vertex>, Vec<u32>) {
|
||||
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<Vertex>, Vec<u32>) {
|
||||
pub struct WorldScene<D: gfx::Device,
|
||||
F: gfx::Factory<D::Resources>> {
|
||||
pso: gfx::PipelineState<D::Resources, pipe::Meta>,
|
||||
locals: gfx::handle::Buffer<D::Resources, Locals>,
|
||||
atlas: gfx::handle::ShaderResourceView<D::Resources,
|
||||
<view::ColorFormat as gfx::format::Formatted>::View>,
|
||||
sampler: gfx::handle::Sampler<D::Resources>,
|
||||
@@ -63,6 +71,8 @@ pub struct WorldScene<D: gfx::Device,
|
||||
|
||||
vbuf: gfx::handle::Buffer<D::Resources, Vertex>,
|
||||
slice: gfx::Slice<D::Resources>,
|
||||
|
||||
start_time: SystemTime,
|
||||
}
|
||||
|
||||
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,
|
||||
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<D: gfx::Device, F: gfx::Factory<D::Resources>> WorldScene<D, F> {
|
||||
|
||||
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<D: gfx::Device,
|
||||
F: gfx::Factory<D::Resources>> scene::Scene<D, F> for WorldScene<D, F> {
|
||||
|
||||
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,
|
||||
@@ -106,6 +130,7 @@ impl<D: gfx::Device,
|
||||
let pipe = pipe::Data {
|
||||
vbuf: self.vbuf.clone(),
|
||||
trans: trans.clone(),
|
||||
locals: self.locals.clone(),
|
||||
atlas: (self.atlas.clone(), self.sampler.clone()),
|
||||
pixcolor: target.clone(),
|
||||
depth: depth.clone(),
|
||||
@@ -142,11 +167,29 @@ const VERTEX_SHADER_SRC: &'static [u8] = br#"
|
||||
uniform b_trans {
|
||||
mat4 u_matrix;
|
||||
};
|
||||
uniform b_locals {
|
||||
uint millis;
|
||||
uint animdata;
|
||||
};
|
||||
|
||||
void main() {
|
||||
v_uv = a_uv;
|
||||
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;
|
||||
out vec4 pixcolor;
|
||||
uniform sampler2D t_atlas;
|
||||
uniform b_locals {
|
||||
uint millis;
|
||||
//uvec4 animdata;
|
||||
uint animdata;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
"#;
|
||||
|
||||
12
src/view.rs
12
src/view.rs
@@ -17,7 +17,7 @@ pub type ColorFormat = gfx::format::Srgba8;
|
||||
pub type DepthFormat = gfx::format::DepthStencil;
|
||||
|
||||
const NEAR: f32 = 0.01;
|
||||
const FAR: f32 = 1000.0;
|
||||
const FAR: f32 = 1000000.0;
|
||||
|
||||
gfx_constant_struct! {
|
||||
Trans {
|
||||
@@ -40,6 +40,10 @@ impl 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::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<gfx_device_gl::Device, ColorFormat, DepthFormat> {
|
||||
|
||||
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<gfx_device_gl::Device, ColorFormat, DepthFormat> {
|
||||
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,
|
||||
|
||||
@@ -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<T, D>
|
||||
}
|
||||
|
||||
pub fn create_eyebuffer<T, D>(factory: &mut gfx_device_gl::Factory,
|
||||
size: vr::common::Size)
|
||||
size: Size)
|
||||
-> Result<EyeBuffer<T, D>, gfx::CombinedError>
|
||||
where T: gfx::format::RenderFormat + gfx::format::TextureFormat,
|
||||
D: gfx::format::DepthFormat + gfx::format::TextureFormat {
|
||||
|
||||
Reference in New Issue
Block a user