Combining colors and LOD.

This commit is contained in:
Joshua Yanovski 2020-04-02 06:49:27 +02:00
parent 88342640c6
commit ed2d0111d9
4 changed files with 38 additions and 21 deletions

View File

@ -15,8 +15,8 @@ out vec4 tgt_color;
void main() { void main() {
vec4 _clouds; vec4 _clouds;
/* vec3 cam_dir = normalize(f_pos - cam_pos.xyz); vec3 cam_dir = normalize(f_pos - cam_pos.xyz);
vec3 world_pos = cam_pos.xyz + cam_dir * 500000.0; /* vec3 world_pos = cam_pos.xyz + cam_dir * 500000.0;
tgt_color = vec4(get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, world_pos, 1.0, true, _clouds), 1.0); */ tgt_color = vec4(get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, world_pos, 1.0, true, _clouds), 1.0); */
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x); float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
@ -24,7 +24,7 @@ void main() {
if (medium.x == 1u) { if (medium.x == 1u) {
dist = UNDERWATER_MIST_DIST; dist = UNDERWATER_MIST_DIST;
} }
vec3 wpos = cam_pos.xyz + normalize(f_pos) * dist; vec3 wpos = cam_pos.xyz + /*normalize(f_pos)*/cam_dir * dist;
tgt_color = vec4(get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, wpos, 1.0, true, _clouds), 1.0); tgt_color = vec4(get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, wpos, 1.0, true, _clouds), 1.0);
} }

View File

@ -71,6 +71,15 @@ pub struct Client {
client_state: ClientState, client_state: ClientState,
thread_pool: ThreadPool, thread_pool: ThreadPool,
pub server_info: ServerInfo, pub server_info: ServerInfo,
/// Just the "base" layer for LOD; currently includes colors and a 1-byte
/// approximation for height. In the future we'll add more layers, like
/// shadows, rivers, and probably foliage, cities, roads, and other
/// structures.
pub lod_base: Arc<DynamicImage>,
/// A fully rendered map image for use with the map and minimap; note that
/// this can be constructed dynamically by combining the layers of world
/// map data (e.g. with shadow map data or river data), but at present
/// we opt not to do this.
pub world_map: (Arc<DynamicImage>, Vec2<u32>), pub world_map: (Arc<DynamicImage>, Vec2<u32>),
pub player_list: HashMap<u64, String>, pub player_list: HashMap<u64, String>,
@ -98,7 +107,7 @@ impl Client {
let mut postbox = PostBox::to(addr)?; let mut postbox = PostBox::to(addr)?;
// Wait for initial sync // Wait for initial sync
let (state, entity, server_info, world_map) = match postbox.next_message()? { let (state, entity, server_info, lod_base, world_map) = match postbox.next_message()? {
ServerMsg::InitialSync { ServerMsg::InitialSync {
entity_package, entity_package,
server_info, server_info,
@ -219,22 +228,26 @@ impl Client {
u32::from_le_bytes([r, g, b, a]); u32::from_le_bytes([r, g, b, a]);
}, },
); );
let mut world_map_raw = vec![0u8; 4 * world_map.len()/*map_size.x * map_size.y*/]; let make_raw = |rgba| -> Result<_, Error> {
LittleEndian::write_u32_into(&world_map, &mut world_map_raw); let mut raw = vec![0u8; 4 * world_map.len()/*map_size.x * map_size.y*/];
let world_map = Arc::new( LittleEndian::write_u32_into(rgba, &mut raw);
image::DynamicImage::ImageRgba8({ Ok(Arc::new(
// Should not fail if the dimensions are correct. image::DynamicImage::ImageRgba8({
let world_map = // Should not fail if the dimensions are correct.
image::ImageBuffer::from_raw(map_size.x, map_size.y, world_map_raw); let map =
world_map.ok_or(Error::Other("Server sent a bad world map image".into()))? image::ImageBuffer::from_raw(map_size.x, map_size.y, raw);
}) map.ok_or(Error::Other("Server sent a bad world map image".into()))?
// Flip the image, since Voxygen uses an orientation where rotation from })
// positive x axis to positive y axis is counterclockwise around the z axis. // Flip the image, since Voxygen uses an orientation where rotation from
.flipv(), // positive x axis to positive y axis is counterclockwise around the z axis.
); .flipv(),
))
};
let lod_base = make_raw(&rgba)?;
let world_map = make_raw(&world_map)?;
log::debug!("Done preparing image..."); log::debug!("Done preparing image...");
(state, entity, server_info, (world_map, map_size)) (state, entity, server_info, lod_base, (world_map, map_size))
}, },
ServerMsg::TooManyPlayers => return Err(Error::TooManyPlayers), ServerMsg::TooManyPlayers => return Err(Error::TooManyPlayers),
_ => return Err(Error::ServerWentMad), _ => return Err(Error::ServerWentMad),
@ -253,6 +266,7 @@ impl Client {
thread_pool, thread_pool,
server_info, server_info,
world_map, world_map,
lod_base,
player_list: HashMap::new(), player_list: HashMap::new(),
postbox, postbox,

View File

@ -1612,7 +1612,8 @@ impl<'a> Widget for SettingsWindow<'a> {
.set(state.ids.lod_detail_text, ui); .set(state.ids.lod_detail_text, ui);
if let Some(new_val) = ImageSlider::discrete( if let Some(new_val) = ImageSlider::discrete(
((self.global_state.settings.graphics.lod_detail as f32 / 100.0).log(5.0) * 10.0).round() as i32, ((self.global_state.settings.graphics.lod_detail as f32 / 100.0).log(5.0) * 10.0)
.round() as i32,
0, 0,
20, 20,
self.imgs.slider_indicator, self.imgs.slider_indicator,
@ -1625,7 +1626,9 @@ impl<'a> Widget for SettingsWindow<'a> {
.pad_track((5.0, 5.0)) .pad_track((5.0, 5.0))
.set(state.ids.lod_detail_slider, ui) .set(state.ids.lod_detail_slider, ui)
{ {
events.push(Event::AdjustLodDetail((5.0f32.powf(new_val as f32 / 10.0) * 100.0) as u32)); events.push(Event::AdjustLodDetail(
(5.0f32.powf(new_val as f32 / 10.0) * 100.0) as u32,
));
} }
Text::new(&format!( Text::new(&format!(

View File

@ -22,7 +22,7 @@ impl Lod {
model: None, model: None,
locals: renderer.create_consts(&[Locals::default()]).unwrap(), locals: renderer.create_consts(&[Locals::default()]).unwrap(),
map: renderer map: renderer
.create_texture(&client.world_map.0, Some(FilterMethod::Trilinear), None) .create_texture(&client.lod_base, Some(FilterMethod::Trilinear), None)
.expect("Failed to generate map texture"), .expect("Failed to generate map texture"),
tgt_detail: settings.graphics.lod_detail.max(100).min(2500), tgt_detail: settings.graphics.lod_detail.max(100).min(2500),
} }