aboutsummaryrefslogtreecommitdiff
path: root/src/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/render')
-rw-r--r--src/render/composite.rs31
-rw-r--r--src/render/mod.rs102
-rw-r--r--src/render/models.rs12
3 files changed, 126 insertions, 19 deletions
diff --git a/src/render/composite.rs b/src/render/composite.rs
index 7409478..99950f1 100644
--- a/src/render/composite.rs
+++ b/src/render/composite.rs
@@ -1,8 +1,5 @@
use image::ImageBuffer;
use image::Rgba;
-
-use crate::SEG_SIZE;
-
pub const REGION_SIZE: usize = 16 * 8;
pub const CHUNK_HEIGHT: usize = 320;
pub const CHUNK_SIZE: usize = 16;
@@ -28,21 +25,21 @@ pub fn image_buffer_blit(
}
}
-pub fn isometric_coord_mapping(x: i32, y: i32, z: i32) -> (u32, u32) {
- // const BASE_X: i32 = 1016;
- const BASE_X: i32 = (SEG_SIZE as i32 * 8) - 8;
- const BASE_Y: i32 = 2040;
+// pub fn isometric_coord_mapping(x: i32, y: i32, z: i32) -> (u32, u32) {
+// // const BASE_X: i32 = 1016;
+// const BASE_X: i32 = (SEG_SIZE as i32 * 8) - 8;
+// const BASE_Y: i32 = 2040;
- const XDIFF: (i32, i32) = (-8, 4);
- const ZDIFF: (i32, i32) = (8, 4);
- const YDIFF: (i32, i32) = (0, -8);
+// const XDIFF: (i32, i32) = (-8, 4);
+// const ZDIFF: (i32, i32) = (8, 4);
+// const YDIFF: (i32, i32) = (0, -8);
- let diff = (
- XDIFF.0 * x + YDIFF.0 * y + ZDIFF.0 * z,
- XDIFF.1 * x + YDIFF.1 * y + ZDIFF.1 * z,
- );
+// let diff = (
+// XDIFF.0 * x + YDIFF.0 * y + ZDIFF.0 * z,
+// XDIFF.1 * x + YDIFF.1 * y + ZDIFF.1 * z,
+// );
- let coords = (BASE_X + diff.0, BASE_Y + diff.1);
+// let coords = (BASE_X + diff.0, BASE_Y + diff.1);
- (coords.0 as u32, coords.1 as u32)
-}
+// (coords.0 as u32, coords.1 as u32)
+// }
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
+ }
+}
diff --git a/src/render/models.rs b/src/render/models.rs
index 24e7817..4a8673d 100644
--- a/src/render/models.rs
+++ b/src/render/models.rs
@@ -37,3 +37,15 @@ pub fn processed_block_texture(name: &str) -> ImageBuffer<Rgba<u8>, Vec<u8>> {
}
}
}
+
+pub fn block_properties(name: &str) -> (bool, bool) {
+ match name {
+ "air" | "cave_air" => (false, false),
+
+ "oak_leaves" | "birch_leaves" | "acacia_leaves" | "jungle_leaves" | "dark_oak_leaves"
+ | "spruce_leaves" => (false, true),
+ "water" => (false, true),
+
+ _ => (true, true),
+ }
+}