alex/beta-minecraft-rust
Minecraft Beta 1.7.3 Rewrite
BRANCH main
SNAPSHOT Draw terrain GPU-driven from packed per-section buffers with GPU occlusion culling, add a render distance slider (2-128) with a quad/disk shape, cut chunk bookkeeping at high render distances, and fix a light underflow at y=0
DOWNLOAD
root crates client src render scene signs.rs
//! `TileEntitySignRenderer`: sign boards and posts with their text.
use common::world::shape::BlockView;
use common::world::{Block, ChunkPos};
use glam::{DVec3, Mat4, Vec3};
use super::Geometry;
use super::models::{Model, Part};
use crate::world::ClientWorld;
const SIGN: i32 = crate::assets::entity_texture("item/sign.png");
impl Geometry {
pub fn signs(
&mut self,
world: &ClientWorld,
eye: DVec3,
font: &crate::gui::Geometry,
sky_darkness: u32,
) {
let start = self.vertices.len() as u32;
let center = ChunkPos::containing(
common::math::floor_f64(eye.x),
common::math::floor_f64(eye.z),
);
for ([x, y, z], lines) in world.signs_near(center, 4) {
let origin = DVec3::new(f64::from(x), f64::from(y), f64::from(z)) + 0.5;
// `TileEntityRenderer` only draws tile entities within 64 blocks
if origin.distance_squared(eye) >= 4096.0 {
continue;
}
let block = world.block(x, y, z);
let metadata = world.metadata(x, y, z);
let brightness = super::brightness_at(world, origin, sky_darkness);
let size = 2.0_f32 / 3.0;
let anchor = origin.with_y(f64::from(y) + 0.75 * f64::from(size));
let mut transform = Mat4::from_translation((anchor - eye).as_vec3());
let post = block == Block::SIGN;
if post {
transform *=
Mat4::from_rotation_y((-f32::from(metadata) * 360.0 / 16.0).to_radians());
} else {
let angle: f32 = match metadata {
2 => 180.0,
4 => 90.0,
5 => -90.0,
_ => 0.0,
};
transform *= Mat4::from_rotation_y((-angle).to_radians())
* Mat4::from_translation(Vec3::new(0.0, -5.0 / 16.0, -7.0 / 16.0));
}
let board = transform * Mat4::from_scale(Vec3::new(size, -size, -size));
let mut model = Model::new(self, board, SIGN, brightness);
model.transform /= 16.0;
model.part(Part::new(
[-12.0, -14.0, -1.0],
[24.0, 12.0, 2.0],
[0.0; 3],
[0.0, 0.0],
));
if post {
model.part(Part::new(
[-1.0, -2.0, -1.0],
[2.0, 14.0, 2.0],
[0.0; 3],
[0.0, 14.0],
));
}
let scale = size / 60.0;
let text = transform
* Mat4::from_translation(Vec3::new(0.0, 0.5 * size, 0.07 * size))
* Mat4::from_scale(Vec3::new(scale, -scale, scale));
for (i, line) in lines.iter().enumerate() {
let (glyphs, width) = font.layout(line, 0xff000000);
let left = -(width / 2.0).floor();
let top = i as f32 * 10.0 - lines.len() as f32 * 5.0;
self.glyphs(glyphs, Vec3::new(left, top, 0.0), text);
}
}
self.signs = start..self.vertices.len() as u32;
}
}