From c77f05ed93026cd26c4cedca8ebb313dd9c842cf Mon Sep 17 00:00:00 2001 From: Thinkofname Date: Fri, 25 Mar 2016 13:47:31 +0000 Subject: [PATCH] Daylight cycle and make the sky color match vanilla --- src/render/mod.rs | 25 ++++++++++++----- src/server.rs | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 7 deletions(-) diff --git a/src/render/mod.rs b/src/render/mod.rs index 8c0f310..0a493be 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -38,8 +38,6 @@ const ATLAS_SIZE: usize = 1024; // TEMP const NUM_SAMPLES: i32 = 1; -const LIGHT_LEVEL: f32 = 0.8; -const SKY_OFFSET: f32 = 1.0; pub struct Camera { pub pos: cgmath::Point3, @@ -76,6 +74,10 @@ pub struct Renderer { last_width: u32, last_height: u32, + + // Light renderering + pub light_level: f32, + pub sky_offset: f32, } pub struct ChunkBuffer { @@ -219,6 +221,9 @@ impl Renderer { frame_id: 1, trans: None, + + light_level: 0.8, + sky_offset: 1.0, } } @@ -277,7 +282,13 @@ impl Renderer { gl::enable(gl::MULTISAMPLE); - gl::clear_color(14.0 / 255.0, 48.0 / 255.0, 92.0 / 255.0, 1.0); + let time_offset = self.sky_offset * 0.9; + gl::clear_color( + (122.0 / 255.0) * time_offset, + (165.0 / 255.0) * time_offset, + (247.0 / 255.0) * time_offset, + 1.0 + ); gl::clear(gl::ClearFlags::Color | gl::ClearFlags::Depth); // Chunk rendering @@ -286,8 +297,8 @@ impl Renderer { self.chunk_shader.perspective_matrix.set_matrix4(&self.perspective_matrix); self.chunk_shader.camera_matrix.set_matrix4(&self.camera_matrix); self.chunk_shader.texture.set_int(0); - self.chunk_shader.light_level.set_float(LIGHT_LEVEL); - self.chunk_shader.sky_offset.set_float(SKY_OFFSET); + self.chunk_shader.light_level.set_float(self.light_level); + self.chunk_shader.sky_offset.set_float(self.sky_offset); for (pos, info) in world.get_render_list() { if let Some(solid) = info.solid.as_ref() { @@ -308,8 +319,8 @@ impl Renderer { self.chunk_shader_alpha.perspective_matrix.set_matrix4(&self.perspective_matrix); self.chunk_shader_alpha.camera_matrix.set_matrix4(&self.camera_matrix); self.chunk_shader_alpha.texture.set_int(0); - self.chunk_shader_alpha.light_level.set_float(LIGHT_LEVEL); - self.chunk_shader_alpha.sky_offset.set_float(SKY_OFFSET); + self.chunk_shader_alpha.light_level.set_float(self.light_level); + self.chunk_shader_alpha.sky_offset.set_float(self.sky_offset); // Copy the depth buffer trans.main.bind_read(); diff --git a/src/server.rs b/src/server.rs index 55831a0..01f12fa 100644 --- a/src/server.rs +++ b/src/server.rs @@ -31,7 +31,12 @@ use sdl2::keyboard::Keycode; pub struct Server { conn: Option, read_queue: Option>>, + pub world: world::World, + world_age: i64, + world_time: f64, + world_time_target: f64, + tick_time: bool, resources: Arc>, console: Arc>, @@ -146,7 +151,13 @@ impl Server { Ok(Server { conn: Some(write), read_queue: Some(rx), + world: world::World::new(), + world_age: 0, + world_time: 0.0, + world_time_target: 0.0, + tick_time: true, + resources: resources, console: console, version: version, @@ -176,7 +187,12 @@ impl Server { Server { conn: None, read_queue: None, + world: world, + world_age: 0, + world_time: 0.0, + world_time_target: 0.0, + tick_time: true, version: version, resources: resources, @@ -212,6 +228,7 @@ impl Server { ChunkData => on_chunk_data, ChunkUnload => on_chunk_unload, TeleportPlayer => on_teleport, + TimeUpdate => on_time_update, } }, Err(err) => panic!("Err: {:?}", err), @@ -246,12 +263,55 @@ impl Server { self.tick_timer -= 3.0; } + self.update_time(renderer, delta); + // Copy to camera renderer.camera.pos = cgmath::Point::from_vec(self.position + cgmath::Vector3::new(0.0, 1.8, 0.0)); renderer.camera.yaw = self.yaw; renderer.camera.pitch = self.pitch; } + fn update_time(&mut self, renderer: &mut render::Renderer, delta: f64) { + if self.tick_time { + self.world_time_target += delta / 3.0; + self.world_time_target = (24000.0 + self.world_time_target) % 24000.0; + let mut diff = self.world_time_target - self.world_time; + if diff < -12000.0 { + diff = 24000.0 + diff + } else if diff > 12000.0 { + diff = diff - 24000.0 + } + self.world_time += diff * (1.5 / 60.0) * delta; + self.world_time = (24000.0 + self.world_time) % 24000.0; + } else { + self.world_time = self.world_time_target; + } + renderer.sky_offset = self.calculate_sky_offset(); + } + + fn calculate_sky_offset(&self) -> f32 { + use std::f32::consts::PI; + let mut offset = ((1.0 + self.world_time as f32) / 24000.0) - 0.25; + if offset < 0.0 { + offset += 1.0; + } else if offset > 1.0 { + offset -= 1.0; + } + + let prev_offset = offset; + offset = 1.0 - (((offset * PI).cos() + 1.0) / 2.0); + offset = prev_offset + (offset - prev_offset) / 3.0; + + offset = 1.0 - ((offset * PI * 2.0).cos() * 2.0 + 0.2); + if offset > 1.0 { + offset = 1.0; + } else if offset < 0.0 { + offset = 0.0; + } + offset = 1.0 - offset; + offset * 0.8 + 0.2 + } + fn calculate_movement(&self) -> (f64, f64) { use std::f64::consts::PI; let mut forward = 0.0f64; @@ -313,6 +373,17 @@ impl Server { }); } + fn on_time_update(&mut self, time_update: packet::play::clientbound::TimeUpdate) { + self.world_age = time_update.time_of_day; + self.world_time_target = (time_update.time_of_day % 24000) as f64; + if self.world_time_target < 0.0 { + self.world_time_target = -self.world_time_target; + self.tick_time = false; + } else { + self.tick_time = true; + } + } + fn on_teleport(&mut self, teleport: packet::play::clientbound::TeleportPlayer) { // TODO: relative teleports self.position.x = teleport.x;