More layout changes to chunk rendering

This commit is contained in:
Thinkofname 2016-03-24 21:47:11 +00:00
parent 70ccd5cd3d
commit 7692c54cf7
3 changed files with 56 additions and 36 deletions

View File

@ -213,6 +213,8 @@ fn main() {
game.tick(delta); game.tick(delta);
game.server.tick(&mut game.renderer, delta); game.server.tick(&mut game.renderer, delta);
game.renderer.update_camera(width, height);
game.server.world.compute_render_list(&mut game.renderer);
game.chunk_builder.tick(&mut game.server.world, &mut game.renderer, delta); game.chunk_builder.tick(&mut game.server.world, &mut game.renderer, delta);
game.screen_sys.tick(delta, &mut game.renderer, &mut ui_container); game.screen_sys.tick(delta, &mut game.renderer, &mut ui_container);

View File

@ -27,7 +27,7 @@ use image;
use image::GenericImage; use image::GenericImage;
use byteorder::{WriteBytesExt, NativeEndian}; use byteorder::{WriteBytesExt, NativeEndian};
use serde_json; use serde_json;
use cgmath::{self, Vector, Point}; use cgmath::{self, Vector, Point, SquareMatrix};
use world; use world;
use collision; use collision;
@ -66,6 +66,9 @@ pub struct Renderer {
pub camera: Camera, pub camera: Camera,
perspective_matrix: cgmath::Matrix4<f32>, perspective_matrix: cgmath::Matrix4<f32>,
camera_matrix: cgmath::Matrix4<f32>,
pub frustum: collision::Frustum<f32>,
pub view_vector: cgmath::Vector3<f32>,
trans: Option<TransInfo>, trans: Option<TransInfo>,
@ -206,24 +209,17 @@ impl Renderer {
yaw: 0.0, yaw: 0.0,
pitch: ::std::f64::consts::PI, pitch: ::std::f64::consts::PI,
}, },
perspective_matrix: cgmath::Matrix4::zero(), perspective_matrix: cgmath::Matrix4::identity(),
camera_matrix: cgmath::Matrix4::identity(),
frustum: collision::Frustum::from_matrix4(cgmath::Matrix4::identity()).unwrap(),
view_vector: cgmath::Vector3::zero(),
trans: None, trans: None,
} }
} }
pub fn tick(&mut self, world: &mut world::World, delta: f64, width: u32, height: u32) { pub fn update_camera(&mut self, width: u32, height: u32) {
use std::f64::consts::PI as PI64; use std::f64::consts::PI as PI64;
{
let rm = self.resources.read().unwrap();
if rm.version() != self.resource_version {
self.resource_version = rm.version();
trace!("Updating textures to {}", self.resource_version);
self.textures.write().unwrap().update_textures(self.resource_version);
}
}
self.update_textures(delta);
if self.last_height != height || self.last_width != width { if self.last_height != height || self.last_width != width {
self.last_width = width; self.last_width = width;
@ -242,6 +238,33 @@ impl Renderer {
self.init_trans(width, height); self.init_trans(width, height);
} }
self.view_vector = cgmath::Vector3::new(
((self.camera.yaw - PI64/2.0).cos() * -self.camera.pitch.cos()) as f32,
(-self.camera.pitch.sin()) as f32,
(-(self.camera.yaw - PI64/2.0).sin() * -self.camera.pitch.cos()) as f32
);
let camera = cgmath::Point3::new(-self.camera.pos.x as f32, -self.camera.pos.y as f32, self.camera.pos.z as f32);
let camera_matrix = cgmath::Matrix4::look_at(
camera,
camera + cgmath::Point3::new(-self.view_vector.x, -self.view_vector.y, self.view_vector.z).to_vec(),
cgmath::Vector3::new(0.0, -1.0, 0.0)
);
self.camera_matrix = camera_matrix * cgmath::Matrix4::from_nonuniform_scale(-1.0, 1.0, 1.0);
self.frustum = collision::Frustum::from_matrix4(self.perspective_matrix * self.camera_matrix).unwrap();
}
pub fn tick(&mut self, world: &mut world::World, delta: f64, width: u32, height: u32) {
{
let rm = self.resources.read().unwrap();
if rm.version() != self.resource_version {
self.resource_version = rm.version();
trace!("Updating textures to {}", self.resource_version);
self.textures.write().unwrap().update_textures(self.resource_version);
}
}
self.update_textures(delta);
let trans = self.trans.as_mut().unwrap(); let trans = self.trans.as_mut().unwrap();
trans.main.bind(); trans.main.bind();
@ -256,28 +279,13 @@ impl Renderer {
// Chunk rendering // Chunk rendering
self.chunk_shader.program.use_program(); self.chunk_shader.program.use_program();
let view_vector = cgmath::Vector3::new(
((self.camera.yaw - PI64/2.0).cos() * -self.camera.pitch.cos()) as f32,
(-self.camera.pitch.sin()) as f32,
(-(self.camera.yaw - PI64/2.0).sin() * -self.camera.pitch.cos()) as f32
);
let camera = cgmath::Point3::new(-self.camera.pos.x as f32, -self.camera.pos.y as f32, self.camera.pos.z as f32);
let camera_matrix = cgmath::Matrix4::look_at(
camera,
camera + cgmath::Point3::new(-view_vector.x, -view_vector.y, view_vector.z).to_vec(),
cgmath::Vector3::new(0.0, -1.0, 0.0)
);
let camera_matrix = camera_matrix * cgmath::Matrix4::from_nonuniform_scale(-1.0, 1.0, 1.0);
self.chunk_shader.perspective_matrix.set_matrix4(&self.perspective_matrix); self.chunk_shader.perspective_matrix.set_matrix4(&self.perspective_matrix);
self.chunk_shader.camera_matrix.set_matrix4(&camera_matrix); self.chunk_shader.camera_matrix.set_matrix4(&self.camera_matrix);
self.chunk_shader.texture.set_int(0); self.chunk_shader.texture.set_int(0);
self.chunk_shader.light_level.set_float(LIGHT_LEVEL); self.chunk_shader.light_level.set_float(LIGHT_LEVEL);
self.chunk_shader.sky_offset.set_float(SKY_OFFSET); self.chunk_shader.sky_offset.set_float(SKY_OFFSET);
let frustum = collision::Frustum::from_matrix4(self.perspective_matrix * camera_matrix).unwrap(); for (pos, info) in world.get_render_list() {
for (pos, info) in world.get_render_list(&frustum) {
if let Some(solid) = info.solid.as_ref() { if let Some(solid) = info.solid.as_ref() {
self.chunk_shader.offset.set_int3(pos.0, pos.1 * 4096, pos.2); self.chunk_shader.offset.set_int3(pos.0, pos.1 * 4096, pos.2);
solid.array.bind(); solid.array.bind();
@ -292,7 +300,7 @@ impl Renderer {
// Trans chunk rendering // Trans chunk rendering
self.chunk_shader_alpha.program.use_program(); self.chunk_shader_alpha.program.use_program();
self.chunk_shader_alpha.perspective_matrix.set_matrix4(&self.perspective_matrix); self.chunk_shader_alpha.perspective_matrix.set_matrix4(&self.perspective_matrix);
self.chunk_shader_alpha.camera_matrix.set_matrix4(&camera_matrix); self.chunk_shader_alpha.camera_matrix.set_matrix4(&self.camera_matrix);
self.chunk_shader_alpha.texture.set_int(0); self.chunk_shader_alpha.texture.set_int(0);
self.chunk_shader_alpha.light_level.set_float(LIGHT_LEVEL); self.chunk_shader_alpha.light_level.set_float(LIGHT_LEVEL);
self.chunk_shader_alpha.sky_offset.set_float(SKY_OFFSET); self.chunk_shader_alpha.sky_offset.set_float(SKY_OFFSET);

View File

@ -28,12 +28,15 @@ pub mod biome;
pub struct World { pub struct World {
chunks: HashMap<CPos, Chunk, BuildHasherDefault<FNVHash>>, chunks: HashMap<CPos, Chunk, BuildHasherDefault<FNVHash>>,
render_list: Vec<(i32, i32, i32)>,
} }
impl World { impl World {
pub fn new() -> World { pub fn new() -> World {
World { World {
chunks: HashMap::with_hasher(BuildHasherDefault::default()), chunks: HashMap::with_hasher(BuildHasherDefault::default()),
render_list: vec![],
} }
} }
@ -57,21 +60,28 @@ impl World {
} }
} }
pub fn get_render_list(&self, frustum: &collision::Frustum<f32>) -> Vec<((i32, i32, i32), &render::ChunkBuffer)> { pub fn compute_render_list(&mut self, renderer: &mut render::Renderer) {
let mut ret = vec![]; self.render_list.clear();
for (pos, chunk) in &self.chunks { for (pos, chunk) in &self.chunks {
for (y, sec) in chunk.sections.iter().enumerate() { for (y, sec) in chunk.sections.iter().enumerate() {
if let Some(sec) = sec.as_ref() { if let Some(sec) = sec.as_ref() {
let pos = (pos.0, y as i32, pos.1); let pos = (pos.0, y as i32, pos.1);
let min = cgmath::Point3::new(pos.0 as f32 * 16.0, -pos.1 as f32 * 16.0, pos.2 as f32 * 16.0); let min = cgmath::Point3::new(pos.0 as f32 * 16.0, -pos.1 as f32 * 16.0, pos.2 as f32 * 16.0);
let bounds = collision::Aabb3::new(min, min + cgmath::Vector3::new(16.0, -16.0, 16.0)); let bounds = collision::Aabb3::new(min, min + cgmath::Vector3::new(16.0, -16.0, 16.0));
if frustum.contains(bounds) != collision::Relation::Out { if renderer.frustum.contains(bounds) != collision::Relation::Out {
ret.push((pos, &sec.render_buffer)); self.render_list.push(pos);
} }
} }
} }
} }
ret }
pub fn get_render_list(&self) -> Vec<((i32, i32, i32), &render::ChunkBuffer)> {
self.render_list.iter().map(|v| {
let chunk = self.chunks.get(&CPos(v.0, v.2)).unwrap();
let sec = chunk.sections[v.1 as usize].as_ref().unwrap();
(*v, &sec.render_buffer)
}).collect()
} }
pub fn get_section_buffer(&mut self, x: i32, y: i32, z: i32) -> Option<&mut render::ChunkBuffer> { pub fn get_section_buffer(&mut self, x: i32, y: i32, z: i32) -> Option<&mut render::ChunkBuffer> {