diff options
author | metamuffin <metamuffin@disroot.org> | 2022-10-17 20:40:21 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2022-10-17 20:40:21 +0200 |
commit | 781dc2ade098b0cb4e3e68a03477476dbadbf985 (patch) | |
tree | 709f6f1a464d3997b29f65c0baea3a458aac5dad /src/render/mod.rs | |
parent | d55dc04fd9f223ada252a6d9e71cabde5f6dd355 (diff) | |
download | trash-map-781dc2ade098b0cb4e3e68a03477476dbadbf985.tar trash-map-781dc2ade098b0cb4e3e68a03477476dbadbf985.tar.bz2 trash-map-781dc2ade098b0cb4e3e68a03477476dbadbf985.tar.zst |
works
Diffstat (limited to 'src/render/mod.rs')
-rw-r--r-- | src/render/mod.rs | 102 |
1 files changed, 100 insertions, 2 deletions
diff --git a/src/render/mod.rs b/src/render/mod.rs index cd9856e..293e566 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -1,3 +1,101 @@ -pub mod processing; -pub mod models; +use std::time::Instant; + +use chashmap::{CHashMap, ReadGuard}; +use image::ImageBuffer; +use log::info; + +use crate::{ + dimension::Dimension, + render::{ + composite::image_buffer_blit, + models::{block_properties, processed_block_texture}, + }, +}; + +use self::processing::Texture; pub mod composite; +pub mod models; +pub mod processing; + +const SEG_SIZE: isize = 128; +const BLOCK_NAMESPACE_LEN: usize = "minecraft:".len(); + +pub struct Renderer { + dimension: Dimension, + textures: CHashMap<String, Texture>, +} +impl Renderer { + pub fn new(dimension: Dimension) -> Self { + Self { + dimension, + textures: Default::default(), + } + } + pub fn load_texture(&self, name: &str) -> ReadGuard<'_, std::string::String, Texture> { + match self.textures.contains_key(name) { + true => self.textures.get(name).unwrap(), + false => { + self.textures + .insert(name.to_owned(), processed_block_texture(name)); + self.load_texture(name) + } + } + } + + pub fn render_segment(&self, sx: isize, sy: isize) -> Texture { + let start_time = Instant::now(); + + let solid = |x: isize, y: isize, z: isize| { + self.dimension + .block(x, y, z) + .map(|b| block_properties(&b.name()[BLOCK_NAMESPACE_LEN..])) + .unwrap_or((true, true)) + }; + + let mut view: Texture = + ImageBuffer::new(16 * (SEG_SIZE + 1) as u32, 16 * (SEG_SIZE + 1) as u32); + + let mut visible = Vec::<((isize, isize, isize), (isize, isize, isize))>::new(); + + for ix in (sx * SEG_SIZE)..((sx + 1) * SEG_SIZE) { + for iy in (sy * (SEG_SIZE * 2))..((sy + 1) * (SEG_SIZE * 2)) { + for off in 0..=1 { + let mut y = 319; + let mut x = -ix + iy; + let mut z = ix + iy + off; + loop { + let (solid, has_texture) = solid(x, y, z); + if has_texture { + visible.push(((x, y, z), (ix, iy, off))); + } + if solid { + break; + } + y -= 1; + x -= 1; + z -= 1; + } + } + } + } + info!("{} visible blocks", visible.len()); + visible.sort_by_cached_key(|((x, y, z), _)| x + y + z); + + info!("compositing textures"); + for ((x, y, z), (ix, iy, off)) in visible { + let name = match self.dimension.block(x, y, z) { + Some(block) => block.name().to_owned(), + None => "minecraft:debug".to_owned(), + }; + let name = &name[BLOCK_NAMESPACE_LEN..]; + let texture = &self.load_texture(name); + let ix = ix * 16 + off * 8; + let iy = iy * 8 + off * 4; + image_buffer_blit(&mut view, texture, (ix as u32, iy as u32)); + } + + let end_time = Instant::now(); + info!("segment rendered in {:?}", end_time - start_time); + view + } +} |