#![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(event_loop: EventLoop<()>, mut callback: F) -> ! where F: 'static + FnMut(&Vec>) -> 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::().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 = 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() }