Files
LemnosLife_Rust/src/support/mod.rs
T

209 lines
6.3 KiB
Rust

#![allow(dead_code)]
use glium::glutin::event::{Event, StartCause};
use glium::glutin::event_loop::{ControlFlow, EventLoop};
use glium::vertex::VertexBufferAny;
use glium::{self, Display};
use std::fs;
use std::time::{Duration, Instant};
pub mod camera;
pub enum Action {
Stop,
Continue,
}
pub fn start_loop<F>(event_loop: EventLoop<()>, mut callback: F) -> !
where
F: 'static + FnMut(&Vec<Event<'_, ()>>) -> Action,
{
let mut events_buffer = Vec::new();
let mut next_frame_time = Instant::now();
event_loop.run(move |event, _, control_flow| {
let run_callback = match event.to_static() {
Some(Event::NewEvents(cause)) => match cause {
StartCause::ResumeTimeReached { .. } | StartCause::Init => true,
_ => false,
},
Some(event) => {
events_buffer.push(event);
false
}
None => {
// Ignore this event.
false
}
};
let action = if run_callback {
let action = callback(&events_buffer);
next_frame_time = Instant::now() + Duration::from_nanos(16666667);
// TODO: Add back the old accumulator loop in some way
events_buffer.clear();
action
} else {
Action::Continue
};
match action {
Action::Continue => {
*control_flow = ControlFlow::WaitUntil(next_frame_time);
}
Action::Stop => *control_flow = ControlFlow::Exit,
}
})
}
fn get_biome(line: &str, index: usize) -> u32 {
let biome_char = line.chars().nth(index).unwrap();
return if '0' <= biome_char && biome_char <= '9' {
biome_char.to_digit(10).unwrap()
} else {
(10 + (biome_char as u8 - 'A' as u8)) as u32
};
}
fn get_altitude(height_columns: &Vec<&str>, columns_index: usize) -> f32 {
let height_str = height_columns[columns_index];
return if height_str == "N" {
-100.0
} else {
height_str.parse::<f32>().unwrap()
};
}
/// Returns a vertex buffer that should be rendered as `TrianglesList`.
pub fn load_ground(display: &Display) -> VertexBufferAny {
#[derive(Copy, Clone)]
struct Vertex {
altitude: f32,
normal: [f32; 3],
index: u32,
biome: u32,
}
implement_vertex!(Vertex, altitude, normal, index, biome);
let mut vertex_data: Vec<Vertex> = Vec::new();
let ground_folder = "Extensions/LemnosLife/Map/Altis/Ground/";
let paths = fs::read_dir(ground_folder).unwrap();
let mut i: u32 = 0;
for path in paths {
let file_name = path
.unwrap()
.path()
.to_str()
.unwrap()
.replace("Extensions/LemnosLife/Map/Altis/Ground/", "")
.replace(".height", "");
println!("{}", file_name);
// have deleted a few height files to make it work
// TODO: use triangle strip
let height_contents = fs::read_to_string(&format!(
"Extensions/LemnosLife/Map/Altis/Ground/{}.height",
file_name
))
.expect("Unable to load ground file!");
let biomes_contents = fs::read_to_string(&format!(
"Extensions/LemnosLife/Map/Altis/Biomes/{}.biomes",
file_name
))
.expect("Unable to load biomes file!");
println!("alpha");
let height_lines: Vec<&str> = height_contents.split('\n').collect();
let biomes_lines: Vec<&str> = biomes_contents.split('\n').collect();
println!("beta");
let mut index: u32 = 0;
for lines_index in 0..height_lines.len() - 1 {
let height_line = height_lines[lines_index];
let height_next_line = height_lines[lines_index + 1];
let height_columns: Vec<&str> = height_line.split(' ').collect();
let height_next_columns: Vec<&str> = height_next_line.split(' ').collect();
let biomes_line = biomes_lines[lines_index / 2];
for columns_index in 0..height_columns.len() - 1 {
let column = get_altitude(&height_columns, columns_index);
let column_right = get_altitude(&height_columns, columns_index + 1);
let column_below = get_altitude(&height_next_columns, columns_index);
let column_below_right = get_altitude(&height_next_columns, columns_index + 1);
let biome = get_biome(biomes_line, columns_index / 2);
// TODO: compute normals if necessary.
// First triangle.
vertex_data.push(Vertex {
altitude: column,
normal: [0.0, 0.0, 1.0],
index,
biome,
});
index += 1;
vertex_data.push(Vertex {
altitude: column_right,
normal: [0.0, 0.0, 1.0],
index,
biome,
});
index += 1;
vertex_data.push(Vertex {
altitude: column_below,
normal: [0.0, 0.0, 1.0],
index,
biome,
});
index += 1;
// Second triangle.
vertex_data.push(Vertex {
altitude: column_below,
normal: [0.0, 0.0, 1.0],
index,
biome,
});
index += 1;
vertex_data.push(Vertex {
altitude: column_right,
normal: [0.0, 0.0, 1.0],
index,
biome,
});
index += 1;
vertex_data.push(Vertex {
altitude: column_below_right,
normal: [0.0, 0.0, 1.0],
index,
biome,
});
index += 1;
}
}
i += 1;
// i == 250 thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: BufferCreationError(OutOfMemory)', src/support/mod.rs:203:10
if i == 200 {
break;
}
}
println!("charlie");
glium::vertex::VertexBuffer::new(display, &vertex_data)
.unwrap()
.into()
}