mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix all clippy issues, clean up Rust code.
This commit is contained in:
parent
6f90e010b3
commit
c79f512f84
@ -233,10 +233,7 @@ impl Client {
|
|||||||
map_size_lg,
|
map_size_lg,
|
||||||
core::ops::RangeInclusive::new(0.0, max_height),
|
core::ops::RangeInclusive::new(0.0, max_height),
|
||||||
);
|
);
|
||||||
// map_config.gain = max_height;
|
|
||||||
map_config.horizons = Some(&horizons);
|
map_config.horizons = Some(&horizons);
|
||||||
// map_config.light_direction = Vec3::new(1.0, -1.0, 0.0);
|
|
||||||
// map_config.focus.z = 0.0;
|
|
||||||
let rescale_height = |h: f32| h / max_height;
|
let rescale_height = |h: f32| h / max_height;
|
||||||
let bounds_check = |pos: Vec2<i32>| {
|
let bounds_check = |pos: Vec2<i32>| {
|
||||||
pos.reduce_partial_min() >= 0
|
pos.reduce_partial_min() >= 0
|
||||||
@ -308,8 +305,7 @@ impl Client {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
let make_raw = |rgba| -> Result<_, Error> {
|
let make_raw = |rgba| -> Result<_, Error> {
|
||||||
let mut raw =
|
let mut raw = vec![0u8; 4 * world_map.len()];
|
||||||
vec![0u8; 4 * world_map.len()/*map_size.x * map_size.y*/];
|
|
||||||
LittleEndian::write_u32_into(rgba, &mut raw);
|
LittleEndian::write_u32_into(rgba, &mut raw);
|
||||||
Ok(Arc::new(
|
Ok(Arc::new(
|
||||||
image::DynamicImage::ImageRgba8({
|
image::DynamicImage::ImageRgba8({
|
||||||
@ -323,15 +319,14 @@ impl Client {
|
|||||||
.flipv(),
|
.flipv(),
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
let lod_base = rgba; //make_raw(&rgba)?;
|
let lod_base = rgba;
|
||||||
let lod_alt = alt; //make_raw(&alt)?;
|
let lod_alt = alt;
|
||||||
let world_map = make_raw(&world_map)?;
|
let world_map = make_raw(&world_map)?;
|
||||||
let horizons = (west.0, west.1, east.0, east.1)
|
let horizons = (west.0, west.1, east.0, east.1)
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|(wa, wh, ea, eh)| u32::from_le_bytes([wa, wh, ea, eh]))
|
.map(|(wa, wh, ea, eh)| u32::from_le_bytes([wa, wh, ea, eh]))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let lod_horizon = horizons; //make_raw(&horizons)?;
|
let lod_horizon = horizons;
|
||||||
// TODO: Get sea_level from server.
|
|
||||||
let map_bounds = Vec2::new(sea_level, max_height);
|
let map_bounds = Vec2::new(sea_level, max_height);
|
||||||
debug!("Done preparing image...");
|
debug!("Done preparing image...");
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ impl MapSizeLg {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn new(map_size_lg: Vec2<u32>) -> Result<Self, ()> {
|
pub const fn new(map_size_lg: Vec2<u32>) -> Result<Self, ()> {
|
||||||
// Assertion on dimensions: must be between
|
// Assertion on dimensions: must be between
|
||||||
// 0 and MAX_WORLD_BLOCKS_LG] - [TERRAIN_CHUNK_BLOCKS_LG
|
// 0 and ([MAX_WORLD_BLOCKS_LG] - [TERRAIN_CHUNK_BLOCKS_LG])
|
||||||
let is_le_max = map_size_lg.x <= MAX_WORLD_BLOCKS_LG.x - TERRAIN_CHUNK_BLOCKS_LG
|
let is_le_max = map_size_lg.x <= MAX_WORLD_BLOCKS_LG.x - TERRAIN_CHUNK_BLOCKS_LG
|
||||||
&& map_size_lg.y <= MAX_WORLD_BLOCKS_LG.y - TERRAIN_CHUNK_BLOCKS_LG;
|
&& map_size_lg.y <= MAX_WORLD_BLOCKS_LG.y - TERRAIN_CHUNK_BLOCKS_LG;
|
||||||
// Assertion on dimensions: chunks must fit in a u16.
|
// Assertion on dimensions: chunks must fit in a u16.
|
||||||
@ -667,14 +667,12 @@ impl<'a> MapConfig<'a> {
|
|||||||
let i_a = Rgb::new(0.1, 0.1, 0.1);
|
let i_a = Rgb::new(0.1, 0.1, 0.1);
|
||||||
// V = direction pointing towards the viewer (e.g. virtual camera).
|
// V = direction pointing towards the viewer (e.g. virtual camera).
|
||||||
let v = Vec3::new(0.0, 0.0, -1.0).normalized();
|
let v = Vec3::new(0.0, 0.0, -1.0).normalized();
|
||||||
// let v = Vec3::new(0.0, -1.0, 0.0).normalized();
|
|
||||||
//
|
|
||||||
// for each light m,
|
// for each light m,
|
||||||
// i_m,d = (RGB) intensity of diffuse component of light source m
|
// i_m,d = (RGB) intensity of diffuse component of light source m
|
||||||
let i_m_d = Rgb::new(1.0, 1.0, 1.0);
|
let i_m_d = Rgb::new(1.0, 1.0, 1.0);
|
||||||
// i_m,s = (RGB) intensity of specular component of light source m
|
// i_m,s = (RGB) intensity of specular component of light source m
|
||||||
let i_m_s = Rgb::new(0.45, 0.45, 0.45);
|
let i_m_s = Rgb::new(0.45, 0.45, 0.45);
|
||||||
// let i_m_s = Rgb::new(0.45, 0.45, 0.45);
|
|
||||||
|
|
||||||
// for each light m and point p,
|
// for each light m and point p,
|
||||||
// L_m = (normalized) direction vector from point on surface to light source m
|
// L_m = (normalized) direction vector from point on surface to light source m
|
||||||
|
@ -6,13 +6,3 @@ pub use ::vek::{
|
|||||||
bezier::repr_c::*, geom::repr_c::*, mat::repr_c::column_major::Mat4, ops::*,
|
bezier::repr_c::*, geom::repr_c::*, mat::repr_c::column_major::Mat4, ops::*,
|
||||||
quaternion::repr_c::*, transform::repr_c::*, transition::*, vec::repr_c::*,
|
quaternion::repr_c::*, transform::repr_c::*, transition::*, vec::repr_c::*,
|
||||||
}; */
|
}; */
|
||||||
/* pub use vek::{
|
|
||||||
bezier::repr_c::*,
|
|
||||||
geom::repr_c::*,
|
|
||||||
mat::repr_simd::column_major::Mat4,
|
|
||||||
ops::*,
|
|
||||||
quaternion::repr_simd::*,
|
|
||||||
transform::repr_c::*,
|
|
||||||
transition::*,
|
|
||||||
vec::repr_simd::*,
|
|
||||||
}; */
|
|
||||||
|
@ -3,6 +3,13 @@ use vek::*;
|
|||||||
|
|
||||||
type TerrainVertex = <TerrainPipeline as render::Pipeline>::Vertex;
|
type TerrainVertex = <TerrainPipeline as render::Pipeline>::Vertex;
|
||||||
|
|
||||||
|
type TodoRect = (
|
||||||
|
Vec3<i32>,
|
||||||
|
Vec2<Vec3<u16>>,
|
||||||
|
guillotiere::Rectangle,
|
||||||
|
Vec3<i32>,
|
||||||
|
);
|
||||||
|
|
||||||
/// `max_size`:
|
/// `max_size`:
|
||||||
///
|
///
|
||||||
/// `draw_delta`:
|
/// `draw_delta`:
|
||||||
@ -162,7 +169,7 @@ impl<'a> GreedyMesh<'a> {
|
|||||||
FS: for<'r> FnMut(&'r mut D, Vec3<i32>, Vec3<i32>, Vec2<Vec3<i32>>) -> Option<(bool, M)>,
|
FS: for<'r> FnMut(&'r mut D, Vec3<i32>, Vec3<i32>, Vec2<Vec3<i32>>) -> Option<(bool, M)>,
|
||||||
FP: FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
FP: FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
||||||
{
|
{
|
||||||
let (bounds, /* opaque, *//*shadow, */ cont) = greedy_mesh(
|
let (bounds, cont) = greedy_mesh(
|
||||||
&mut self.atlas,
|
&mut self.atlas,
|
||||||
&mut self.col_lights_size,
|
&mut self.col_lights_size,
|
||||||
self.max_size,
|
self.max_size,
|
||||||
@ -183,7 +190,10 @@ impl<'a> GreedyMesh<'a> {
|
|||||||
/// Returns the ColLightsInfo corresponding to the consstructed atlas.
|
/// Returns the ColLightsInfo corresponding to the consstructed atlas.
|
||||||
pub fn finalize(self) -> ColLightInfo {
|
pub fn finalize(self) -> ColLightInfo {
|
||||||
let cur_size = self.col_lights_size;
|
let cur_size = self.col_lights_size;
|
||||||
let col_lights = vec![/*Default::default()*/TerrainVertex::make_col_light(254, Rgb::broadcast(254)); usize::from(cur_size.x) * usize::from(cur_size.y)];
|
let col_lights = vec![
|
||||||
|
TerrainVertex::make_col_light(254, Rgb::broadcast(254));
|
||||||
|
usize::from(cur_size.x) * usize::from(cur_size.y)
|
||||||
|
];
|
||||||
let mut col_lights_info = (col_lights, cur_size);
|
let mut col_lights_info = (col_lights, cur_size);
|
||||||
self.suspended.into_iter().for_each(|cont| {
|
self.suspended.into_iter().for_each(|cont| {
|
||||||
cont(&mut col_lights_info);
|
cont(&mut col_lights_info);
|
||||||
@ -209,12 +219,7 @@ fn greedy_mesh<'a, M: PartialEq, D: 'a, FL, FC, FO, FS, FP>(
|
|||||||
mut should_draw,
|
mut should_draw,
|
||||||
mut push_quad,
|
mut push_quad,
|
||||||
}: GreedyConfig<D, FL, FC, FO, FS, FP>,
|
}: GreedyConfig<D, FL, FC, FO, FS, FP>,
|
||||||
) -> (
|
) -> (Aabb<u16>, Box<SuspendedMesh<'a>>)
|
||||||
Aabb<u16>,
|
|
||||||
// Mesh<O>,
|
|
||||||
// Mesh<S>,
|
|
||||||
Box<SuspendedMesh<'a>>,
|
|
||||||
)
|
|
||||||
where
|
where
|
||||||
FL: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
FL: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||||
FC: for<'r> FnMut(&'r mut D, Vec3<i32>) -> Rgb<u8> + 'a,
|
FC: for<'r> FnMut(&'r mut D, Vec3<i32>) -> Rgb<u8> + 'a,
|
||||||
@ -222,24 +227,9 @@ where
|
|||||||
FS: for<'r> FnMut(&'r mut D, Vec3<i32>, Vec3<i32>, Vec2<Vec3<i32>>) -> Option<(bool, M)>,
|
FS: for<'r> FnMut(&'r mut D, Vec3<i32>, Vec3<i32>, Vec2<Vec3<i32>>) -> Option<(bool, M)>,
|
||||||
FP: FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
FP: FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
||||||
{
|
{
|
||||||
// let mut opaque_mesh = Mesh::new();
|
|
||||||
// let mut shadow_mesh = Mesh::new();
|
|
||||||
|
|
||||||
// TODO: Collect information to see if we can choose a good value here.
|
// TODO: Collect information to see if we can choose a good value here.
|
||||||
let mut todo_rects = Vec::with_capacity(1024);
|
let mut todo_rects = Vec::with_capacity(1024);
|
||||||
|
|
||||||
/* let mut bounds = Aabb {
|
|
||||||
min: Vec3::zero(),
|
|
||||||
max: Vec3::zero(),
|
|
||||||
}; */
|
|
||||||
|
|
||||||
/* let compute_bounds = |pos: Vec3<usize>, dim: Vec2<usize>, uv: Vec2<Vec3<u16>>/*, norm: Vec3<u16>, faces_forward: bool*/| {
|
|
||||||
Aabb {
|
|
||||||
min: pos,
|
|
||||||
max: pos + uv.x.map(usize::from) * dim.x + uv.y.map(usize::from) * dim.y,
|
|
||||||
}
|
|
||||||
}; */
|
|
||||||
|
|
||||||
// x (u = y, v = z)
|
// x (u = y, v = z)
|
||||||
greedy_mesh_cross_section(
|
greedy_mesh_cross_section(
|
||||||
Vec3::new(greedy_size.y, greedy_size.z, greedy_size_cross.x),
|
Vec3::new(greedy_size.y, greedy_size.z, greedy_size_cross.x),
|
||||||
@ -247,7 +237,7 @@ where
|
|||||||
should_draw(
|
should_draw(
|
||||||
&mut data,
|
&mut data,
|
||||||
draw_delta + Vec3::new(pos.z, pos.x, pos.y),
|
draw_delta + Vec3::new(pos.z, pos.x, pos.y),
|
||||||
Vec3::unit_x(), /* , pos.z, 0, x_size */
|
Vec3::unit_x(),
|
||||||
Vec2::new(Vec3::unit_y(), Vec3::unit_z()),
|
Vec2::new(Vec3::unit_y(), Vec3::unit_z()),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -255,7 +245,6 @@ where
|
|||||||
let pos = Vec3::new(pos.z, pos.x, pos.y);
|
let pos = Vec3::new(pos.z, pos.x, pos.y);
|
||||||
let uv = Vec2::new(Vec3::unit_y(), Vec3::unit_z());
|
let uv = Vec2::new(Vec3::unit_y(), Vec3::unit_z());
|
||||||
let norm = Vec3::unit_x();
|
let norm = Vec3::unit_x();
|
||||||
// bounds.expand_to_contain(compute_bounds(pos, dim, uv));
|
|
||||||
let atlas_pos = if let Some(atlas_pos) = add_to_atlas(
|
let atlas_pos = if let Some(atlas_pos) = add_to_atlas(
|
||||||
atlas,
|
atlas,
|
||||||
&mut todo_rects,
|
&mut todo_rects,
|
||||||
@ -267,29 +256,18 @@ where
|
|||||||
max_size,
|
max_size,
|
||||||
col_lights_size,
|
col_lights_size,
|
||||||
) {
|
) {
|
||||||
// assert!(atlas_pos.max.x - atlas_pos.min.x == dim.x as i32);
|
|
||||||
// assert!(atlas_pos.max.y - atlas_pos.min.y == dim.y as i32);
|
|
||||||
atlas_pos
|
atlas_pos
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
create_quad_greedy(
|
create_quad_greedy(
|
||||||
// &mut shadow_mesh,
|
|
||||||
// &mut opaque_mesh,
|
|
||||||
/* Vec3::new(pos.z, pos.x, pos.y) */
|
|
||||||
pos,
|
pos,
|
||||||
dim,
|
dim,
|
||||||
uv,
|
uv,
|
||||||
norm,
|
norm,
|
||||||
faces_forward,
|
faces_forward,
|
||||||
// Rgba::from_opaque(flat_get(pos).color),
|
|
||||||
// lightm
|
|
||||||
// ao,
|
|
||||||
meta,
|
meta,
|
||||||
atlas_pos,
|
atlas_pos,
|
||||||
// |pos| flat_get(pos),
|
|
||||||
// |pos, norm, meta| create_shadow(pos, norm, meta),
|
|
||||||
// |atlas_pos, pos, norm, meta| create_opaque(atlas_pos, pos, norm, meta),
|
|
||||||
|atlas_pos, dim, pos, draw_dim, norm, meta| {
|
|atlas_pos, dim, pos, draw_dim, norm, meta| {
|
||||||
push_quad(atlas_pos, dim, pos, draw_dim, norm, meta)
|
push_quad(atlas_pos, dim, pos, draw_dim, norm, meta)
|
||||||
},
|
},
|
||||||
@ -312,7 +290,6 @@ where
|
|||||||
let pos = Vec3::new(pos.y, pos.z, pos.x);
|
let pos = Vec3::new(pos.y, pos.z, pos.x);
|
||||||
let uv = Vec2::new(Vec3::unit_z(), Vec3::unit_x());
|
let uv = Vec2::new(Vec3::unit_z(), Vec3::unit_x());
|
||||||
let norm = Vec3::unit_y();
|
let norm = Vec3::unit_y();
|
||||||
// bounds.expand_to_contain(compute_bounds(pos, dim, uv));
|
|
||||||
let atlas_pos = if let Some(atlas_pos) = add_to_atlas(
|
let atlas_pos = if let Some(atlas_pos) = add_to_atlas(
|
||||||
atlas,
|
atlas,
|
||||||
&mut todo_rects,
|
&mut todo_rects,
|
||||||
@ -329,18 +306,13 @@ where
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
create_quad_greedy(
|
create_quad_greedy(
|
||||||
// &mut shadow_mesh,
|
|
||||||
// &mut opaque_mesh,
|
|
||||||
pos,
|
pos,
|
||||||
dim,
|
dim,
|
||||||
uv,
|
uv,
|
||||||
norm,
|
norm,
|
||||||
faces_forward,
|
faces_forward,
|
||||||
// Rgba::from_opaque(flat_get(pos).color),
|
|
||||||
meta,
|
meta,
|
||||||
atlas_pos,
|
atlas_pos,
|
||||||
// |pos, norm, meta| create_shadow(pos, norm, meta),
|
|
||||||
// |atlas_pos, pos, norm, meta| create_opaque(atlas_pos, pos, norm, meta),
|
|
||||||
|atlas_pos, dim, pos, draw_dim, norm, meta| {
|
|atlas_pos, dim, pos, draw_dim, norm, meta| {
|
||||||
push_quad(atlas_pos, dim, pos, draw_dim, norm, meta)
|
push_quad(atlas_pos, dim, pos, draw_dim, norm, meta)
|
||||||
},
|
},
|
||||||
@ -352,25 +324,17 @@ where
|
|||||||
greedy_mesh_cross_section(
|
greedy_mesh_cross_section(
|
||||||
Vec3::new(greedy_size.x, greedy_size.y, greedy_size_cross.z),
|
Vec3::new(greedy_size.x, greedy_size.y, greedy_size_cross.z),
|
||||||
|pos| {
|
|pos| {
|
||||||
/* if pos.z == 0 {
|
|
||||||
let pos = pos.map(|e| e as i32) + draw_delta; // - delta;
|
|
||||||
let to = flat_get(pos).is_opaque(); //map(|v| v.is_opaque()).unwrap_or(false);
|
|
||||||
if to { Some(false) } else { None }
|
|
||||||
} else */
|
|
||||||
{
|
|
||||||
should_draw(
|
should_draw(
|
||||||
&mut data,
|
&mut data,
|
||||||
draw_delta + Vec3::new(pos.x, pos.y, pos.z),
|
draw_delta + Vec3::new(pos.x, pos.y, pos.z),
|
||||||
Vec3::unit_z(),
|
Vec3::unit_z(),
|
||||||
Vec2::new(Vec3::unit_x(), Vec3::unit_y()),
|
Vec2::new(Vec3::unit_x(), Vec3::unit_y()),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|pos, dim, &(faces_forward, ref meta)| {
|
|pos, dim, &(faces_forward, ref meta)| {
|
||||||
let pos = Vec3::new(pos.x, pos.y, pos.z);
|
let pos = Vec3::new(pos.x, pos.y, pos.z);
|
||||||
let uv = Vec2::new(Vec3::unit_x(), Vec3::unit_y());
|
let uv = Vec2::new(Vec3::unit_x(), Vec3::unit_y());
|
||||||
let norm = Vec3::unit_z();
|
let norm = Vec3::unit_z();
|
||||||
// bounds.expand_to_contain(compute_bounds(pos, dim, uv));
|
|
||||||
let atlas_pos = if let Some(atlas_pos) = add_to_atlas(
|
let atlas_pos = if let Some(atlas_pos) = add_to_atlas(
|
||||||
atlas,
|
atlas,
|
||||||
&mut todo_rects,
|
&mut todo_rects,
|
||||||
@ -387,18 +351,13 @@ where
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
create_quad_greedy(
|
create_quad_greedy(
|
||||||
// &mut shadow_mesh,
|
|
||||||
// &mut opaque_mesh,
|
|
||||||
pos,
|
pos,
|
||||||
dim,
|
dim,
|
||||||
uv,
|
uv,
|
||||||
norm,
|
norm,
|
||||||
faces_forward,
|
faces_forward,
|
||||||
// Rgba::from_opaque(flat_get(pos).color),
|
|
||||||
meta,
|
meta,
|
||||||
atlas_pos,
|
atlas_pos,
|
||||||
// |pos, norm, meta| create_shadow(pos, norm, meta),
|
|
||||||
// |atlas_pos, pos, norm, meta| create_opaque(atlas_pos, pos, norm, meta),
|
|
||||||
|atlas_pos, dim, pos, draw_dim, norm, meta| {
|
|atlas_pos, dim, pos, draw_dim, norm, meta| {
|
||||||
push_quad(atlas_pos, dim, pos, draw_dim, norm, meta)
|
push_quad(atlas_pos, dim, pos, draw_dim, norm, meta)
|
||||||
},
|
},
|
||||||
@ -406,9 +365,6 @@ where
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// NOTE: Safe because bound dimensions actually fit in a u16.
|
|
||||||
// let bounds = bounds.map(|e| e as u16);
|
|
||||||
// NOTE: Safe because draw_delta fits in i16.
|
|
||||||
let bounds = Aabb {
|
let bounds = Aabb {
|
||||||
min: Vec3::zero(),
|
min: Vec3::zero(),
|
||||||
// NOTE: Safe because greedy_size fit in u16.
|
// NOTE: Safe because greedy_size fit in u16.
|
||||||
@ -416,7 +372,6 @@ where
|
|||||||
};
|
};
|
||||||
(
|
(
|
||||||
bounds,
|
bounds,
|
||||||
/* opaque_mesh, *//*shadow_mesh, */
|
|
||||||
Box::new(move |col_lights_info| {
|
Box::new(move |col_lights_info| {
|
||||||
let mut data = data;
|
let mut data = data;
|
||||||
draw_col_lights(
|
draw_col_lights(
|
||||||
@ -435,7 +390,6 @@ where
|
|||||||
|
|
||||||
// Greedy meshing a single cross-section.
|
// Greedy meshing a single cross-section.
|
||||||
fn greedy_mesh_cross_section<M: PartialEq>(
|
fn greedy_mesh_cross_section<M: PartialEq>(
|
||||||
/* mask: &mut [bool], */
|
|
||||||
dims: Vec3<usize>,
|
dims: Vec3<usize>,
|
||||||
// Should we draw a face here (below this vertex)? If so, provide its meta information.
|
// Should we draw a face here (below this vertex)? If so, provide its meta information.
|
||||||
mut draw_face: impl FnMut(Vec3<i32>) -> Option<M>,
|
mut draw_face: impl FnMut(Vec3<i32>) -> Option<M>,
|
||||||
@ -477,7 +431,7 @@ fn greedy_mesh_cross_section<M: PartialEq>(
|
|||||||
.count();
|
.count();
|
||||||
let max_y = j + height;
|
let max_y = j + height;
|
||||||
// Add quad.
|
// Add quad.
|
||||||
push_quads(Vec3::new(i, j, d /* + 1 */), Vec2::new(width, height), ori);
|
push_quads(Vec3::new(i, j, d), Vec2::new(width, height), ori);
|
||||||
// Unset mask bits in drawn region, so we don't try to re-draw them.
|
// Unset mask bits in drawn region, so we don't try to re-draw them.
|
||||||
(j..max_y).for_each(|l| {
|
(j..max_y).for_each(|l| {
|
||||||
mask[l * dims.x + i..l * dims.x + max_x]
|
mask[l * dims.x + i..l * dims.x + max_x]
|
||||||
@ -498,12 +452,7 @@ fn greedy_mesh_cross_section<M: PartialEq>(
|
|||||||
|
|
||||||
fn add_to_atlas(
|
fn add_to_atlas(
|
||||||
atlas: &mut guillotiere::SimpleAtlasAllocator,
|
atlas: &mut guillotiere::SimpleAtlasAllocator,
|
||||||
todo_rects: &mut Vec<(
|
todo_rects: &mut Vec<TodoRect>,
|
||||||
Vec3<i32>,
|
|
||||||
Vec2<Vec3<u16>>,
|
|
||||||
guillotiere::Rectangle,
|
|
||||||
Vec3<i32>,
|
|
||||||
)>,
|
|
||||||
pos: Vec3<usize>,
|
pos: Vec3<usize>,
|
||||||
uv: Vec2<Vec3<u16>>,
|
uv: Vec2<Vec3<u16>>,
|
||||||
dim: Vec2<usize>,
|
dim: Vec2<usize>,
|
||||||
@ -542,7 +491,6 @@ fn add_to_atlas(
|
|||||||
(max texture size={:?}, so we are discarding this rectangle.",
|
(max texture size={:?}, so we are discarding this rectangle.",
|
||||||
pos, dim, max_size
|
pos, dim, max_size
|
||||||
);
|
);
|
||||||
// return None;
|
|
||||||
}
|
}
|
||||||
// Otherwise, we haven't reached max size yet, so double the size (or reach the
|
// Otherwise, we haven't reached max size yet, so double the size (or reach the
|
||||||
// max texture size) and try again.
|
// max texture size) and try again.
|
||||||
@ -551,7 +499,6 @@ fn add_to_atlas(
|
|||||||
max_size.height.min(current_size.height.saturating_mul(2)),
|
max_size.height.min(current_size.height.saturating_mul(2)),
|
||||||
);
|
);
|
||||||
atlas.grow(new_size);
|
atlas.grow(new_size);
|
||||||
// atlas.grow((current_size * 2).min(max_size));
|
|
||||||
}
|
}
|
||||||
// NOTE: Conversion is correct because our initial max size for the atlas was
|
// NOTE: Conversion is correct because our initial max size for the atlas was
|
||||||
// a u16 and we never grew the atlas, meaning all valid coordinates within the
|
// a u16 and we never grew the atlas, meaning all valid coordinates within the
|
||||||
@ -561,14 +508,6 @@ fn add_to_atlas(
|
|||||||
cur_size.y.max(atlas_rect.max.y as u16),
|
cur_size.y.max(atlas_rect.max.y as u16),
|
||||||
);
|
);
|
||||||
|
|
||||||
/* let (dim, uv, norm) = if faces_forward {
|
|
||||||
// NOTE: Conversion to u16 safe by function precondition.
|
|
||||||
(dim.map(|e| e as u16), uv, norm)
|
|
||||||
} else {
|
|
||||||
// NOTE: Conversion to u16 safe by function precondition.
|
|
||||||
(Vec2::new(dim.y as u16, dim.x as u16), Vec2::new(uv.y, uv.x), -norm)
|
|
||||||
}; */
|
|
||||||
|
|
||||||
// NOTE: pos can be converted safely from usize to i32 because all legal block
|
// NOTE: pos can be converted safely from usize to i32 because all legal block
|
||||||
// coordinates in this chunk must fit in an i32 (actually we have the much
|
// coordinates in this chunk must fit in an i32 (actually we have the much
|
||||||
// stronger property that this holds across the whole map).
|
// stronger property that this holds across the whole map).
|
||||||
@ -591,46 +530,28 @@ fn add_to_atlas(
|
|||||||
fn draw_col_lights<D>(
|
fn draw_col_lights<D>(
|
||||||
(col_lights, cur_size): &mut ColLightInfo,
|
(col_lights, cur_size): &mut ColLightInfo,
|
||||||
data: &mut D,
|
data: &mut D,
|
||||||
todo_rects: Vec<(
|
todo_rects: Vec<TodoRect>,
|
||||||
Vec3<i32>,
|
|
||||||
Vec2<Vec3<u16>>,
|
|
||||||
guillotiere::Rectangle,
|
|
||||||
Vec3<i32>,
|
|
||||||
)>,
|
|
||||||
draw_delta: Vec3<i32>,
|
draw_delta: Vec3<i32>,
|
||||||
mut get_light: impl FnMut(&mut D, Vec3<i32>) -> f32,
|
mut get_light: impl FnMut(&mut D, Vec3<i32>) -> f32,
|
||||||
mut get_color: impl FnMut(&mut D, Vec3<i32>) -> Rgb<u8>,
|
mut get_color: impl FnMut(&mut D, Vec3<i32>) -> Rgb<u8>,
|
||||||
mut get_opacity: impl FnMut(&mut D, Vec3<i32>) -> bool,
|
mut get_opacity: impl FnMut(&mut D, Vec3<i32>) -> bool,
|
||||||
mut make_col_light: impl FnMut(u8, Rgb<u8>) -> <<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType,
|
mut make_col_light: impl FnMut(u8, Rgb<u8>) -> <<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType,
|
||||||
) {
|
) {
|
||||||
/* for i in 0..todo_rects.len() {
|
todo_rects.into_iter().for_each(|(pos, uv, rect, delta)| {
|
||||||
for j in 0..todo_rects.len() {
|
|
||||||
if i == j {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(!todo_rects[i].2.intersects(&todo_rects[j].2));
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
todo_rects
|
|
||||||
.into_iter()
|
|
||||||
// .rev()
|
|
||||||
.for_each(|(pos, uv, rect, delta)| {
|
|
||||||
// NOTE: Conversions are safe because width, height, and offset must be
|
// NOTE: Conversions are safe because width, height, and offset must be
|
||||||
// non-negative, and because every allocated coordinate in the atlas must be in
|
// non-negative, and because every allocated coordinate in the atlas must be in
|
||||||
// bounds for the original size, max_texture_size, which fit into a u16.
|
// bounds for the original size, max_texture_size, which fit into a u16.
|
||||||
let width = (rect.max.x - rect.min.x) as u16;//rect.width() as u16;
|
let width = (rect.max.x - rect.min.x) as u16;
|
||||||
let height = (rect.max.y - rect.min.y) as u16;//rect.height() as u16;
|
let height = (rect.max.y - rect.min.y) as u16;
|
||||||
/* if width > 32 || height > 32 {
|
|
||||||
println!("Rect: {:?}", rect);
|
|
||||||
} */
|
|
||||||
let left = rect.min.x as u16;
|
let left = rect.min.x as u16;
|
||||||
let top = rect.min.y as u16;
|
let top = rect.min.y as u16;
|
||||||
let uv = uv.map(|e| e.map(i32::from));
|
let uv = uv.map(|e| e.map(i32::from));
|
||||||
let pos = pos + draw_delta;//Vec3::new(0, 0, z_start - 1);// + mesh_delta;// + draw_delta;
|
let pos = pos + draw_delta;
|
||||||
(0..height).for_each(|v| {
|
(0..height).for_each(|v| {
|
||||||
let start = usize::from(cur_size.x) * usize::from(top + v) + usize::from(left);
|
let start = usize::from(cur_size.x) * usize::from(top + v) + usize::from(left);
|
||||||
(0..width).zip(&mut col_lights[start..start + usize::from(width)]).for_each(|(u, col_light)| {
|
(0..width)
|
||||||
|
.zip(&mut col_lights[start..start + usize::from(width)])
|
||||||
|
.for_each(|(u, col_light)| {
|
||||||
let pos = pos + uv.x * i32::from(u) + uv.y * i32::from(v);
|
let pos = pos + uv.x * i32::from(u) + uv.y * i32::from(v);
|
||||||
// TODO: Consider optimizing to take advantage of the fact that this whole
|
// TODO: Consider optimizing to take advantage of the fact that this whole
|
||||||
// face should be facing nothing but air (this is not currently true, but
|
// face should be facing nothing but air (this is not currently true, but
|
||||||
@ -642,33 +563,23 @@ fn draw_col_lights<D>(
|
|||||||
// direct_opacity, and indirect_uv_opacity is multiplied by
|
// direct_opacity, and indirect_uv_opacity is multiplied by
|
||||||
// the maximum of both of u and v's indirect opacities (since there are
|
// the maximum of both of u and v's indirect opacities (since there are
|
||||||
// two choices for how to get to the direct surface).
|
// two choices for how to get to the direct surface).
|
||||||
let pos = pos +
|
let pos = pos
|
||||||
if u + 1 == width { -uv.x } else { Vec3::zero() } +
|
+ if u + 1 == width { -uv.x } else { Vec3::zero() }
|
||||||
if v + 1 == height { -uv.y } else { Vec3::zero() };
|
+ if v + 1 == height { -uv.y } else { Vec3::zero() };
|
||||||
let uv = Vec2::new(
|
let uv = Vec2::new(
|
||||||
if u + 1 == width { -uv.x } else { uv.x },
|
if u + 1 == width { -uv.x } else { uv.x },
|
||||||
if v + 1 == height { -uv.y } else { uv.y },
|
if v + 1 == height { -uv.y } else { uv.y },
|
||||||
);
|
);
|
||||||
|
|
||||||
let light_pos = pos + /*range.min + */delta;
|
let light_pos = pos + delta;
|
||||||
// let block = flat_get(pos);
|
|
||||||
|
|
||||||
// Currently, we assume that direct_opacity is 1 (if it's 0, you can't see
|
// Currently, we assume that direct_opacity is 1 (if it's 0, you can't see
|
||||||
// the face anyway, since it's blocked by the block directly in front of it).
|
// the face anyway, since it's blocked by the block directly in front of it).
|
||||||
// TODO: If we add non-0/1 opacities, fix this.
|
// TODO: If we add non-0/1 opacities, fix this.
|
||||||
// top-left block
|
|
||||||
// let direct_opacity = !flat_get(pos + delta).is_opaque();
|
|
||||||
// bottom-left block
|
// bottom-left block
|
||||||
let direct_u_opacity = get_opacity(data, light_pos - uv.x);
|
let direct_u_opacity = get_opacity(data, light_pos - uv.x);
|
||||||
// top-right block
|
// top-right block
|
||||||
let direct_v_opacity = get_opacity(data, light_pos - uv.y);
|
let direct_v_opacity = get_opacity(data, light_pos - uv.y);
|
||||||
// top-left block
|
|
||||||
// NOTE: Currently, since we only have 0 / 1 opacities, we don't worry
|
|
||||||
// about whether the uv block itself is opaque, because if it is its light
|
|
||||||
// value will be 0 anyway. But if we add translucent objects, we'll need
|
|
||||||
// to care about uv's opacity as well.
|
|
||||||
// let direct_uv_opacity = !flat_get(pos + delta - uv.x - uv.y).is_opaque();
|
|
||||||
// let indirect_opacity = direct_uv_opacity && (direct_u_opacity || direct_v_opacity) && direct_opacity;
|
|
||||||
|
|
||||||
// NOTE: Since we only support 0/1 opacities currently, we asssume
|
// NOTE: Since we only support 0/1 opacities currently, we asssume
|
||||||
// direct_opacity is 1, and the light value will be zero anyway for objects
|
// direct_opacity is 1, and the light value will be zero anyway for objects
|
||||||
@ -680,12 +591,16 @@ fn draw_col_lights<D>(
|
|||||||
// Light from the bottom-right-front block to this vertex always
|
// Light from the bottom-right-front block to this vertex always
|
||||||
// appears on this face, since it's the block this face is facing (so
|
// appears on this face, since it's the block this face is facing (so
|
||||||
// it can't be blocked by anything).
|
// it can't be blocked by anything).
|
||||||
if /*direct_u_opacity || direct_v_opacity*/true/* || !flat_get(pos - uv.x - uv.y).is_opaque()*//* || !block.is_opaque()*/ { get_light(data, light_pos) } else { 0.0 } +
|
get_light(data, light_pos)
|
||||||
if /*direct_opacity || direct_uv_opacity*/true/* || !flat_get(pos - uv.y).is_opaque()*/ { get_light(data, light_pos - uv.x) } else { 0.0 } +
|
+ get_light(data, light_pos - uv.x)
|
||||||
if /*direct_opacity || direct_uv_opacity*/true/* || !flat_get(pos - uv.x).is_opaque()*/ { get_light(data, light_pos - uv.y) } else { 0.0 } +
|
+ get_light(data, light_pos - uv.y)
|
||||||
if direct_u_opacity || direct_v_opacity/* || !block.is_opaque()*/ { get_light(data, light_pos - uv.x - uv.y) } else { 0.0 }
|
+ if direct_u_opacity || direct_v_opacity {
|
||||||
|
get_light(data, light_pos - uv.x - uv.y)
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
) / 4.0;
|
) / 4.0;
|
||||||
let col = get_color(data, pos);//.map(Rgba::from_opaque).unwrap_or(Rgba::zero());
|
let col = get_color(data, pos);
|
||||||
let light = (darkness * 255.0) as u8;
|
let light = (darkness * 255.0) as u8;
|
||||||
*col_light = make_col_light(light, col);
|
*col_light = make_col_light(light, col);
|
||||||
});
|
});
|
||||||
@ -695,9 +610,7 @@ fn draw_col_lights<D>(
|
|||||||
|
|
||||||
/// Precondition: when this function is called, atlas_pos should reflect an
|
/// Precondition: when this function is called, atlas_pos should reflect an
|
||||||
/// actual valid position in a texture atlas (meaning it should fit into a u16).
|
/// actual valid position in a texture atlas (meaning it should fit into a u16).
|
||||||
fn create_quad_greedy</* S: render::Pipeline, *//*O: render::Pipeline, */ M>(
|
fn create_quad_greedy<M>(
|
||||||
// shadow_mesh: &mut Mesh<S>,
|
|
||||||
// opaque_mesh: &mut Mesh<O>,
|
|
||||||
origin: Vec3<usize>,
|
origin: Vec3<usize>,
|
||||||
dim: Vec2<usize>,
|
dim: Vec2<usize>,
|
||||||
uv: Vec2<Vec3<u16>>,
|
uv: Vec2<Vec3<u16>>,
|
||||||
@ -705,26 +618,16 @@ fn create_quad_greedy</* S: render::Pipeline, *//*O: render::Pipeline, */ M>(
|
|||||||
faces_forward: bool,
|
faces_forward: bool,
|
||||||
meta: &M,
|
meta: &M,
|
||||||
atlas_pos: guillotiere::Rectangle,
|
atlas_pos: guillotiere::Rectangle,
|
||||||
// origin, norm, meta
|
|
||||||
// create_shadow: impl Fn(Vec3<f32>, Vec3<f32>, &M) -> S::Vertex,
|
|
||||||
// create_opaque: impl Fn(Vec2<u16>, Vec3<f32>, Vec3<f32>, &M) -> O::Vertex,
|
|
||||||
mut push_quad: impl FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
mut push_quad: impl FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
||||||
) /* -> Quad<ShadowPipeline> */
|
) {
|
||||||
{
|
|
||||||
let origin = origin.map(|e| e as f32);
|
let origin = origin.map(|e| e as f32);
|
||||||
/* // NOTE: Conversion to u16 safe by function precondition.
|
|
||||||
let dim = uv.map2(dim.map(|e| e as u16), |e, f| e * f); */
|
|
||||||
// NOTE: Conversion to f32 safe by function precondition (u16 can losslessly
|
// NOTE: Conversion to f32 safe by function precondition (u16 can losslessly
|
||||||
// cast to f32, and dim fits in a u16).
|
// cast to f32, and dim fits in a u16).
|
||||||
let draw_dim = uv.map2(dim.map(|e| e as f32), |e, f| e.map(f32::from) * f);
|
let draw_dim = uv.map2(dim.map(|e| e as f32), |e, f| e.map(f32::from) * f);
|
||||||
let dim = Vec2::new(Vec2::new(dim.x as u16, 0), Vec2::new(0, dim.y as u16));
|
let dim = Vec2::new(Vec2::new(dim.x as u16, 0), Vec2::new(0, dim.y as u16));
|
||||||
let (draw_dim, dim, /* uv, */ norm) = if faces_forward {
|
let (draw_dim, dim, /* uv, */ norm) = if faces_forward {
|
||||||
/* // NOTE: Conversion to u16 safe by function precondition.
|
|
||||||
(dim.map(|e| e as u16), uv, norm) */
|
|
||||||
(draw_dim, dim, norm)
|
(draw_dim, dim, norm)
|
||||||
} else {
|
} else {
|
||||||
/* // NOTE: Conversion to u16 safe by function precondition.
|
|
||||||
(Vec2::new(dim.y as u16, dim.x as u16), Vec2::new(uv.y, uv.x), -norm) */
|
|
||||||
(
|
(
|
||||||
Vec2::new(draw_dim.y, draw_dim.x),
|
Vec2::new(draw_dim.y, draw_dim.x),
|
||||||
Vec2::new(dim.y, dim.x),
|
Vec2::new(dim.y, dim.x),
|
||||||
@ -732,21 +635,8 @@ fn create_quad_greedy</* S: render::Pipeline, *//*O: render::Pipeline, */ M>(
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
let norm = norm.map(f32::from);
|
let norm = norm.map(f32::from);
|
||||||
// let draw_dim = draw_dim.map(|e| e.map(f32::from));
|
|
||||||
// NOTE: Conversion to u16 safe by function precondition.
|
// NOTE: Conversion to u16 safe by function precondition.
|
||||||
let atlas_pos = Vec2::new(atlas_pos.min.x as u16, atlas_pos.min.y as u16);
|
let atlas_pos = Vec2::new(atlas_pos.min.x as u16, atlas_pos.min.y as u16);
|
||||||
/* shadow_mesh.push_quad(Quad::new(
|
|
||||||
create_shadow(origin, norm, &meta/*, atlas_pos*/),
|
|
||||||
create_shadow(origin + draw_dim.x, norm, &meta/*, atlas_pos + dim.x*/),
|
|
||||||
create_shadow(origin + draw_dim.x + draw_dim.y, norm, &meta/*, atlas_pos + dim.x + dim.y*/),
|
|
||||||
create_shadow(origin + draw_dim.y, norm, &meta/*, atlas_pos + dim.y*/),
|
|
||||||
)); */
|
|
||||||
/* opaque_mesh.push_quad(Quad::new(
|
|
||||||
create_opaque(atlas_pos, origin, norm, &meta),
|
|
||||||
create_opaque(atlas_pos + dim.x, origin + draw_dim.x, norm, &meta),
|
|
||||||
create_opaque(atlas_pos + dim.x + dim.y, origin + draw_dim.x + draw_dim.y, norm, &meta),
|
|
||||||
create_opaque(atlas_pos + dim.y, origin + draw_dim.y, norm, &meta),
|
|
||||||
)); */
|
|
||||||
push_quad(atlas_pos, dim, origin, draw_dim, norm, meta);
|
push_quad(atlas_pos, dim, origin, draw_dim, norm, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,9 +659,5 @@ pub fn create_quad<O: render::Pipeline, M>(
|
|||||||
meta,
|
meta,
|
||||||
),
|
),
|
||||||
create_vertex(atlas_pos + dim.y, origin + draw_dim.y, norm, meta),
|
create_vertex(atlas_pos + dim.y, origin + draw_dim.y, norm, meta),
|
||||||
/* create_vertex(atlas_pos, origin, norm, meta),
|
|
||||||
create_vertex(atlas_pos + dim.y, origin + draw_dim.y, norm, meta),
|
|
||||||
create_vertex(atlas_pos + dim.x + dim.y, origin + draw_dim.x + draw_dim.y, norm, meta),
|
|
||||||
create_vertex(atlas_pos + dim.x, origin + draw_dim.x, norm, meta), */
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,13 @@ pub mod terrain;
|
|||||||
|
|
||||||
use crate::render::{self, Mesh};
|
use crate::render::{self, Mesh};
|
||||||
|
|
||||||
|
pub type MeshGen<P, T, M> = (
|
||||||
|
Mesh<<M as Meshable<P, T>>::Pipeline>,
|
||||||
|
Mesh<<M as Meshable<P, T>>::TranslucentPipeline>,
|
||||||
|
Mesh<<M as Meshable<P, T>>::ShadowPipeline>,
|
||||||
|
<M as Meshable<P, T>>::Result,
|
||||||
|
);
|
||||||
|
|
||||||
pub trait Meshable<P: render::Pipeline, T> {
|
pub trait Meshable<P: render::Pipeline, T> {
|
||||||
type Pipeline: render::Pipeline;
|
type Pipeline: render::Pipeline;
|
||||||
type TranslucentPipeline: render::Pipeline;
|
type TranslucentPipeline: render::Pipeline;
|
||||||
@ -12,13 +19,5 @@ pub trait Meshable<P: render::Pipeline, T> {
|
|||||||
type Result;
|
type Result;
|
||||||
|
|
||||||
// Generate meshes - one opaque, one translucent, one shadow
|
// Generate meshes - one opaque, one translucent, one shadow
|
||||||
fn generate_mesh(
|
fn generate_mesh(self, supp: Self::Supplement) -> MeshGen<P, T, Self>;
|
||||||
self,
|
|
||||||
supp: Self::Supplement,
|
|
||||||
) -> (
|
|
||||||
Mesh<Self::Pipeline>,
|
|
||||||
Mesh<Self::TranslucentPipeline>,
|
|
||||||
Mesh<Self::ShadowPipeline>,
|
|
||||||
Self::Result,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
mesh::{
|
mesh::{
|
||||||
greedy::{self, GreedyConfig, GreedyMesh},
|
greedy::{self, GreedyConfig, GreedyMesh},
|
||||||
Meshable,
|
MeshGen, Meshable,
|
||||||
},
|
},
|
||||||
render::{self, FigurePipeline, Mesh, ShadowPipeline, SpritePipeline, TerrainPipeline},
|
render::{self, FigurePipeline, Mesh, ShadowPipeline, SpritePipeline, TerrainPipeline},
|
||||||
};
|
};
|
||||||
@ -32,12 +32,7 @@ where
|
|||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
self,
|
self,
|
||||||
(greedy, offs, scale): Self::Supplement,
|
(greedy, offs, scale): Self::Supplement,
|
||||||
) -> (
|
) -> MeshGen<FigurePipeline, &'b mut GreedyMesh<'a>, Self> {
|
||||||
Mesh<Self::Pipeline>,
|
|
||||||
Mesh<Self::TranslucentPipeline>,
|
|
||||||
Mesh<Self::ShadowPipeline>,
|
|
||||||
Self::Result,
|
|
||||||
) {
|
|
||||||
let max_size = greedy.max_size();
|
let max_size = greedy.max_size();
|
||||||
// NOTE: Required because we steal two bits from the normal in the shadow uint
|
// NOTE: Required because we steal two bits from the normal in the shadow uint
|
||||||
// in order to store the bone index. The two bits are instead taken out
|
// in order to store the bone index. The two bits are instead taken out
|
||||||
@ -114,7 +109,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a: 'b, 'b, V: 'a> Meshable<SpritePipeline, /* SpritePipeline */ &'b mut GreedyMesh<'a>> for V
|
impl<'a: 'b, 'b, V: 'a> Meshable<SpritePipeline, &'b mut GreedyMesh<'a>> for V
|
||||||
where
|
where
|
||||||
V: BaseVol<Vox = Cell> + ReadVol + SizedVol,
|
V: BaseVol<Vox = Cell> + ReadVol + SizedVol,
|
||||||
/* TODO: Use VolIterator instead of manually iterating
|
/* TODO: Use VolIterator instead of manually iterating
|
||||||
@ -132,12 +127,7 @@ where
|
|||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
self,
|
self,
|
||||||
(greedy, vertical_stripes): Self::Supplement,
|
(greedy, vertical_stripes): Self::Supplement,
|
||||||
) -> (
|
) -> MeshGen<SpritePipeline, &'b mut GreedyMesh<'a>, Self> {
|
||||||
Mesh<Self::Pipeline>,
|
|
||||||
Mesh<Self::TranslucentPipeline>,
|
|
||||||
Mesh<Self::ShadowPipeline>,
|
|
||||||
(),
|
|
||||||
) {
|
|
||||||
let max_size = greedy.max_size();
|
let max_size = greedy.max_size();
|
||||||
// NOTE: Required because we steal two bits from the normal in the shadow uint
|
// NOTE: Required because we steal two bits from the normal in the shadow uint
|
||||||
// in order to store the bone index. The two bits are instead taken out
|
// in order to store the bone index. The two bits are instead taken out
|
||||||
@ -182,15 +172,8 @@ where
|
|||||||
vol.get(vox).map(|vox| *vox).unwrap_or(Vox::empty())
|
vol.get(vox).map(|vox| *vox).unwrap_or(Vox::empty())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
// NOTE: Conversion to f32 is fine since this i32 is actually in bounds for u16.
|
let create_opaque =
|
||||||
// let create_shadow = |pos, norm, _meta| ShadowVertex::new_figure((pos + offs)
|
|atlas_pos, pos: Vec3<f32>, norm, _meta| SpriteVertex::new(atlas_pos, pos, norm);
|
||||||
// * scale, norm, 0);
|
|
||||||
let create_opaque = |atlas_pos, pos: Vec3<f32>, norm, _meta| {
|
|
||||||
/* if pos.x >= 15.0 || pos.y >= 15.0 || pos.z >= 63.0 {
|
|
||||||
println!("{:?}", pos);
|
|
||||||
} */
|
|
||||||
SpriteVertex::new(atlas_pos, pos, norm /* , ao */)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut opaque_mesh = Mesh::new();
|
let mut opaque_mesh = Mesh::new();
|
||||||
let _bounds = greedy.push(GreedyConfig {
|
let _bounds = greedy.push(GreedyConfig {
|
||||||
@ -224,10 +207,8 @@ fn should_draw_greedy(
|
|||||||
_uv: Vec2<Vec3<i32>>,
|
_uv: Vec2<Vec3<i32>>,
|
||||||
flat_get: impl Fn(Vec3<i32>) -> Cell,
|
flat_get: impl Fn(Vec3<i32>) -> Cell,
|
||||||
) -> Option<(bool, /* u8 */ ())> {
|
) -> Option<(bool, /* u8 */ ())> {
|
||||||
// TODO: Verify conversion.
|
let from = flat_get(pos - delta);
|
||||||
// let pos = pos.map(|e| e as i32) + draw_delta; // - delta;
|
let to = flat_get(pos);
|
||||||
let from = flat_get(pos - delta); // map(|v| v.is_opaque()).unwrap_or(false);
|
|
||||||
let to = flat_get(pos); //map(|v| v.is_opaque()).unwrap_or(false);
|
|
||||||
let from_opaque = !from.is_empty();
|
let from_opaque = !from.is_empty();
|
||||||
if from_opaque == !to.is_empty() {
|
if from_opaque == !to.is_empty() {
|
||||||
None
|
None
|
||||||
@ -244,52 +225,17 @@ fn should_draw_greedy_ao(
|
|||||||
delta: Vec3<i32>,
|
delta: Vec3<i32>,
|
||||||
_uv: Vec2<Vec3<i32>>,
|
_uv: Vec2<Vec3<i32>>,
|
||||||
flat_get: impl Fn(Vec3<i32>) -> Cell,
|
flat_get: impl Fn(Vec3<i32>) -> Cell,
|
||||||
) -> Option<(bool, /* u8 */ bool)> {
|
) -> Option<(bool, bool)> {
|
||||||
// TODO: Verify conversion.
|
let from = flat_get(pos - delta);
|
||||||
// let pos = pos.map(|e| e as i32) + draw_delta; // - delta;
|
let to = flat_get(pos);
|
||||||
let from = flat_get(pos - delta); // map(|v| v.is_opaque()).unwrap_or(false);
|
|
||||||
let to = flat_get(pos); //map(|v| v.is_opaque()).unwrap_or(false);
|
|
||||||
let from_opaque = !from.is_empty();
|
let from_opaque = !from.is_empty();
|
||||||
if from_opaque == !to.is_empty() {
|
if from_opaque == !to.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let faces_forward = from_opaque;
|
let faces_forward = from_opaque;
|
||||||
let ao = /* if delta.z != 0 {
|
let ao = !vertical_stripes || (pos.z & 1) != 0;
|
||||||
0u8
|
|
||||||
} else {
|
|
||||||
(pos.z & 1) as u8
|
|
||||||
// (((pos.x & 1) as u8) << 1) | (pos.y & 1) as u8
|
|
||||||
}*/!vertical_stripes || /*((pos.x & 1) ^ (pos.y & 1))*/(pos.z & 1) != 0/* as u8*/;
|
|
||||||
/* let (from, delta, uv) = if faces_forward {
|
|
||||||
(pos - delta - uv.x - uv.y, delta, uv)
|
|
||||||
} else {
|
|
||||||
(pos, -delta, Vec2::new(-uv.y, -uv.x))
|
|
||||||
};
|
|
||||||
let ao_vertex = |from: Vec3<i32>, delta: Vec3<i32>, uv: Vec2<Vec3<i32>>| {
|
|
||||||
let corner = !flat_get(from + delta - uv.x - uv.y).is_empty();
|
|
||||||
let s1 = !flat_get(from + delta - uv.x).is_empty();
|
|
||||||
let s2 = !flat_get(from + delta - uv.y).is_empty();
|
|
||||||
if s1 && s2 {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
3 - (if corner { 1 } else { 0 } + if s1 { 1 } else { 0 } + if s2 { 1 } else { 0 })
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// We only care about the vertices we are *not* merging, since the shared vertices
|
|
||||||
// by definition have the same AO values. But snce we go both down and right we end up
|
|
||||||
// needing all but the bottom right vertex.
|
|
||||||
let ao_corner = ao_vertex(from, delta, uv);
|
|
||||||
let ao1 = ao_vertex(from + uv.x, delta, uv);
|
|
||||||
let ao2 = ao_vertex(from + uv.y, delta, uv);
|
|
||||||
let ao3 = ao_vertex(from + uv.x + uv.y, delta, uv);
|
|
||||||
// NOTE: ao's 4 values correspond (from 0 to 3) to 0.25, 0.5, 0.75, 1.0.
|
|
||||||
//
|
|
||||||
// 0.0 is the None case.
|
|
||||||
let ao = (ao_corner << 6) | (ao1 << 4) | (ao2 << 2) | ao3; */
|
|
||||||
// let ao = ao_vertex(from, delta, uv);
|
|
||||||
// If going from transparent to opaque, backward facing; otherwise, forward
|
// If going from transparent to opaque, backward facing; otherwise, forward
|
||||||
// facing.
|
// facing.
|
||||||
Some((faces_forward, ao))
|
Some((faces_forward, ao))
|
||||||
// Some((faces_forward, ()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
mesh::{
|
mesh::{
|
||||||
greedy::{self, GreedyConfig, GreedyMesh},
|
greedy::{self, GreedyConfig, GreedyMesh},
|
||||||
Meshable,
|
MeshGen, Meshable,
|
||||||
},
|
},
|
||||||
render::{self, ColLightInfo, FluidPipeline, Mesh, ShadowPipeline, TerrainPipeline},
|
render::{self, ColLightInfo, FluidPipeline, Mesh, ShadowPipeline, TerrainPipeline},
|
||||||
};
|
};
|
||||||
@ -230,12 +230,7 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
self,
|
self,
|
||||||
(range, max_texture_size): Self::Supplement,
|
(range, max_texture_size): Self::Supplement,
|
||||||
) -> (
|
) -> MeshGen<TerrainPipeline, FluidPipeline, Self> {
|
||||||
Mesh<Self::Pipeline>,
|
|
||||||
Mesh<Self::TranslucentPipeline>,
|
|
||||||
Mesh<Self::ShadowPipeline>,
|
|
||||||
Self::Result,
|
|
||||||
) {
|
|
||||||
let mut light = calc_light(range, self);
|
let mut light = calc_light(range, self);
|
||||||
|
|
||||||
let mut lowest_opaque = range.size().d;
|
let mut lowest_opaque = range.size().d;
|
||||||
@ -315,180 +310,6 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
}
|
}
|
||||||
.min(range.size().d - 1);
|
.min(range.size().d - 1);
|
||||||
|
|
||||||
// // We use multiple meshes and then combine them later such that we can group
|
|
||||||
// similar z // levels together (better rendering performance)
|
|
||||||
// let mut opaque_meshes = vec![Mesh::new(); ((z_end + 1 - z_start).clamped(1,
|
|
||||||
// 60) as usize / 10).max(1)];
|
|
||||||
// let mut opaque_mesh = Mesh::new();
|
|
||||||
// let mut fluid_mesh = Mesh::new();
|
|
||||||
|
|
||||||
/* for x in 1..range.size().w - 1 {
|
|
||||||
for y in 1..range.size().w - 1 {
|
|
||||||
let mut blocks = [[[None; 3]; 3]; 3];
|
|
||||||
for i in 0..3 {
|
|
||||||
for j in 0..3 {
|
|
||||||
for k in 0..3 {
|
|
||||||
blocks[k][j][i] = Some(flat_get(
|
|
||||||
Vec3::new(x, y, z_start) + Vec3::new(i as i32, j as i32, k as i32)
|
|
||||||
- 1,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut lights = [[[None; 3]; 3]; 3];
|
|
||||||
for i in 0..3 {
|
|
||||||
for j in 0..3 {
|
|
||||||
for k in 0..3 {
|
|
||||||
lights[k][j][i] = if blocks[k][j][i]
|
|
||||||
.map(|block| block.is_opaque())
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(light(
|
|
||||||
Vec3::new(
|
|
||||||
x + range.min.x,
|
|
||||||
y + range.min.y,
|
|
||||||
z_start + range.min.z,
|
|
||||||
) + Vec3::new(i as i32, j as i32, k as i32)
|
|
||||||
- 1,
|
|
||||||
))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let get_color = |maybe_block: Option<&Block>, neighbour: bool| {
|
|
||||||
maybe_block
|
|
||||||
.filter(|vox| vox.is_opaque() && (!neighbour || vox.is_blended()))
|
|
||||||
.and_then(|vox| vox.get_color())
|
|
||||||
.map(Rgba::from_opaque)
|
|
||||||
.unwrap_or(Rgba::zero())
|
|
||||||
};
|
|
||||||
|
|
||||||
for z in z_start..z_end + 1 {
|
|
||||||
let pos = Vec3::new(x, y, z);
|
|
||||||
let offs = (pos - Vec3::new(1, 1, -range.min.z)).map(|e| e as f32);
|
|
||||||
|
|
||||||
lights[0] = lights[1];
|
|
||||||
lights[1] = lights[2];
|
|
||||||
blocks[0] = blocks[1];
|
|
||||||
blocks[1] = blocks[2];
|
|
||||||
|
|
||||||
for i in 0..3 {
|
|
||||||
for j in 0..3 {
|
|
||||||
let block = Some(flat_get(pos + Vec3::new(i as i32, j as i32, 2) - 1));
|
|
||||||
blocks[2][j][i] = block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i in 0..3 {
|
|
||||||
for j in 0..3 {
|
|
||||||
lights[2][j][i] = if blocks[2][j][i]
|
|
||||||
.map(|block| block.is_opaque())
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(light(
|
|
||||||
pos + range.min + Vec3::new(i as i32, j as i32, 2) - 1,
|
|
||||||
))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let block = blocks[1][1][1];
|
|
||||||
let colors = if block.map_or(false, |vox| vox.is_blended()) {
|
|
||||||
let mut colors = [[[Rgba::zero(); 3]; 3]; 3];
|
|
||||||
for i in 0..3 {
|
|
||||||
for j in 0..3 {
|
|
||||||
for k in 0..3 {
|
|
||||||
colors[i][j][k] = get_color(
|
|
||||||
blocks[i][j][k].as_ref(),
|
|
||||||
i != 1 || j != 1 || k != 1,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
colors
|
|
||||||
} else {
|
|
||||||
[[[get_color(blocks[1][1][1].as_ref(), false); 3]; 3]; 3]
|
|
||||||
};
|
|
||||||
|
|
||||||
// let opaque_mesh_index = ((z - z_start) * opaque_meshes.len() as i32 / (z_end
|
|
||||||
// + 1 - z_start).max(1)) as usize; let selected_opaque_mesh
|
|
||||||
// = &mut opaque_meshes[opaque_mesh_index]; Create mesh
|
|
||||||
// polygons
|
|
||||||
/* if block.map_or(false, |vox| vox.is_opaque()) {
|
|
||||||
vol::push_vox_verts(
|
|
||||||
&mut opaque_mesh, //selected_opaque_mesh,
|
|
||||||
faces_to_make(&blocks, None, |vox| {
|
|
||||||
if vox.is_opaque() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(vox.is_fluid())
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
offs,
|
|
||||||
&colors,
|
|
||||||
|pos, norm, col, light, ao, &meta| {
|
|
||||||
//let light = (light.min(ao) * 255.0) as u32;
|
|
||||||
let light = (light * 255.0) as u32;
|
|
||||||
let ao = (ao * 255.0) as u32;
|
|
||||||
let norm = if norm.x != 0.0 {
|
|
||||||
if norm.x < 0.0 { 0 } else { 1 }
|
|
||||||
} else if norm.y != 0.0 {
|
|
||||||
if norm.y < 0.0 { 2 } else { 3 }
|
|
||||||
} else {
|
|
||||||
if norm.z < 0.0 { 4 } else { 5 }
|
|
||||||
};
|
|
||||||
TerrainVertex::new(norm, light, ao, pos, col, meta)
|
|
||||||
},
|
|
||||||
&lights,
|
|
||||||
);
|
|
||||||
} else */if block.map_or(false, |vox| vox.is_fluid()) {
|
|
||||||
vol::push_vox_verts(
|
|
||||||
&mut fluid_mesh,
|
|
||||||
// NOTE: want to skip blocks that aren't either next to air, or next to
|
|
||||||
// opaque blocks like ground. Addnig the blocks next to ground lets us
|
|
||||||
// make sure we compute lighting effects both at the water surface, and
|
|
||||||
// just before hitting the ground.
|
|
||||||
faces_to_make(&blocks, Some(()), |vox| {
|
|
||||||
if vox.is_air() { Some(()) } else { None }
|
|
||||||
}),
|
|
||||||
offs,
|
|
||||||
&colors,
|
|
||||||
|pos, norm, col, light, _ao, _meta| {
|
|
||||||
/* let rel_pos = pos - offs;
|
|
||||||
let rel_vox_pos = if rel_pos == offs {
|
|
||||||
rel_pos + norm + 1.0
|
|
||||||
} else {
|
|
||||||
rel_pos + 1.0
|
|
||||||
}.map(|e| e as usize);
|
|
||||||
let vox_neighbor = blocks[rel_vox_pos.z][rel_vox_pos.y][rel_vox_pos.x];
|
|
||||||
if vox_neighbor.is_opaque() {
|
|
||||||
} else {
|
|
||||||
} */
|
|
||||||
FluidVertex::new(pos, norm, col, light, 0.3)
|
|
||||||
},
|
|
||||||
&lights,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// let opaque_mesh = opaque_meshes
|
|
||||||
// .into_iter()
|
|
||||||
// .rev()
|
|
||||||
// .fold(Mesh::new(), |mut opaque_mesh, m: Mesh<Self::Pipeline>| {
|
|
||||||
// m.verts().chunks_exact(3).rev().for_each(|vs| {
|
|
||||||
// opaque_mesh.push(vs[0]);
|
|
||||||
// opaque_mesh.push(vs[1]);
|
|
||||||
// opaque_mesh.push(vs[2]);
|
|
||||||
// });
|
|
||||||
// opaque_mesh
|
|
||||||
// });
|
|
||||||
let max_size =
|
let max_size =
|
||||||
guillotiere::Size::new(i32::from(max_texture_size.x), i32::from(max_texture_size.y));
|
guillotiere::Size::new(i32::from(max_texture_size.x), i32::from(max_texture_size.y));
|
||||||
let greedy_size = Vec3::new(
|
let greedy_size = Vec3::new(
|
||||||
@ -508,8 +329,6 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
should_draw_greedy(pos, delta, flat_get)
|
should_draw_greedy(pos, delta, flat_get)
|
||||||
};
|
};
|
||||||
// NOTE: Conversion to f32 is fine since this i32 is actually in bounds for u16.
|
// NOTE: Conversion to f32 is fine since this i32 is actually in bounds for u16.
|
||||||
// let create_shadow = |pos, norm, meta| ShadowVertex::new(pos + Vec3::new(0.0,
|
|
||||||
// 0.0, (z_start + range.min.z) as f32), norm, meta);
|
|
||||||
let mesh_delta = Vec3::new(0.0, 0.0, (z_start + range.min.z) as f32);
|
let mesh_delta = Vec3::new(0.0, 0.0, (z_start + range.min.z) as f32);
|
||||||
let create_opaque = |atlas_pos, pos, norm, meta| {
|
let create_opaque = |atlas_pos, pos, norm, meta| {
|
||||||
TerrainVertex::new(atlas_pos, pos + mesh_delta, norm, meta)
|
TerrainVertex::new(atlas_pos, pos + mesh_delta, norm, meta)
|
||||||
@ -560,7 +379,6 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
max: bounds.max + mesh_delta,
|
max: bounds.max + mesh_delta,
|
||||||
};
|
};
|
||||||
let (col_lights, col_lights_size) = greedy.finalize();
|
let (col_lights, col_lights_size) = greedy.finalize();
|
||||||
// println!("z_bounds{:?}, bounds: {:?}", (mesh_delta.z, mesh_delta.z +
|
|
||||||
|
|
||||||
(
|
(
|
||||||
opaque_mesh,
|
opaque_mesh,
|
||||||
@ -576,10 +394,8 @@ fn should_draw_greedy(
|
|||||||
delta: Vec3<i32>,
|
delta: Vec3<i32>,
|
||||||
flat_get: impl Fn(Vec3<i32>) -> Block,
|
flat_get: impl Fn(Vec3<i32>) -> Block,
|
||||||
) -> Option<(bool, FaceKind)> {
|
) -> Option<(bool, FaceKind)> {
|
||||||
// TODO: Verify conversion.
|
let from = flat_get(pos - delta);
|
||||||
// let pos = pos.map(|e| e as i32) + draw_delta; // - delta;
|
let to = flat_get(pos);
|
||||||
let from = flat_get(pos - delta); // map(|v| v.is_opaque()).unwrap_or(false);
|
|
||||||
let to = flat_get(pos); //map(|v| v.is_opaque()).unwrap_or(false);
|
|
||||||
let from_opaque = from.is_opaque();
|
let from_opaque = from.is_opaque();
|
||||||
if from_opaque == to.is_opaque() {
|
if from_opaque == to.is_opaque() {
|
||||||
// Check the interface of fluid and non-tangible non-fluids (e.g. air).
|
// Check the interface of fluid and non-tangible non-fluids (e.g. air).
|
||||||
|
@ -17,15 +17,6 @@ impl<T: Copy + gfx::traits::Pod> Consts<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* /// Create a new immutable `Const<T>`.
|
|
||||||
pub fn new_immutable(factory: &mut gfx_backend::Factory, data: &[T]) -> Result<gfx::handle::RawBuffer<T>, RenderError> {
|
|
||||||
Ok(Self {
|
|
||||||
ibuf: factory
|
|
||||||
.create_buffer_immutable_raw(gfx::memory::cast_slice(data), core::mem::size_of::<T>(), gfx::buffer::Role::Constant, gfx::memory::Bind::empty())
|
|
||||||
.map_err(|err| RenderError::BufferCreationError(err))?,
|
|
||||||
})
|
|
||||||
} */
|
|
||||||
|
|
||||||
/// Update the GPU-side value represented by this constant handle.
|
/// Update the GPU-side value represented by this constant handle.
|
||||||
|
|
||||||
pub fn update(
|
pub fn update(
|
||||||
|
@ -4,7 +4,6 @@ use std::iter::FromIterator;
|
|||||||
/// A `Vec`-based mesh structure used to store mesh data on the CPU.
|
/// A `Vec`-based mesh structure used to store mesh data on the CPU.
|
||||||
pub struct Mesh<P: Pipeline> {
|
pub struct Mesh<P: Pipeline> {
|
||||||
verts: Vec<P::Vertex>,
|
verts: Vec<P::Vertex>,
|
||||||
// textures: Vec<>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Pipeline> Clone for Mesh<P>
|
impl<P: Pipeline> Clone for Mesh<P>
|
||||||
|
@ -21,7 +21,7 @@ pub use self::{
|
|||||||
Locals as FigureLocals,
|
Locals as FigureLocals,
|
||||||
},
|
},
|
||||||
fluid::FluidPipeline,
|
fluid::FluidPipeline,
|
||||||
lod_terrain::{Locals as LodTerrainLocals, LodTerrainPipeline},
|
lod_terrain::{Locals as LodTerrainLocals, LodData, LodTerrainPipeline},
|
||||||
postprocess::{
|
postprocess::{
|
||||||
create_mesh as create_pp_mesh, Locals as PostProcessLocals, PostProcessPipeline,
|
create_mesh as create_pp_mesh, Locals as PostProcessLocals, PostProcessPipeline,
|
||||||
},
|
},
|
||||||
@ -33,7 +33,7 @@ pub use self::{
|
|||||||
create_quad as create_ui_quad, create_tri as create_ui_tri, Locals as UiLocals,
|
create_quad as create_ui_quad, create_tri as create_ui_tri, Locals as UiLocals,
|
||||||
Mode as UiMode, UiPipeline,
|
Mode as UiMode, UiPipeline,
|
||||||
},
|
},
|
||||||
Globals, Light, Shadow,
|
GlobalModel, Globals, Light, Shadow,
|
||||||
},
|
},
|
||||||
renderer::{
|
renderer::{
|
||||||
ColLightFmt, ColLightInfo, LodAltFmt, LodColorFmt, LodTextureFmt, Renderer,
|
ColLightFmt, ColLightInfo, LodAltFmt, LodColorFmt, LodTextureFmt, Renderer,
|
||||||
|
@ -119,7 +119,6 @@ impl Pipeline for FigurePipeline {
|
|||||||
pub struct FigureModel {
|
pub struct FigureModel {
|
||||||
pub bounds: Aabb<f32>,
|
pub bounds: Aabb<f32>,
|
||||||
pub opaque: Model<TerrainPipeline>,
|
pub opaque: Model<TerrainPipeline>,
|
||||||
// pub shadow: Model<ShadowPipeline>,
|
|
||||||
// TODO: Consider using mipmaps instead of storing multiple texture atlases for different LOD
|
// TODO: Consider using mipmaps instead of storing multiple texture atlases for different LOD
|
||||||
// levels.
|
// levels.
|
||||||
pub col_lights: Texture<ColLightFmt>,
|
pub col_lights: Texture<ColLightFmt>,
|
||||||
|
@ -11,7 +11,6 @@ use vek::*;
|
|||||||
gfx_defines! {
|
gfx_defines! {
|
||||||
vertex Vertex {
|
vertex Vertex {
|
||||||
pos_norm: u32 = "v_pos_norm",
|
pos_norm: u32 = "v_pos_norm",
|
||||||
// col_light: u32 = "v_col_light",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline pipe {
|
pipeline pipe {
|
||||||
@ -41,31 +40,6 @@ gfx_defines! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Vertex {
|
impl Vertex {
|
||||||
/* pub fn new(pos: Vec3<f32>, norm: Vec3<f32>, col: Rgb<f32>, light: f32, _opac: f32) -> Self {
|
|
||||||
let (norm_axis, norm_dir) = norm
|
|
||||||
.as_slice()
|
|
||||||
.into_iter()
|
|
||||||
.enumerate()
|
|
||||||
.find(|(_i, e)| **e != 0.0)
|
|
||||||
.unwrap_or((0, &1.0));
|
|
||||||
let norm_bits = ((norm_axis << 1) | if *norm_dir > 0.0 { 1 } else { 0 }) as u32;
|
|
||||||
|
|
||||||
const EXTRA_NEG_Z: f32 = 65536.0;
|
|
||||||
|
|
||||||
Self {
|
|
||||||
pos_norm: 0
|
|
||||||
| ((pos.x as u32) & 0x003F) << 0
|
|
||||||
| ((pos.y as u32) & 0x003F) << 6
|
|
||||||
| (((pos.z + EXTRA_NEG_Z).max(0.0).min((1 << 17) as f32) as u32) & 0x1FFFF) << 12
|
|
||||||
| (norm_bits & 0x7) << 29,
|
|
||||||
col_light: 0
|
|
||||||
| ((col.r.mul(200.0) as u32) & 0xFF) << 8
|
|
||||||
| ((col.g.mul(200.0) as u32) & 0xFF) << 16
|
|
||||||
| ((col.b.mul(200.0) as u32) & 0xFF) << 24
|
|
||||||
| ((light.mul(255.0) as u32) & 0xFF) << 0,
|
|
||||||
//| ((opac.mul(0.4) as u32) & 0xFF) << 0,
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
#[allow(clippy::identity_op)] // TODO: Pending review in #587
|
#[allow(clippy::identity_op)] // TODO: Pending review in #587
|
||||||
#[allow(clippy::into_iter_on_ref)] // TODO: Pending review in #587
|
#[allow(clippy::into_iter_on_ref)] // TODO: Pending review in #587
|
||||||
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>) -> Self {
|
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>) -> Self {
|
||||||
@ -85,12 +59,6 @@ impl Vertex {
|
|||||||
| ((pos.y as u32) & 0x003F) << 6
|
| ((pos.y as u32) & 0x003F) << 6
|
||||||
| (((pos.z + EXTRA_NEG_Z).max(0.0).min((1 << 17) as f32) as u32) & 0x1FFFF) << 12
|
| (((pos.z + EXTRA_NEG_Z).max(0.0).min((1 << 17) as f32) as u32) & 0x1FFFF) << 12
|
||||||
| (norm_bits & 0x7) << 29,
|
| (norm_bits & 0x7) << 29,
|
||||||
/* col_light: 0
|
|
||||||
| ((col.r.mul(200.0) as u32) & 0xFF) << 8
|
|
||||||
| ((col.g.mul(200.0) as u32) & 0xFF) << 16
|
|
||||||
| ((col.b.mul(200.0) as u32) & 0xFF) << 24
|
|
||||||
| ((light.mul(255.0) as u32) & 0xFF) << 0,
|
|
||||||
//| ((opac.mul(0.4) as u32) & 0xFF) << 0, */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
use super::{
|
use super::{
|
||||||
super::{Pipeline, TgtColorFmt, TgtDepthStencilFmt},
|
super::{
|
||||||
|
LodAltFmt, LodColorFmt, LodTextureFmt, Pipeline, Renderer, Texture, TgtColorFmt,
|
||||||
|
TgtDepthStencilFmt,
|
||||||
|
},
|
||||||
Globals,
|
Globals,
|
||||||
};
|
};
|
||||||
use gfx::{
|
use gfx::{
|
||||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||||
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
gfx_pipeline_inner, gfx_vertex_struct_meta, texture::SamplerInfo,
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -51,3 +54,64 @@ pub struct LodTerrainPipeline;
|
|||||||
impl Pipeline for LodTerrainPipeline {
|
impl Pipeline for LodTerrainPipeline {
|
||||||
type Vertex = Vertex;
|
type Vertex = Vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct LodData {
|
||||||
|
pub map: Texture<LodColorFmt>,
|
||||||
|
pub alt: Texture<LodAltFmt>,
|
||||||
|
pub horizon: Texture<LodTextureFmt>,
|
||||||
|
pub tgt_detail: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LodData {
|
||||||
|
pub fn new(
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
map_size: Vec2<u16>,
|
||||||
|
lod_base: &[u32],
|
||||||
|
lod_alt: &[u32],
|
||||||
|
lod_horizon: &[u32],
|
||||||
|
tgt_detail: u32,
|
||||||
|
border_color: gfx::texture::PackedColor,
|
||||||
|
) -> Self {
|
||||||
|
let kind = gfx::texture::Kind::D2(map_size.x, map_size.y, gfx::texture::AaMode::Single);
|
||||||
|
let info = gfx::texture::SamplerInfo::new(
|
||||||
|
gfx::texture::FilterMethod::Bilinear,
|
||||||
|
gfx::texture::WrapMode::Border,
|
||||||
|
);
|
||||||
|
Self {
|
||||||
|
map: renderer
|
||||||
|
.create_texture_immutable_raw(
|
||||||
|
kind,
|
||||||
|
gfx::texture::Mipmap::Provided,
|
||||||
|
&[gfx::memory::cast_slice(lod_base)],
|
||||||
|
SamplerInfo {
|
||||||
|
border: border_color,
|
||||||
|
..info
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("Failed to generate map texture"),
|
||||||
|
alt: renderer
|
||||||
|
.create_texture_immutable_raw(
|
||||||
|
kind,
|
||||||
|
gfx::texture::Mipmap::Provided,
|
||||||
|
&[gfx::memory::cast_slice(lod_alt)],
|
||||||
|
SamplerInfo {
|
||||||
|
border: [0.0, 0.0, 0.0, 0.0].into(),
|
||||||
|
..info
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("Failed to generate alt texture"),
|
||||||
|
horizon: renderer
|
||||||
|
.create_texture_immutable_raw(
|
||||||
|
kind,
|
||||||
|
gfx::texture::Mipmap::Provided,
|
||||||
|
&[gfx::memory::cast_slice(lod_horizon)],
|
||||||
|
SamplerInfo {
|
||||||
|
border: [1.0, 0.0, 1.0, 0.0].into(),
|
||||||
|
..info
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("Failed to generate horizon texture"),
|
||||||
|
tgt_detail,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@ pub mod sprite;
|
|||||||
pub mod terrain;
|
pub mod terrain;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
|
|
||||||
|
use super::Consts;
|
||||||
use crate::scene::camera::CameraMode;
|
use crate::scene::camera::CameraMode;
|
||||||
use common::terrain::BlockKind;
|
use common::terrain::BlockKind;
|
||||||
use gfx::{self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta};
|
use gfx::{self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta};
|
||||||
@ -25,9 +26,6 @@ gfx_defines! {
|
|||||||
cam_pos: [f32; 4] = "cam_pos",
|
cam_pos: [f32; 4] = "cam_pos",
|
||||||
focus_off: [f32; 4] = "focus_off",
|
focus_off: [f32; 4] = "focus_off",
|
||||||
focus_pos: [f32; 4] = "focus_pos",
|
focus_pos: [f32; 4] = "focus_pos",
|
||||||
/// NOTE: max_intensity is computed as the ratio between the brightest and least bright
|
|
||||||
/// intensities among all lights in the scene.
|
|
||||||
// hdr_ratio: [f32; 4] = "max_intensity",
|
|
||||||
/// NOTE: view_distance.x is the horizontal view distance, view_distance.y is the LOD
|
/// NOTE: view_distance.x is the horizontal view distance, view_distance.y is the LOD
|
||||||
/// detail, view_distance.z is the
|
/// detail, view_distance.z is the
|
||||||
/// minimum height over any land chunk (i.e. the sea level), and view_distance.w is the
|
/// minimum height over any land chunk (i.e. the sea level), and view_distance.w is the
|
||||||
@ -54,7 +52,6 @@ gfx_defines! {
|
|||||||
constant Light {
|
constant Light {
|
||||||
pos: [f32; 4] = "light_pos",
|
pos: [f32; 4] = "light_pos",
|
||||||
col: [f32; 4] = "light_col",
|
col: [f32; 4] = "light_col",
|
||||||
// proj: [[f32; 4]; 4] = "light_proj";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constant Shadow {
|
constant Shadow {
|
||||||
@ -201,3 +198,11 @@ impl Shadow {
|
|||||||
impl Default for Shadow {
|
impl Default for Shadow {
|
||||||
fn default() -> Self { Self::new(Vec3::zero(), 0.0) }
|
fn default() -> Self { Self::new(Vec3::zero(), 0.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Global scene data spread across several arrays.
|
||||||
|
pub struct GlobalModel {
|
||||||
|
pub globals: Consts<Globals>,
|
||||||
|
pub lights: Consts<Light>,
|
||||||
|
pub shadows: Consts<Shadow>,
|
||||||
|
pub shadow_mats: Consts<shadow::Locals>,
|
||||||
|
}
|
||||||
|
@ -13,10 +13,7 @@ use vek::*;
|
|||||||
|
|
||||||
gfx_defines! {
|
gfx_defines! {
|
||||||
vertex Vertex {
|
vertex Vertex {
|
||||||
// pos: [f32; 4] = "v_pos",
|
|
||||||
pos_norm: u32 = "v_pos_norm",
|
pos_norm: u32 = "v_pos_norm",
|
||||||
// col_light: u32 = "v_col_light",
|
|
||||||
// atlas_pos: u32 = "v_atlas_pos",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constant Locals {
|
constant Locals {
|
||||||
@ -26,17 +23,10 @@ gfx_defines! {
|
|||||||
|
|
||||||
pipeline pipe {
|
pipeline pipe {
|
||||||
// Terrain vertex stuff
|
// Terrain vertex stuff
|
||||||
vbuf: gfx::VertexBuffer</*Vertex*/terrain::Vertex> = (),
|
vbuf: gfx::VertexBuffer<terrain::Vertex> = (),
|
||||||
|
|
||||||
locals: gfx::ConstantBuffer<TerrainLocals> = "u_locals",
|
locals: gfx::ConstantBuffer<TerrainLocals> = "u_locals",
|
||||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||||
// lights: gfx::ConstantBuffer<Light> = "u_lights",
|
|
||||||
// shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
|
||||||
|
|
||||||
// alt: gfx::TextureSampler<[f32; 2]> = "t_map",
|
|
||||||
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
|
||||||
|
|
||||||
// noise: gfx::TextureSampler<f32> = "t_noise",
|
|
||||||
|
|
||||||
// Shadow stuff
|
// Shadow stuff
|
||||||
light_shadows: gfx::ConstantBuffer<Locals> = "u_light_shadows",
|
light_shadows: gfx::ConstantBuffer<Locals> = "u_light_shadows",
|
||||||
@ -45,23 +35,15 @@ gfx_defines! {
|
|||||||
fun: gfx::state::Comparison::Less,
|
fun: gfx::state::Comparison::Less,
|
||||||
write: true,
|
write: true,
|
||||||
},
|
},
|
||||||
// tgt_depth_stencil: gfx::DepthTarget<ShadowDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,//,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline figure_pipe {
|
pipeline figure_pipe {
|
||||||
// Terrain vertex stuff
|
// Terrain vertex stuff
|
||||||
vbuf: gfx::VertexBuffer</*Vertex*/terrain::Vertex> = (),
|
vbuf: gfx::VertexBuffer<terrain::Vertex> = (),
|
||||||
|
|
||||||
locals: gfx::ConstantBuffer<figure::Locals> = "u_locals",
|
locals: gfx::ConstantBuffer<figure::Locals> = "u_locals",
|
||||||
bones: gfx::ConstantBuffer<figure::BoneData> = "u_bones",
|
bones: gfx::ConstantBuffer<figure::BoneData> = "u_bones",
|
||||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||||
// lights: gfx::ConstantBuffer<Light> = "u_lights",
|
|
||||||
// shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
|
||||||
|
|
||||||
// alt: gfx::TextureSampler<[f32; 2]> = "t_map",
|
|
||||||
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
|
||||||
|
|
||||||
// noise: gfx::TextureSampler<f32> = "t_noise",
|
|
||||||
|
|
||||||
// Shadow stuff
|
// Shadow stuff
|
||||||
light_shadows: gfx::ConstantBuffer<Locals> = "u_light_shadows",
|
light_shadows: gfx::ConstantBuffer<Locals> = "u_light_shadows",
|
||||||
@ -70,16 +52,11 @@ gfx_defines! {
|
|||||||
fun: gfx::state::Comparison::Less,
|
fun: gfx::state::Comparison::Less,
|
||||||
write: true,
|
write: true,
|
||||||
},
|
},
|
||||||
// tgt_depth_stencil: gfx::DepthTarget<ShadowDepthStencilFmt> = gfx::preset::depth::LESS_WRITE,//,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vertex {
|
impl Vertex {
|
||||||
pub fn new(
|
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>, meta: bool) -> Self {
|
||||||
pos: Vec3<f32>,
|
|
||||||
norm: Vec3<f32>,
|
|
||||||
meta: bool, /* , atlas_pos: Vec2<u16> */
|
|
||||||
) -> Self {
|
|
||||||
let norm_bits = if norm.x != 0.0 {
|
let norm_bits = if norm.x != 0.0 {
|
||||||
if norm.x < 0.0 { 0 } else { 1 }
|
if norm.x < 0.0 { 0 } else { 1 }
|
||||||
} else if norm.y != 0.0 {
|
} else if norm.y != 0.0 {
|
||||||
@ -89,10 +66,6 @@ impl Vertex {
|
|||||||
} else {
|
} else {
|
||||||
5
|
5
|
||||||
};
|
};
|
||||||
// let ao = 0xFFu32;
|
|
||||||
// let light = 0xFFu32;
|
|
||||||
// let col = Rgb::new(1.0f32, 0.0, 0.0);
|
|
||||||
// let meta = true;
|
|
||||||
|
|
||||||
const EXTRA_NEG_Z: f32 = 32768.0;
|
const EXTRA_NEG_Z: f32 = 32768.0;
|
||||||
|
|
||||||
@ -103,23 +76,10 @@ impl Vertex {
|
|||||||
| (((pos + EXTRA_NEG_Z).z.max(0.0).min((1 << 16) as f32) as u32) & 0xFFFF) << 12
|
| (((pos + EXTRA_NEG_Z).z.max(0.0).min((1 << 16) as f32) as u32) & 0xFFFF) << 12
|
||||||
| if meta { 1 } else { 0 } << 28
|
| if meta { 1 } else { 0 } << 28
|
||||||
| (norm_bits & 0x7) << 29,
|
| (norm_bits & 0x7) << 29,
|
||||||
/* atlas_pos: 0
|
|
||||||
| ((atlas_pos.x as u32) & 0xFFFF) << 0
|
|
||||||
| ((atlas_pos.y as u32) & 0xFFFF) << 16, */
|
|
||||||
/* col_light: 0
|
|
||||||
| (((col.r * 255.0) as u32) & 0xFF) << 8
|
|
||||||
| (((col.g * 255.0) as u32) & 0xFF) << 16
|
|
||||||
| (((col.b * 255.0) as u32) & 0xFF) << 24
|
|
||||||
| (ao >> 6) << 6
|
|
||||||
| ((light >> 2) & 0x3F) << 0, */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_figure(
|
pub fn new_figure(pos: Vec3<f32>, norm: Vec3<f32>, bone_idx: u8) -> Self {
|
||||||
pos: Vec3<f32>,
|
|
||||||
norm: Vec3<f32>,
|
|
||||||
/* col: Rgb<f32>, ao: f32, */ bone_idx: u8,
|
|
||||||
) -> Self {
|
|
||||||
let norm_bits = if norm.x.min(norm.y).min(norm.z) < 0.0 {
|
let norm_bits = if norm.x.min(norm.y).min(norm.z) < 0.0 {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
@ -133,10 +93,6 @@ impl Vertex {
|
|||||||
.reduce_bitor()
|
.reduce_bitor()
|
||||||
| (((bone_idx & 0xF) as u32) << 27)
|
| (((bone_idx & 0xF) as u32) << 27)
|
||||||
| (norm_bits << 31),
|
| (norm_bits << 31),
|
||||||
// col: col
|
|
||||||
// .map2(Rgb::new(0, 8, 16), |e, shift| ((e * 255.0) as u32) << shift)
|
|
||||||
// .reduce_bitor(),
|
|
||||||
// ao_bone: (bone_idx << 2) | ((ao * 3.9999) as u8),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +128,7 @@ impl ShadowPipeline {
|
|||||||
gfx::texture::AaMode::Single,
|
gfx::texture::AaMode::Single,
|
||||||
),
|
),
|
||||||
gfx::texture::Mipmap::Provided,
|
gfx::texture::Mipmap::Provided,
|
||||||
&[&col_lights /* .raw_pixels() */],
|
&[&col_lights],
|
||||||
gfx::texture::SamplerInfo::new(
|
gfx::texture::SamplerInfo::new(
|
||||||
gfx::texture::FilterMethod::Bilinear,
|
gfx::texture::FilterMethod::Bilinear,
|
||||||
gfx::texture::WrapMode::Clamp,
|
gfx::texture::WrapMode::Clamp,
|
||||||
|
@ -29,7 +29,6 @@ gfx_defines! {
|
|||||||
|
|
||||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||||
tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_TEST,
|
tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_TEST,
|
||||||
// tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
|
||||||
// tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
// tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ use vek::*;
|
|||||||
gfx_defines! {
|
gfx_defines! {
|
||||||
vertex Vertex {
|
vertex Vertex {
|
||||||
pos: [f32; 3] = "v_pos",
|
pos: [f32; 3] = "v_pos",
|
||||||
// pos_norm: u32 = "v_pos_norm",
|
|
||||||
// Because we try to restrict terrain sprite data to a 128×128 block
|
// Because we try to restrict terrain sprite data to a 128×128 block
|
||||||
// we need an offset into the texture atlas.
|
// we need an offset into the texture atlas.
|
||||||
atlas_pos: u32 = "v_atlas_pos",
|
atlas_pos: u32 = "v_atlas_pos",
|
||||||
@ -40,21 +39,17 @@ gfx_defines! {
|
|||||||
inst_mat1: [f32; 4] = "inst_mat1",
|
inst_mat1: [f32; 4] = "inst_mat1",
|
||||||
inst_mat2: [f32; 4] = "inst_mat2",
|
inst_mat2: [f32; 4] = "inst_mat2",
|
||||||
inst_mat3: [f32; 4] = "inst_mat3",
|
inst_mat3: [f32; 4] = "inst_mat3",
|
||||||
// inst_mat: [[f32; 4]; 4] = "inst_mat",
|
|
||||||
// inst_col: [f32; 3] = "inst_col",
|
|
||||||
inst_wind_sway: f32 = "inst_wind_sway",
|
inst_wind_sway: f32 = "inst_wind_sway",
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline pipe {
|
pipeline pipe {
|
||||||
vbuf: gfx::VertexBuffer<Vertex> = (),
|
vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||||
ibuf: gfx::InstanceBuffer<Instance> = (),
|
ibuf: gfx::InstanceBuffer<Instance> = (),
|
||||||
// ibuf: gfx::/*handle::RawBuffer*/ConstantBuffer<Instance> = "u_ibuf",
|
|
||||||
col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
||||||
|
|
||||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||||
// A sprite instance is a cross between a sprite and a terrain chunk.
|
// A sprite instance is a cross between a sprite and a terrain chunk.
|
||||||
terrain_locals: gfx::ConstantBuffer<terrain::Locals> = "u_terrain_locals",
|
terrain_locals: gfx::ConstantBuffer<terrain::Locals> = "u_terrain_locals",
|
||||||
// locals: gfx::ConstantBuffer<terrain::Locals> = "u_locals",
|
|
||||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||||
@ -113,24 +108,16 @@ impl Vertex {
|
|||||||
// | if meta { 1 } else { 0 } << 28
|
// | if meta { 1 } else { 0 } << 28
|
||||||
// | (norm_bits & 0x7) << 29,
|
// | (norm_bits & 0x7) << 29,
|
||||||
pos: pos.into_array(),
|
pos: pos.into_array(),
|
||||||
/* col: col
|
|
||||||
.map2(Rgb::new(0, 8, 16), |e, shift| ((e * 255.0) as u32) << shift)
|
|
||||||
.reduce_bitor(), */
|
|
||||||
atlas_pos: 0
|
atlas_pos: 0
|
||||||
| ((atlas_pos.x as u32) & 0xFFFF) << 0
|
| ((atlas_pos.x as u32) & 0xFFFF) << 0
|
||||||
| ((atlas_pos.y as u32) & 0xFFFF) << 16, /* | axis_bits & 3 */
|
| ((atlas_pos.y as u32) & 0xFFFF) << 16,
|
||||||
norm_ao: norm_bits, /* | (((ao * 3.9999) as u32) << 3) */
|
norm_ao: norm_bits,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance {
|
impl Instance {
|
||||||
pub fn new(
|
pub fn new(mat: Mat4<f32>, wind_sway: f32, pos: Vec3<i32>, ori_bits: u8) -> Self {
|
||||||
mat: Mat4<f32>,
|
|
||||||
/* col: Rgb<f32>, */ wind_sway: f32,
|
|
||||||
pos: Vec3<i32>,
|
|
||||||
ori_bits: u8,
|
|
||||||
) -> Self {
|
|
||||||
const EXTRA_NEG_Z: i32 = 32768;
|
const EXTRA_NEG_Z: i32 = 32768;
|
||||||
|
|
||||||
let mat_arr = mat.into_col_arrays();
|
let mat_arr = mat.into_col_arrays();
|
||||||
@ -138,29 +125,19 @@ impl Instance {
|
|||||||
pos_ori: 0
|
pos_ori: 0
|
||||||
| ((pos.x as u32) & 0x003F) << 0
|
| ((pos.x as u32) & 0x003F) << 0
|
||||||
| ((pos.y as u32) & 0x003F) << 6
|
| ((pos.y as u32) & 0x003F) << 6
|
||||||
| (((pos + EXTRA_NEG_Z).z.max(0).min(1 << 16/* as f32*/) as u32) & 0xFFFF) << 12
|
| (((pos + EXTRA_NEG_Z).z.max(0).min(1 << 16) as u32) & 0xFFFF) << 12
|
||||||
// | if meta { 1 } else { 0 } << 28
|
|
||||||
| (u32::from(ori_bits) & 0x7) << 29,
|
| (u32::from(ori_bits) & 0x7) << 29,
|
||||||
inst_mat0: mat_arr[0],
|
inst_mat0: mat_arr[0],
|
||||||
inst_mat1: mat_arr[1],
|
inst_mat1: mat_arr[1],
|
||||||
inst_mat2: mat_arr[2],
|
inst_mat2: mat_arr[2],
|
||||||
inst_mat3: mat_arr[3],
|
inst_mat3: mat_arr[3],
|
||||||
// inst_mat: mat_arr,
|
|
||||||
// inst_col: col.into_array(),
|
|
||||||
inst_wind_sway: wind_sway,
|
inst_wind_sway: wind_sway,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Instance {
|
impl Default for Instance {
|
||||||
fn default() -> Self {
|
fn default() -> Self { Self::new(Mat4::identity(), 0.0, Vec3::zero(), 0) }
|
||||||
Self::new(
|
|
||||||
Mat4::identity(),
|
|
||||||
/* Rgb::broadcast(1.0), */ 0.0,
|
|
||||||
Vec3::zero(),
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Locals {
|
impl Default for Locals {
|
||||||
|
@ -10,8 +10,6 @@ use vek::*;
|
|||||||
|
|
||||||
gfx_defines! {
|
gfx_defines! {
|
||||||
vertex Vertex {
|
vertex Vertex {
|
||||||
// pos_norm: u32 = "v_pos_norm",
|
|
||||||
// col_light: u32 = "v_col_light",
|
|
||||||
pos_norm: u32 = "v_pos_norm",
|
pos_norm: u32 = "v_pos_norm",
|
||||||
atlas_pos: u32 = "v_atlas_pos",
|
atlas_pos: u32 = "v_atlas_pos",
|
||||||
}
|
}
|
||||||
@ -23,8 +21,7 @@ gfx_defines! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pipeline pipe {
|
pipeline pipe {
|
||||||
vbuf: gfx::VertexBuffer</*shadow::Vertex*/Vertex> = (),
|
vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||||
// abuf: gfx::VertexBuffer<Vertex> = (),
|
|
||||||
col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
||||||
|
|
||||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||||
@ -73,22 +70,10 @@ impl Vertex {
|
|||||||
atlas_pos: 0
|
atlas_pos: 0
|
||||||
| ((atlas_pos.x as u32) & 0xFFFF) << 0
|
| ((atlas_pos.x as u32) & 0xFFFF) << 0
|
||||||
| ((atlas_pos.y as u32) & 0xFFFF) << 16,
|
| ((atlas_pos.y as u32) & 0xFFFF) << 16,
|
||||||
/* col_light: 0
|
|
||||||
| (((col.r * 255.0) as u32) & 0xFF) << 8
|
|
||||||
| (((col.g * 255.0) as u32) & 0xFF) << 16
|
|
||||||
| (((col.b * 255.0) as u32) & 0xFF) << 24
|
|
||||||
| (ao >> 6) << 6
|
|
||||||
| ((light >> 2) & 0x3F) << 0, */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_figure(
|
pub fn new_figure(atlas_pos: Vec2<u16>, pos: Vec3<f32>, norm: Vec3<f32>, bone_idx: u8) -> Self {
|
||||||
// norm: Vec3<f32>,
|
|
||||||
atlas_pos: Vec2<u16>,
|
|
||||||
pos: Vec3<f32>,
|
|
||||||
norm: Vec3<f32>,
|
|
||||||
bone_idx: u8,
|
|
||||||
) -> Self {
|
|
||||||
let norm_bits = if norm.x.min(norm.y).min(norm.z) < 0.0 {
|
let norm_bits = if norm.x.min(norm.y).min(norm.z) < 0.0 {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
@ -113,57 +98,15 @@ impl Vertex {
|
|||||||
| ((atlas_pos.x as u32) & 0x7FFF) << 2
|
| ((atlas_pos.x as u32) & 0x7FFF) << 2
|
||||||
| ((atlas_pos.y as u32) & 0x7FFF) << 17
|
| ((atlas_pos.y as u32) & 0x7FFF) << 17
|
||||||
| axis_bits & 3,
|
| axis_bits & 3,
|
||||||
/* col_light: 0
|
|
||||||
| (((col.r * 255.0) as u32) & 0xFF) << 8
|
|
||||||
| (((col.g * 255.0) as u32) & 0xFF) << 16
|
|
||||||
| (((col.b * 255.0) as u32) & 0xFF) << 24
|
|
||||||
| (ao >> 6) << 6
|
|
||||||
| ((light >> 2) & 0x3F) << 0, */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pub fn new(
|
|
||||||
norm_bits: u32,
|
|
||||||
light: u32,
|
|
||||||
ao: u32,
|
|
||||||
pos: Vec3<f32>,
|
|
||||||
col: Rgb<f32>,
|
|
||||||
meta: bool,
|
|
||||||
) -> Self {
|
|
||||||
const EXTRA_NEG_Z: f32 = 32768.0;
|
|
||||||
|
|
||||||
Self {
|
|
||||||
pos_norm: 0
|
|
||||||
| ((pos.x as u32) & 0x003F) << 0
|
|
||||||
| ((pos.y as u32) & 0x003F) << 6
|
|
||||||
| (((pos + EXTRA_NEG_Z).z.max(0.0).min((1 << 16) as f32) as u32) & 0xFFFF) << 12
|
|
||||||
| if meta { 1 } else { 0 } << 28
|
|
||||||
| (norm_bits & 0x7) << 29,
|
|
||||||
col_light: 0
|
|
||||||
| ((col.r.mul(255.0) as u32) & 0xFF) << 8
|
|
||||||
| ((col.g.mul(255.0) as u32) & 0xFF) << 16
|
|
||||||
| ((col.b.mul(255.0) as u32) & 0xFF) << 24
|
|
||||||
| (ao >> 6) << 6
|
|
||||||
| ((light >> 2) & 0x3F) << 0,
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
|
|
||||||
pub fn make_col_light(
|
pub fn make_col_light(
|
||||||
light: /* u32 */ u8,
|
light: u8,
|
||||||
// ao: u32,
|
|
||||||
// col: Rgb<f32>,
|
|
||||||
col: Rgb<u8>,
|
col: Rgb<u8>,
|
||||||
) -> <<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType
|
) -> <<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType
|
||||||
{
|
{
|
||||||
[
|
[col.r, col.g, col.b, light]
|
||||||
col.r, //.mul(255.0) as u8,
|
|
||||||
col.g, //.mul(255.0) as u8,
|
|
||||||
col.b, //.mul(255.0) as u8,
|
|
||||||
light,
|
|
||||||
/* | (ao as u8 >> 6) << 6
|
|
||||||
* | //((light as u8 >> 2) & 0x3F) << 0,
|
|
||||||
* | light */
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_bone_idx(self, bone_idx: u8) -> Self {
|
pub fn with_bone_idx(self, bone_idx: u8) -> Self {
|
||||||
@ -187,5 +130,5 @@ impl Locals {
|
|||||||
pub struct TerrainPipeline;
|
pub struct TerrainPipeline;
|
||||||
|
|
||||||
impl Pipeline for TerrainPipeline {
|
impl Pipeline for TerrainPipeline {
|
||||||
type Vertex = Vertex; //<<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType;
|
type Vertex = Vertex;
|
||||||
}
|
}
|
||||||
|
@ -131,18 +131,6 @@ pub fn create_quad(
|
|||||||
v([l, b], [uv_l, uv_b]),
|
v([l, b], [uv_l, uv_b]),
|
||||||
v([r, b], [uv_r, uv_b]),
|
v([r, b], [uv_r, uv_b]),
|
||||||
),
|
),
|
||||||
/* (true, true) | (false, false) => Quad::new(
|
|
||||||
v([l, t], [uv_l, uv_t]),
|
|
||||||
v([r, t], [uv_l, uv_b]),
|
|
||||||
v([r, b], [uv_r, uv_b]),
|
|
||||||
v([l, b], [uv_r, uv_t]),
|
|
||||||
),
|
|
||||||
_ => Quad::new(
|
|
||||||
v([l, t], [uv_l, uv_t]),
|
|
||||||
v([l, b], [uv_l, uv_b]),
|
|
||||||
v([r, b], [uv_r, uv_b]),
|
|
||||||
v([r, t], [uv_r, uv_t]),
|
|
||||||
) */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ use super::{
|
|||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
model::{DynamicModel, Model},
|
model::{DynamicModel, Model},
|
||||||
pipelines::{
|
pipelines::{
|
||||||
figure, fluid, lod_terrain, postprocess, shadow, skybox, sprite, terrain, ui, Globals,
|
figure, fluid, lod_terrain, postprocess, shadow, skybox, sprite, terrain, ui, GlobalModel,
|
||||||
Light, Shadow,
|
Globals,
|
||||||
},
|
},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
AaMode, CloudMode, FilterMethod, FluidMode, LightingMode, Pipeline, RenderError, RenderMode,
|
AaMode, CloudMode, FilterMethod, FluidMode, LightingMode, Pipeline, RenderError, RenderMode,
|
||||||
@ -49,13 +49,13 @@ pub type WinColorView = gfx::handle::RenderTargetView<gfx_backend::Resources, Wi
|
|||||||
pub type WinDepthView = gfx::handle::DepthStencilView<gfx_backend::Resources, WinDepthFmt>;
|
pub type WinDepthView = gfx::handle::DepthStencilView<gfx_backend::Resources, WinDepthFmt>;
|
||||||
|
|
||||||
/// Represents the format of LOD shadows.
|
/// Represents the format of LOD shadows.
|
||||||
pub type LodTextureFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm); //[gfx::format::U8Norm; 4];
|
pub type LodTextureFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm);
|
||||||
|
|
||||||
/// Represents the format of LOD altitudes.
|
/// Represents the format of LOD altitudes.
|
||||||
pub type LodAltFmt = (gfx::format::R16_G16, gfx::format::Unorm); //[gfx::format::U8Norm; 4];
|
pub type LodAltFmt = (gfx::format::R16_G16, gfx::format::Unorm);
|
||||||
|
|
||||||
/// Represents the format of LOD map colors.
|
/// Represents the format of LOD map colors.
|
||||||
pub type LodColorFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb); //[gfx::format::U8Norm; 4];
|
pub type LodColorFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb);
|
||||||
|
|
||||||
/// Represents the format of greedy meshed color-light textures.
|
/// Represents the format of greedy meshed color-light textures.
|
||||||
pub type ColLightFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb);
|
pub type ColLightFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb);
|
||||||
@ -420,6 +420,9 @@ impl Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create textures and views for shadow maps.
|
/// Create textures and views for shadow maps.
|
||||||
|
// This is a one-use type and the two halves are not guaranteed to remain identical, so we
|
||||||
|
// disable the type complexity lint.
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
fn create_shadow_views(
|
fn create_shadow_views(
|
||||||
factory: &mut gfx_device_gl::Factory,
|
factory: &mut gfx_device_gl::Factory,
|
||||||
size: (u16, u16),
|
size: (u16, u16),
|
||||||
@ -457,7 +460,7 @@ impl Renderer {
|
|||||||
}
|
}
|
||||||
}))?;
|
}))?;
|
||||||
|
|
||||||
let levels = 1; //10;
|
let levels = 1;
|
||||||
let two_size = vec2_result(size.map(|e| {
|
let two_size = vec2_result(size.map(|e| {
|
||||||
u16::checked_next_power_of_two(e)
|
u16::checked_next_power_of_two(e)
|
||||||
.filter(|&e| e <= max_texture_size)
|
.filter(|&e| e <= max_texture_size)
|
||||||
@ -501,67 +504,26 @@ impl Renderer {
|
|||||||
diag_size
|
diag_size
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
/* let color_cty = <<TgtColorFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped
|
|
||||||
>::get_channel_type();
|
|
||||||
let tgt_color_tex = factory.create_texture(
|
|
||||||
kind,
|
|
||||||
levels,
|
|
||||||
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::RENDER_TARGET,
|
|
||||||
gfx::memory::Usage::Data,
|
|
||||||
Some(color_cty),
|
|
||||||
)?;
|
|
||||||
let tgt_color_res = factory.view_texture_as_shader_resource::<TgtColorFmt>(
|
|
||||||
&tgt_color_tex,
|
|
||||||
(0, levels - 1),
|
|
||||||
gfx::format::Swizzle::new(),
|
|
||||||
)?;
|
|
||||||
let tgt_color_view = factory.view_texture_as_render_target(&tgt_color_tex, 0, None)?;
|
|
||||||
|
|
||||||
let depth_stencil_cty = <<TgtDepthStencilFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type();
|
|
||||||
let tgt_depth_stencil_tex = factory.create_texture(
|
|
||||||
kind,
|
|
||||||
levels,
|
|
||||||
gfx::memory::Bind::DEPTH_STENCIL,
|
|
||||||
gfx::memory::Usage::Data,
|
|
||||||
Some(depth_stencil_cty),
|
|
||||||
)?;
|
|
||||||
let tgt_depth_stencil_view =
|
|
||||||
factory.view_texture_as_depth_stencil_trivial(&tgt_depth_stencil_tex)?; */
|
|
||||||
let depth_stencil_cty = <<ShadowDepthStencilFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type();
|
let depth_stencil_cty = <<ShadowDepthStencilFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type();
|
||||||
|
|
||||||
let point_shadow_tex = factory
|
let point_shadow_tex = factory
|
||||||
.create_texture(
|
.create_texture(
|
||||||
gfx::texture::Kind::/*CubeArray*/Cube(
|
gfx::texture::Kind::Cube(diag_two_size / 4),
|
||||||
/* max_two_size */ diag_two_size / 4, /* size * 2*//*, 32 */
|
|
||||||
),
|
|
||||||
levels as gfx::texture::Level,
|
levels as gfx::texture::Level,
|
||||||
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::DEPTH_STENCIL,
|
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::DEPTH_STENCIL,
|
||||||
gfx::memory::Usage::Data,
|
gfx::memory::Usage::Data,
|
||||||
Some(depth_stencil_cty),
|
Some(depth_stencil_cty),
|
||||||
/* Some(<<F as gfx::format::Formatted>::Channel as
|
|
||||||
* gfx::format::ChannelTyped>::get_channel_type()), */
|
|
||||||
)
|
)
|
||||||
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Texture(err)))?;
|
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Texture(err)))?;
|
||||||
|
|
||||||
let point_tgt_shadow_view = factory
|
let point_tgt_shadow_view = factory
|
||||||
.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
||||||
&point_shadow_tex,
|
&point_shadow_tex,
|
||||||
0, // levels,
|
0,
|
||||||
None, // Some(1),
|
None,
|
||||||
gfx::texture::DepthStencilFlags::empty(),
|
gfx::texture::DepthStencilFlags::empty(),
|
||||||
)?;
|
)?;
|
||||||
// let tgt_shadow_view =
|
|
||||||
// factory.view_texture_as_depth_stencil_trivial(&shadow_tex)?;
|
|
||||||
/* let tgt_shadow_res = factory.view_texture_as_shader_resource::<TgtColorFmt>(
|
|
||||||
&tgt_color_tex,
|
|
||||||
(0, levels - 1),
|
|
||||||
gfx::format::Swizzle::new(),
|
|
||||||
)?; */
|
|
||||||
|
|
||||||
// let tgt_shadow_view =
|
|
||||||
// factory.view_texture_as_depth_stencil_trivial(&tgt_color_tex)?;
|
|
||||||
// let tgt_shadow_view = factory.view_texture_as_shader_resource(&tgt_color_tex,
|
|
||||||
// 0, None)?;
|
|
||||||
let point_tgt_shadow_res = factory
|
let point_tgt_shadow_res = factory
|
||||||
.view_texture_as_shader_resource::<ShadowDepthStencilFmt>(
|
.view_texture_as_shader_resource::<ShadowDepthStencilFmt>(
|
||||||
&point_shadow_tex,
|
&point_shadow_tex,
|
||||||
@ -569,21 +531,9 @@ impl Renderer {
|
|||||||
gfx::format::Swizzle::new(),
|
gfx::format::Swizzle::new(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
/* println!(
|
|
||||||
"size: {:?}, two_size: {:?}, diag_size: {:?}, diag_two_size: {:?}",
|
|
||||||
size, two_size, diag_size, diag_two_size,
|
|
||||||
); */
|
|
||||||
let directed_shadow_tex = factory
|
let directed_shadow_tex = factory
|
||||||
.create_texture(
|
.create_texture(
|
||||||
gfx::texture::Kind::D2(
|
gfx::texture::Kind::D2(diag_two_size, diag_two_size, gfx::texture::AaMode::Single),
|
||||||
/* size.x,// two_size.x,// 2 * size.x,
|
|
||||||
size.y,// two_size.y,// 2 * size.y, */
|
|
||||||
diag_two_size, /* max_two_size*//*two_size.x */
|
|
||||||
diag_two_size, /* max_two_size*//*two_size.y */
|
|
||||||
/* 6*//*1, */ gfx::texture::AaMode::Single,
|
|
||||||
),
|
|
||||||
// gfx::texture::Kind::D2Array(max_size/* * 2*/, max_size/* * 2*/, /*6*/1,
|
|
||||||
// gfx::texture::AaMode::Single),
|
|
||||||
levels as gfx::texture::Level,
|
levels as gfx::texture::Level,
|
||||||
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::DEPTH_STENCIL,
|
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::DEPTH_STENCIL,
|
||||||
gfx::memory::Usage::Data,
|
gfx::memory::Usage::Data,
|
||||||
@ -593,8 +543,8 @@ impl Renderer {
|
|||||||
let directed_tgt_shadow_view = factory
|
let directed_tgt_shadow_view = factory
|
||||||
.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
||||||
&directed_shadow_tex,
|
&directed_shadow_tex,
|
||||||
0, // levels,
|
0,
|
||||||
None, // Some(1),
|
None,
|
||||||
gfx::texture::DepthStencilFlags::empty(),
|
gfx::texture::DepthStencilFlags::empty(),
|
||||||
)?;
|
)?;
|
||||||
let directed_tgt_shadow_res = factory
|
let directed_tgt_shadow_res = factory
|
||||||
@ -606,31 +556,14 @@ impl Renderer {
|
|||||||
|
|
||||||
let mut sampler_info = gfx::texture::SamplerInfo::new(
|
let mut sampler_info = gfx::texture::SamplerInfo::new(
|
||||||
gfx::texture::FilterMethod::Bilinear,
|
gfx::texture::FilterMethod::Bilinear,
|
||||||
gfx::texture::WrapMode::Border, //Clamp,
|
// Lights should always be assumed to flood areas we can't see.
|
||||||
|
gfx::texture::WrapMode::Border,
|
||||||
);
|
);
|
||||||
sampler_info.comparison = Some(Comparison::LessEqual);
|
sampler_info.comparison = Some(Comparison::LessEqual);
|
||||||
// sampler_info.lod_bias = (-3.0).into();
|
|
||||||
// sampler_info.lod_range = (1.into(), (levels - 1).into());
|
|
||||||
// Point lights should clamp to whatever edge value there is.
|
|
||||||
sampler_info.border = [1.0; 4].into();
|
sampler_info.border = [1.0; 4].into();
|
||||||
let point_shadow_tex_sampler = factory.create_sampler(sampler_info);
|
let point_shadow_tex_sampler = factory.create_sampler(sampler_info);
|
||||||
/* // Directed lights should always be assumed to flood areas we can't see.
|
|
||||||
sampler_info.wrap_mode = (gfx::texture::WrapMode::Border, gfx::texture::WrapMode::Border, gfx::texture::WrapMode::Border); */
|
|
||||||
let directed_shadow_tex_sampler = factory.create_sampler(sampler_info);
|
let directed_shadow_tex_sampler = factory.create_sampler(sampler_info);
|
||||||
|
|
||||||
/* let tgt_sun_res = factory.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
|
||||||
&shadow_tex,
|
|
||||||
0,
|
|
||||||
Some(0),
|
|
||||||
gfx::texture::DepthStencilFlags::RO_DEPTH,
|
|
||||||
)?;
|
|
||||||
let tgt_moon_res = factory.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
|
||||||
&shadow_tex,
|
|
||||||
0,
|
|
||||||
Some(1),
|
|
||||||
gfx::texture::DepthStencilFlags::RO_DEPTH,
|
|
||||||
)?; */
|
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
point_tgt_shadow_view,
|
point_tgt_shadow_view,
|
||||||
point_tgt_shadow_res,
|
point_tgt_shadow_res,
|
||||||
@ -676,7 +609,6 @@ impl Renderer {
|
|||||||
// let directed_encoder = &mut shadow_map.directed_encoder;
|
// let directed_encoder = &mut shadow_map.directed_encoder;
|
||||||
let directed_encoder = &mut self.encoder;
|
let directed_encoder = &mut self.encoder;
|
||||||
directed_encoder.clear_depth(&shadow_map.directed_depth_stencil_view, 1.0);
|
directed_encoder.clear_depth(&shadow_map.directed_depth_stencil_view, 1.0);
|
||||||
// encoder.clear_stencil(&shadow_map.depth_stencil_view, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,7 +625,6 @@ impl Renderer {
|
|||||||
// NOTE: Currently just fail silently rather than complain if the computer is on
|
// NOTE: Currently just fail silently rather than complain if the computer is on
|
||||||
// a version lower than 3.2, where seamless cubemaps were introduced.
|
// a version lower than 3.2, where seamless cubemaps were introduced.
|
||||||
if !device.get_info().is_version_supported(3, 2) {
|
if !device.get_info().is_version_supported(3, 2) {
|
||||||
// println!("whoops");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,7 +650,6 @@ impl Renderer {
|
|||||||
// and having depth clamping disabled won't cause undefined
|
// and having depth clamping disabled won't cause undefined
|
||||||
// behavior, just incorrect shadowing from objects behind the viewer.
|
// behavior, just incorrect shadowing from objects behind the viewer.
|
||||||
if !device.get_info().is_version_supported(3, 3) {
|
if !device.get_info().is_version_supported(3, 3) {
|
||||||
// println!("whoops");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -729,8 +659,6 @@ impl Renderer {
|
|||||||
// essentially always be safe regardless of the state of the OpenGL
|
// essentially always be safe regardless of the state of the OpenGL
|
||||||
// context, so no further checks are needed.
|
// context, so no further checks are needed.
|
||||||
device.with_gl(|gl| {
|
device.with_gl(|gl| {
|
||||||
// println!("gl.Enable(gfx_gl::DEPTH_CLAMP) = {:?}",
|
|
||||||
// gl.IsEnabled(gfx_gl::DEPTH_CLAMP));
|
|
||||||
if depth_clamp {
|
if depth_clamp {
|
||||||
gl.Enable(gfx_gl::DEPTH_CLAMP);
|
gl.Enable(gfx_gl::DEPTH_CLAMP);
|
||||||
} else {
|
} else {
|
||||||
@ -759,7 +687,7 @@ impl Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform all queued draw calls for shadows.
|
/// Perform all queued draw calls for global.shadows.
|
||||||
pub fn flush_shadows(&mut self) {
|
pub fn flush_shadows(&mut self) {
|
||||||
if !self.mode.shadow.is_map() {
|
if !self.mode.shadow.is_map() {
|
||||||
return;
|
return;
|
||||||
@ -848,14 +776,6 @@ impl Renderer {
|
|||||||
Ok(consts)
|
Ok(consts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* /// Create a raw set of constants with the provided values.
|
|
||||||
pub fn create_consts_immutable<T: Copy + gfx::traits::Pod>(
|
|
||||||
&mut self,
|
|
||||||
vals: &[T],
|
|
||||||
) -> Result<RawBuffer<T>, RenderError> {
|
|
||||||
Consts::new_immutable(&mut self.factory, vals)
|
|
||||||
} */
|
|
||||||
|
|
||||||
/// Update a set of constants with the provided values.
|
/// Update a set of constants with the provided values.
|
||||||
pub fn update_consts<T: Copy + gfx::traits::Pod>(
|
pub fn update_consts<T: Copy + gfx::traits::Pod>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -865,25 +785,6 @@ impl Renderer {
|
|||||||
consts.update(&mut self.encoder, vals, 0)
|
consts.update(&mut self.encoder, vals, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* /// Update a set of shadow constants with the provided values.
|
|
||||||
pub fn update_shadow_consts<T: Copy + gfx::traits::Pod>(
|
|
||||||
&mut self,
|
|
||||||
consts: &mut Consts<T>,
|
|
||||||
vals: &[T],
|
|
||||||
directed_offset: usize,
|
|
||||||
point_offset: usize,
|
|
||||||
) -> Result<(), RenderError> {
|
|
||||||
if let Some(shadow_map) = self.shadow_map.as_mut() {
|
|
||||||
let directed_encoder = &mut shadow_map.directed_encoder;
|
|
||||||
consts.update(directed_encoder, &vals[directed_offset..point_offset], directed_offset)?;
|
|
||||||
let point_encoder = &mut shadow_map.point_encoder;
|
|
||||||
consts.update(point_encoder, &vals[point_offset..], point_offset)
|
|
||||||
} else {
|
|
||||||
// Fail silently if shadows aren't working in the first place.
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
|
|
||||||
/// Create a new set of instances with the provided values.
|
/// Create a new set of instances with the provided values.
|
||||||
pub fn create_instances<T: Copy + gfx::traits::Pod>(
|
pub fn create_instances<T: Copy + gfx::traits::Pod>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -1004,22 +905,6 @@ impl Renderer {
|
|||||||
Texture::new_dynamic(&mut self.factory, dims.x, dims.y)
|
Texture::new_dynamic(&mut self.factory, dims.x, dims.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* /// Create a new greedy texture array (of color-lights).
|
|
||||||
pub fn create_greedy_texture<F: gfx::format::Formatted>(
|
|
||||||
&mut self,
|
|
||||||
kind: gfx::texture::Kind,
|
|
||||||
mipmap: gfx::texture::MipMap,
|
|
||||||
data: &[&[<F::Surface as gfx::format::SurfaceTyped>::DataType]],
|
|
||||||
sampler_info: gfx::texture::SamplerInfo,
|
|
||||||
) -> Result<Texture<F>, RenderError>
|
|
||||||
where
|
|
||||||
F::Surface: gfx::format::TextureSurface,
|
|
||||||
F::Channel: gfx::format::TextureChannel,
|
|
||||||
<F::Surface as gfx::format::SurfaceTyped>::DataType: Copy,
|
|
||||||
{
|
|
||||||
Texture::new_immutable_raw(&mut self.factory, kind, mipmap, data, sampler_info)
|
|
||||||
} */
|
|
||||||
|
|
||||||
/// Update a texture with the provided offset, size, and data.
|
/// Update a texture with the provided offset, size, and data.
|
||||||
pub fn update_texture(
|
pub fn update_texture(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -1082,10 +967,9 @@ impl Renderer {
|
|||||||
pub fn render_skybox(
|
pub fn render_skybox(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &Model<skybox::SkyboxPipeline>,
|
model: &Model<skybox::SkyboxPipeline>,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
locals: &Consts<skybox::Locals>,
|
locals: &Consts<skybox::Locals>,
|
||||||
alt: &Texture<LodAltFmt>,
|
lod: &lod_terrain::LodData,
|
||||||
horizon: &Texture<LodTextureFmt>,
|
|
||||||
) {
|
) {
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&gfx::Slice {
|
&gfx::Slice {
|
||||||
@ -1099,10 +983,10 @@ impl Renderer {
|
|||||||
&skybox::pipe::Data {
|
&skybox::pipe::Data {
|
||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
locals: locals.buf.clone(),
|
locals: locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: global.globals.buf.clone(),
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
||||||
},
|
},
|
||||||
@ -1114,16 +998,11 @@ impl Renderer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
model: &figure::FigureModel,
|
model: &figure::FigureModel,
|
||||||
_col_lights: &Texture<ColLightFmt>,
|
_col_lights: &Texture<ColLightFmt>,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
locals: &Consts<figure::Locals>,
|
locals: &Consts<figure::Locals>,
|
||||||
bones: &Consts<figure::BoneData>,
|
bones: &Consts<figure::BoneData>,
|
||||||
lights: &Consts<Light>,
|
lod: &lod_terrain::LodData,
|
||||||
shadows: &Consts<Shadow>,
|
|
||||||
light_shadows: &Consts<shadow::Locals>,
|
|
||||||
alt: &Texture<LodAltFmt>,
|
|
||||||
horizon: &Texture<LodTextureFmt>,
|
|
||||||
) {
|
) {
|
||||||
// return;
|
|
||||||
let (point_shadow_maps, directed_shadow_maps) =
|
let (point_shadow_maps, directed_shadow_maps) =
|
||||||
if let Some(shadow_map) = &mut self.shadow_map {
|
if let Some(shadow_map) = &mut self.shadow_map {
|
||||||
(
|
(
|
||||||
@ -1144,8 +1023,6 @@ impl Renderer {
|
|||||||
};
|
};
|
||||||
let col_lights = &model.col_lights;
|
let col_lights = &model.col_lights;
|
||||||
let model = &model.opaque;
|
let model = &model.opaque;
|
||||||
// let atlas_model = &model.opaque;
|
|
||||||
// let model = &model.shadow;
|
|
||||||
|
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&gfx::Slice {
|
&gfx::Slice {
|
||||||
@ -1158,20 +1035,18 @@ impl Renderer {
|
|||||||
&self.figure_pipeline.pso,
|
&self.figure_pipeline.pso,
|
||||||
&figure::pipe::Data {
|
&figure::pipe::Data {
|
||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
// abuf: atlas_model.vbuf.clone(),
|
|
||||||
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
||||||
// col_lights: (alt.srv.clone(), alt.sampler.clone()),
|
|
||||||
locals: locals.buf.clone(),
|
locals: locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: global.globals.buf.clone(),
|
||||||
bones: bones.buf.clone(),
|
bones: bones.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: global.lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: global.shadows.buf.clone(),
|
||||||
light_shadows: light_shadows.buf.clone(),
|
light_shadows: global.shadow_mats.buf.clone(),
|
||||||
point_shadow_maps,
|
point_shadow_maps,
|
||||||
directed_shadow_maps,
|
directed_shadow_maps,
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
||||||
},
|
},
|
||||||
@ -1183,15 +1058,12 @@ impl Renderer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_model: &figure::FigureModel,
|
_model: &figure::FigureModel,
|
||||||
_col_lights: &Texture<ColLightFmt>,
|
_col_lights: &Texture<ColLightFmt>,
|
||||||
_globals: &Consts<Globals>,
|
_global: &GlobalModel,
|
||||||
_locals: &Consts<figure::Locals>,
|
|
||||||
_bones: &Consts<figure::BoneData>,
|
_bones: &Consts<figure::BoneData>,
|
||||||
_lights: &Consts<Light>,
|
_lod: &lod_terrain::LodData,
|
||||||
_shadows: &Consts<Shadow>,
|
_locals: &Consts<shadow::Locals>,
|
||||||
_light_shadows: &Consts<shadow::Locals>,
|
|
||||||
_alt: &Texture<LodAltFmt>,
|
|
||||||
_horizon: &Texture<LodTextureFmt>,
|
|
||||||
) {
|
) {
|
||||||
|
// FIXME: Consider reenabling at some point.
|
||||||
/* let (point_shadow_maps, directed_shadow_maps) =
|
/* let (point_shadow_maps, directed_shadow_maps) =
|
||||||
if let Some(shadow_map) = &mut self.shadow_map {
|
if let Some(shadow_map) = &mut self.shadow_map {
|
||||||
(
|
(
|
||||||
@ -1228,18 +1100,18 @@ impl Renderer {
|
|||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
// abuf: atlas_model.vbuf.clone(),
|
// abuf: atlas_model.vbuf.clone(),
|
||||||
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
||||||
// col_lights: (alt.srv.clone(), alt.sampler.clone()),
|
// col_lights: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()),
|
||||||
locals: locals.buf.clone(),
|
locals: locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: global.globals.buf.clone(),
|
||||||
bones: bones.buf.clone(),
|
bones: bones.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: global.lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: global.shadows.buf.clone(),
|
||||||
light_shadows: light_shadows.buf.clone(),
|
light_shadows: global.shadow_mats.buf.clone(),
|
||||||
point_shadow_maps,
|
point_shadow_maps,
|
||||||
directed_shadow_maps,
|
directed_shadow_maps,
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (0, 0) */),
|
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (0, 0) */),
|
||||||
},
|
},
|
||||||
@ -1251,14 +1123,10 @@ impl Renderer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
model: &figure::FigureModel,
|
model: &figure::FigureModel,
|
||||||
_col_lights: &Texture<ColLightFmt>,
|
_col_lights: &Texture<ColLightFmt>,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
locals: &Consts<figure::Locals>,
|
locals: &Consts<figure::Locals>,
|
||||||
bones: &Consts<figure::BoneData>,
|
bones: &Consts<figure::BoneData>,
|
||||||
lights: &Consts<Light>,
|
lod: &lod_terrain::LodData,
|
||||||
shadows: &Consts<Shadow>,
|
|
||||||
light_shadows: &Consts<shadow::Locals>,
|
|
||||||
alt: &Texture<LodAltFmt>,
|
|
||||||
horizon: &Texture<LodTextureFmt>,
|
|
||||||
) {
|
) {
|
||||||
let (point_shadow_maps, directed_shadow_maps) =
|
let (point_shadow_maps, directed_shadow_maps) =
|
||||||
if let Some(shadow_map) = &mut self.shadow_map {
|
if let Some(shadow_map) = &mut self.shadow_map {
|
||||||
@ -1280,8 +1148,6 @@ impl Renderer {
|
|||||||
};
|
};
|
||||||
let col_lights = &model.col_lights;
|
let col_lights = &model.col_lights;
|
||||||
let model = &model.opaque;
|
let model = &model.opaque;
|
||||||
// let atlas_model = &model.opaque;
|
|
||||||
// let model = &model.shadow;
|
|
||||||
|
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&gfx::Slice {
|
&gfx::Slice {
|
||||||
@ -1294,20 +1160,18 @@ impl Renderer {
|
|||||||
&self.figure_pipeline.pso,
|
&self.figure_pipeline.pso,
|
||||||
&figure::pipe::Data {
|
&figure::pipe::Data {
|
||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
// abuf: atlas_model.vbuf.clone(),
|
|
||||||
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
||||||
// col_lights: (alt.srv.clone(), alt.sampler.clone()),
|
|
||||||
locals: locals.buf.clone(),
|
locals: locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: global.globals.buf.clone(),
|
||||||
bones: bones.buf.clone(),
|
bones: bones.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: global.lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: global.shadows.buf.clone(),
|
||||||
light_shadows: light_shadows.buf.clone(),
|
light_shadows: global.shadow_mats.buf.clone(),
|
||||||
point_shadow_maps,
|
point_shadow_maps,
|
||||||
directed_shadow_maps,
|
directed_shadow_maps,
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
||||||
},
|
},
|
||||||
@ -1318,17 +1182,11 @@ impl Renderer {
|
|||||||
/// frame.
|
/// frame.
|
||||||
pub fn render_terrain_chunk(
|
pub fn render_terrain_chunk(
|
||||||
&mut self,
|
&mut self,
|
||||||
// atlas_model: &Model<terrain::TerrainPipeline>,
|
|
||||||
// model: &Model<shadow::ShadowPipeline>,
|
|
||||||
model: &Model<terrain::TerrainPipeline>,
|
model: &Model<terrain::TerrainPipeline>,
|
||||||
col_lights: &Texture<ColLightFmt>,
|
col_lights: &Texture<ColLightFmt>,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
locals: &Consts<terrain::Locals>,
|
locals: &Consts<terrain::Locals>,
|
||||||
lights: &Consts<Light>,
|
lod: &lod_terrain::LodData,
|
||||||
shadows: &Consts<Shadow>,
|
|
||||||
light_shadows: &Consts<shadow::Locals>,
|
|
||||||
alt: &Texture<LodAltFmt>,
|
|
||||||
horizon: &Texture<LodTextureFmt>,
|
|
||||||
) {
|
) {
|
||||||
let (point_shadow_maps, directed_shadow_maps) =
|
let (point_shadow_maps, directed_shadow_maps) =
|
||||||
if let Some(shadow_map) = &mut self.shadow_map {
|
if let Some(shadow_map) = &mut self.shadow_map {
|
||||||
@ -1361,20 +1219,18 @@ impl Renderer {
|
|||||||
&terrain::pipe::Data {
|
&terrain::pipe::Data {
|
||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
// TODO: Consider splitting out texture atlas data into a separate vertex buffer,
|
// TODO: Consider splitting out texture atlas data into a separate vertex buffer,
|
||||||
// since we don't need it for things like shadows.
|
// since we don't need it for things like global.shadows.
|
||||||
// abuf: atlas_model.vbuf.clone(),
|
|
||||||
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
||||||
// col_lights: (alt.srv.clone(), alt.sampler.clone()),
|
|
||||||
locals: locals.buf.clone(),
|
locals: locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: global.globals.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: global.lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: global.shadows.buf.clone(),
|
||||||
light_shadows: light_shadows.buf.clone(),
|
light_shadows: global.shadow_mats.buf.clone(),
|
||||||
point_shadow_maps,
|
point_shadow_maps,
|
||||||
directed_shadow_maps,
|
directed_shadow_maps,
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
||||||
},
|
},
|
||||||
@ -1386,14 +1242,9 @@ impl Renderer {
|
|||||||
pub fn render_shadow_point(
|
pub fn render_shadow_point(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &Model<terrain::TerrainPipeline>,
|
model: &Model<terrain::TerrainPipeline>,
|
||||||
// model: &Model<shadow::ShadowPipeline>,
|
global: &GlobalModel,
|
||||||
globals: &Consts<Globals>,
|
|
||||||
terrain_locals: &Consts<terrain::Locals>,
|
terrain_locals: &Consts<terrain::Locals>,
|
||||||
locals: &Consts<shadow::Locals>,
|
locals: &Consts<shadow::Locals>,
|
||||||
/* lights: &Consts<Light>,
|
|
||||||
* shadows: &Consts<Shadow>,
|
|
||||||
* alt: &Texture<LodAltFmt>,
|
|
||||||
* horizon: &Texture<LodTextureFmt>, */
|
|
||||||
) {
|
) {
|
||||||
if !self.mode.shadow.is_map() {
|
if !self.mode.shadow.is_map() {
|
||||||
return;
|
return;
|
||||||
@ -1420,18 +1271,11 @@ impl Renderer {
|
|||||||
// Terrain vertex stuff
|
// Terrain vertex stuff
|
||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
locals: terrain_locals.buf.clone(),
|
locals: terrain_locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: global.globals.buf.clone(),
|
||||||
// lights: lights.buf.clone(),
|
|
||||||
// shadows: shadows.buf.clone(),
|
|
||||||
// noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
|
||||||
// alt: (alt.srv.clone(), alt.sampler.clone()),
|
|
||||||
// horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
|
||||||
|
|
||||||
// Shadow stuff
|
// Shadow stuff
|
||||||
light_shadows: locals.buf.clone(),
|
light_shadows: locals.buf.clone(),
|
||||||
tgt_depth_stencil: shadow_map.point_depth_stencil_view.clone(),
|
tgt_depth_stencil: shadow_map.point_depth_stencil_view.clone(),
|
||||||
/* tgt_depth_stencil: (self.shadow_depth_stencil_view.clone(), (1, 1)),
|
|
||||||
* shadow_tex: (self.shadow_res.clone(), self.shadow_sampler.clone()), */
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1440,15 +1284,10 @@ impl Renderer {
|
|||||||
/// the upcoming frame.
|
/// the upcoming frame.
|
||||||
pub fn render_terrain_shadow_directed(
|
pub fn render_terrain_shadow_directed(
|
||||||
&mut self,
|
&mut self,
|
||||||
// model: &Model<shadow::ShadowPipeline>,
|
|
||||||
model: &Model<terrain::TerrainPipeline>,
|
model: &Model<terrain::TerrainPipeline>,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
terrain_locals: &Consts<terrain::Locals>,
|
terrain_locals: &Consts<terrain::Locals>,
|
||||||
locals: &Consts<shadow::Locals>,
|
locals: &Consts<shadow::Locals>,
|
||||||
/* lights: &Consts<Light>,
|
|
||||||
* shadows: &Consts<Shadow>,
|
|
||||||
* alt: &Texture<LodAltFmt>,
|
|
||||||
* horizon: &Texture<LodTextureFmt>, */
|
|
||||||
) {
|
) {
|
||||||
if !self.mode.shadow.is_map() {
|
if !self.mode.shadow.is_map() {
|
||||||
return;
|
return;
|
||||||
@ -1475,18 +1314,11 @@ impl Renderer {
|
|||||||
// Terrain vertex stuff
|
// Terrain vertex stuff
|
||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
locals: terrain_locals.buf.clone(),
|
locals: terrain_locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: global.globals.buf.clone(),
|
||||||
// lights: lights.buf.clone(),
|
|
||||||
// shadows: shadows.buf.clone(),
|
|
||||||
// noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
|
||||||
// alt: (alt.srv.clone(), alt.sampler.clone()),
|
|
||||||
// horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
|
||||||
|
|
||||||
// Shadow stuff
|
// Shadow stuff
|
||||||
light_shadows: locals.buf.clone(),
|
light_shadows: locals.buf.clone(),
|
||||||
tgt_depth_stencil: shadow_map.directed_depth_stencil_view.clone(),
|
tgt_depth_stencil: shadow_map.directed_depth_stencil_view.clone(),
|
||||||
/* tgt_depth_stencil: (self.shadow_depth_stencil_view.clone(), (1, 1)),
|
|
||||||
* shadow_tex: (self.shadow_res.clone(), self.shadow_sampler.clone()), */
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1495,16 +1327,11 @@ impl Renderer {
|
|||||||
/// the upcoming frame.
|
/// the upcoming frame.
|
||||||
pub fn render_figure_shadow_directed(
|
pub fn render_figure_shadow_directed(
|
||||||
&mut self,
|
&mut self,
|
||||||
// model: &Model<shadow::ShadowPipeline>,
|
|
||||||
model: &figure::FigureModel,
|
model: &figure::FigureModel,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
figure_locals: &Consts<figure::Locals>,
|
figure_locals: &Consts<figure::Locals>,
|
||||||
bones: &Consts<figure::BoneData>,
|
bones: &Consts<figure::BoneData>,
|
||||||
locals: &Consts<shadow::Locals>,
|
locals: &Consts<shadow::Locals>,
|
||||||
/* lights: &Consts<Light>,
|
|
||||||
* shadows: &Consts<Shadow>,
|
|
||||||
* alt: &Texture<LodAltFmt>,
|
|
||||||
* horizon: &Texture<LodTextureFmt>, */
|
|
||||||
) {
|
) {
|
||||||
if !self.mode.shadow.is_map() {
|
if !self.mode.shadow.is_map() {
|
||||||
return;
|
return;
|
||||||
@ -1533,18 +1360,11 @@ impl Renderer {
|
|||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
locals: figure_locals.buf.clone(),
|
locals: figure_locals.buf.clone(),
|
||||||
bones: bones.buf.clone(),
|
bones: bones.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: global.globals.buf.clone(),
|
||||||
// lights: lights.buf.clone(),
|
|
||||||
// shadows: shadows.buf.clone(),
|
|
||||||
// noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
|
||||||
// alt: (alt.srv.clone(), alt.sampler.clone()),
|
|
||||||
// horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
|
||||||
|
|
||||||
// Shadow stuff
|
// Shadow stuff
|
||||||
light_shadows: locals.buf.clone(),
|
light_shadows: locals.buf.clone(),
|
||||||
tgt_depth_stencil: shadow_map.directed_depth_stencil_view.clone(),
|
tgt_depth_stencil: shadow_map.directed_depth_stencil_view.clone(),
|
||||||
/* tgt_depth_stencil: (self.shadow_depth_stencil_view.clone(), (1, 1)),
|
|
||||||
* shadow_tex: (self.shadow_res.clone(), self.shadow_sampler.clone()), */
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1554,13 +1374,9 @@ impl Renderer {
|
|||||||
pub fn render_fluid_chunk(
|
pub fn render_fluid_chunk(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &Model<fluid::FluidPipeline>,
|
model: &Model<fluid::FluidPipeline>,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
locals: &Consts<terrain::Locals>,
|
locals: &Consts<terrain::Locals>,
|
||||||
lights: &Consts<Light>,
|
lod: &lod_terrain::LodData,
|
||||||
shadows: &Consts<Shadow>,
|
|
||||||
light_shadows: &Consts<shadow::Locals>,
|
|
||||||
alt: &Texture<LodAltFmt>,
|
|
||||||
horizon: &Texture<LodTextureFmt>,
|
|
||||||
waves: &Texture,
|
waves: &Texture,
|
||||||
) {
|
) {
|
||||||
let (point_shadow_maps, directed_shadow_maps) =
|
let (point_shadow_maps, directed_shadow_maps) =
|
||||||
@ -1594,14 +1410,14 @@ impl Renderer {
|
|||||||
&fluid::pipe::Data {
|
&fluid::pipe::Data {
|
||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
locals: locals.buf.clone(),
|
locals: locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: global.globals.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: global.lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: global.shadows.buf.clone(),
|
||||||
light_shadows: light_shadows.buf.clone(),
|
light_shadows: global.shadow_mats.buf.clone(),
|
||||||
point_shadow_maps,
|
point_shadow_maps,
|
||||||
directed_shadow_maps,
|
directed_shadow_maps,
|
||||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()),
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
waves: (waves.srv.clone(), waves.sampler.clone()),
|
waves: (waves.srv.clone(), waves.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
@ -1616,17 +1432,11 @@ impl Renderer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
model: &Model<sprite::SpritePipeline>,
|
model: &Model<sprite::SpritePipeline>,
|
||||||
col_lights: &Texture<ColLightFmt>,
|
col_lights: &Texture<ColLightFmt>,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
terrain_locals: &Consts<terrain::Locals>,
|
terrain_locals: &Consts<terrain::Locals>,
|
||||||
locals: &Consts<sprite::Locals>,
|
locals: &Consts<sprite::Locals>,
|
||||||
// instance_count: usize,
|
|
||||||
// instances: &Consts<sprite::Instance>,
|
|
||||||
instances: &Instances<sprite::Instance>,
|
instances: &Instances<sprite::Instance>,
|
||||||
lights: &Consts<Light>,
|
lod: &lod_terrain::LodData,
|
||||||
shadows: &Consts<Shadow>,
|
|
||||||
light_shadows: &Consts<shadow::Locals>,
|
|
||||||
alt: &Texture<LodAltFmt>,
|
|
||||||
horizon: &Texture<LodTextureFmt>,
|
|
||||||
) {
|
) {
|
||||||
let (point_shadow_maps, directed_shadow_maps) =
|
let (point_shadow_maps, directed_shadow_maps) =
|
||||||
if let Some(shadow_map) = &mut self.shadow_map {
|
if let Some(shadow_map) = &mut self.shadow_map {
|
||||||
@ -1652,26 +1462,25 @@ impl Renderer {
|
|||||||
start: model.vertex_range().start,
|
start: model.vertex_range().start,
|
||||||
end: model.vertex_range().end,
|
end: model.vertex_range().end,
|
||||||
base_vertex: 0,
|
base_vertex: 0,
|
||||||
instances: Some((instances.count()/*instance_count*/ as u32, 0)),
|
instances: Some((instances.count() as u32, 0)),
|
||||||
buffer: gfx::IndexBuffer::Auto,
|
buffer: gfx::IndexBuffer::Auto,
|
||||||
},
|
},
|
||||||
&self.sprite_pipeline.pso,
|
&self.sprite_pipeline.pso,
|
||||||
&sprite::pipe::Data {
|
&sprite::pipe::Data {
|
||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
ibuf: instances.ibuf.clone(),
|
ibuf: instances.ibuf.clone(),
|
||||||
// ibuf: instances.buf.clone(),
|
|
||||||
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
col_lights: (col_lights.srv.clone(), col_lights.sampler.clone()),
|
||||||
terrain_locals: terrain_locals.buf.clone(),
|
terrain_locals: terrain_locals.buf.clone(),
|
||||||
locals: locals.buf.clone(),
|
locals: locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: global.globals.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: global.lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: global.shadows.buf.clone(),
|
||||||
light_shadows: light_shadows.buf.clone(),
|
light_shadows: global.shadow_mats.buf.clone(),
|
||||||
point_shadow_maps,
|
point_shadow_maps,
|
||||||
directed_shadow_maps,
|
directed_shadow_maps,
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
||||||
},
|
},
|
||||||
@ -1683,11 +1492,9 @@ impl Renderer {
|
|||||||
pub fn render_lod_terrain(
|
pub fn render_lod_terrain(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &Model<lod_terrain::LodTerrainPipeline>,
|
model: &Model<lod_terrain::LodTerrainPipeline>,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
locals: &Consts<lod_terrain::Locals>,
|
locals: &Consts<lod_terrain::Locals>,
|
||||||
map: &Texture<LodColorFmt>,
|
lod: &lod_terrain::LodData,
|
||||||
alt: &Texture<LodAltFmt>,
|
|
||||||
horizon: &Texture<LodTextureFmt>,
|
|
||||||
) {
|
) {
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&gfx::Slice {
|
&gfx::Slice {
|
||||||
@ -1701,11 +1508,11 @@ impl Renderer {
|
|||||||
&lod_terrain::pipe::Data {
|
&lod_terrain::pipe::Data {
|
||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
locals: locals.buf.clone(),
|
locals: locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: global.globals.buf.clone(),
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
map: (map.srv.clone(), map.sampler.clone()),
|
map: (lod.map.srv.clone(), lod.map.sampler.clone()),
|
||||||
alt: (alt.srv.clone(), alt.sampler.clone()),
|
alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone()/* , (1, 1) */),
|
||||||
},
|
},
|
||||||
@ -1926,13 +1733,6 @@ fn create_pipelines(
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
/* let directed_shadow_geom =
|
|
||||||
&assets::load_watched::<String>(
|
|
||||||
"voxygen.shaders.light-shadows-directed-geom",
|
|
||||||
shader_reload_indicator,
|
|
||||||
)
|
|
||||||
.unwrap(); */
|
|
||||||
|
|
||||||
let directed_shadow_frag = &assets::load_watched::<String>(
|
let directed_shadow_frag = &assets::load_watched::<String>(
|
||||||
"voxygen.shaders.light-shadows-directed-frag",
|
"voxygen.shaders.light-shadows-directed-frag",
|
||||||
shader_reload_indicator,
|
shader_reload_indicator,
|
||||||
@ -2094,8 +1894,7 @@ fn create_pipelines(
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
&include_ctx,
|
&include_ctx,
|
||||||
gfx::state::CullFace::Back,
|
gfx::state::CullFace::Back,
|
||||||
None,
|
None, // Some(gfx::state::Offset(2, 0))
|
||||||
// Some(gfx::state::Offset(2, /* 10 */ 0)),
|
|
||||||
) {
|
) {
|
||||||
Ok(pipe) => Some(pipe),
|
Ok(pipe) => Some(pipe),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -2109,14 +1908,11 @@ fn create_pipelines(
|
|||||||
factory,
|
factory,
|
||||||
shadow::pipe::new(),
|
shadow::pipe::new(),
|
||||||
&terrain_directed_shadow_vert,
|
&terrain_directed_shadow_vert,
|
||||||
None, // &directed_shadow_geom,
|
None,
|
||||||
&directed_shadow_frag,
|
&directed_shadow_frag,
|
||||||
&include_ctx,
|
&include_ctx,
|
||||||
gfx::state::CullFace::Back,
|
gfx::state::CullFace::Back,
|
||||||
/* None, */
|
None, // Some(gfx::state::Offset(2, 1))
|
||||||
/* Some(gfx::state::Offset(4, 10)), */
|
|
||||||
None,
|
|
||||||
// Some(gfx::state::Offset(2, /*10*/1)),
|
|
||||||
) {
|
) {
|
||||||
Ok(pipe) => Some(pipe),
|
Ok(pipe) => Some(pipe),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -2133,14 +1929,11 @@ fn create_pipelines(
|
|||||||
factory,
|
factory,
|
||||||
shadow::figure_pipe::new(),
|
shadow::figure_pipe::new(),
|
||||||
&figure_directed_shadow_vert,
|
&figure_directed_shadow_vert,
|
||||||
None, // &directed_shadow_geom,
|
None,
|
||||||
&directed_shadow_frag,
|
&directed_shadow_frag,
|
||||||
&include_ctx,
|
&include_ctx,
|
||||||
gfx::state::CullFace::Back,
|
gfx::state::CullFace::Back,
|
||||||
/* None, */
|
None, // Some(gfx::state::Offset(2, 1))
|
||||||
/* Some(gfx::state::Offset(4, 10)), */
|
|
||||||
/*Some(gfx::state::Offset(2, 1))*/None,
|
|
||||||
/* Some(gfx::state::Offset(2, 10)), */
|
|
||||||
) {
|
) {
|
||||||
Ok(pipe) => Some(pipe),
|
Ok(pipe) => Some(pipe),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -2230,14 +2023,14 @@ fn create_shadow_pipeline<P: gfx::pso::PipelineInit>(
|
|||||||
// Second-depth shadow mapping: should help reduce z-fighting provided all objects
|
// Second-depth shadow mapping: should help reduce z-fighting provided all objects
|
||||||
// are "watertight" (every triangle edge is shared with at most one other
|
// are "watertight" (every triangle edge is shared with at most one other
|
||||||
// triangle); this *should* be true for Veloren.
|
// triangle); this *should* be true for Veloren.
|
||||||
cull_face: /*gfx::state::CullFace::Nothing*/match cull_face {
|
cull_face: match cull_face {
|
||||||
gfx::state::CullFace::Front => gfx::state::CullFace::Back,
|
gfx::state::CullFace::Front => gfx::state::CullFace::Back,
|
||||||
gfx::state::CullFace::Back => gfx::state::CullFace::Front,
|
gfx::state::CullFace::Back => gfx::state::CullFace::Front,
|
||||||
gfx::state::CullFace::Nothing => gfx::state::CullFace::Nothing,
|
gfx::state::CullFace::Nothing => gfx::state::CullFace::Nothing,
|
||||||
},
|
},
|
||||||
method: gfx::state::RasterMethod::Fill,
|
method: gfx::state::RasterMethod::Fill,
|
||||||
offset,
|
offset,
|
||||||
samples: None, // Some(gfx::state::MultiSample),
|
samples: None,
|
||||||
},
|
},
|
||||||
pipe,
|
pipe,
|
||||||
)?,
|
)?,
|
||||||
|
@ -139,8 +139,6 @@ where
|
|||||||
)
|
)
|
||||||
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Texture(err)))?;
|
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Texture(err)))?;
|
||||||
|
|
||||||
// device.cleanup();
|
|
||||||
|
|
||||||
let srv = factory
|
let srv = factory
|
||||||
.view_texture_as_shader_resource::<F>(&tex, levels, swizzle)
|
.view_texture_as_shader_resource::<F>(&tex, levels, swizzle)
|
||||||
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Resource(err)))?;
|
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Resource(err)))?;
|
||||||
|
@ -91,8 +91,6 @@ impl Camera {
|
|||||||
(_, Err(_)) => self.dist,
|
(_, Err(_)) => self.dist,
|
||||||
}
|
}
|
||||||
.max(0.0)
|
.max(0.0)
|
||||||
// .max(NEAR_PLANE)
|
|
||||||
// self.dist.max(0.0)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.dependents.view_mat = Mat4::<f32>::identity()
|
self.dependents.view_mat = Mat4::<f32>::identity()
|
||||||
|
@ -936,14 +936,14 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
.unwrap_or_else(<Skel::Attr as Default>::default);
|
.unwrap_or_else(<Skel::Attr as Default>::default);
|
||||||
|
|
||||||
let manifest_indicator = &mut self.manifest_indicator;
|
let manifest_indicator = &mut self.manifest_indicator;
|
||||||
let mut make_model = |generate_mesh: for<'a> fn(&mut GreedyMesh<'a>, _, _) -> _| {
|
let mut make_model =
|
||||||
|
|generate_mesh: for<'a> fn(&mut GreedyMesh<'a>, _, _) -> _| {
|
||||||
let mut greedy = FigureModel::make_greedy();
|
let mut greedy = FigureModel::make_greedy();
|
||||||
let mut opaque = Mesh::new();
|
let mut opaque = Mesh::new();
|
||||||
let mut figure_bounds = Aabb {
|
let mut figure_bounds = Aabb {
|
||||||
min: Vec3::zero(),
|
min: Vec3::zero(),
|
||||||
max: Vec3::zero(),
|
max: Vec3::zero(),
|
||||||
};
|
};
|
||||||
// let mut shadow = Mesh::new();
|
|
||||||
Self::bone_meshes(
|
Self::bone_meshes(
|
||||||
body,
|
body,
|
||||||
loadout,
|
loadout,
|
||||||
@ -953,16 +953,19 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
|segment, offset| generate_mesh(&mut greedy, segment, offset),
|
|segment, offset| generate_mesh(&mut greedy, segment, offset),
|
||||||
)
|
)
|
||||||
.iter()
|
.iter()
|
||||||
// .zip(&mut figure_bounds)
|
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(i, bm)| bm.as_ref().map(|bm| (i, bm)))
|
.filter_map(|(i, bm)| bm.as_ref().map(|bm| (i, bm)))
|
||||||
.for_each(|(i, (opaque_mesh/*, shadow_mesh*/, bounds)/*, bone_bounds*/)| {
|
.for_each(
|
||||||
// opaque.push_mesh_map(opaque_mesh, |vert| vert.with_bone_idx(i as u8));
|
|(i, (opaque_mesh, bounds))| {
|
||||||
opaque.push_mesh_map(opaque_mesh, |vert| vert.with_bone_idx(i as u8));
|
opaque.push_mesh_map(opaque_mesh, |vert| {
|
||||||
figure_bounds.expand_to_contain(*bounds);
|
vert.with_bone_idx(i as u8)
|
||||||
// shadow.push_mesh_map(shadow_mesh, |vert| vert.with_bone_idx(i as u8));
|
|
||||||
});
|
});
|
||||||
col_lights.create_figure(renderer, greedy, (opaque/*, shadow*/, figure_bounds)).unwrap()
|
figure_bounds.expand_to_contain(*bounds);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
col_lights
|
||||||
|
.create_figure(renderer, greedy, (opaque, figure_bounds))
|
||||||
|
.unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
fn generate_mesh<'a>(
|
fn generate_mesh<'a>(
|
||||||
@ -970,11 +973,12 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
segment: Segment,
|
segment: Segment,
|
||||||
offset: Vec3<f32>,
|
offset: Vec3<f32>,
|
||||||
) -> BoneMeshes {
|
) -> BoneMeshes {
|
||||||
let (opaque, _, /*shadow*/_, bounds) = Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh(
|
let (opaque, _, _, bounds) =
|
||||||
|
Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh(
|
||||||
segment,
|
segment,
|
||||||
(greedy, offset, Vec3::one()),
|
(greedy, offset, Vec3::one()),
|
||||||
);
|
);
|
||||||
(opaque/*, shadow*/, bounds)
|
(opaque, bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_mesh_lod_mid<'a>(
|
fn generate_mesh_lod_mid<'a>(
|
||||||
@ -983,11 +987,12 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
offset: Vec3<f32>,
|
offset: Vec3<f32>,
|
||||||
) -> BoneMeshes {
|
) -> BoneMeshes {
|
||||||
let lod_scale = Vec3::broadcast(0.6);
|
let lod_scale = Vec3::broadcast(0.6);
|
||||||
let (opaque, _, /*shadow*/_, bounds) = Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh(
|
let (opaque, _, _, bounds) =
|
||||||
|
Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh(
|
||||||
segment.scaled_by(lod_scale),
|
segment.scaled_by(lod_scale),
|
||||||
(greedy, offset * lod_scale, Vec3::one() / lod_scale),
|
(greedy, offset * lod_scale, Vec3::one() / lod_scale),
|
||||||
);
|
);
|
||||||
(opaque/*, shadow*/, bounds)
|
(opaque, bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_mesh_lod_low<'a>(
|
fn generate_mesh_lod_low<'a>(
|
||||||
@ -997,11 +1002,12 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
) -> BoneMeshes {
|
) -> BoneMeshes {
|
||||||
let lod_scale = Vec3::broadcast(0.3);
|
let lod_scale = Vec3::broadcast(0.3);
|
||||||
let segment = segment.scaled_by(lod_scale);
|
let segment = segment.scaled_by(lod_scale);
|
||||||
let (opaque, _, /*shadow*/_, bounds) = Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh(
|
let (opaque, _, _, bounds) =
|
||||||
|
Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh(
|
||||||
segment,
|
segment,
|
||||||
(greedy, offset * lod_scale, Vec3::one() / lod_scale),
|
(greedy, offset * lod_scale, Vec3::one() / lod_scale),
|
||||||
);
|
);
|
||||||
(opaque/*, shadow*/, bounds)
|
(opaque, bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
|
@ -793,7 +793,7 @@ impl HumMainWeaponSpec {
|
|||||||
let tool_kind = if let Some(ItemKind::Tool(Tool { kind, .. })) = item_kind {
|
let tool_kind = if let Some(ItemKind::Tool(Tool { kind, .. })) = item_kind {
|
||||||
kind
|
kind
|
||||||
} else {
|
} else {
|
||||||
return (Mesh::new() /* , Mesh::new() */, Aabb::default());
|
return (Mesh::new(), Aabb::default());
|
||||||
};
|
};
|
||||||
|
|
||||||
let spec = match self.0.get(tool_kind) {
|
let spec = match self.0.get(tool_kind) {
|
||||||
|
@ -8,8 +8,8 @@ use crate::{
|
|||||||
ecs::comp::Interpolated,
|
ecs::comp::Interpolated,
|
||||||
mesh::greedy::GreedyMesh,
|
mesh::greedy::GreedyMesh,
|
||||||
render::{
|
render::{
|
||||||
BoneMeshes, ColLightFmt, Consts, FigureBoneData, FigureLocals, FigureModel, Globals, Light,
|
BoneMeshes, ColLightFmt, Consts, FigureBoneData, FigureLocals, FigureModel, GlobalModel,
|
||||||
RenderError, Renderer, Shadow, ShadowLocals, ShadowPipeline, Texture,
|
RenderError, Renderer, ShadowPipeline, Texture,
|
||||||
},
|
},
|
||||||
scene::{
|
scene::{
|
||||||
camera::{Camera, CameraMode, Dependents},
|
camera::{Camera, CameraMode, Dependents},
|
||||||
@ -48,6 +48,9 @@ const DAMAGE_FADE_COEFFICIENT: f64 = 5.0;
|
|||||||
const MOVING_THRESHOLD: f32 = 0.7;
|
const MOVING_THRESHOLD: f32 = 0.7;
|
||||||
const MOVING_THRESHOLD_SQR: f32 = MOVING_THRESHOLD * MOVING_THRESHOLD;
|
const MOVING_THRESHOLD_SQR: f32 = MOVING_THRESHOLD * MOVING_THRESHOLD;
|
||||||
|
|
||||||
|
/// camera data, fiigure LOD render distance.
|
||||||
|
pub type CameraData<'a> = (&'a Camera, f32);
|
||||||
|
|
||||||
struct FigureMgrStates {
|
struct FigureMgrStates {
|
||||||
character_states: HashMap<EcsEntity, FigureState<CharacterSkeleton>>,
|
character_states: HashMap<EcsEntity, FigureState<CharacterSkeleton>>,
|
||||||
quadruped_small_states: HashMap<EcsEntity, FigureState<QuadrupedSmallSkeleton>>,
|
quadruped_small_states: HashMap<EcsEntity, FigureState<QuadrupedSmallSkeleton>>,
|
||||||
@ -1996,12 +1999,9 @@ impl FigureMgr {
|
|||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
state: &State,
|
state: &State,
|
||||||
tick: u64,
|
tick: u64,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
shadow_mats: &Consts<ShadowLocals>,
|
(is_daylight, _light_data): super::LightData,
|
||||||
is_daylight: bool,
|
(camera, figure_lod_render_distance): CameraData,
|
||||||
_light_data: &[Light],
|
|
||||||
camera: &Camera,
|
|
||||||
figure_lod_render_distance: f32,
|
|
||||||
) {
|
) {
|
||||||
let ecs = state.ecs();
|
let ecs = state.ecs();
|
||||||
|
|
||||||
@ -2034,10 +2034,10 @@ impl FigureMgr {
|
|||||||
) {
|
) {
|
||||||
renderer.render_figure_shadow_directed(
|
renderer.render_figure_shadow_directed(
|
||||||
model,
|
model,
|
||||||
globals,
|
global,
|
||||||
locals,
|
locals,
|
||||||
bone_consts,
|
bone_consts,
|
||||||
shadow_mats,
|
&global.shadow_mats,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -2051,13 +2051,9 @@ impl FigureMgr {
|
|||||||
state: &State,
|
state: &State,
|
||||||
player_entity: EcsEntity,
|
player_entity: EcsEntity,
|
||||||
tick: u64,
|
tick: u64,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
lights: &Consts<Light>,
|
|
||||||
shadows: &Consts<Shadow>,
|
|
||||||
shadow_mats: &Consts<ShadowLocals>,
|
|
||||||
lod: &LodData,
|
lod: &LodData,
|
||||||
camera: &Camera,
|
(camera, figure_lod_render_distance): CameraData,
|
||||||
figure_lod_render_distance: f32,
|
|
||||||
) {
|
) {
|
||||||
let ecs = state.ecs();
|
let ecs = state.ecs();
|
||||||
|
|
||||||
@ -2096,14 +2092,10 @@ impl FigureMgr {
|
|||||||
renderer.render_figure(
|
renderer.render_figure(
|
||||||
model,
|
model,
|
||||||
&col_lights.col_lights,
|
&col_lights.col_lights,
|
||||||
globals,
|
global,
|
||||||
locals,
|
locals,
|
||||||
bone_consts,
|
bone_consts,
|
||||||
lights,
|
lod,
|
||||||
shadows,
|
|
||||||
shadow_mats,
|
|
||||||
&lod.alt,
|
|
||||||
&lod.horizon,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2117,13 +2109,9 @@ impl FigureMgr {
|
|||||||
state: &State,
|
state: &State,
|
||||||
player_entity: EcsEntity,
|
player_entity: EcsEntity,
|
||||||
tick: u64,
|
tick: u64,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
lights: &Consts<Light>,
|
|
||||||
shadows: &Consts<Shadow>,
|
|
||||||
shadow_mats: &Consts<ShadowLocals>,
|
|
||||||
lod: &LodData,
|
lod: &LodData,
|
||||||
camera: &Camera,
|
(camera, figure_lod_render_distance): CameraData,
|
||||||
figure_lod_render_distance: f32,
|
|
||||||
) {
|
) {
|
||||||
let ecs = state.ecs();
|
let ecs = state.ecs();
|
||||||
|
|
||||||
@ -2160,26 +2148,18 @@ impl FigureMgr {
|
|||||||
renderer.render_player(
|
renderer.render_player(
|
||||||
model,
|
model,
|
||||||
&col_lights.col_lights,
|
&col_lights.col_lights,
|
||||||
globals,
|
global,
|
||||||
locals,
|
locals,
|
||||||
bone_consts,
|
bone_consts,
|
||||||
lights,
|
lod,
|
||||||
shadows,
|
|
||||||
shadow_mats,
|
|
||||||
&lod.alt,
|
|
||||||
&lod.horizon,
|
|
||||||
);
|
);
|
||||||
renderer.render_player_shadow(
|
renderer.render_player_shadow(
|
||||||
model,
|
model,
|
||||||
&col_lights.col_lights,
|
&col_lights.col_lights,
|
||||||
globals,
|
global,
|
||||||
locals,
|
|
||||||
bone_consts,
|
bone_consts,
|
||||||
lights,
|
lod,
|
||||||
shadows,
|
&global.shadow_mats,
|
||||||
shadow_mats,
|
|
||||||
&lod.alt,
|
|
||||||
&lod.horizon,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,89 +1,24 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
render::{
|
render::{
|
||||||
pipelines::lod_terrain::{Locals, Vertex},
|
pipelines::lod_terrain::{Locals, LodData, Vertex},
|
||||||
Consts, Globals, LodAltFmt, LodColorFmt, LodTerrainPipeline, LodTextureFmt, Mesh, Model,
|
Consts, GlobalModel, LodTerrainPipeline, Mesh, Model, Quad, Renderer,
|
||||||
Quad, Renderer, Texture,
|
|
||||||
},
|
},
|
||||||
settings::Settings,
|
settings::Settings,
|
||||||
};
|
};
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use common::{spiral::Spiral2d, util::srgba_to_linear};
|
use common::{spiral::Spiral2d, util::srgba_to_linear};
|
||||||
use gfx::texture::SamplerInfo;
|
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
pub struct LodData {
|
|
||||||
pub map: Texture<LodColorFmt>,
|
|
||||||
pub alt: Texture<LodAltFmt>,
|
|
||||||
pub horizon: Texture<LodTextureFmt>,
|
|
||||||
pub tgt_detail: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Lod {
|
pub struct Lod {
|
||||||
model: Option<(u32, Model<LodTerrainPipeline>)>,
|
model: Option<(u32, Model<LodTerrainPipeline>)>,
|
||||||
locals: Consts<Locals>,
|
locals: Consts<Locals>,
|
||||||
data: LodData,
|
data: LodData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LodData {
|
|
||||||
pub fn new(
|
|
||||||
renderer: &mut Renderer,
|
|
||||||
map_size: Vec2<u16>,
|
|
||||||
lod_base: &[u32],
|
|
||||||
lod_alt: &[u32],
|
|
||||||
lod_horizon: &[u32],
|
|
||||||
tgt_detail: u32,
|
|
||||||
border_color: gfx::texture::PackedColor,
|
|
||||||
) -> Self {
|
|
||||||
let kind = gfx::texture::Kind::D2(map_size.x, map_size.y, gfx::texture::AaMode::Single);
|
|
||||||
let info = gfx::texture::SamplerInfo::new(
|
|
||||||
gfx::texture::FilterMethod::Bilinear,
|
|
||||||
gfx::texture::WrapMode::Border,
|
|
||||||
);
|
|
||||||
Self {
|
|
||||||
map: renderer
|
|
||||||
.create_texture_immutable_raw(
|
|
||||||
kind,
|
|
||||||
gfx::texture::Mipmap::Provided,
|
|
||||||
&[gfx::memory::cast_slice(lod_base)],
|
|
||||||
SamplerInfo {
|
|
||||||
border: border_color,
|
|
||||||
..info
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.expect("Failed to generate map texture"),
|
|
||||||
alt: renderer
|
|
||||||
.create_texture_immutable_raw(
|
|
||||||
kind,
|
|
||||||
gfx::texture::Mipmap::Provided,
|
|
||||||
&[gfx::memory::cast_slice(lod_alt)],
|
|
||||||
SamplerInfo {
|
|
||||||
border: [0.0, 0.0, 0.0, 0.0].into(),
|
|
||||||
..info
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.expect("Failed to generate alt texture"),
|
|
||||||
horizon: renderer
|
|
||||||
.create_texture_immutable_raw(
|
|
||||||
kind,
|
|
||||||
gfx::texture::Mipmap::Provided,
|
|
||||||
&[gfx::memory::cast_slice(lod_horizon)],
|
|
||||||
SamplerInfo {
|
|
||||||
// filter: gfx::texture::FilterMethod::Nearest,
|
|
||||||
// filter: gfx::texture::FilterMethod::TriLinear,
|
|
||||||
border: [1.0, 0.0, 1.0, 0.0].into(),
|
|
||||||
..info
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.expect("Failed to generate horizon texture"),
|
|
||||||
tgt_detail,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Make constant when possible.
|
// TODO: Make constant when possible.
|
||||||
pub fn water_color() -> Rgba<f32> {
|
pub fn water_color() -> Rgba<f32> {
|
||||||
/* Rgba::new(0.2, 0.5, 1.0, 0.0) */
|
/* Rgba::new(0.2, 0.5, 1.0, 0.0) */
|
||||||
srgba_to_linear(Rgba::new(0.0, 0.25, 0.5, 0.0)/* * 0.5*/)
|
srgba_to_linear(Rgba::new(0.0, 0.25, 0.5, 0.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Lod {
|
impl Lod {
|
||||||
@ -123,16 +58,9 @@ impl Lod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self, renderer: &mut Renderer, globals: &Consts<Globals>) {
|
pub fn render(&self, renderer: &mut Renderer, global: &GlobalModel) {
|
||||||
if let Some((_, model)) = self.model.as_ref() {
|
if let Some((_, model)) = self.model.as_ref() {
|
||||||
renderer.render_lod_terrain(
|
renderer.render_lod_terrain(&model, global, &self.locals, &self.data);
|
||||||
&model,
|
|
||||||
globals,
|
|
||||||
&self.locals,
|
|
||||||
&self.data.map,
|
|
||||||
&self.data.alt,
|
|
||||||
&self.data.horizon,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,16 +103,6 @@ pub fn clip_points_by_plane<T: Float + MulAdd<T, T, Output = T> + core::fmt::Deb
|
|||||||
plane: (Vec3<T>, T),
|
plane: (Vec3<T>, T),
|
||||||
intersection_points: &mut Vec<Vec3<T>>,
|
intersection_points: &mut Vec<Vec3<T>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
/* enum Intersection {
|
|
||||||
/// Previous point was inside the plane.
|
|
||||||
Inside,
|
|
||||||
/// Previous line segment was completely outside the plane.
|
|
||||||
Outside,
|
|
||||||
/// Previous line segment went from inside the plane to outside it.
|
|
||||||
InsideOut,
|
|
||||||
} */
|
|
||||||
// println!("points@clip_points_by_plane before clipping by {:?}: {:?}", plane,
|
|
||||||
// points);
|
|
||||||
if points.len() < 3 {
|
if points.len() < 3 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -135,36 +125,12 @@ pub fn clip_points_by_plane<T: Float + MulAdd<T, T, Output = T> + core::fmt::Deb
|
|||||||
};
|
};
|
||||||
let last_is_outside = point_before_plane(current_point, plane);
|
let last_is_outside = point_before_plane(current_point, plane);
|
||||||
let mut is_outside = last_is_outside;
|
let mut is_outside = last_is_outside;
|
||||||
/* // Might not actually be total, but if it is partial and the point is inside it will be
|
|
||||||
// written regardless, and if it is partial and the point is outside, it means the
|
|
||||||
// second-to-last point is inside; thus, the second-to-last point will be written regardless,
|
|
||||||
// current_point will hold the new intersection point, and is_total will be false, when the
|
|
||||||
// loop ends; thus all we need to do to take this case into account is to push current_point
|
|
||||||
// onto the points vector if (is_total || is_outside) is false at the end of the loop.
|
|
||||||
let mut is_total = true; */
|
|
||||||
let mut old_points = Vec::with_capacity((3 * points.len()) / 2);
|
let mut old_points = Vec::with_capacity((3 * points.len()) / 2);
|
||||||
mem::swap(&mut old_points, points);
|
mem::swap(&mut old_points, points);
|
||||||
old_points.into_iter().for_each(|point| {
|
old_points.into_iter().for_each(|point| {
|
||||||
/* let prev_point = current_point;
|
|
||||||
// Swap point i with the previous point in the polygon, so it is the one we normally save
|
|
||||||
// when we return false.
|
|
||||||
mem::swap(&mut current_point, point); */
|
|
||||||
let prev_point = mem::replace(&mut current_point, point);
|
let prev_point = mem::replace(&mut current_point, point);
|
||||||
/* if point_before_plane(current_point) {
|
|
||||||
// If we are an outside point, we should only calculate an intersection if the previous
|
|
||||||
// point was inside.
|
|
||||||
if
|
|
||||||
is_outside s
|
|
||||||
// point was outside.
|
|
||||||
} else {
|
|
||||||
// If we are an inside point, then we should only calculate an intersection if the previous
|
|
||||||
// point was outside.
|
|
||||||
} */
|
|
||||||
let before_plane = point_before_plane(current_point, plane);
|
let before_plane = point_before_plane(current_point, plane);
|
||||||
let prev_is_outside = mem::replace(&mut is_outside, before_plane);
|
let prev_is_outside = mem::replace(&mut is_outside, before_plane);
|
||||||
// println!("points@clip_points_by_plane clipping segment by {:?} (prev={:?} /
|
|
||||||
// outside={:?}, current={:?} / outside={:?})", plane, prev_point,
|
|
||||||
// prev_is_outside, current_point, is_outside);
|
|
||||||
if !prev_is_outside {
|
if !prev_is_outside {
|
||||||
// Push previous point.
|
// Push previous point.
|
||||||
points.push(prev_point);
|
points.push(prev_point);
|
||||||
@ -176,115 +142,7 @@ pub fn clip_points_by_plane<T: Float + MulAdd<T, T, Output = T> + core::fmt::Deb
|
|||||||
points.push(intersection_point);
|
points.push(intersection_point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* let prev_is_total = mem::replace(
|
|
||||||
&mut is_total,
|
|
||||||
// Save the intersection point only if we go from outside to inside or inside to
|
|
||||||
// outside, and definitely intersect the plane edge.
|
|
||||||
prev_is_outside != is_outside &&
|
|
||||||
|
|
||||||
.map(|intersection_point| {
|
|
||||||
intersection_points.push(intersection_point);
|
|
||||||
if prev_is_outside {
|
|
||||||
// If the previous point is outside, we know
|
|
||||||
*point = intersection_point;
|
|
||||||
} else {
|
|
||||||
// i o i o
|
|
||||||
//
|
|
||||||
// i o (2)
|
|
||||||
// i i/o o/i (3)
|
|
||||||
//
|
|
||||||
// i o i (3)
|
|
||||||
// i i/o o/i i (4)
|
|
||||||
//
|
|
||||||
// i o i o (4)
|
|
||||||
// i i/o o/i i i/o o/i (6)
|
|
||||||
//
|
|
||||||
// i o i o i (5)
|
|
||||||
// i i/o o/i i i/o o/i i (7)
|
|
||||||
//
|
|
||||||
// i o i o i o (6)
|
|
||||||
// i i/o o/i i i/o o/i i i/o o/i (9)
|
|
||||||
current_point = intersection_point;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
})
|
|
||||||
.is_none(),
|
|
||||||
);
|
|
||||||
// Save the previous point if it is either inside, or has been replaced by an intersection
|
|
||||||
// point.
|
|
||||||
!prev_is_outside || prev_is_total
|
|
||||||
/* match (prev_is_outside, is_outside) {
|
|
||||||
(true, true) => {
|
|
||||||
prev_is_total
|
|
||||||
},
|
|
||||||
(true, false) => {
|
|
||||||
// Outside to inside, so save the previous point only if it's been replaced by an
|
|
||||||
// intersection point.
|
|
||||||
do_intersection();
|
|
||||||
prev_is_total
|
|
||||||
},
|
|
||||||
(false, true) => {
|
|
||||||
// Inside to outside, so always save the previous point, and save the intersection
|
|
||||||
// point only if we definitively intersect the plane edge.
|
|
||||||
false
|
|
||||||
},
|
|
||||||
(false, false) => {
|
|
||||||
// Both points inside the plane, so always save the previous point.
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} */ */
|
|
||||||
});
|
});
|
||||||
/* if !(is_total || is_outside) {
|
|
||||||
points.push(current_point);
|
|
||||||
}
|
|
||||||
/* match (before_plane, is_outside) {
|
|
||||||
(true, Previous::Outside) => {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let cur_is_outside = {
|
|
||||||
if let Intersection::Inside = is_outside {
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
let prev_is_outside = mem::replace(&mut is_outside, {
|
|
||||||
let if let Intersection::Inside = is_outside {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
} point_before_plane(current_point) {
|
|
||||||
});
|
|
||||||
match (prev_is_outside, is_outside) {
|
|
||||||
(true, Some(is_outside)) => {
|
|
||||||
// Both points outside the plane, so save the previous point only if it's been
|
|
||||||
// replaced by an intersection point.
|
|
||||||
is_outside
|
|
||||||
},
|
|
||||||
(true, false) => {
|
|
||||||
// Outside to inside, so calculate the intersection, and save it.
|
|
||||||
intersect_points.push(*point);
|
|
||||||
false
|
|
||||||
},
|
|
||||||
(false, true) => {
|
|
||||||
// Inside to outside, so calculate the intersection, and save it and the current
|
|
||||||
// point.
|
|
||||||
intersect_points.push(*point);
|
|
||||||
false
|
|
||||||
},
|
|
||||||
(false, false) => {
|
|
||||||
// Both points inside the plane, so save previous point
|
|
||||||
*point = *
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if is_outside {
|
|
||||||
if prev_is_outside {
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if prev_is_outside {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});*/ }*/
|
|
||||||
last_is_outside
|
last_is_outside
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,11 +196,14 @@ fn append_intersection_points<T: Float + core::fmt::Debug>(
|
|||||||
// We use floating points rounded to tolerance in order to make our HashMap
|
// We use floating points rounded to tolerance in order to make our HashMap
|
||||||
// lookups work. Otherwise we'd have to use a sorted structure, like a
|
// lookups work. Otherwise we'd have to use a sorted structure, like a
|
||||||
// btree, which wouldn't be the end of the world but would have
|
// btree, which wouldn't be the end of the world but would have
|
||||||
// theoretically worse complexity. NOTE: Definitely non-ideal that we
|
// theoretically worse complexity.
|
||||||
// panic if the rounded value can't fit in an i64... TODO: If necessary,
|
//
|
||||||
// let the caller specify how to hash these keys, since in cases where
|
// NOTE: Definitely non-ideal that we panic if the rounded value can't fit in an
|
||||||
// we know the kind of floating point we're using we can just cast to bits or
|
// i64...
|
||||||
// something.
|
//
|
||||||
|
// TODO: If necessary, let the caller specify how to hash these keys, since in
|
||||||
|
// cases where we know the kind of floating point we're using we can
|
||||||
|
// just cast to bits or something.
|
||||||
point.map(|e| {
|
point.map(|e| {
|
||||||
(e * tol)
|
(e * tol)
|
||||||
.round()
|
.round()
|
||||||
@ -362,45 +223,17 @@ fn append_intersection_points<T: Float + core::fmt::Debug>(
|
|||||||
// than lines).
|
// than lines).
|
||||||
(u_key != make_key(v)).then_some((u_key, v))
|
(u_key != make_key(v)).then_some((u_key, v))
|
||||||
});
|
});
|
||||||
// .map(|uv| (make_key(uv[0]), uv[1]))
|
|
||||||
|
|
||||||
if let Some((last_key, first)) = lines_iter.next()
|
if let Some((last_key, first)) = lines_iter.next() {
|
||||||
/* [last, first, rest @ ..] = &*intersection_points = &*intersection_points */
|
|
||||||
{
|
|
||||||
let lines = lines_iter.collect::<HashMap<_, _>>();
|
let lines = lines_iter.collect::<HashMap<_, _>>();
|
||||||
/* if rest.len() < 4 {
|
|
||||||
// You need at least 3 sides for a polygon
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let lines = rest
|
|
||||||
.chunks_exact(2)
|
|
||||||
.filter_map(|uv| {
|
|
||||||
let u_key = make_key(uv[0]);
|
|
||||||
let v = uv[1];
|
|
||||||
(u_key != make_key(v)).then_some((u_key, v))
|
|
||||||
})
|
|
||||||
// .map(|uv| (make_key(uv[0]), uv[1]))
|
|
||||||
.collect::<HashMap<_, _>>(); */
|
|
||||||
if lines.len() < 2 {
|
if lines.len() < 2 {
|
||||||
// You need at least 3 sides for a polygon
|
// You need at least 3 sides for a polygon
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// println!("lines@append_intersection_points before merging points (last={:?},
|
|
||||||
// cur={:?}): {:?}", last, cur, lines);
|
|
||||||
// let mut poly = Vec::with_capacity(lines.len() + 1);
|
|
||||||
// poly.push(first);
|
|
||||||
// NOTE: Guaranteed to terminate, provided we have no cycles besides the one
|
// NOTE: Guaranteed to terminate, provided we have no cycles besides the one
|
||||||
// that touches every point (which should be the case given how these
|
// that touches every point (which should be the case given how these
|
||||||
// points were generated).
|
// points were generated).
|
||||||
let /*mut */poly_iter = iter::successors(Some(first), |&cur| lines.get(&make_key(cur)).copied());
|
let poly_iter = iter::successors(Some(first), |&cur| lines.get(&make_key(cur)).copied());
|
||||||
/* poly.extend(poly_iter.next());
|
|
||||||
// TODO: If we were smart and pre-tested whether (last, first) was a dup (guaranteeing we
|
|
||||||
// started on a non-dup), we would not need the take_while part.
|
|
||||||
poly.extend(poly_iter.take_while(|&cur| make_key(cur) != make_key(first)));
|
|
||||||
/* while let Some(&v) = lines.get(&make_key(cur)) {
|
|
||||||
cur = v;
|
|
||||||
poly.push(cur);
|
|
||||||
} */ */
|
|
||||||
let poly: Vec<_> = poly_iter.collect();
|
let poly: Vec<_> = poly_iter.collect();
|
||||||
// We have to check to make sure we really went through the whole cycle.
|
// We have to check to make sure we really went through the whole cycle.
|
||||||
// TODO: Consider adaptively decreasing precision until we can make the cycle
|
// TODO: Consider adaptively decreasing precision until we can make the cycle
|
||||||
@ -421,7 +254,6 @@ pub fn clip_object_by_plane<T: Float + MulAdd<T, T, Output = T> + core::fmt::Deb
|
|||||||
polys.drain_filter(|points| {
|
polys.drain_filter(|points| {
|
||||||
let len = intersection_points.len();
|
let len = intersection_points.len();
|
||||||
let outside_first = clip_points_by_plane(points, plane, &mut intersection_points);
|
let outside_first = clip_points_by_plane(points, plane, &mut intersection_points);
|
||||||
// println!("points@clip_object_by_plane after clipping by {:?} (outside_first={:?}, intersection_points={:?}): {:?}", plane, outside_first, intersection_points, points);
|
|
||||||
// Only remember intersections that are not coplanar with this side; i.e. those
|
// Only remember intersections that are not coplanar with this side; i.e. those
|
||||||
// that have segment length 2.
|
// that have segment length 2.
|
||||||
if len + 2 != intersection_points.len() {
|
if len + 2 != intersection_points.len() {
|
||||||
@ -444,8 +276,6 @@ pub fn clip_object_by_plane<T: Float + MulAdd<T, T, Output = T> + core::fmt::Deb
|
|||||||
// Remove polygon if it was clipped away
|
// Remove polygon if it was clipped away
|
||||||
points.is_empty()
|
points.is_empty()
|
||||||
});
|
});
|
||||||
// println!("polys@clip_object_by_plane after clipping by {:?} (before appending
|
|
||||||
// interection points {:?}): {:?}", plane, intersection_points, polys);
|
|
||||||
// Add a polygon of all intersection points with the plane to close out the
|
// Add a polygon of all intersection points with the plane to close out the
|
||||||
// object.
|
// object.
|
||||||
append_intersection_points(polys, intersection_points, tolerance);
|
append_intersection_points(polys, intersection_points, tolerance);
|
||||||
@ -457,11 +287,8 @@ pub fn clip_object_by_aabb<T: Float + MulAdd<T, T, Output = T> + core::fmt::Debu
|
|||||||
tolerance: T,
|
tolerance: T,
|
||||||
) {
|
) {
|
||||||
let planes = aabb_to_planes(bounds);
|
let planes = aabb_to_planes(bounds);
|
||||||
// println!("planes@clip_object_by_aabb: {:?}", planes);
|
|
||||||
planes.iter().for_each(|&plane| {
|
planes.iter().for_each(|&plane| {
|
||||||
clip_object_by_plane(polys, plane, tolerance);
|
clip_object_by_plane(polys, plane, tolerance);
|
||||||
// println!("polys@clip_object_by_aabb (after clipping by {:?}):
|
|
||||||
// {:?}", plane, polys);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,7 +296,6 @@ pub fn clip_object_by_aabb<T: Float + MulAdd<T, T, Output = T> + core::fmt::Debu
|
|||||||
/// test plane. Otherwise 'None' is returned in which case the line
|
/// test plane. Otherwise 'None' is returned in which case the line
|
||||||
/// segment is entirely clipped.
|
/// segment is entirely clipped.
|
||||||
pub fn clip_test<T: Float + core::fmt::Debug>(p: T, q: T, (u1, u2): (T, T)) -> Option<(T, T)> {
|
pub fn clip_test<T: Float + core::fmt::Debug>(p: T, q: T, (u1, u2): (T, T)) -> Option<(T, T)> {
|
||||||
/* let res = */
|
|
||||||
if p == T::zero() {
|
if p == T::zero() {
|
||||||
if q >= T::zero() { Some((u1, u2)) } else { None }
|
if q >= T::zero() { Some((u1, u2)) } else { None }
|
||||||
} else {
|
} else {
|
||||||
@ -485,9 +311,7 @@ pub fn clip_test<T: Float + core::fmt::Debug>(p: T, q: T, (u1, u2): (T, T)) -> O
|
|||||||
} else {
|
} else {
|
||||||
Some((u1, if r < u2 { r } else { u2 }))
|
Some((u1, if r < u2 { r } else { u2 }))
|
||||||
}
|
}
|
||||||
} /*;
|
}
|
||||||
// println!("clip_test@(p={:?}, q={:?}, (u1, u2)=({:?}. {:?})):
|
|
||||||
// res={:?}", p, q, u1, u2, res); res*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intersection_line_aabb<T: Float + MulAdd<T, T, Output = T> + core::fmt::Debug>(
|
pub fn intersection_line_aabb<T: Float + MulAdd<T, T, Output = T> + core::fmt::Debug>(
|
||||||
@ -495,9 +319,6 @@ pub fn intersection_line_aabb<T: Float + MulAdd<T, T, Output = T> + core::fmt::D
|
|||||||
dir: Vec3<T>,
|
dir: Vec3<T>,
|
||||||
bounds: Aabb<T>,
|
bounds: Aabb<T>,
|
||||||
) -> Option<Vec3<T>> {
|
) -> Option<Vec3<T>> {
|
||||||
// println!("before@intersection_line_aabb: p={:?} dir={:?} bounds={:?}", p,
|
|
||||||
// dir, bounds);
|
|
||||||
/* let res = */
|
|
||||||
clip_test(-dir.z, p.z - bounds.min.z, (T::zero(), T::infinity()))
|
clip_test(-dir.z, p.z - bounds.min.z, (T::zero(), T::infinity()))
|
||||||
.and_then(|t| clip_test(dir.z, bounds.max.z - p.z, t))
|
.and_then(|t| clip_test(dir.z, bounds.max.z - p.z, t))
|
||||||
.and_then(|t| clip_test(-dir.y, p.y - bounds.min.y, t))
|
.and_then(|t| clip_test(-dir.y, p.y - bounds.min.y, t))
|
||||||
@ -512,9 +333,7 @@ pub fn intersection_line_aabb<T: Float + MulAdd<T, T, Output = T> + core::fmt::D
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}) /*;
|
})
|
||||||
//println!("after@intersection_line_aabb (p={:?} dir={:?} bounds={:?}):
|
|
||||||
// {:?}", p, dir, bounds, res); res */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn include_object_light_volume<
|
pub fn include_object_light_volume<
|
||||||
@ -525,12 +344,12 @@ pub fn include_object_light_volume<
|
|||||||
light_dir: Vec3<T>,
|
light_dir: Vec3<T>,
|
||||||
bounds: Aabb<T>,
|
bounds: Aabb<T>,
|
||||||
) -> impl Iterator<Item = Vec3<T>> {
|
) -> impl Iterator<Item = Vec3<T>> {
|
||||||
/* obj.filter_map(move |pt| intersection_line_aabb(pt, -light_dir, bounds)) */
|
|
||||||
// obj.map(move |pt| intersection_line_aabb(pt, -light_dir,
|
|
||||||
// bounds).unwrap_or(pt))
|
|
||||||
obj.flat_map(move |pt| iter::once(pt).chain(intersection_line_aabb(pt, -light_dir, bounds)))
|
obj.flat_map(move |pt| iter::once(pt).chain(intersection_line_aabb(pt, -light_dir, bounds)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Currently specialized to skip extending to the end of the light ray,
|
||||||
|
// since our light ray is already infinite. Correct code is commented out
|
||||||
|
// below.
|
||||||
pub fn calc_focused_light_volume_points<T: Float + MulAdd<T, T, Output = T> + core::fmt::Debug>(
|
pub fn calc_focused_light_volume_points<T: Float + MulAdd<T, T, Output = T> + core::fmt::Debug>(
|
||||||
inv_proj_view: Mat4<T>,
|
inv_proj_view: Mat4<T>,
|
||||||
_light_dir: Vec3<T>,
|
_light_dir: Vec3<T>,
|
||||||
@ -538,13 +357,8 @@ pub fn calc_focused_light_volume_points<T: Float + MulAdd<T, T, Output = T> + co
|
|||||||
tolerance: T,
|
tolerance: T,
|
||||||
) -> impl Iterator<Item = Vec3<T>> {
|
) -> impl Iterator<Item = Vec3<T>> {
|
||||||
let world_pts = calc_view_frustum_world_coord(inv_proj_view);
|
let world_pts = calc_view_frustum_world_coord(inv_proj_view);
|
||||||
// println!("world_pts: {:?}", world_pts);
|
|
||||||
let mut world_frust_object = calc_view_frust_object(&world_pts);
|
let mut world_frust_object = calc_view_frust_object(&world_pts);
|
||||||
// println!("world_frust_object: {:?}", world_frust_object);
|
|
||||||
clip_object_by_aabb(&mut world_frust_object, scene_bounding_box, tolerance);
|
clip_object_by_aabb(&mut world_frust_object, scene_bounding_box, tolerance);
|
||||||
// println!("world_frust_object@clip_object_by_aabb: {:?}", world_frust_object);
|
|
||||||
/* let object_points = world_frust_object.into_iter().flat_map(|e| e.into_iter());
|
|
||||||
object_points.clone().chain(include_object_light_volume(object_points, light_dir, scene_bounding_box)) */
|
|
||||||
world_frust_object.into_iter().flat_map(|e| e.into_iter())
|
world_frust_object.into_iter().flat_map(|e| e.into_iter())
|
||||||
/* include_object_light_volume(
|
/* include_object_light_volume(
|
||||||
world_frust_object.into_iter().flat_map(|e| e.into_iter()),
|
world_frust_object.into_iter().flat_map(|e| e.into_iter()),
|
||||||
@ -574,50 +388,4 @@ pub fn fit_psr<
|
|||||||
min: min.xyz(),
|
min: min.xyz(),
|
||||||
max: max.xyz(),
|
max: max.xyz(),
|
||||||
}
|
}
|
||||||
/* let mut make_p = |x: f32, y: f32, z: f32| -> Vec3<f32> {
|
|
||||||
do_p(mat * Vec4::new(x, y, z, 1.0))
|
|
||||||
};
|
|
||||||
let p1 = make_p(bounds.min.x, bounds.min.y, bounds.min.z);
|
|
||||||
let p2 = make_p(bounds.max.x, bounds.min.y, bounds.min.z);
|
|
||||||
let p3 = make_p(bounds.min.x, bounds.max.y, bounds.min.z);
|
|
||||||
let p4 = make_p(bounds.max.x, bounds.max.y, bounds.min.z);
|
|
||||||
let p5 = make_p(bounds.min.x, bounds.min.y, bounds.max.z);
|
|
||||||
let p6 = make_p(bounds.max.x, bounds.min.y, bounds.max.z);
|
|
||||||
let p7 = make_p(bounds.min.x, bounds.max.y, bounds.max.z);
|
|
||||||
let p8 = make_p(bounds.max.x, bounds.max.y, bounds.max.z);
|
|
||||||
// let p1: Vec4<f32> = mat * Vec4::new(bounds.min.x, bounds.min.y, bounds.min.z, 1.0);
|
|
||||||
// let p2: Vec4<f32> = mat * Vec4::new(0.0, bounds.min.y, 0.0, 1.0);
|
|
||||||
// let p3: Vec4<f32> = mat * Vec4::new(0.0, 0.0, bounds.min.z, 1.0);
|
|
||||||
// let p4: Vec4<f32> = mat * Vec4::new(bounds.max.x, 0.0, 0.0, 1.0);
|
|
||||||
// let p5: Vec4<f32> = mat * Vec4::new(0.0, bounds.max.y, 0.0, 1.0);
|
|
||||||
// let p6: Vec4<f32> = mat * Vec4::new(bounds.max.x, bounds.max.y, bounds.max.z, 1.0);
|
|
||||||
// println!("p1 p6 {:?} {:?}", p1, p6);
|
|
||||||
// let xmin = p1.x.min(p6.x);
|
|
||||||
// let xmax = p1.x.max(p6.x);
|
|
||||||
// println!("p1 p2 p3 p4 p5 p6: {:?} {:?} {:?} {:?} {:?} {:?}", p1, p2, p3, p4, p5, p6);
|
|
||||||
let xmin = p1.x.min(p2.x.min(p3.x.min(p4.x.min(p5.x.min(p6.x.min(p7.x.min(p8.x)))))));
|
|
||||||
let xmax = p1.x.max(p2.x.max(p3.x.max(p4.x.max(p5.x.max(p6.x.max(p7.x.max(p8.x)))))));
|
|
||||||
// let xmin = p1.x.min(p2.x.min(p3.x.min(p4.x.min(p5.x.min(p6.x)))));
|
|
||||||
// let xmax = p1.x.max(p2.x.max(p3.x.max(p4.x.max(p5.x.max(p6.x)))));
|
|
||||||
// println!("xmin: {:?}, xmax: {:?}", xmin, xmax);
|
|
||||||
// let ymin = p1.y.min(p6.y);
|
|
||||||
// let ymax = p1.y.max(p6.y);
|
|
||||||
let ymin = p1.y.min(p2.y.min(p3.y.min(p4.y.min(p5.y.min(p6.y.min(p7.y.min(p8.y)))))));
|
|
||||||
let ymax = p1.y.max(p2.y.max(p3.y.max(p4.y.max(p5.y.max(p6.y.max(p7.y.max(p8.y)))))));
|
|
||||||
// println!("ymin: {:?}, ymax: {:?}", ymin, ymax);
|
|
||||||
|
|
||||||
// let p1: Vec4<f32> = view_mat * Vec4::new(scene_bounds.min.x, scene_bounds.min.y, scene_bounds.min.z, 1.0);
|
|
||||||
// let p2: Vec4<f32> = view_mat * Vec4::new(0.0, scene_bounds.min.y, 0.0, 1.0);
|
|
||||||
// let p3: Vec4<f32> = view_mat * Vec4::new(0.0, 0.0, scene_bounds.min.z, 1.0);
|
|
||||||
// let p4: Vec4<f32> = view_mat * Vec4::new(scene_bounds.max.x, scene_bounds.max.y, scene_bounds.max.z, 1.0);
|
|
||||||
// let p5: Vec4<f32> = view_mat * Vec4::new(0.0, scene_bounds.max.y, 0.0, 1.0);
|
|
||||||
// let p6: Vec4<f32> = view_mat * Vec4::new(0.0, 0.0, scene_bounds.max.z, 1.0);
|
|
||||||
// println!("p1 p2 p3 p4 p5 p6: {:?} {:?} {:?} {:?} {:?} {:?}", p1, p2, p3, p4, p5, p6);
|
|
||||||
// println!("p1 p4 {:?} {:?}", p1, p4);
|
|
||||||
let zmin = p1.z.min(p2.z.min(p3.z.min(p4.z.min(p5.z.min(p6.z.min(p7.z.min(p8.z)))))));
|
|
||||||
let zmax = p1.z.max(p2.z.max(p3.z.max(p4.z.max(p5.z.max(p6.z.max(p7.z.max(p8.z)))))));
|
|
||||||
Aabb {
|
|
||||||
min: Vec3::new(xmin, ymin, zmin),
|
|
||||||
max: Vec3::new(xmax, ymax, zmax),
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,8 +2,8 @@ use crate::{
|
|||||||
mesh::{greedy::GreedyMesh, Meshable},
|
mesh::{greedy::GreedyMesh, Meshable},
|
||||||
render::{
|
render::{
|
||||||
create_pp_mesh, create_skybox_mesh, BoneMeshes, Consts, FigureModel, FigurePipeline,
|
create_pp_mesh, create_skybox_mesh, BoneMeshes, Consts, FigureModel, FigurePipeline,
|
||||||
Globals, Light, Model, PostProcessLocals, PostProcessPipeline, Renderer, Shadow,
|
GlobalModel, Globals, Light, Model, PostProcessLocals, PostProcessPipeline, Renderer,
|
||||||
ShadowLocals, SkyboxLocals, SkyboxPipeline,
|
Shadow, ShadowLocals, SkyboxLocals, SkyboxPipeline,
|
||||||
},
|
},
|
||||||
scene::{
|
scene::{
|
||||||
camera::{self, Camera, CameraMode},
|
camera::{self, Camera, CameraMode},
|
||||||
@ -68,10 +68,7 @@ struct PostProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
globals: Consts<Globals>,
|
data: GlobalModel,
|
||||||
lights: Consts<Light>,
|
|
||||||
shadows: Consts<Shadow>,
|
|
||||||
shadow_mats: Consts<ShadowLocals>,
|
|
||||||
camera: Camera,
|
camera: Camera,
|
||||||
|
|
||||||
skybox: Skybox,
|
skybox: Skybox,
|
||||||
@ -105,18 +102,8 @@ impl Scene {
|
|||||||
|
|
||||||
let map_bounds = Vec2::new(-65536.0, 131071.0);
|
let map_bounds = Vec2::new(-65536.0, 131071.0);
|
||||||
let map_border = [0.0, 0.0, 0.0, 0.0];
|
let map_border = [0.0, 0.0, 0.0, 0.0];
|
||||||
/* let map_image = image::DynamicImage::ImageRgba8(image::RgbaImage::from_pixel(
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
image::Rgba([0, 0, 0, 0]),
|
|
||||||
)); */
|
|
||||||
let map_image = [0];
|
let map_image = [0];
|
||||||
let alt_image = [0];
|
let alt_image = [0];
|
||||||
/* let horizon_image = image::DynamicImage::ImageRgba8(image::RgbaImage::from_pixel(
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
image::Rgba([0, 1, 0, 1]),
|
|
||||||
)); */
|
|
||||||
let horizon_image = [0x_00_01_00_01];
|
let horizon_image = [0x_00_01_00_01];
|
||||||
|
|
||||||
let mut camera = Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson);
|
let mut camera = Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson);
|
||||||
@ -127,10 +114,14 @@ impl Scene {
|
|||||||
let mut col_lights = FigureColLights::new(renderer);
|
let mut col_lights = FigureColLights::new(renderer);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
data: GlobalModel {
|
||||||
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
||||||
lights: renderer.create_consts(&[Light::default(); 32]).unwrap(),
|
lights: renderer.create_consts(&[Light::default(); 32]).unwrap(),
|
||||||
shadows: renderer.create_consts(&[Shadow::default(); 32]).unwrap(),
|
shadows: renderer.create_consts(&[Shadow::default(); 32]).unwrap(),
|
||||||
shadow_mats: renderer.create_consts(&[ShadowLocals::default(); 6]).unwrap(),
|
shadow_mats: renderer
|
||||||
|
.create_consts(&[ShadowLocals::default(); 6])
|
||||||
|
.unwrap(),
|
||||||
|
},
|
||||||
|
|
||||||
skybox: Skybox {
|
skybox: Skybox {
|
||||||
model: renderer.create_model(&create_skybox_mesh()).unwrap(),
|
model: renderer.create_model(&create_skybox_mesh()).unwrap(),
|
||||||
@ -142,8 +133,16 @@ impl Scene {
|
|||||||
.create_consts(&[PostProcessLocals::default()])
|
.create_consts(&[PostProcessLocals::default()])
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
},
|
},
|
||||||
lod: LodData::new(renderer, Vec2::new(1, 1), &map_image, &alt_image, &horizon_image, 1, map_border.into()),// Lod::new(renderer, client, settings),
|
lod: LodData::new(
|
||||||
map_bounds,//: client.world_map.2,
|
renderer,
|
||||||
|
Vec2::new(1, 1),
|
||||||
|
&map_image,
|
||||||
|
&alt_image,
|
||||||
|
&horizon_image,
|
||||||
|
1,
|
||||||
|
map_border.into(),
|
||||||
|
),
|
||||||
|
map_bounds,
|
||||||
|
|
||||||
figure_model_cache: FigureModelCache::new(),
|
figure_model_cache: FigureModelCache::new(),
|
||||||
figure_state: FigureState::new(renderer, CharacterSkeleton::default()),
|
figure_state: FigureState::new(renderer, CharacterSkeleton::default()),
|
||||||
@ -173,21 +172,18 @@ impl Scene {
|
|||||||
&camera,
|
&camera,
|
||||||
&mut buf,
|
&mut buf,
|
||||||
);
|
);
|
||||||
(
|
(model, state)
|
||||||
model,
|
|
||||||
state,
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
col_lights,
|
col_lights,
|
||||||
|
|
||||||
camera,
|
camera,
|
||||||
|
|
||||||
turning: false,
|
turning: false,
|
||||||
char_ori: /*0.0*/-start_angle,
|
char_ori: -start_angle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn globals(&self) -> &Consts<Globals> { &self.globals }
|
pub fn globals(&self) -> &Consts<Globals> { &self.data.globals }
|
||||||
|
|
||||||
pub fn camera_mut(&mut self) -> &mut Camera { &mut self.camera }
|
pub fn camera_mut(&mut self) -> &mut Camera { &mut self.camera }
|
||||||
|
|
||||||
@ -234,19 +230,18 @@ impl Scene {
|
|||||||
cam_pos,
|
cam_pos,
|
||||||
} = self.camera.dependents();
|
} = self.camera.dependents();
|
||||||
const VD: f32 = 115.0; // View Distance
|
const VD: f32 = 115.0; // View Distance
|
||||||
// const MAP_BOUNDS: Vec2<f32> = Vec2::new(140.0, 2048.0);
|
const TIME: f64 = 10.0 * 60.0 * 60.0;
|
||||||
const TIME: f64 = 10.0 * 60.0 * 60.0; //43200.0; // 12 hours*3600 seconds
|
|
||||||
const SHADOW_NEAR: f32 = 1.0;
|
const SHADOW_NEAR: f32 = 1.0;
|
||||||
const SHADOW_FAR: f32 = 25.0;
|
const SHADOW_FAR: f32 = 25.0;
|
||||||
|
|
||||||
if let Err(e) = renderer.update_consts(&mut self.globals, &[Globals::new(
|
if let Err(e) = renderer.update_consts(&mut self.data.globals, &[Globals::new(
|
||||||
view_mat,
|
view_mat,
|
||||||
proj_mat,
|
proj_mat,
|
||||||
cam_pos,
|
cam_pos,
|
||||||
self.camera.get_focus_pos(),
|
self.camera.get_focus_pos(),
|
||||||
VD,
|
VD,
|
||||||
self.lod.tgt_detail as f32,
|
self.lod.tgt_detail as f32,
|
||||||
self.map_bounds, //MAP_BOUNDS,
|
self.map_bounds,
|
||||||
TIME,
|
TIME,
|
||||||
scene_data.time,
|
scene_data.time,
|
||||||
renderer.get_resolution(),
|
renderer.get_resolution(),
|
||||||
@ -338,10 +333,9 @@ impl Scene {
|
|||||||
) {
|
) {
|
||||||
renderer.render_skybox(
|
renderer.render_skybox(
|
||||||
&self.skybox.model,
|
&self.skybox.model,
|
||||||
&self.globals,
|
&self.data,
|
||||||
&self.skybox.locals,
|
&self.skybox.locals,
|
||||||
&self.lod.alt,
|
&self.lod,
|
||||||
&self.lod.horizon,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(body) = body {
|
if let Some(body) = body {
|
||||||
@ -361,14 +355,10 @@ impl Scene {
|
|||||||
renderer.render_figure(
|
renderer.render_figure(
|
||||||
&model[0],
|
&model[0],
|
||||||
&self.col_lights.texture(),
|
&self.col_lights.texture(),
|
||||||
&self.globals,
|
&self.data,
|
||||||
self.figure_state.locals(),
|
self.figure_state.locals(),
|
||||||
self.figure_state.bone_consts(),
|
self.figure_state.bone_consts(),
|
||||||
&self.lights,
|
&self.lod,
|
||||||
&self.shadows,
|
|
||||||
&self.shadow_mats,
|
|
||||||
&self.lod.alt,
|
|
||||||
&self.lod.horizon,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,20 +366,16 @@ impl Scene {
|
|||||||
renderer.render_figure(
|
renderer.render_figure(
|
||||||
model,
|
model,
|
||||||
&self.col_lights.texture(),
|
&self.col_lights.texture(),
|
||||||
&self.globals,
|
&self.data,
|
||||||
state.locals(),
|
state.locals(),
|
||||||
state.bone_consts(),
|
state.bone_consts(),
|
||||||
&self.lights,
|
&self.lod,
|
||||||
&self.shadows,
|
|
||||||
&self.shadow_mats,
|
|
||||||
&self.lod.alt,
|
|
||||||
&self.lod.horizon,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.render_post_process(
|
renderer.render_post_process(
|
||||||
&self.postprocess.model,
|
&self.postprocess.model,
|
||||||
&self.globals,
|
&self.data.globals,
|
||||||
&self.postprocess.locals,
|
&self.postprocess.locals,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
mesh::{greedy::GreedyMesh, Meshable},
|
mesh::{greedy::GreedyMesh, Meshable},
|
||||||
render::{
|
render::{
|
||||||
ColLightFmt, ColLightInfo, Consts, FluidPipeline, Globals, Instances, Light, Mesh, Model,
|
ColLightFmt, ColLightInfo, Consts, FluidPipeline, GlobalModel, Instances, Mesh, Model,
|
||||||
RenderError, Renderer, Shadow, ShadowLocals, ShadowPipeline, SpriteInstance, SpriteLocals,
|
RenderError, Renderer, ShadowPipeline, SpriteInstance, SpriteLocals, SpritePipeline,
|
||||||
SpritePipeline, TerrainLocals, TerrainPipeline, Texture,
|
TerrainLocals, TerrainPipeline, Texture,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,13 +40,8 @@ struct TerrainChunkData {
|
|||||||
load_time: f32,
|
load_time: f32,
|
||||||
opaque_model: Model<TerrainPipeline>,
|
opaque_model: Model<TerrainPipeline>,
|
||||||
fluid_model: Option<Model<FluidPipeline>>,
|
fluid_model: Option<Model<FluidPipeline>>,
|
||||||
// shadow_model: Model<ShadowPipeline>,
|
|
||||||
// col_lights: Texture<ColLightFmt>,
|
|
||||||
col_lights: guillotiere::AllocId,
|
col_lights: guillotiere::AllocId,
|
||||||
sprite_instances: HashMap<
|
sprite_instances: HashMap<(BlockKind, usize), Instances<SpriteInstance>>,
|
||||||
(BlockKind, usize),
|
|
||||||
Instances<SpriteInstance>, /* RawBuffer*//*(Consts<SpriteInstance>, usize) */
|
|
||||||
>,
|
|
||||||
locals: Consts<TerrainLocals>,
|
locals: Consts<TerrainLocals>,
|
||||||
|
|
||||||
visible: Visibility,
|
visible: Visibility,
|
||||||
@ -386,12 +381,10 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
|||||||
volume: <VolGrid2d<V> as SampleVol<Aabr<i32>>>::Sample,
|
volume: <VolGrid2d<V> as SampleVol<Aabr<i32>>>::Sample,
|
||||||
max_texture_size: u16,
|
max_texture_size: u16,
|
||||||
range: Aabb<i32>,
|
range: Aabb<i32>,
|
||||||
sprite_models: &HashMap<(BlockKind, usize), Vec</* Range<u32> */ SpriteData>>,
|
sprite_models: &HashMap<(BlockKind, usize), Vec<SpriteData>>,
|
||||||
) -> MeshWorkerResponse {
|
) -> MeshWorkerResponse {
|
||||||
let (opaque_mesh /* col_lights */, fluid_mesh, _shadow_mesh, (bounds, col_lights_info)) =
|
let (opaque_mesh, fluid_mesh, _shadow_mesh, (bounds, col_lights_info)) =
|
||||||
volume.generate_mesh((range, Vec2::new(max_texture_size, max_texture_size)));
|
volume.generate_mesh((range, Vec2::new(max_texture_size, max_texture_size)));
|
||||||
// println!("z_bounds{:?}, bounds: {:?}", z_bounds, (bounds.min.z,
|
|
||||||
// bounds.max.z));
|
|
||||||
MeshWorkerResponse {
|
MeshWorkerResponse {
|
||||||
pos,
|
pos,
|
||||||
z_bounds: (bounds.min.z, bounds.max.z),
|
z_bounds: (bounds.min.z, bounds.max.z),
|
||||||
@ -422,23 +415,12 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
|||||||
let sprite_data = &sprite_models[&key][0];
|
let sprite_data = &sprite_models[&key][0];
|
||||||
let instance = SpriteInstance::new(
|
let instance = SpriteInstance::new(
|
||||||
Mat4::identity()
|
Mat4::identity()
|
||||||
/*sprite_models[&key][0].mat
|
|
||||||
/* .scaled_3d(
|
|
||||||
lod_scale
|
|
||||||
) */
|
|
||||||
/* .translated_3d(
|
|
||||||
offset
|
|
||||||
) */
|
|
||||||
// * 1.0 / 11.0
|
|
||||||
.rotated_z(f32::consts::PI * 0.25 * ori as f32)
|
|
||||||
*/
|
|
||||||
.translated_3d(sprite_data.offset)
|
.translated_3d(sprite_data.offset)
|
||||||
// .scaled_3d(SPRITE_SCALE)
|
|
||||||
.rotated_z(f32::consts::PI * 0.25 * ori as f32)
|
.rotated_z(f32::consts::PI * 0.25 * ori as f32)
|
||||||
.translated_3d(
|
.translated_3d(
|
||||||
(rel_pos.map(|e| e as f32) + Vec3::new(0.5, 0.5, 0.0)) / SPRITE_SCALE,
|
(rel_pos.map(|e| e as f32) + Vec3::new(0.5, 0.5, 0.0))
|
||||||
|
/ SPRITE_SCALE,
|
||||||
),
|
),
|
||||||
// Rgb::broadcast(1.0),
|
|
||||||
cfg.wind_sway,
|
cfg.wind_sway,
|
||||||
rel_pos,
|
rel_pos,
|
||||||
ori,
|
ori,
|
||||||
@ -490,8 +472,7 @@ pub struct Terrain<V: RectRasterableVol> {
|
|||||||
mesh_todo: HashMap<Vec2<i32>, ChunkMeshState>,
|
mesh_todo: HashMap<Vec2<i32>, ChunkMeshState>,
|
||||||
|
|
||||||
// GPU data
|
// GPU data
|
||||||
// sprite_model_data: Model<SpritePipeline>,
|
sprite_models: Arc<HashMap<(BlockKind, usize), Vec<SpriteData>>>,
|
||||||
sprite_models: Arc<HashMap<(BlockKind, usize), Vec</* Range<u32> */ SpriteData>>>,
|
|
||||||
sprite_col_lights: Texture<ColLightFmt>,
|
sprite_col_lights: Texture<ColLightFmt>,
|
||||||
col_lights: Texture<ColLightFmt>,
|
col_lights: Texture<ColLightFmt>,
|
||||||
waves: Texture,
|
waves: Texture,
|
||||||
@ -518,9 +499,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
let max_texture_size = renderer.max_texture_size();
|
let max_texture_size = renderer.max_texture_size();
|
||||||
let max_size =
|
let max_size =
|
||||||
guillotiere::Size::new(i32::from(max_texture_size), i32::from(max_texture_size));
|
guillotiere::Size::new(i32::from(max_texture_size), i32::from(max_texture_size));
|
||||||
// let max_sprite_size = guillotiere::Size::new(128, 64);
|
|
||||||
let mut greedy = GreedyMesh::new(max_size);
|
let mut greedy = GreedyMesh::new(max_size);
|
||||||
// let mut mesh = Mesh::new();
|
|
||||||
let mut locals_buffer = [SpriteLocals::default(); 8];
|
let mut locals_buffer = [SpriteLocals::default(); 8];
|
||||||
let mut make_models = |(kind, variation), s, offset, lod_axes: Vec3<f32>| {
|
let mut make_models = |(kind, variation), s, offset, lod_axes: Vec3<f32>| {
|
||||||
let scaled = [1.0, 0.8, 0.6, 0.4, 0.2];
|
let scaled = [1.0, 0.8, 0.6, 0.4, 0.2];
|
||||||
@ -545,10 +524,6 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
scale
|
scale
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
/* println!(
|
|
||||||
"model_size: {:?} (model_scale = {:?})",
|
|
||||||
model_size, model_scale
|
|
||||||
); */
|
|
||||||
let wind_sway = sprite_config_for(kind).map(|c| c.wind_sway).unwrap_or(0.0);
|
let wind_sway = sprite_config_for(kind).map(|c| c.wind_sway).unwrap_or(0.0);
|
||||||
let sprite_mat: Mat4<f32> = Mat4::translation_3d(offset).scaled_3d(SPRITE_SCALE);
|
let sprite_mat: Mat4<f32> = Mat4::translation_3d(offset).scaled_3d(SPRITE_SCALE);
|
||||||
(
|
(
|
||||||
@ -556,45 +531,44 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
scaled
|
scaled
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&lod_scale_orig| {
|
.map(|&lod_scale_orig| {
|
||||||
let lod_scale = model_scale * if lod_scale_orig == 1.0 {
|
let lod_scale = model_scale
|
||||||
|
* if lod_scale_orig == 1.0 {
|
||||||
Vec3::broadcast(1.0)
|
Vec3::broadcast(1.0)
|
||||||
} else {
|
} else {
|
||||||
lod_axes * lod_scale_orig + lod_axes.map(|e| if e == 0.0 { 1.0 } else { 0.0 })
|
lod_axes * lod_scale_orig
|
||||||
|
+ lod_axes.map(|e| if e == 0.0 { 1.0 } else { 0.0 })
|
||||||
};
|
};
|
||||||
let opaque_model =
|
let opaque_model =
|
||||||
Meshable::<SpritePipeline, &mut GreedyMesh>::generate_mesh(
|
Meshable::<SpritePipeline, &mut GreedyMesh>::generate_mesh(
|
||||||
Segment::from(model.as_ref()).scaled_by(lod_scale),
|
Segment::from(model.as_ref()).scaled_by(lod_scale),
|
||||||
(&mut greedy, wind_sway >= 0.4 && lod_scale_orig == 1.0/*>= 0.8*//*lod_axes.x == 0.0 && lod_axes.y == 0.0*//* && lod_scale.z >= 0.8*//*, offset * lod_scale, Vec3::one() / lod_scale*/),
|
(&mut greedy, wind_sway >= 0.4 && lod_scale_orig == 1.0),
|
||||||
)
|
)
|
||||||
.0;
|
.0;
|
||||||
let sprite_scale = Vec3::one() / lod_scale;
|
let sprite_scale = Vec3::one() / lod_scale;
|
||||||
let sprite_mat: Mat4<f32> = sprite_mat * Mat4::scaling_3d(sprite_scale);
|
let sprite_mat: Mat4<f32> = sprite_mat * Mat4::scaling_3d(sprite_scale);
|
||||||
locals_buffer.iter_mut().enumerate().for_each(|(ori, locals)| {
|
locals_buffer
|
||||||
let sprite_mat = sprite_mat.rotated_z(f32::consts::PI * 0.25 * ori as f32);
|
.iter_mut()
|
||||||
*locals = SpriteLocals::new(sprite_mat, sprite_scale, offset, wind_sway);
|
.enumerate()
|
||||||
|
.for_each(|(ori, locals)| {
|
||||||
|
let sprite_mat =
|
||||||
|
sprite_mat.rotated_z(f32::consts::PI * 0.25 * ori as f32);
|
||||||
|
*locals =
|
||||||
|
SpriteLocals::new(sprite_mat, sprite_scale, offset, wind_sway);
|
||||||
});
|
});
|
||||||
|
|
||||||
SpriteData {
|
SpriteData {
|
||||||
/* scale: sprite_scale, */
|
|
||||||
offset,
|
offset,
|
||||||
/* mat: sprite_mat, */
|
model: renderer.create_model(&opaque_model).unwrap(),
|
||||||
model: renderer.create_model(&opaque_model)
|
locals: renderer
|
||||||
.unwrap(),
|
.create_consts(&locals_buffer)
|
||||||
locals: renderer.create_consts(&locals_buffer)
|
|
||||||
.expect("Failed to upload sprite locals to the GPU!"),
|
.expect("Failed to upload sprite locals to the GPU!"),
|
||||||
}
|
}
|
||||||
/* // NOTE: Safe because atlas size is an upper bound on vertex count, and atlas
|
|
||||||
// width and height are at most u16::MAX.
|
|
||||||
let start = mesh.vertices().len() as u32;
|
|
||||||
let vbuf = (start..start + opaque_model.vertices().len() as u32);
|
|
||||||
mesh.push_mesh(&opaque_model);
|
|
||||||
vbuf */
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let sprite_models: HashMap<(BlockKind, usize), /* Vec<Range<u32>> */ _> = vec![
|
let sprite_models: HashMap<(BlockKind, usize), _> = vec![
|
||||||
// Windows
|
// Windows
|
||||||
make_models(
|
make_models(
|
||||||
(BlockKind::Window1, 0),
|
(BlockKind::Window1, 0),
|
||||||
@ -2308,11 +2282,6 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect();
|
.collect();
|
||||||
/* let sprite_model_data = renderer
|
|
||||||
.create_model(&mesh)
|
|
||||||
.expect("Failed to upload sprite vertex to the GPU!"); */
|
|
||||||
// println!("{:?}, {:?}", sprite_model_data.vbuf,
|
|
||||||
// sprite_model_data.vertex_range); println!("{:?}", sprite_models);
|
|
||||||
let sprite_col_lights = ShadowPipeline::create_col_lights(renderer, greedy.finalize())
|
let sprite_col_lights = ShadowPipeline::create_col_lights(renderer, greedy.finalize())
|
||||||
.expect("Failed to upload sprite color and light data to the GPU!");
|
.expect("Failed to upload sprite color and light data to the GPU!");
|
||||||
Self {
|
Self {
|
||||||
@ -2322,23 +2291,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
mesh_send_tmp: send,
|
mesh_send_tmp: send,
|
||||||
mesh_recv: recv,
|
mesh_recv: recv,
|
||||||
mesh_todo: HashMap::default(),
|
mesh_todo: HashMap::default(),
|
||||||
// sprite_model_data,
|
|
||||||
sprite_models: Arc::new(sprite_models),
|
sprite_models: Arc::new(sprite_models),
|
||||||
sprite_col_lights, /*renderer
|
sprite_col_lights,
|
||||||
.create_texture_immutable_raw(
|
|
||||||
gfx::texture::Kind::D2(
|
|
||||||
tex_size.x,
|
|
||||||
tex_size.y,
|
|
||||||
gfx::texture::AaMode::Single,
|
|
||||||
),
|
|
||||||
gfx::texture::Mipmap::Provided,
|
|
||||||
&[&tex],
|
|
||||||
gfx::texture::SamplerInfo::new(
|
|
||||||
gfx::texture::FilterMethod::Bilinear,
|
|
||||||
gfx::texture::WrapMode::Clamp,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.expect("Failed to upload sprite color and light data to the GPU!"),*/
|
|
||||||
waves: renderer
|
waves: renderer
|
||||||
.create_texture(
|
.create_texture(
|
||||||
&assets::load_expect("voxygen.texture.waves"),
|
&assets::load_expect("voxygen.texture.waves"),
|
||||||
@ -2358,14 +2312,12 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
let max_texture_size = renderer.max_texture_size();
|
let max_texture_size = renderer.max_texture_size();
|
||||||
let atlas_size =
|
let atlas_size =
|
||||||
guillotiere::Size::new(i32::from(max_texture_size), i32::from(max_texture_size));
|
guillotiere::Size::new(i32::from(max_texture_size), i32::from(max_texture_size));
|
||||||
// let atlas_size = guillotiere::Size::new(1, 1);
|
|
||||||
let atlas = AtlasAllocator::with_options(atlas_size, &guillotiere::AllocatorOptions {
|
let atlas = AtlasAllocator::with_options(atlas_size, &guillotiere::AllocatorOptions {
|
||||||
// TODO: Verify some good empirical constants.
|
// TODO: Verify some good empirical constants.
|
||||||
small_size_threshold: 128,
|
small_size_threshold: 128,
|
||||||
large_size_threshold: 1024,
|
large_size_threshold: 1024,
|
||||||
..guillotiere::AllocatorOptions::default()
|
..guillotiere::AllocatorOptions::default()
|
||||||
});
|
});
|
||||||
// renderer.flush();
|
|
||||||
let texture = renderer.create_texture_raw(
|
let texture = renderer.create_texture_raw(
|
||||||
gfx::texture::Kind::D2(
|
gfx::texture::Kind::D2(
|
||||||
max_texture_size,
|
max_texture_size,
|
||||||
@ -2373,8 +2325,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
gfx::texture::AaMode::Single,
|
gfx::texture::AaMode::Single,
|
||||||
),
|
),
|
||||||
1 as gfx::texture::Level,
|
1 as gfx::texture::Level,
|
||||||
// gfx::memory::Upload,
|
gfx::memory::Bind::SHADER_RESOURCE,
|
||||||
gfx::memory::Bind::SHADER_RESOURCE, /* | gfx::memory::Bind::TRANSFER_DST */
|
|
||||||
gfx::memory::Usage::Dynamic,
|
gfx::memory::Usage::Dynamic,
|
||||||
(0, 0),
|
(0, 0),
|
||||||
gfx::format::Swizzle::new(),
|
gfx::format::Swizzle::new(),
|
||||||
@ -2383,33 +2334,10 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
gfx::texture::WrapMode::Clamp,
|
gfx::texture::WrapMode::Clamp,
|
||||||
),
|
),
|
||||||
)?;
|
)?;
|
||||||
/* renderer.flush();
|
|
||||||
let ten_millis = core::time::Duration::from_millis(10);
|
|
||||||
std::thread::sleep(ten_millis);
|
|
||||||
|
|
||||||
renderer.update_texture(
|
|
||||||
&texture,
|
|
||||||
[0, 0],
|
|
||||||
[max_texture_size, max_texture_size],
|
|
||||||
&vec![[0u8; 4]; (usize::from(max_texture_size) * usize::from(max_texture_size))],
|
|
||||||
//&[[255u8; 4]; 64 * 64],
|
|
||||||
// NOTE: Cast is safe since the origin was a u16.
|
|
||||||
)?;
|
|
||||||
renderer.flush(); */
|
|
||||||
// texture.cleanup();
|
|
||||||
// Not sure if this is necessary...
|
|
||||||
// renderer.flush();
|
|
||||||
// texture.update();
|
|
||||||
// // FIXME: Currently, there seems to be a bug where the very first texture
|
|
||||||
// update always // fails. Not sure why, but we currently work around
|
|
||||||
// it with a dummy allocation (which we // proceed to leak, in case the
|
|
||||||
// bug can return after it's freed). let _ = atlas.allocate(guillotiere:
|
|
||||||
// :Size::new(64, 64));
|
|
||||||
Ok((atlas, texture))
|
Ok((atlas, texture))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_chunk_meta(&mut self, _pos: Vec2<i32>, chunk: &TerrainChunkData) {
|
fn remove_chunk_meta(&mut self, _pos: Vec2<i32>, chunk: &TerrainChunkData) {
|
||||||
/* println!("Terrain chunk already existed: {:?}", pos); */
|
|
||||||
self.atlas.deallocate(chunk.col_lights);
|
self.atlas.deallocate(chunk.col_lights);
|
||||||
/* let (zmin, zmax) = chunk.z_bounds;
|
/* let (zmin, zmax) = chunk.z_bounds;
|
||||||
self.z_index_up.remove(Vec3::from(zmin, pos.x, pos.y));
|
self.z_index_up.remove(Vec3::from(zmin, pos.x, pos.y));
|
||||||
@ -2426,15 +2354,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn remove_chunk(&mut self, pos: Vec2<i32>) {
|
fn remove_chunk(&mut self, pos: Vec2<i32>) {
|
||||||
// println!("Terrain chunk removed: {:?}", pos);
|
|
||||||
if let Some(chunk) = self.chunks.remove(&pos) {
|
if let Some(chunk) = self.chunks.remove(&pos) {
|
||||||
self.remove_chunk_meta(pos, &chunk);
|
self.remove_chunk_meta(pos, &chunk);
|
||||||
// Temporarily remember dead chunks for shadowing purposes.
|
// Temporarily remember dead chunks for shadowing purposes.
|
||||||
self.shadow_chunks.push((pos, chunk));
|
self.shadow_chunks.push((pos, chunk));
|
||||||
}
|
}
|
||||||
if let Some(_todo) = self.mesh_todo.remove(&pos) {
|
if let Some(_todo) = self.mesh_todo.remove(&pos) {
|
||||||
/* println!("Terrain chunk was being meshed: {:?}",
|
//Do nothing on todo mesh removal.
|
||||||
* (todo.pos, todo.started_tick)); */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2452,11 +2378,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
loaded_distance: f32,
|
loaded_distance: f32,
|
||||||
view_mat: Mat4<f32>,
|
view_mat: Mat4<f32>,
|
||||||
proj_mat: Mat4<f32>,
|
proj_mat: Mat4<f32>,
|
||||||
) -> (
|
) -> (Aabb<f32>, Vec<math::Vec3<f32>>, math::Aabr<f32>) {
|
||||||
Aabb<f32>,
|
|
||||||
/* Aabb<f32>, Aabb<f32> */ Vec<math::Vec3<f32>>,
|
|
||||||
math::Aabr<f32>,
|
|
||||||
) {
|
|
||||||
let current_tick = scene_data.tick;
|
let current_tick = scene_data.tick;
|
||||||
let current_time = scene_data.state.get_time();
|
let current_time = scene_data.state.get_time();
|
||||||
let mut visible_bounding_box: Option<Aabb<f32>> = None;
|
let mut visible_bounding_box: Option<Aabb<f32>> = None;
|
||||||
@ -2478,7 +2400,6 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
.map(|c| (false, c)),
|
.map(|c| (false, c)),
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// println!("Terrain chunk change: {:?}", (modified, pos));
|
|
||||||
// TODO: ANOTHER PROBLEM HERE!
|
// TODO: ANOTHER PROBLEM HERE!
|
||||||
// What happens if the block on the edge of a chunk gets modified? We need to
|
// What happens if the block on the edge of a chunk gets modified? We need to
|
||||||
// spawn a mesh worker to remesh its neighbour(s) too since their
|
// spawn a mesh worker to remesh its neighbour(s) too since their
|
||||||
@ -2500,7 +2421,6 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if neighbours {
|
if neighbours {
|
||||||
// println!("Insert mesh_todo:: {:?}", (pos, current_tick));
|
|
||||||
self.mesh_todo.insert(pos, ChunkMeshState {
|
self.mesh_todo.insert(pos, ChunkMeshState {
|
||||||
pos,
|
pos,
|
||||||
started_tick: current_tick,
|
started_tick: current_tick,
|
||||||
@ -2521,7 +2441,6 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|(p, _)| *p)
|
.map(|(p, _)| *p)
|
||||||
{
|
{
|
||||||
// println!("Terrain block change: {:?}", pos);
|
|
||||||
let chunk_pos = scene_data.state.terrain().pos_key(pos);
|
let chunk_pos = scene_data.state.terrain().pos_key(pos);
|
||||||
// Only mesh if this chunk has all its neighbors
|
// Only mesh if this chunk has all its neighbors
|
||||||
let mut neighbours = true;
|
let mut neighbours = true;
|
||||||
@ -2535,7 +2454,6 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if neighbours {
|
if neighbours {
|
||||||
// println!("Insert mesh_todo: {:?}", (chunk_pos, current_tick));
|
|
||||||
self.mesh_todo.insert(chunk_pos, ChunkMeshState {
|
self.mesh_todo.insert(chunk_pos, ChunkMeshState {
|
||||||
pos: chunk_pos,
|
pos: chunk_pos,
|
||||||
started_tick: current_tick,
|
started_tick: current_tick,
|
||||||
@ -2566,8 +2484,6 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if neighbours {
|
if neighbours {
|
||||||
// println!("Insert mesh_todo:: {:?}", (neighbour_chunk_pos,
|
|
||||||
// current_tick));
|
|
||||||
self.mesh_todo.insert(neighbour_chunk_pos, ChunkMeshState {
|
self.mesh_todo.insert(neighbour_chunk_pos, ChunkMeshState {
|
||||||
pos: neighbour_chunk_pos,
|
pos: neighbour_chunk_pos,
|
||||||
started_tick: current_tick,
|
started_tick: current_tick,
|
||||||
@ -2673,8 +2589,6 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
// data structure (convert the mesh to a model first of course).
|
// data structure (convert the mesh to a model first of course).
|
||||||
Some(todo) if response.started_tick <= todo.started_tick => {
|
Some(todo) if response.started_tick <= todo.started_tick => {
|
||||||
let started_tick = todo.started_tick;
|
let started_tick = todo.started_tick;
|
||||||
// println!("Finished meshing worker: (pos={:?}, response={:?}, todo={:?})",
|
|
||||||
// response.pos, response.started_tick, todo.started_tick);
|
|
||||||
let load_time = self
|
let load_time = self
|
||||||
.chunks
|
.chunks
|
||||||
.get(&response.pos)
|
.get(&response.pos)
|
||||||
@ -2682,30 +2596,6 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
.unwrap_or(current_time as f32);
|
.unwrap_or(current_time as f32);
|
||||||
// TODO: Allocate new atlas on allocation faillure.
|
// TODO: Allocate new atlas on allocation faillure.
|
||||||
let (tex, tex_size) = response.col_lights_info;
|
let (tex, tex_size) = response.col_lights_info;
|
||||||
/* if self.chunks.len() == 0 {
|
|
||||||
println!("{:?}\n{:?}", tex, tex_size);
|
|
||||||
/*// HACK
|
|
||||||
let (atlas_, col_lights_) = Self::make_atlas(renderer)
|
|
||||||
.expect("Failed to create atlas texture");
|
|
||||||
// renderer.flush();
|
|
||||||
let ten_millis = core::time::Duration::from_millis(1000);
|
|
||||||
std::thread::sleep(ten_millis);
|
|
||||||
if let Err(err) = renderer.update_texture(
|
|
||||||
&self.col_lights,
|
|
||||||
// &col_lights,
|
|
||||||
// NOTE: Cast is safe since the origin was a u16.
|
|
||||||
[0, 0],
|
|
||||||
[1, 1],
|
|
||||||
&[[0u8; 4]],
|
|
||||||
) {
|
|
||||||
panic!("Ahhh {:?}", err);
|
|
||||||
warn!("Failed to update texture: {:?}", err);
|
|
||||||
}
|
|
||||||
renderer.flush();
|
|
||||||
std::thread::sleep(ten_millis);
|
|
||||||
self.atlas = atlas_;
|
|
||||||
self.col_lights = col_lights_; */
|
|
||||||
} */
|
|
||||||
let atlas = &mut self.atlas;
|
let atlas = &mut self.atlas;
|
||||||
let allocation = atlas
|
let allocation = atlas
|
||||||
.allocate(guillotiere::Size::new(
|
.allocate(guillotiere::Size::new(
|
||||||
@ -2713,57 +2603,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
i32::from(tex_size.y),
|
i32::from(tex_size.y),
|
||||||
))
|
))
|
||||||
.expect("Not yet implemented: allocate new atlas on allocation faillure.");
|
.expect("Not yet implemented: allocate new atlas on allocation faillure.");
|
||||||
// println!("Allocation {:?} for {:?} (original size = {:?}... ugh)",
|
// NOTE: Cast is safe since the origin was a u16.
|
||||||
// allocation, response.pos, tex_size); NOTE: Cast is safe
|
|
||||||
// since the origin was a u16.
|
|
||||||
let atlas_offs = Vec2::new(
|
let atlas_offs = Vec2::new(
|
||||||
allocation.rectangle.min.x as u16,
|
allocation.rectangle.min.x as u16,
|
||||||
allocation.rectangle.min.y as u16,
|
allocation.rectangle.min.y as u16,
|
||||||
);
|
);
|
||||||
if atlas_offs == Vec2::zero() {
|
|
||||||
// println!("Model: {:?}",
|
|
||||||
// &response.opaque_mesh.vertices());
|
|
||||||
// println!("Texture: {:?}", tex);
|
|
||||||
}
|
|
||||||
// let atlas_offs : Vec2<u16> = Vec2::zero();
|
|
||||||
/* let col_lights = renderer
|
|
||||||
.create_texture_immutable_raw(
|
|
||||||
gfx::texture::Kind::D2(
|
|
||||||
tex_size.x,
|
|
||||||
tex_size.y,
|
|
||||||
gfx::texture::AaMode::Single,
|
|
||||||
),
|
|
||||||
gfx::texture::Mipmap::Provided,
|
|
||||||
&[&tex],
|
|
||||||
gfx::texture::SamplerInfo::new(
|
|
||||||
gfx::texture::FilterMethod::Bilinear,
|
|
||||||
gfx::texture::WrapMode::Clamp,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.expect("Failed to upload terrain color and light data to the GPU!"); */
|
|
||||||
/* let col_lights = renderer
|
|
||||||
.create_texture_raw(
|
|
||||||
gfx::texture::Kind::D2(
|
|
||||||
tex_size.x,
|
|
||||||
tex_size.y,
|
|
||||||
gfx::texture::AaMode::Single,
|
|
||||||
),
|
|
||||||
1 as gfx::texture::Level,
|
|
||||||
// gfx::memory::Upload,
|
|
||||||
gfx::memory::Bind::SHADER_RESOURCE,
|
|
||||||
gfx::memory::Usage::Dynamic,
|
|
||||||
(0, 0),
|
|
||||||
gfx::format::Swizzle::new(),
|
|
||||||
gfx::texture::SamplerInfo::new(
|
|
||||||
gfx::texture::FilterMethod::Bilinear,
|
|
||||||
gfx::texture::WrapMode::Clamp,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.expect("Failed to upload col lights data to the GPU!"); */
|
|
||||||
if let Err(err) = renderer.update_texture(
|
if let Err(err) = renderer.update_texture(
|
||||||
&self.col_lights,
|
&self.col_lights,
|
||||||
// &col_lights,
|
|
||||||
// NOTE: Cast is safe since the origin was a u16.
|
|
||||||
atlas_offs.into_array(),
|
atlas_offs.into_array(),
|
||||||
tex_size.into_array(),
|
tex_size.into_array(),
|
||||||
&tex,
|
&tex,
|
||||||
@ -2785,27 +2631,10 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
/* shadow_model: renderer
|
col_lights: allocation.id,
|
||||||
.create_model(&response.shadow_mesh)
|
|
||||||
.expect("Failed to upload chunk mesh to the GPU!"), */
|
|
||||||
col_lights: allocation.id,/*ShadowPipeline::create_col_lights(renderer, /*response.col_lights_info*/(tex, tex_size))
|
|
||||||
.expect("Failed to upload chunk light-color texture to the GPU!"),*/
|
|
||||||
/* sprite_instances: response
|
|
||||||
.sprite_instances
|
|
||||||
.into_iter()
|
|
||||||
.map(|(kind, instances)| {
|
|
||||||
(
|
|
||||||
kind,
|
|
||||||
(renderer./*create_consts_immutable*/create_consts(&instances).expect(
|
|
||||||
"Failed to upload chunk sprite instances to the GPU!",
|
|
||||||
), instances.len()),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect(), */
|
|
||||||
sprite_instances: response
|
sprite_instances: response
|
||||||
.sprite_instances
|
.sprite_instances
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
||||||
.map(|(kind, instances)| {
|
.map(|(kind, instances)| {
|
||||||
(
|
(
|
||||||
kind,
|
kind,
|
||||||
@ -2823,7 +2652,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.into_array(),
|
.into_array(),
|
||||||
atlas_offs: Vec4::new(i32::from(atlas_offs.x), i32::from(atlas_offs.y), 0, 0).into_array(),
|
atlas_offs: Vec4::new(
|
||||||
|
i32::from(atlas_offs.x),
|
||||||
|
i32::from(atlas_offs.y),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
.into_array(),
|
||||||
load_time,
|
load_time,
|
||||||
}])
|
}])
|
||||||
.expect("Failed to upload chunk locals to the GPU!"),
|
.expect("Failed to upload chunk locals to the GPU!"),
|
||||||
@ -2835,25 +2670,17 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if response.started_tick == started_tick {
|
if response.started_tick == started_tick {
|
||||||
// println!("Terrain chunk removed from meshing: {:?}", (response.pos,
|
|
||||||
// response.started_tick));
|
|
||||||
self.mesh_todo.remove(&response.pos);
|
self.mesh_todo.remove(&response.pos);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Chunk must have been removed, or it was spawned on an old tick. Drop the mesh
|
// Chunk must have been removed, or it was spawned on an old tick. Drop the mesh
|
||||||
// since it's either out of date or no longer needed.
|
// since it's either out of date or no longer needed.
|
||||||
Some(_todo) => {
|
Some(_todo) => {},
|
||||||
/* println!("Finished meshing worker: (pos={:?}, response={:?}, todo={:?})", response.pos, response.started_tick, todo.started_tick);
|
|
||||||
println!("Terrain chunk removed from meshing due to being out of date: {:?}", (response.pos, response.started_tick));
|
|
||||||
self.mesh_todo.remove(&response.pos); */
|
|
||||||
},
|
|
||||||
None => {},
|
None => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct view frustum
|
// Construct view frustum
|
||||||
let _all_mat = proj_mat * view_mat;
|
|
||||||
//.scaled_3d(Vec3::new(proj_mat[(0, 0)], proj_mat[(1, 1)], 1.0));
|
|
||||||
let focus_off = focus_pos.map(|e| e.trunc());
|
let focus_off = focus_pos.map(|e| e.trunc());
|
||||||
let frustum = Frustum::from_modelview_projection(
|
let frustum = Frustum::from_modelview_projection(
|
||||||
(proj_mat * view_mat * Mat4::translation_3d(-focus_off)).into_col_arrays(),
|
(proj_mat * view_mat * Mat4::translation_3d(-focus_off)).into_col_arrays(),
|
||||||
@ -2861,13 +2688,6 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
|
|
||||||
// Update chunk visibility
|
// Update chunk visibility
|
||||||
let chunk_sz = V::RECT_SIZE.x as f32;
|
let chunk_sz = V::RECT_SIZE.x as f32;
|
||||||
let _scene_bounding_box: Aabb<f32> = Aabb {
|
|
||||||
min: focus_pos - 2.0, /*
|
|
||||||
* - /0.5f32 */
|
|
||||||
max: focus_pos + 2.0, /* + 0.5f32 */
|
|
||||||
};
|
|
||||||
/* let mut shadow_queue =
|
|
||||||
* std::collections::VecDeque::with_capacity(self.chunks.len()); */
|
|
||||||
for (pos, chunk) in &mut self.chunks {
|
for (pos, chunk) in &mut self.chunks {
|
||||||
let chunk_pos = pos.map(|e| e as f32 * chunk_sz);
|
let chunk_pos = pos.map(|e| e as f32 * chunk_sz);
|
||||||
|
|
||||||
@ -2905,22 +2725,12 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
min: Vec3::from(chunk_min),
|
min: Vec3::from(chunk_min),
|
||||||
max: Vec3::from(chunk_max),
|
max: Vec3::from(chunk_max),
|
||||||
};
|
};
|
||||||
// scene_bounding_box.expand_to_contain(chunk_box);
|
|
||||||
|
|
||||||
if in_frustum {
|
if in_frustum {
|
||||||
/* let visible_box = Aabb {
|
|
||||||
min: chunk_box.min - focus_off,
|
|
||||||
max: chunk_box.max - focus_off,
|
|
||||||
};
|
|
||||||
let visible_box = super::fit_psr(all_mat, visible_box, |p| Vec3::from(p) / p.w/*.clamped(-p.w.abs(), p.w.abs())*/)
|
|
||||||
.map(|e| e.clamped(-1.0, 1.0))
|
|
||||||
; */
|
|
||||||
let visible_box = chunk_box;
|
let visible_box = chunk_box;
|
||||||
visible_bounding_box = visible_bounding_box
|
visible_bounding_box = visible_bounding_box
|
||||||
.map(|e| e.union(visible_box))
|
.map(|e| e.union(visible_box))
|
||||||
.or(Some(visible_box));
|
.or(Some(visible_box));
|
||||||
/* shadow_queue.push_back(chunk_box);
|
|
||||||
// shadow_queue.push(chunk_min + chunk_sz * 0.5); */
|
|
||||||
}
|
}
|
||||||
// FIXME: Hack that only works when only the lantern casts point shadows
|
// FIXME: Hack that only works when only the lantern casts point shadows
|
||||||
// (and hardcodes the shadow distance). Should ideally exist per-light, too.
|
// (and hardcodes the shadow distance). Should ideally exist per-light, too.
|
||||||
@ -2929,17 +2739,11 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
|
|
||||||
// PSRs: potential shadow receivers
|
// PSRs: potential shadow receivers
|
||||||
let visible_bounding_box = visible_bounding_box.unwrap_or(Aabb {
|
let visible_bounding_box = visible_bounding_box.unwrap_or(Aabb {
|
||||||
min: focus_pos - 2.0, /*
|
min: focus_pos - 2.0,
|
||||||
* - 0.5 */
|
max: focus_pos + 2.0,
|
||||||
max: focus_pos + 2.0, /* + 0.5 */
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// PSCs: Potential shadow casters
|
// PSCs: Potential shadow casters
|
||||||
let _psc_bounding_box: Aabb<f32> = visible_bounding_box;
|
|
||||||
/*Aabb {
|
|
||||||
min: focus_pos - 0.5f32,
|
|
||||||
max: focus_pos + 0.5f32,
|
|
||||||
}; */
|
|
||||||
let ray_direction = scene_data.get_sun_dir();
|
let ray_direction = scene_data.get_sun_dir();
|
||||||
let collides_with_aabr = |a: math::Aabr<f32>, b: math::Aabr<f32>| {
|
let collides_with_aabr = |a: math::Aabr<f32>, b: math::Aabr<f32>| {
|
||||||
a.min.partial_cmple(&b.max).reduce_and() && a.max.partial_cmpge(&b.min).reduce_and()
|
a.min.partial_cmple(&b.max).reduce_and() && a.max.partial_cmpge(&b.min).reduce_and()
|
||||||
@ -2956,9 +2760,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
min: math::Vec3::from(visible_bounding_box.min.map(f64::from)),
|
min: math::Vec3::from(visible_bounding_box.min.map(f64::from)),
|
||||||
max: math::Vec3::from(visible_bounding_box.max.map(f64::from)),
|
max: math::Vec3::from(visible_bounding_box.max.map(f64::from)),
|
||||||
};
|
};
|
||||||
let inv_proj_view = math::Mat4::from_col_arrays(
|
let inv_proj_view =
|
||||||
(proj_mat * view_mat/* * Mat4::translation_3d(-focus_off)*/).into_col_arrays(),
|
math::Mat4::from_col_arrays((proj_mat * view_mat).into_col_arrays())
|
||||||
)
|
|
||||||
.map(f64::from)
|
.map(f64::from)
|
||||||
.inverted();
|
.inverted();
|
||||||
let ray_direction = math::Vec3::<f32>::from(ray_direction);
|
let ray_direction = math::Vec3::<f32>::from(ray_direction);
|
||||||
@ -2971,44 +2774,16 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
.map(|v| v.map(|e| e as f32))
|
.map(|v| v.map(|e| e as f32))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let cam_pos = math::Vec4::from(view_mat.inverted() * Vec4::unit_w()).xyz()/* + focus_off*/;
|
let cam_pos = math::Vec4::from(view_mat.inverted() * Vec4::unit_w()).xyz();
|
||||||
/* let view_dir = (focus_pos.map(f32::fract)) - cam_pos;
|
let up: math::Vec3<f32> = { math::Vec3::up() };
|
||||||
// let new_dir: Vec3<f32> = light_volume/*visible_light_volume*/.iter().map(|p|
|
|
||||||
// p - cam_pos).sum();
|
|
||||||
let new_dir = view_dir;
|
|
||||||
let new_dir = new_dir.normalized();
|
|
||||||
let dot_prod = f64::from(ray_direction.dot(new_dir));
|
|
||||||
let sin_gamma = (1.0 - dot_prod * dot_prod).sqrt();
|
|
||||||
// let sin_gamma = 0.0;
|
|
||||||
let _new_dir = if sin_gamma > super::EPSILON_GAMMA {
|
|
||||||
new_dir
|
|
||||||
} else {
|
|
||||||
Vec3::from(view_mat * Vec4::from_direction(Vec3::up())).normalized()
|
|
||||||
}; */
|
|
||||||
let up: math::Vec3<f32> = {
|
|
||||||
/* (ray_direction)
|
|
||||||
.cross(new_dir)
|
|
||||||
.cross(ray_direction)
|
|
||||||
.normalized() */
|
|
||||||
math::Vec3::up()
|
|
||||||
};
|
|
||||||
|
|
||||||
let ray_mat = math::Mat4::look_at_rh(
|
let ray_mat = math::Mat4::look_at_rh(cam_pos, cam_pos + ray_direction, up);
|
||||||
cam_pos,
|
|
||||||
cam_pos + ray_direction,
|
|
||||||
up,
|
|
||||||
// Vec3::up(),
|
|
||||||
);
|
|
||||||
// println!("old: {:?} new: {:?}", visible_bounding_box, visible_light_volume);
|
|
||||||
let visible_bounds = math::Aabr::from(math::fit_psr(
|
let visible_bounds = math::Aabr::from(math::fit_psr(
|
||||||
ray_mat,
|
ray_mat,
|
||||||
/* super::aabb_to_points(visible_bounding_box).iter().copied() */
|
|
||||||
visible_light_volume.iter().copied(),
|
visible_light_volume.iter().copied(),
|
||||||
|p| p, //math::Vec3::from(p), /* / p.w */
|
|p| p,
|
||||||
));
|
));
|
||||||
let ray_mat = ray_mat * math::Mat4::translation_3d(-focus_off);
|
let ray_mat = ray_mat * math::Mat4::translation_3d(-focus_off);
|
||||||
/* let visible_bounds_old = Aabr::from(super::fit_psr(ray_mat, super::aabb_to_points(visible_bounding_box).iter().copied(), |p| Vec3::from(p) / p.w));
|
|
||||||
println!("old: {:?} new: {:?}", visible_bounds_old, visible_bounds); */
|
|
||||||
|
|
||||||
let can_shadow_sun = |pos: Vec2<i32>, chunk: &TerrainChunkData| {
|
let can_shadow_sun = |pos: Vec2<i32>, chunk: &TerrainChunkData| {
|
||||||
let chunk_pos = pos.map(|e| e as f32 * chunk_sz);
|
let chunk_pos = pos.map(|e| e as f32 * chunk_sz);
|
||||||
@ -3026,20 +2801,9 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
let chunk_from_light = math::Aabr::from(math::fit_psr(
|
let chunk_from_light = math::Aabr::from(math::fit_psr(
|
||||||
ray_mat,
|
ray_mat,
|
||||||
math::aabb_to_points(chunk_box).iter().copied(),
|
math::aabb_to_points(chunk_box).iter().copied(),
|
||||||
|p| p, /* math::Vec3::from(p)/* / p.w*/ */
|
|p| p,
|
||||||
));
|
));
|
||||||
/* let chunk_from_light = Aabr {
|
|
||||||
min: (ray_mat * Vec4::from_point(chunk_box.min)).xy(),
|
|
||||||
max: (ray_mat * Vec4::from_point(chunk_box.max)).xy(),
|
|
||||||
}.made_valid(); */
|
|
||||||
/* let can_shadow_sun = */
|
|
||||||
collides_with_aabr(chunk_from_light, visible_bounds)
|
collides_with_aabr(chunk_from_light, visible_bounds)
|
||||||
/* let can_shadow_sun_old = collides_with_aabr(chunk_from_light, visible_bounds_old);
|
|
||||||
if can_shadow_sun != can_shadow_sun_old {
|
|
||||||
println!("Different results for chunk {:?} (from light = {:?}):\n\
|
|
||||||
old = {:?} new = {:?}",
|
|
||||||
chunk_box, chunk_from_light, can_shadow_sun_old, can_shadow_sun);
|
|
||||||
} */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle potential shadow casters (chunks that aren't visible, but are still in
|
// Handle potential shadow casters (chunks that aren't visible, but are still in
|
||||||
@ -3078,63 +2842,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
max: math::Vec2::zero(),
|
max: math::Vec2::zero(),
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
/* let cam_pos = Vec3::from(view_mat.inverted() * Vec4::unit_w()) + focus_off; let look_at = visible_box.center();
|
|
||||||
let view_dir = (focus_pos - cam_pos).normalized();
|
|
||||||
let up_vec = ray_direction.cross(view_dir).cross(light_dir).normalized();
|
|
||||||
let sun_light_mat = Mat4::look_at_rh(look_at - ray_direction, look_at, view_dir);
|
|
||||||
let sun_bounding_box = super::fit_psr(all_mat, visible_box, |p| Vec3::from(p) / p.w/*.clamped(-p.w.abs(), p.w.abs())*/)
|
|
||||||
Aabb {
|
|
||||||
min: -0.5,
|
|
||||||
max: 0.5,
|
|
||||||
}; */
|
|
||||||
/* if ray_direction.z < 0.0 && renderer.render_mode().shadow.is_map() {
|
|
||||||
let ray = if ray_direction.x.abs() * scene_bounding_box.size().d > ray_direction.z.abs() * chunk_sz {
|
|
||||||
-ray_direction / ray_direction.x * chunk_sz
|
|
||||||
} else {
|
|
||||||
/* -ray_direction / ray_direction.z * scene_bounding_box.size().d */
|
|
||||||
Vec3::new(0.0, 0.0, scene_bounding_box.size().d)
|
|
||||||
};
|
|
||||||
while let Some(shadow_chunk) = shadow_queue.pop_front() {
|
|
||||||
let collides_with_aabb = |a: Aabb<f32>, b: Aabb<f32>|
|
|
||||||
a.min.partial_cmple(&b.max).reduce_and() &&
|
|
||||||
a.max.partial_cmpge(&b.min).reduce_and();
|
|
||||||
if !collides_with_aabb(scene_bounding_box, shadow_chunk) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let min_chunk_pos = Vec2::from(shadow_chunk.min.map(|e| (e / chunk_sz).floor()))
|
|
||||||
.map(|e: f32| e as i32);
|
|
||||||
let max_chunk_pos = Vec2::from(shadow_chunk.max.map(|e| (e / chunk_sz).ceil()))
|
|
||||||
.map(|e: f32| e as i32);
|
|
||||||
let mut check_chunk = |x, y| {
|
|
||||||
if let Some(mut chunk) = self.chunks.get_mut(&Vec2::new(x, y)) {
|
|
||||||
let (minz, maxz) = chunk.z_bounds;
|
|
||||||
if minz <= shadow_chunk.max.z && maxz >= shadow_chunk.min.z {
|
|
||||||
chunk.can_shadow_sun = true;
|
|
||||||
// NOTE: These casts are safe because the maximum chunk index we are
|
|
||||||
// currently considering is 16384.
|
|
||||||
let x = x as f32;
|
|
||||||
let y = y as f32;
|
|
||||||
psc_bounding_box.expand_to_contain(shadow_chunk.intersection(Aabb {
|
|
||||||
min: Vec3::new(x * chunk_sz, y * chunk_sz, minz),
|
|
||||||
max: Vec3::new((x + 1.0) * chunk_sz, (y + 1.0) * chunk_sz, maxz),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
(min_chunk_pos.y..max_chunk_pos.y).for_each(|y| {
|
|
||||||
(min_chunk_pos.x..max_chunk_pos.x).for_each(|x| {
|
|
||||||
check_chunk(x, y);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
shadow_queue.push_back(Aabb {
|
|
||||||
min: shadow_chunk.min + ray,
|
|
||||||
max: shadow_chunk.max + ray,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
|
|
||||||
(
|
(
|
||||||
/* scene_bounding_box, visible_bounding_box, psc_bounding_box */
|
|
||||||
visible_bounding_box,
|
visible_bounding_box,
|
||||||
visible_light_volume,
|
visible_light_volume,
|
||||||
visible_psr_bounds,
|
visible_psr_bounds,
|
||||||
@ -3155,11 +2864,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
pub fn render_shadows(
|
pub fn render_shadows(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
// lights: &Consts<Light>,
|
(is_daylight, light_data): super::LightData,
|
||||||
shadow_mats: &Consts<ShadowLocals>,
|
|
||||||
light_data: &[Light],
|
|
||||||
is_daylight: bool,
|
|
||||||
focus_pos: Vec3<f32>,
|
focus_pos: Vec3<f32>,
|
||||||
) {
|
) {
|
||||||
if !renderer.render_mode().shadow.is_map() {
|
if !renderer.render_mode().shadow.is_map() {
|
||||||
@ -3177,8 +2883,6 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
})
|
})
|
||||||
.take(self.chunks.len());
|
.take(self.chunks.len());
|
||||||
|
|
||||||
// let is_daylight = sun_dir.z < 0.0/*0.6*/;
|
|
||||||
|
|
||||||
// Directed shadows
|
// Directed shadows
|
||||||
//
|
//
|
||||||
// NOTE: We also render shadows for dead chunks that were found to still be
|
// NOTE: We also render shadows for dead chunks that were found to still be
|
||||||
@ -3192,15 +2896,10 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
.for_each(|chunk| {
|
.for_each(|chunk| {
|
||||||
// Directed light shadows.
|
// Directed light shadows.
|
||||||
renderer.render_terrain_shadow_directed(
|
renderer.render_terrain_shadow_directed(
|
||||||
// &chunk.shadow_model,
|
|
||||||
&chunk.opaque_model,
|
&chunk.opaque_model,
|
||||||
globals,
|
global,
|
||||||
&chunk.locals,
|
&chunk.locals,
|
||||||
shadow_mats,
|
&global.shadow_mats,
|
||||||
/* lights, */
|
|
||||||
/* shadows,
|
|
||||||
* &lod.alt,
|
|
||||||
* &lod.horizon, */
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -3212,17 +2911,11 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
light_data.iter().take(1).for_each(|_light| {
|
light_data.iter().take(1).for_each(|_light| {
|
||||||
chunk_iter.clone().for_each(|chunk| {
|
chunk_iter.clone().for_each(|chunk| {
|
||||||
if chunk.can_shadow_point {
|
if chunk.can_shadow_point {
|
||||||
// shadow_vertex_count += chunk.shadow_model.vertex_range.len();
|
|
||||||
renderer.render_shadow_point(
|
renderer.render_shadow_point(
|
||||||
&chunk.opaque_model,
|
&chunk.opaque_model,
|
||||||
// &chunk.shadow_model,
|
global,
|
||||||
globals,
|
|
||||||
&chunk.locals,
|
&chunk.locals,
|
||||||
shadow_mats,
|
&global.shadow_mats,
|
||||||
/* lights, */
|
|
||||||
/* shadows,
|
|
||||||
* &lod.alt,
|
|
||||||
* &lod.horizon, */
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -3232,14 +2925,9 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
pub fn render(
|
pub fn render(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
lights: &Consts<Light>,
|
|
||||||
shadows: &Consts<Shadow>,
|
|
||||||
shadow_mats: &Consts<ShadowLocals>,
|
|
||||||
lod: &LodData,
|
lod: &LodData,
|
||||||
focus_pos: Vec3<f32>,
|
focus_pos: Vec3<f32>,
|
||||||
/* sun_dir: Vec3<f32>,
|
|
||||||
* light_data: &[Light], */
|
|
||||||
) {
|
) {
|
||||||
let focus_chunk = Vec2::from(focus_pos).map2(TerrainChunk::RECT_SIZE, |e: f32, sz| {
|
let focus_chunk = Vec2::from(focus_pos).map2(TerrainChunk::RECT_SIZE, |e: f32, sz| {
|
||||||
(e as i32).div_euclid(sz as i32)
|
(e as i32).div_euclid(sz as i32)
|
||||||
@ -3252,105 +2940,23 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
})
|
})
|
||||||
.take(self.chunks.len());
|
.take(self.chunks.len());
|
||||||
|
|
||||||
// // Flush renderer to synchronize commands sent on the main encoder with the
|
|
||||||
// // start of the shadow encoder.
|
|
||||||
// renderer.flush();
|
|
||||||
|
|
||||||
// Shadows
|
|
||||||
|
|
||||||
/*scene_data.thread_pool.execute(move || {
|
|
||||||
let _ = send.send(mesh_worker(
|
|
||||||
pos,
|
|
||||||
(min_z as f32, max_z as f32),
|
|
||||||
started_tick,
|
|
||||||
volume,
|
|
||||||
max_texture_size,
|
|
||||||
aabb,
|
|
||||||
));
|
|
||||||
});*/
|
|
||||||
// let mut shadow_vertex_count = 0;
|
|
||||||
/* let is_daylight = sun_dir.z < 0.0/*0.6*/;
|
|
||||||
|
|
||||||
// Directed shadows
|
|
||||||
for (_, chunk) in chunk_iter.clone() {
|
|
||||||
if is_daylight {
|
|
||||||
// Directed light shadows.
|
|
||||||
renderer.render_shadow_directed(
|
|
||||||
// &chunk.shadow_model,
|
|
||||||
&chunk.opaque_model,
|
|
||||||
globals,
|
|
||||||
&chunk.locals,
|
|
||||||
shadow_mats,
|
|
||||||
// lights,
|
|
||||||
// shadows,
|
|
||||||
// &lod.alt,
|
|
||||||
// &lod.horizon,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Point shadows
|
|
||||||
for _light in light_data.iter().take(1) {
|
|
||||||
for (_, chunk) in chunk_iter.clone() {
|
|
||||||
if chunk.can_shadow_point {
|
|
||||||
// shadow_vertex_count += chunk.shadow_model.vertex_range.len();
|
|
||||||
renderer.render_shadow_point(
|
|
||||||
&chunk.opaque_model,
|
|
||||||
// &chunk.shadow_model,
|
|
||||||
globals,
|
|
||||||
&chunk.locals,
|
|
||||||
shadow_mats,
|
|
||||||
// lights,
|
|
||||||
// shadows,
|
|
||||||
// &lod.alt,
|
|
||||||
// &lod.horizon,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush shadows.
|
|
||||||
if is_daylight || light_data.len() > 0 {
|
|
||||||
renderer.flush_shadows();
|
|
||||||
} */
|
|
||||||
|
|
||||||
// Terrain
|
|
||||||
// let mut terrain_vertex_count = 0;
|
|
||||||
for (_, chunk) in chunk_iter {
|
for (_, chunk) in chunk_iter {
|
||||||
// terrain_vertex_count += chunk.opaque_model.vertex_range.len();
|
if chunk.visible == Visibility::Visible {
|
||||||
if chunk.visible == Visibility::Visible
|
|
||||||
/* || chunk.can_shadow_sun() */
|
|
||||||
{
|
|
||||||
renderer.render_terrain_chunk(
|
renderer.render_terrain_chunk(
|
||||||
&chunk.opaque_model,
|
&chunk.opaque_model,
|
||||||
// &chunk.shadow_model,
|
|
||||||
// &chunk.col_lights,
|
|
||||||
&self.col_lights,
|
&self.col_lights,
|
||||||
globals,
|
global,
|
||||||
&chunk.locals,
|
&chunk.locals,
|
||||||
lights,
|
lod,
|
||||||
shadows,
|
|
||||||
shadow_mats,
|
|
||||||
&lod.alt,
|
|
||||||
&lod.horizon,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* println!(
|
|
||||||
"Vertex count (shadow / terrain / ratio): {:?} / {:?} / {:?}",
|
|
||||||
shadow_vertex_count,
|
|
||||||
terrain_vertex_count,
|
|
||||||
shadow_vertex_count as f64 / terrain_vertex_count as f64
|
|
||||||
); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_translucent(
|
pub fn render_translucent(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
globals: &Consts<Globals>,
|
global: &GlobalModel,
|
||||||
lights: &Consts<Light>,
|
|
||||||
shadows: &Consts<Shadow>,
|
|
||||||
shadow_mats: &Consts<ShadowLocals>,
|
|
||||||
lod: &LodData,
|
lod: &LodData,
|
||||||
focus_pos: Vec3<f32>,
|
focus_pos: Vec3<f32>,
|
||||||
cam_pos: Vec3<f32>,
|
cam_pos: Vec3<f32>,
|
||||||
@ -3394,10 +3000,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
chunk_center + chunk_size.x * 0.5 - chunk_size.y * 0.5,
|
chunk_center + chunk_size.x * 0.5 - chunk_size.y * 0.5,
|
||||||
));
|
));
|
||||||
if focus_dist_sqrd < sprite_render_distance.powf(2.0) {
|
if focus_dist_sqrd < sprite_render_distance.powf(2.0) {
|
||||||
for (kind, /*(instances, instance_count)*/instances) in (&chunk.sprite_instances).into_iter()/*.take(1)*/ {
|
for (kind, instances) in (&chunk.sprite_instances).into_iter() {
|
||||||
let SpriteData { model, locals, .. } =
|
let SpriteData { model, locals, .. } = if sprite_config_for(kind.0)
|
||||||
if sprite_config_for(kind.0).map(|config| config.wind_sway >= 0.4).unwrap_or(false) && dist_sqrd <= chunk_mag
|
.map(|config| config.wind_sway >= 0.4)
|
||||||
|| dist_sqrd < sprite_high_detail_distance.powf(2.0) {
|
.unwrap_or(false)
|
||||||
|
&& dist_sqrd <= chunk_mag
|
||||||
|
|| dist_sqrd < sprite_high_detail_distance.powf(2.0)
|
||||||
|
{
|
||||||
&self.sprite_models[&kind][0]
|
&self.sprite_models[&kind][0]
|
||||||
} else if dist_sqrd < sprite_hid_detail_distance.powf(2.0) {
|
} else if dist_sqrd < sprite_hid_detail_distance.powf(2.0) {
|
||||||
&self.sprite_models[&kind][1]
|
&self.sprite_models[&kind][1]
|
||||||
@ -3409,34 +3018,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
&self.sprite_models[&kind][4]
|
&self.sprite_models[&kind][4]
|
||||||
};
|
};
|
||||||
renderer.render_sprites(
|
renderer.render_sprites(
|
||||||
/*Model {
|
|
||||||
vbuf: self.sprite_model_data.vbuf.clone(),
|
|
||||||
vertex_range: /*self.sprite_model_data.vertex_range()*/*/
|
|
||||||
/* if sprite_config_for(kind.0).map(|config| config.wind_sway >= 0.4).unwrap_or(false) && dist_sqrd <= chunk_mag
|
|
||||||
|| dist_sqrd < sprite_high_detail_distance.powf(2.0) {
|
|
||||||
&self.sprite_models[&kind][0].model
|
|
||||||
} else if dist_sqrd < sprite_hid_detail_distance.powf(2.0) {
|
|
||||||
&self.sprite_models[&kind][1].model
|
|
||||||
} else if dist_sqrd < sprite_mid_detail_distance.powf(2.0) {
|
|
||||||
&self.sprite_models[&kind][2].model
|
|
||||||
} else if dist_sqrd < sprite_low_detail_distance.powf(2.0) {
|
|
||||||
&self.sprite_models[&kind][3].model
|
|
||||||
} else {
|
|
||||||
&self.sprite_models[&kind][4].model
|
|
||||||
}/*.clone(),
|
|
||||||
}*/,*/
|
|
||||||
model,
|
model,
|
||||||
&self.sprite_col_lights,
|
&self.sprite_col_lights,
|
||||||
globals,
|
global,
|
||||||
&chunk.locals,
|
&chunk.locals,
|
||||||
locals,
|
locals,
|
||||||
// *instance_count,
|
|
||||||
&instances,
|
&instances,
|
||||||
lights,
|
lod,
|
||||||
shadows,
|
|
||||||
shadow_mats,
|
|
||||||
&lod.alt,
|
|
||||||
&lod.horizon,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3459,13 +3047,9 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
.for_each(|(model, locals)| {
|
.for_each(|(model, locals)| {
|
||||||
renderer.render_fluid_chunk(
|
renderer.render_fluid_chunk(
|
||||||
model,
|
model,
|
||||||
globals,
|
global,
|
||||||
locals,
|
locals,
|
||||||
lights,
|
lod,
|
||||||
shadows,
|
|
||||||
shadow_mats,
|
|
||||||
&lod.alt,
|
|
||||||
&lod.horizon,
|
|
||||||
&self.waves,
|
&self.waves,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user