diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 87b66ae8a6..83ab013899 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -144,7 +144,7 @@ widget_ids! { pub(self) struct Imgs { //Missing: ActionBar, Health/Mana/Energy Bar & Char Window BG/Frame //Logo - v_logo: ImgId, + //v_logo: ImgId, // Bag bag: ImgId, bag_hover: ImgId, @@ -249,7 +249,7 @@ pub(self) struct Imgs { } impl Imgs { fn new(ui: &mut Ui, renderer: &mut Renderer) -> Imgs { - let mut load = |filename| { + let mut load = |filename, ui: &mut Ui| { let fullpath: String = ["/voxygen/", filename].concat(); let image = image::load_from_memory( assets::load(fullpath.as_str()) @@ -261,113 +261,112 @@ impl Imgs { }; Imgs { // Bag - bag: load("element/buttons/bag/closed.png"), - bag_hover: load("element/buttons/bag/closed_hover.png"), - bag_press: load("element/buttons/bag/closed_press.png"), - bag_open: load("element/buttons/bag/open.png"), - bag_open_hover: load("element/buttons/bag/open_hover.png"), - bag_open_press: load("element/buttons/bag/open_press.png"), - bag_contents: load("element/frames/bag.png"), - inv_grid: load("element/frames/inv_grid.png"), - inv_slot: load("element/buttons/inv_slot.png"), + bag: load("element/buttons/bag/closed.png", ui), + bag_hover: load("element/buttons/bag/closed_hover.png", ui), + bag_press: load("element/buttons/bag/closed_press.png", ui), + bag_open: load("element/buttons/bag/open.png", ui), + bag_open_hover: load("element/buttons/bag/open_hover.png", ui), + bag_open_press: load("element/buttons/bag/open_press.png", ui), + bag_contents: load("element/frames/bag.png", ui), + inv_grid: load("element/frames/inv_grid.png", ui), + inv_slot: load("element/buttons/inv_slot.png", ui), // Close button - close_button: load("element/buttons/x.png"), - close_button_hover: load("element/buttons/x_hover.png"), - close_button_press: load("element/buttons/x_press.png"), + close_button: load("element/buttons/x.png", ui), + close_button_hover: load("element/buttons/x_hover.png", ui), + close_button_press: load("element/buttons/x_press.png", ui), // Esc-Menu - esc_bg: load("element/frames/menu.png"), - fireplace: load("element/misc_backgrounds/fireplace.png"), - button_dark: load("element/buttons/button_dark.png"), - button_dark_hover: load("element/buttons/button_dark_hover.png"), - button_dark_press: load("element/buttons/button_dark_press.png"), + esc_bg: load("element/frames/menu.png", ui), + fireplace: load("element/misc_backgrounds/fireplace.png", ui), + button_dark: load("element/buttons/button_dark.png", ui), + button_dark_hover: load("element/buttons/button_dark_hover.png", ui), + button_dark_press: load("element/buttons/button_dark_press.png", ui), // MiniMap - mmap_frame: load("element/frames/mmap.png"), - mmap_frame_bg: load("element/misc_backgrounds/mmap_bg.png"), - mmap_icons: load("element/buttons/mmap_icons.png"), + mmap_frame: load("element/frames/mmap.png", ui), + mmap_frame_bg: load("element/misc_backgrounds/mmap_bg.png", ui), + mmap_icons: load("element/buttons/mmap_icons.png", ui), // Settings at Mini-Map - mmap_button: load("element/buttons/border.png"), - mmap_button_hover: load("element/buttons/border_mo.png"), - mmap_button_press: load("element/buttons/border_press.png"), - mmap_button_open: load("element/buttons/border_pressed.png"), + mmap_button: load("element/buttons/border.png", ui), + mmap_button_hover: load("element/buttons/border_mo.png", ui), + mmap_button_press: load("element/buttons/border_press.png", ui), + mmap_button_open: load("element/buttons/border_pressed.png", ui), // Skillbar Module - sb_grid: load("element/skill_bar/sbar_grid.png"), - sb_grid_bg: load("element/skill_bar/sbar_grid_bg.png"), - l_click: load("element/skill_bar/l.png"), - r_click: load("element/skill_bar/r.png"), - mana_bar: load("element/skill_bar/mana_bar.png"), - health_bar: load("element/skill_bar/health_bar.png"), - xp_bar: load("element/skill_bar/xp_bar.png"), + sb_grid: load("element/skill_bar/sbar_grid.png", ui), + sb_grid_bg: load("element/skill_bar/sbar_grid_bg.png", ui), + l_click: load("element/skill_bar/l.png", ui), + r_click: load("element/skill_bar/r.png", ui), + mana_bar: load("element/skill_bar/mana_bar.png", ui), + health_bar: load("element/skill_bar/health_bar.png", ui), + xp_bar: load("element/skill_bar/xp_bar.png", ui), //Buff Frame(s) - //buff_frame: load("element/skill_bar/buff_frame.png"), - //buff_frame_bg: load("element/skill_bar/buff_frame_bg.png"), - //buff_frame_red: load("element/skill_bar/buff_frame_red.png"), - //buff_frame_green: load("element/skill_bar/buff_frame_green.png"), + //buff_frame: load("element/skill_bar/buff_frame.png", ui), + //buff_frame_bg: load("element/skill_bar/buff_frame_bg.png", ui), + //buff_frame_red: load("element/skill_bar/buff_frame_red.png", ui), + //buff_frame_green: load("element/skill_bar/buff_frame_green.png", ui), //Missing: Buff Frame Animation (.gif ?!) (we could do animation in ui.maintain(), or in shader?) - window_frame: load("element/frames/window.png"), - window_frame_2: load("element/frames/window_2.png"), + window_frame: load("element/frames/window.png", ui), + window_frame_2: load("element/frames/window_2.png", ui), //Settings Window - settings_bg: load("element/frames/settings.png"), - settings_icon: load("element/icons/settings.png"), - settings_button_mo: load("element/buttons/blue_mo.png"), - check: load("element/buttons/check/no.png"), - check_mo: load("element/buttons/check/no_mo.png"), - check_press: load("element/buttons/check/press.png"), - check_checked: load("element/buttons/check/yes.png"), - check_checked_mo: load("element/buttons/check/yes_mo.png"), - slider: load("element/slider/track.png"), - slider_indicator: load("element/slider/indicator.png"), - button_blank: load("element/nothing.png"), - button_blue_mo: load("element/buttons/blue_mo.png"), - button_blue_press: load("element/buttons/blue_press.png"), + settings_bg: load("element/frames/settings.png", ui), + settings_icon: load("element/icons/settings.png", ui), + settings_button_mo: load("element/buttons/blue_mo.png", ui), + check: load("element/buttons/check/no.png", ui), + check_mo: load("element/buttons/check/no_mo.png", ui), + check_press: load("element/buttons/check/press.png", ui), + check_checked: load("element/buttons/check/yes.png", ui), + check_checked_mo: load("element/buttons/check/yes_mo.png", ui), + slider: load("element/slider/track.png", ui), + slider_indicator: load("element/slider/indicator.png", ui), + button_blank: ui.new_graphic(ui::Graphic::Blank), + button_blue_mo: load("element/buttons/blue_mo.png", ui), + button_blue_press: load("element/buttons/blue_press.png", ui), // Window BG - window_bg: load("element/misc_backgrounds/window_bg.png"), - v_logo: load("element/v_logo.png"), + window_bg: load("element/misc_backgrounds/window_bg.png", ui), //Social Window - social_bg: load("element/misc_backgrounds/small_bg.png"), - social_icon: load("element/icons/social.png"), + social_bg: load("element/misc_backgrounds/small_bg.png", ui), + social_icon: load("element/icons/social.png", ui), //Map Window - map_bg: load("element/misc_backgrounds/small_bg.png"), - map_icon: load("element/icons/map.png"), - map_frame: load("element/frames/window_map.png"), + map_bg: load("element/misc_backgrounds/small_bg.png", ui), + map_icon: load("element/icons/map.png", ui), + map_frame: load("element/frames/window_map.png", ui), // Spell Book Window - spellbook_bg: load("element/misc_backgrounds/small_bg.png"), - spellbook_icon: load("element/icons/spellbook.png"), + spellbook_bg: load("element/misc_backgrounds/small_bg.png", ui), + spellbook_icon: load("element/icons/spellbook.png", ui), //Char Window - charwindow: load("element/misc_backgrounds/charwindow.png"), - charwindow_icon: load("element/icons/charwindow.png"), - charwindow_tab_bg: load("element/frames/tab.png"), - charwindow_tab: load("element/buttons/tab.png"), - charwindow_expbar: load("element/misc_backgrounds/small_bg.png"), - progress_frame: load("element/frames/progress_bar.png"), - progress: load("element/misc_backgrounds/progress.png"), + charwindow: load("element/misc_backgrounds/charwindow.png", ui), + charwindow_icon: load("element/icons/charwindow.png", ui), + charwindow_tab_bg: load("element/frames/tab.png", ui), + charwindow_tab: load("element/buttons/tab.png", ui), + charwindow_expbar: load("element/misc_backgrounds/small_bg.png", ui), + progress_frame: load("element/frames/progress_bar.png", ui), + progress: load("element/misc_backgrounds/progress.png", ui), //Quest-Log Window - questlog_bg: load("element/misc_backgrounds/small_bg.png"), - questlog_icon: load("element/icons/questlog.png"), + questlog_bg: load("element/misc_backgrounds/small_bg.png", ui), + questlog_icon: load("element/icons/questlog.png", ui), // Chat-Arrows - chat_arrow: load("element/buttons/arrow/chat_arrow.png"), - chat_arrow_mo: load("element/buttons/arrow/chat_arrow_mo.png"), - chat_arrow_press: load("element/buttons/arrow/chat_arrow_press.png"), - chat_arrow_up: load("element/buttons/arrow/chat_arrow_up.png"), - chat_arrow_up_mo: load("element/buttons/arrow/chat_arrow_up_mo.png"), - chat_arrow_up_press: load("element/buttons/arrow/chat_arrow_up_press.png"), - chat_arrow_down: load("element/buttons/arrow/chat_arrow_down.png"), - chat_arrow_down_mo: load("element/buttons/arrow/chat_arrow_down_mo.png"), - chat_arrow_down_press: load("element/buttons/arrow/chat_arrow_down_press.png"), + chat_arrow: load("element/buttons/arrow/chat_arrow.png", ui), + chat_arrow_mo: load("element/buttons/arrow/chat_arrow_mo.png", ui), + chat_arrow_press: load("element/buttons/arrow/chat_arrow_press.png", ui), + chat_arrow_up: load("element/buttons/arrow/chat_arrow_up.png", ui), + chat_arrow_up_mo: load("element/buttons/arrow/chat_arrow_up_mo.png", ui), + chat_arrow_up_press: load("element/buttons/arrow/chat_arrow_up_press.png", ui), + chat_arrow_down: load("element/buttons/arrow/chat_arrow_down.png", ui), + chat_arrow_down_mo: load("element/buttons/arrow/chat_arrow_down_mo.png", ui), + chat_arrow_down_press: load("element/buttons/arrow/chat_arrow_down_press.png", ui), } } } diff --git a/voxygen/src/menu/main/ui.rs b/voxygen/src/menu/main/ui.rs index 41e5b17561..ee80b48c7c 100644 --- a/voxygen/src/menu/main/ui.rs +++ b/voxygen/src/menu/main/ui.rs @@ -4,7 +4,10 @@ use crate::{ window::Window, DEFAULT_PUBLIC_SERVER, }; -use common::assets; +use common::{ + assets, + figure::Segment, +}; use conrod_core::{ color, color::TRANSPARENT, @@ -41,6 +44,7 @@ widget_ids! { // Error error_frame, button_ok, + test_vox, } } @@ -62,10 +66,13 @@ struct Imgs { button_dark: ImgId, button_dark_hover: ImgId, button_dark_press: ImgId, + test_vox: ImgId, } impl Imgs { fn new(ui: &mut Ui, renderer: &mut Renderer) -> Imgs { - // TODO: update paths + fn load_segment(filename: &'static str) -> Segment { + Segment::from(dot_vox::load(&(concat!(env!("CARGO_MANIFEST_DIR"), "/../assets/voxygen/").to_string() + filename)).unwrap()) + } let mut load = |filename| { let fullpath: String = ["/voxygen/", filename].concat(); let image = image::load_from_memory( @@ -98,6 +105,7 @@ impl Imgs { button_dark: load("element/buttons/button_dark.png"), button_dark_hover: load("element/buttons/button_dark_hover.png"), button_dark_press: load("element/buttons/button_dark_press.png"), + test_vox: ui.new_graphic(ui::Graphic::Voxel(load_segment("test.vox"))), } } } @@ -178,6 +186,11 @@ impl MainMenuUi { .label_x(Relative::Scalar(-100.0)) .set(self.ids.v_logo, ui_widgets); + Image::new(self.imgs.test_vox) + .w_h(750.0, 750.0) + .top_right_with_margins_on(self.ids.bg, 50.0, 50.0) + .set(self.ids.test_vox, ui_widgets); + // Input fields // Used when the login button is pressed, or enter is pressed within input field macro_rules! login { diff --git a/voxygen/src/ui/graphic.rs b/voxygen/src/ui/graphic.rs index 8e93f8b168..0affe2012f 100644 --- a/voxygen/src/ui/graphic.rs +++ b/voxygen/src/ui/graphic.rs @@ -11,6 +11,7 @@ use vek::*; pub enum Graphic { Image(DynamicImage), Voxel(Segment), + Blank, } #[derive(PartialEq, Eq, Hash, Copy, Clone)] pub struct Id(u32); @@ -41,6 +42,9 @@ impl GraphicCache { id } + pub fn get_graphic(&self, id: Id) -> Option<&Graphic> { + self.graphic_map.get(&id) + } pub fn cache_res(&mut self, graphic_id: Id, dims: Vec2, source: Aabr, mut cacher: F) -> Option> where F: FnMut(Aabr, Vec<[u8; 4]>) { match self.rect_map.get(&(graphic_id, dims, source.map(|e| e.to_bits()))) { //<-------- TODO: Replace this with rounded representation of source Some(aabr) => Some(*aabr), @@ -74,6 +78,7 @@ impl GraphicCache { Graphic::Voxel(segment) => { super::veuc::draw_vox(&segment, aabr.size().into()) } + Graphic::Blank => return None, }; // Draw to allocated area diff --git a/voxygen/src/ui/mod.rs b/voxygen/src/ui/mod.rs index e6015af6c0..f91c83934a 100644 --- a/voxygen/src/ui/mod.rs +++ b/voxygen/src/ui/mod.rs @@ -246,8 +246,6 @@ impl Ui { self.image_map.insert(self.cache.new_graphic(graphic)) } - // TODO: add function that creates a blank graphic - pub fn new_font(&mut self, font: Font) -> FontId { self.ui.fonts.insert(font) } @@ -320,6 +318,7 @@ impl Ui { let mut mesh = Mesh::new(); // TODO: this could be removed entirely if the draw call just used both textures + // however this allows for flexibility if we want to interleave other draw calls later enum State { Image, Plain, @@ -396,6 +395,14 @@ impl Ui { use conrod_core::render::PrimitiveKind; match kind { PrimitiveKind::Image { image_id, color, source_rect } => { + let graphic_id = self.image_map.get(&image_id).expect("Image does not exist in image map"); + let (graphic_cache, cache_tex) = self.cache.graphic_cache_mut_and_tex(); + + match graphic_cache.get_graphic(*graphic_id) { + Some(Graphic::Blank) | None => continue, + _ => {} + } + // Switch to the `Image` state for this image if we're not in it already. if let State::Plain = current_state { self.draw_commands.push(DrawCommand::plain(renderer.create_model(&mesh).unwrap())); @@ -405,7 +412,6 @@ impl Ui { let color = srgb_to_linear(color.unwrap_or(conrod_core::color::WHITE).to_fsa()); - let (graphic_cache, cache_tex) = self.cache.graphic_cache_mut_and_tex(); let resolution = Vec2::new( (rect.w() * p_scale_factor) as u16, @@ -429,7 +435,6 @@ impl Ui { max: Vec2::new(uv_r, uv_t), } }; - let graphic_id = self.image_map.get(&image_id).expect("Image does not exist in image map"); let (cache_w, cache_h) = cache_tex.get_dimensions().map(|e| e as f32).into_tuple(); // Cache graphic at particular resolution diff --git a/voxygen/src/ui/veuc.rs b/voxygen/src/ui/veuc.rs index 65e95f78af..6f89dae2fd 100644 --- a/voxygen/src/ui/veuc.rs +++ b/voxygen/src/ui/veuc.rs @@ -15,54 +15,43 @@ use common::{ use vek::*; -trait Shader { - type VertExtra; - type VsOut: Clone + Interpolate; - fn vert(&self, v_color: Rgba, v_pos: Vec3, vert_extra: &Self::VertExtra) -> (Vec3, Self::VsOut); - fn frag(&self, vs_out: &Self::VsOut) -> Rgba; -} - -struct Voxel where S: Shader { +struct Voxel { mvp: Mat4, - shader: S, } -struct SimpleShader; -impl Shader for SimpleShader { - type VertExtra = (); +#[derive(Copy, Clone)] +struct Vert { + pos: Vec3, + col: Rgb, + norm: Vec3, + ao_level: u8, +} +impl Vert { + fn new(pos: Vec3, col: Rgb, norm: Vec3, ao_level: u8) -> Self { + Vert { + pos, + col, + norm, + ao_level, + } + } +} + +impl<'a> Pipeline for Voxel { + type Vertex = Vert; type VsOut = Rgba; - fn vert(&self, v_color: Rgba, v_pos: Vec3, _: &Self::VertExtra) -> (Vec3, Self::VsOut) { - ( - v_pos, - v_color, - ) - } - fn frag(&self, vs_out: &Self::VsOut) -> Rgba { - *vs_out - } -} - -impl<'a, S> Pipeline for Voxel where S: Shader { - type Vertex = (Vec3, Rgb, S::VertExtra); - type VsOut = S::VsOut; type Pixel = [u8; 4]; #[inline(always)] - fn vert(&self, (v_pos, v_color, v_extra): &Self::Vertex) -> ([f32; 3], Self::VsOut) { - let (pos, out) = self.shader.vert( - srgb_to_linear(Rgba::from_opaque(*v_color)), - Vec3::from(self.mvp * Vec4::from_point(*v_pos)), - v_extra, - ); - ( - pos.into_array(), - out, - ) + fn vert(&self, Vert { pos, col, norm, ao_level}: &Self::Vertex) -> ([f32; 3], Self::VsOut) { + let light = Rgba::from_opaque(Rgb::from(*ao_level as f32 / 4.0 + 0.25)); + let color = light * srgb_to_linear(Rgba::from_opaque(*col)); + let position = Vec3::from(self.mvp * Vec4::from_point(*pos)).into_array(); + (position, color) } #[inline(always)] - fn frag(&self, vs_out: &Self::VsOut) -> Self::Pixel { - let color = self.shader.frag(vs_out); - linear_to_srgb(color).map(|e| (e * 255.0) as u8).into_array() + fn frag(&self, color: &Self::VsOut) -> Self::Pixel { + linear_to_srgb(*color).map(|e| (e * 255.0) as u8).into_array() } } @@ -71,14 +60,17 @@ pub fn draw_vox(segment: &Segment, output_size: Vec2) -> Vec<[u8; 4]> { let mut color = Buffer2d::new(dims, [50; 4]); let mut depth = Buffer2d::new(dims, 1.0); + let (w, h, d) = segment.get_size().map(|e| e as f32).into_tuple(); + let mvp = - Mat4::rotation_y(0.6) * - Mat4::::scaling_3d(1.0 / 14.0) * - Mat4::translation_2d([-14.0, -14.0]) * - Mat4::rotation_x(-std::f32::consts::PI / 2.0 ); + Mat4::::orthographic_rh_no(FrustumPlanes { + left: -1.0, right: 1.0, bottom: -1.0, top: 1.0, + near: 0.0, far: 1.0 + }) * + Mat4::scaling_3d(2.0 / w.max(h)) * + Mat4::translation_3d([-w / 2.0, -h / 2.0, -d / 2.0]); Voxel { mvp, - shader: SimpleShader, } .draw::, _>( &generate_mesh(segment, Vec3::from(0.0)), @@ -90,25 +82,46 @@ pub fn draw_vox(segment: &Segment, output_size: Vec2) -> Vec<[u8; 4]> { color.as_ref().to_vec() } -type Vert = as Pipeline>::Vertex; - -// TODO: generalise meshing code +fn ao_level(side1: bool, corner: bool, side2: bool) -> u8 { + if side1 && side2 { + 0 + } else { + 3 - [side1, corner, side2].iter().filter(|e| **e).count() as u8 + } +} +// TODO: generalize meshing code.... fn create_quad( origin: Vec3, unit_x: Vec3, unit_y: Vec3, - //norm: Vec3, + norm: Vec3, col: Rgb, + occluders: [bool; 8], ) -> [Vert; 6] { - let a = (origin, col, ()); - let b = (origin + unit_x, col, ()); - let c = (origin + unit_x + unit_y, col, ()); - let d = (origin + unit_y, col, ()); + + let a_ao = ao_level(occluders[0], occluders[1], occluders[2]); + let b_ao = ao_level(occluders[2], occluders[3], occluders[4]); + let c_ao = ao_level(occluders[4], occluders[5], occluders[6]); + let d_ao = ao_level(occluders[6], occluders[7], occluders[0]); + + let a = Vert::new(origin, col, norm, a_ao); + let b = Vert::new(origin + unit_x, col, norm, b_ao); + let c = Vert::new(origin + unit_x + unit_y, col, norm, c_ao); + let d = Vert::new(origin + unit_y, col, norm, d_ao); + + // Flip to fix anisotropy + let (a, b, c, d) = if a_ao + c_ao > b_ao + d_ao { + (d, a, b, c) + } else { + (a, b, c, d) + }; + [ a, b, c, // Tri 1 c, d, a, // Tri 2 ] } + fn generate_mesh(segment: &Segment, offs: Vec3) -> Vec { let mut vertices = Vec::new(); @@ -120,82 +133,120 @@ fn generate_mesh(segment: &Segment, offs: Vec3) -> Vec { { let col = col.map(|e| e as f32 / 255.0); + let is_empty = |pos| { + segment.get(pos) + .map(|v| v.is_empty()) + .unwrap_or(true) + }; + + let occluders = |unit_x, unit_y, dir| { + // would be nice to generate unit_x and unit_y from a given direction + [ + !is_empty(pos + dir - unit_x), + !is_empty(pos + dir - unit_x - unit_y), + !is_empty(pos + dir - unit_y), + !is_empty(pos + dir + unit_x - unit_y), + !is_empty(pos + dir + unit_x), + !is_empty(pos + dir + unit_x + unit_y), + !is_empty(pos + dir + unit_y), + !is_empty(pos + dir - unit_x + unit_y), + ] + }; + // -x - if segment.get(pos - Vec3::unit_x()) - .map(|v| v.is_empty()) - .unwrap_or(true) + if is_empty(pos - Vec3::unit_x()) { vertices.extend_from_slice(&create_quad( offs + pos.map(|e| e as f32) + Vec3::unit_y(), -Vec3::unit_y(), Vec3::unit_z(), - //-Vec3::unit_x(), + -Vec3::unit_x(), col, + occluders( + -Vec3::unit_y(), + Vec3::unit_z(), + -Vec3::unit_x(), + ), )); } // +x - if segment.get(pos + Vec3::unit_x()) - .map(|v| v.is_empty()) - .unwrap_or(true) + if is_empty(pos + Vec3::unit_x()) { - vertices.extend_from_slice(&create_quad( + vertices.extend_from_slice(&create_quad( offs + pos.map(|e| e as f32) + Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z(), - //Vec3::unit_x(), + Vec3::unit_x(), col, + occluders( + Vec3::unit_y(), + Vec3::unit_z(), + Vec3::unit_x(), + ), )); } // -y - if segment.get(pos - Vec3::unit_y()) - .map(|v| v.is_empty()) - .unwrap_or(true) + if is_empty(pos - Vec3::unit_y()) { - vertices.extend_from_slice(&create_quad( + vertices.extend_from_slice(&create_quad( offs + pos.map(|e| e as f32), Vec3::unit_x(), Vec3::unit_z(), - //-Vec3::unit_y(), + -Vec3::unit_y(), col, + occluders( + Vec3::unit_x(), + Vec3::unit_z(), + -Vec3::unit_y(), + ), )); } // +y - if segment.get(pos + Vec3::unit_y()) - .map(|v| v.is_empty()) - .unwrap_or(true) + if is_empty(pos + Vec3::unit_y()) { - vertices.extend_from_slice(&create_quad( + vertices.extend_from_slice(&create_quad( offs + pos.map(|e| e as f32) + Vec3::unit_y(), Vec3::unit_z(), Vec3::unit_x(), - //Vec3::unit_y(), + Vec3::unit_y(), col, + occluders( + Vec3::unit_z(), + Vec3::unit_x(), + Vec3::unit_y(), + ), )); } // -z - if segment.get(pos - Vec3::unit_z()) - .map(|v| v.is_empty()) - .unwrap_or(true) + if is_empty(pos - Vec3::unit_z()) { - vertices.extend_from_slice(&create_quad( + vertices.extend_from_slice(&create_quad( offs + pos.map(|e| e as f32), Vec3::unit_y(), Vec3::unit_x(), - //-Vec3::unit_z(), + -Vec3::unit_z(), col, + occluders( + Vec3::unit_y(), + Vec3::unit_x(), + -Vec3::unit_z(), + ), )); } // +z - if segment.get(pos + Vec3::unit_z()) - .map(|v| v.is_empty()) - .unwrap_or(true) + if is_empty(pos + Vec3::unit_z()) { - vertices.extend_from_slice(&create_quad( + vertices.extend_from_slice(&create_quad( offs + pos.map(|e| e as f32) + Vec3::unit_z(), Vec3::unit_x(), Vec3::unit_y(), - //Vec3::unit_z(), + Vec3::unit_z(), col, + occluders( + Vec3::unit_x(), + Vec3::unit_y(), + Vec3::unit_z(), + ), )); } } @@ -206,23 +257,15 @@ fn generate_mesh(segment: &Segment, offs: Vec3) -> Vec { // TODO: put these in utility a module #[inline(always)] -fn to_linear(x: f32) -> f32 { - if x <= 0.04045 { - x / 12.92 - } else { - ((x + 0.055) / 1.055).powf(2.4) - } -} -#[inline(always)] -fn to_srgb(x: f32) -> f32 { - if x <= 0.0031308 { - x * 12.92 - } else { - x.powf(1.0 / 2.4) * 1.055 - 0.055 - } -} -#[inline(always)] fn srgb_to_linear(c: Rgba) -> Rgba { + #[inline(always)] + fn to_linear(x: f32) -> f32 { + if x <= 0.04045 { + x / 12.92 + } else { + ((x + 0.055) / 1.055).powf(2.4) + } + } Rgba { r: to_linear(c.r), g: to_linear(c.g), @@ -232,6 +275,14 @@ fn srgb_to_linear(c: Rgba) -> Rgba { } #[inline(always)] fn linear_to_srgb(c: Rgba) -> Rgba { + #[inline(always)] + fn to_srgb(x: f32) -> f32 { + if x <= 0.0031308 { + x * 12.92 + } else { + x.powf(1.0 / 2.4) * 1.055 - 0.055 + } + } Rgba { r: to_srgb(c.r), g: to_srgb(c.g),