veloren/voxygen/src/render/pipelines/figure.rs

110 lines
3.2 KiB
Rust
Raw Normal View History

use super::{
2020-04-04 19:36:55 +00:00
super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthStencilFmt},
2019-09-25 12:00:00 +00:00
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,
2020-04-04 19:36:55 +00:00
state::{ColorMask, Comparison, Stencil, StencilOp},
};
use vek::*;
gfx_defines! {
vertex Vertex {
pos_norm: u32 = "v_pos_norm",
col: u32 = "v_col",
// BBBBBBAA
// B = Bone
// A = AO
ao_bone: u8 = "v_ao_bone",
}
constant Locals {
model_mat: [[f32; 4]; 4] = "model_mat",
model_col: [f32; 4] = "model_col",
2020-04-04 19:36:55 +00:00
flags: u32 = "flags",
}
constant BoneData {
bone_mat: [[f32; 4]; 4] = "bone_mat",
}
pipeline pipe {
vbuf: gfx::VertexBuffer<Vertex> = (),
locals: gfx::ConstantBuffer<Locals> = "u_locals",
globals: gfx::ConstantBuffer<Globals> = "u_globals",
bones: gfx::ConstantBuffer<BoneData> = "u_bones",
2019-07-21 15:04:36 +00:00
lights: gfx::ConstantBuffer<Light> = "u_lights",
2019-09-25 12:00:00 +00:00
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
2019-11-17 22:41:00 +00:00
noise: gfx::TextureSampler<f32> = "t_noise",
2020-04-04 19:36:55 +00:00
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Replace))),
}
}
impl Vertex {
#[allow(clippy::collapsible_if)]
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>, col: Rgb<f32>, ao: f32, bone_idx: u8) -> Self {
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
.map2(Vec3::new(0, 9, 18), |e, shift| {
(((e * 2.0 + 256.0) as u32) & 0x3FF) << shift
})
.reduce_bitor()
| (norm_bits << 29),
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),
}
}
pub fn with_bone_idx(mut self, bone_idx: u8) -> Self {
self.ao_bone = (self.ao_bone & 0b11) | (bone_idx << 2);
self
}
}
impl Locals {
2020-04-04 19:36:55 +00:00
pub fn new(model_mat: Mat4<f32>, col: Rgba<f32>, is_player: bool) -> Self {
let mut flags = 0;
flags |= is_player as u32;
Self {
model_mat: arr_to_mat(model_mat.into_col_array()),
model_col: col.into_array(),
2020-04-04 19:36:55 +00:00
flags,
}
}
}
impl Default for Locals {
2020-04-04 19:36:55 +00:00
fn default() -> Self { Self::new(Mat4::identity(), Rgba::broadcast(1.0), false) }
}
impl BoneData {
pub fn new(bone_mat: Mat4<f32>) -> Self {
Self {
bone_mat: arr_to_mat(bone_mat.into_col_array()),
}
}
pub fn default() -> Self { Self::new(Mat4::identity()) }
}
pub struct FigurePipeline;
impl Pipeline for FigurePipeline {
type Vertex = Vertex;
}