From e4ad531a7ed6a7e6cc7fd160cabb589ee7732b5d Mon Sep 17 00:00:00 2001 From: Benjamin Loison Date: Mon, 31 Oct 2022 20:12:46 +0100 Subject: [PATCH] Display multiple instances of OBJs --- Cargo.toml | 1 + src/main.rs | 76 +++++++++++++++++++++++++++++++++++++++---- src/support/camera.rs | 7 ++-- src/support/mod.rs | 51 +++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9bf31ae..0f1735a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" glium = "0.32.1" image = "0.24.4" glutin = "0.29.1" +obj = "0.10.2" load_file = "1.0.1" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 43677d1..6653e52 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,12 @@ use glium::{glutin, Surface}; mod support; +#[derive(Copy, Clone, Debug)] +struct PerInstance { + pub w_position: (f32, f32, f32), +} +implement_vertex!(PerInstance, w_position); + const BIOMES_NUMBER: usize = 19; const BIOMES: [&str; BIOMES_NUMBER] = [ "dirt", @@ -46,7 +52,7 @@ fn main() { let display = glium::Display::new(wb, cb, &event_loop).unwrap(); // building the vertex and index buffers - let vertex_buffer = support::load_ground(&display); + let ground_vertex_buffer = support::load_ground(&display); let textures: [SrgbTexture2d; BIOMES_NUMBER] = BIOMES.map(|biome| { println!("{}", biome); @@ -113,7 +119,7 @@ fn main() { ); // the program - let program = program!(&display, + let ground_program = program!(&display, 140 => { vertex: " #version 140 @@ -175,12 +181,51 @@ fn main() { let mut camera = support::camera::CameraState::new(); + let vertex_buffer = support::load_wavefront(&display, &load_bytes!("../Extensions/LemnosLife/Map/Common/Structures/24.obj")); + + let structures_program = program!(&display, + 140 => { + vertex: " + #version 140 + + uniform mat4 persp_matrix; + uniform mat4 view_matrix; + + in vec3 w_position; + in vec3 position; + + void main() { + gl_Position = persp_matrix * view_matrix * vec4(position + w_position, 1.0); + } + ", + + fragment: " + #version 140 + + out vec4 f_color; + + void main() { + f_color = vec4(1.0, 1.0, 1.0, 1.0); + } + ", + }, + ).unwrap(); + + let per_instance = vec![ + PerInstance { + w_position: (0.0, 0.0, 0.0), + }, + PerInstance { + w_position: (1.0, 0.0, 0.0), + }, + ]; + // the main loop support::start_loop(event_loop, move |events| { camera.update(); // building the uniforms - let uniforms = uniform! { + let ground_uniforms = uniform! { persp_matrix: camera.get_perspective(), view_matrix: camera.get_view(), tex0: &textures[0], @@ -204,6 +249,11 @@ fn main() { tex18: &textures[18], }; + let structures_uniforms = uniform! { + persp_matrix: camera.get_perspective(), + view_matrix: camera.get_view(), + }; + // draw parameters let params = glium::DrawParameters { depth: glium::Depth { @@ -216,19 +266,33 @@ fn main() { ..Default::default() }; + let per_instance_buffer = + glium::vertex::VertexBuffer::new(&display, &per_instance).unwrap(); + // drawing a frame let start = Instant::now(); let mut target = display.draw(); target.clear_color_and_depth((0.0, 0.0, 0.0, 0.0), 1.0); target .draw( - &vertex_buffer, + &ground_vertex_buffer, &glium::index::NoIndices(glium::index::PrimitiveType::TriangleStrip), - &program, - &uniforms, + &ground_program, + &ground_uniforms, ¶ms, ) .unwrap(); + + target + .draw( + (&vertex_buffer, per_instance_buffer.per_instance().unwrap()), + &glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList), + &structures_program, + &structures_uniforms, + ¶ms, + ) + .unwrap(); + target.finish().unwrap(); let duration = start.elapsed(); println!("Time elapsed is: {:?}", duration); diff --git a/src/support/camera.rs b/src/support/camera.rs index 540236c..a8b25a8 100644 --- a/src/support/camera.rs +++ b/src/support/camera.rs @@ -13,14 +13,15 @@ pub struct CameraState { rotate_right: bool, } -const SPEED: f32 = 100.0; //1.0; +const SPEED: f32 = 1.0; //1.0; impl CameraState { pub fn new() -> CameraState { CameraState { aspect_ratio: 1_024.0 / 768.0, // The second coordinate is for the altitude. - position: (3_646.41, 12.3622, 13_113.7), + //position: (3_646.41, 12.3622, 13_113.7), + position: (0.0, 0.0, 0.0), direction: (0.0, 0.0, -1.0), moving_up: false, moving_left: false, @@ -36,7 +37,7 @@ impl CameraState { pub fn get_perspective(&self) -> [[f32; 4]; 4] { let fov: f32 = std::f32::consts::PI / 2.0; let zfar = 53_209.0; - let znear = 1.0; //0.01; + let znear = 0.01; let f = 1.0 / (fov / 2.0).tan(); diff --git a/src/support/mod.rs b/src/support/mod.rs index 72bbedc..3d6b670 100644 --- a/src/support/mod.rs +++ b/src/support/mod.rs @@ -196,3 +196,54 @@ pub fn load_ground(display: &Display) -> VertexBufferAny { .unwrap() .into() } + +pub fn load_wavefront(display: &Display, data: &[u8]) -> VertexBufferAny { + #[derive(Copy, Clone)] + struct Vertex { + position: [f32; 3], + texture: [f32; 2], + } + + implement_vertex!(Vertex, position, texture); + + let mut data = ::std::io::BufReader::new(data); + let data = obj::ObjData::load_buf(&mut data).unwrap(); + + let mut vertex_data = Vec::new(); + + for object in data.objects.iter() { + for polygon in object.groups.iter().flat_map(|g| g.polys.iter()) { + match polygon { + obj::SimplePolygon(indices) => { + for i in 0..=2 { + let v = indices[i]; + let position = data.position[v.0]; + let texture = v.1.map(|index| data.texture[index]); + + let texture = texture.unwrap_or([0.0, 0.0]); + + vertex_data.push(Vertex { + position, + texture, + }) + } + for i in [0, 2, 3] { + let v = indices[i]; + let position = data.position[v.0]; + let texture = v.1.map(|index| data.texture[index]); + + let texture = texture.unwrap_or([0.0, 0.0]); + + vertex_data.push(Vertex { + position, + texture, + }) + } + }, + } + } + } + glium::vertex::VertexBuffer::new(display, &vertex_data) + .unwrap() + .into() +} \ No newline at end of file