aboutsummaryrefslogtreecommitdiff
path: root/src/render/mod.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2022-10-17 20:40:21 +0200
committermetamuffin <metamuffin@disroot.org>2022-10-17 20:40:21 +0200
commit781dc2ade098b0cb4e3e68a03477476dbadbf985 (patch)
tree709f6f1a464d3997b29f65c0baea3a458aac5dad /src/render/mod.rs
parentd55dc04fd9f223ada252a6d9e71cabde5f6dd355 (diff)
downloadtrash-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.rs102
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
+ }
+}