134 lines
4.3 KiB
Rust
134 lines
4.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,
|
|
}
|
|
})
|
|
}
|
|
|
|
/// Returns a vertex buffer that should be rendered as `TrianglesList`.
|
|
pub fn load_ground(display: &Display) -> VertexBufferAny {
|
|
#[derive(Copy, Clone)]
|
|
struct Vertex {
|
|
position: [f32; 3],
|
|
normal: [f32; 3],
|
|
tex_coords: [f32; 2],
|
|
}
|
|
|
|
implement_vertex!(Vertex, position, normal, tex_coords);
|
|
|
|
let mut vertex_data: Vec<Vertex> = Vec::new();
|
|
|
|
let contents = fs::read_to_string("Extensions/LemnosLife/Map/Altis/Ground/13 13.height").expect("Unable to load ground file!");
|
|
|
|
let lines: Vec<&str> = contents.split('\n').collect();
|
|
|
|
for lines_index in 0..lines.len() - 1 {
|
|
let line = lines[lines_index];
|
|
let next_line = lines[lines_index + 1];
|
|
let columns: Vec<&str> = line.split(' ').collect();
|
|
let next_columns: Vec<&str> = next_line.split(' ').collect();
|
|
for columns_index in 0..columns.len() - 1 {
|
|
let column = columns[columns_index].parse::<f32>().unwrap();
|
|
let column_right = columns[columns_index + 1].parse::<f32>().unwrap();
|
|
let column_below = next_columns[columns_index].parse::<f32>().unwrap();
|
|
let column_below_right = next_columns[columns_index + 1].parse::<f32>().unwrap();
|
|
|
|
// TODO: normals if necessary.
|
|
|
|
// First triangle.
|
|
|
|
vertex_data.push(Vertex {
|
|
position: [lines_index as f32, column, columns_index as f32],
|
|
normal: [0.0, 0.0, 1.0],
|
|
tex_coords: [0.0, 0.0],
|
|
});
|
|
|
|
vertex_data.push(Vertex {
|
|
position: [lines_index as f32, column_right, (columns_index + 1) as f32],
|
|
normal: [0.0, 0.0, 1.0],
|
|
tex_coords: [0.0, 1.0],
|
|
});
|
|
|
|
vertex_data.push(Vertex {
|
|
position: [(lines_index + 1) as f32, column_below, columns_index as f32],
|
|
normal: [0.0, 0.0, 1.0],
|
|
tex_coords: [1.0, 0.0],
|
|
});
|
|
|
|
// Second triangle.
|
|
|
|
vertex_data.push(Vertex {
|
|
position: [(lines_index + 1) as f32, column_below_right, (columns_index + 1) as f32],
|
|
normal: [0.0, 0.0, 1.0],
|
|
tex_coords: [1.0, 1.0],
|
|
});
|
|
|
|
vertex_data.push(Vertex {
|
|
position: [lines_index as f32, column_right, (columns_index + 1) as f32],
|
|
normal: [0.0, 0.0, 1.0],
|
|
tex_coords: [0.0, 1.0],
|
|
});
|
|
|
|
vertex_data.push(Vertex {
|
|
position: [(lines_index + 1) as f32, column_below, columns_index as f32],
|
|
normal: [0.0, 0.0, 1.0],
|
|
tex_coords: [1.0, 0.0],
|
|
});
|
|
}
|
|
}
|
|
|
|
glium::vertex::VertexBuffer::new(display, &vertex_data)
|
|
.unwrap()
|
|
.into()
|
|
}
|