mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
125 lines
3.9 KiB
Rust
125 lines
3.9 KiB
Rust
use super::{
|
|
super::{ColLightFmt, Pipeline, TgtColorFmt, TgtDepthStencilFmt},
|
|
shadow, Globals, Light, Shadow,
|
|
};
|
|
use gfx::{
|
|
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
|
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
|
};
|
|
use vek::*;
|
|
|
|
gfx_defines! {
|
|
vertex Vertex {
|
|
pos_norm: u32 = "v_pos_norm",
|
|
atlas_pos: u32 = "v_atlas_pos",
|
|
}
|
|
|
|
constant Locals {
|
|
model_offs: [f32; 3] = "model_offs",
|
|
load_time: f32 = "load_time",
|
|
atlas_offs: [i32; 4] = "atlas_offs",
|
|
}
|
|
|
|
pipeline pipe {
|
|
vbuf: gfx::VertexBuffer<Vertex> = (),
|
|
col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
|
|
|
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
|
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
|
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
|
|
|
point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
|
directed_shadow_maps: gfx::TextureSampler<f32> = "t_directed_shadow_maps",
|
|
|
|
alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
|
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
|
|
|
noise: gfx::TextureSampler<f32> = "t_noise",
|
|
|
|
// Shadow stuff
|
|
light_shadows: gfx::ConstantBuffer<shadow::Locals> = "u_light_shadows",
|
|
|
|
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
|
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))),
|
|
}
|
|
}
|
|
|
|
impl Vertex {
|
|
#[allow(clippy::identity_op)] // TODO: Pending review in #587
|
|
/// NOTE: meta is true when the terrain vertex is touching water.
|
|
pub fn new(atlas_pos: Vec2<u16>, pos: Vec3<f32>, norm: Vec3<f32>, meta: bool) -> Self {
|
|
const EXTRA_NEG_Z: f32 = 32768.0;
|
|
|
|
let norm_bits = 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
|
|
};
|
|
Self {
|
|
pos_norm: ((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,
|
|
atlas_pos: ((atlas_pos.x as u32) & 0xFFFF) << 0 | ((atlas_pos.y as u32) & 0xFFFF) << 16,
|
|
}
|
|
}
|
|
|
|
pub fn new_figure(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 {
|
|
0
|
|
} else {
|
|
1
|
|
};
|
|
let axis_bits = if norm.x != 0.0 {
|
|
0
|
|
} else if norm.y != 0.0 {
|
|
1
|
|
} else {
|
|
2
|
|
};
|
|
Self {
|
|
pos_norm: pos
|
|
.map2(Vec3::new(0, 9, 18), |e, shift| {
|
|
(((e * 2.0 + 256.0) as u32) & 0x1FF) << shift
|
|
})
|
|
.reduce_bitor()
|
|
| (((bone_idx & 0xF) as u32) << 27)
|
|
| (norm_bits << 31),
|
|
atlas_pos: ((atlas_pos.x as u32) & 0x7FFF) << 2
|
|
| ((atlas_pos.y as u32) & 0x7FFF) << 17
|
|
| axis_bits & 3,
|
|
}
|
|
}
|
|
|
|
pub fn make_col_light(
|
|
light: u8,
|
|
col: Rgb<u8>,
|
|
) -> <<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType
|
|
{
|
|
[col.r, col.g, col.b, light]
|
|
}
|
|
}
|
|
|
|
impl Locals {
|
|
pub fn default() -> Self {
|
|
Self {
|
|
model_offs: [0.0; 3],
|
|
load_time: 0.0,
|
|
atlas_offs: [0; 4],
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct TerrainPipeline;
|
|
|
|
impl Pipeline for TerrainPipeline {
|
|
type Vertex = Vertex;
|
|
}
|