From c526ebe9778cd132fbc9bad227012c719a69f967 Mon Sep 17 00:00:00 2001 From: Benjamin Loison Date: Mon, 17 Oct 2022 02:35:05 +0200 Subject: [PATCH] Ready to use an uniform array of textures for the biomes --- Cargo.toml | 3 ++- src/main.rs | 40 +++++++++++++++++++++++---------- src/support/mod.rs | 55 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 73 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b99720b..9bf31ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" [dependencies] glium = "0.32.1" image = "0.24.4" -glutin = "0.29.1" \ No newline at end of file +glutin = "0.29.1" +load_file = "1.0.1" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 43deb5b..a28804e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,20 @@ #[macro_use] extern crate glium; +#[macro_use] +extern crate load_file; + use std::io::Cursor; +use glium::texture::SrgbTexture2d; #[allow(unused_imports)] use glium::{glutin, Surface}; mod support; +const BIOMES_NUMBER: usize = 19; +const BIOMES: [&str; BIOMES_NUMBER] = ["dirt", "grassDry", "grassGreen", "concrete", "soil", "beach", "seabed", "thorn", "wildField", "rock", "grassWild", "stony", "forestPine", "mud", "stonyThistle", "marsh", "dead", "desert", "weed"]; + fn main() { // building the display, ie. the main object let event_loop = glutin::event_loop::EventLoop::new(); @@ -18,16 +25,21 @@ fn main() { // building the vertex and index buffers let vertex_buffer = support::load_ground(&display); - let image = image::load( - Cursor::new(&include_bytes!("../grassGreen.jpg")), - image::ImageFormat::Jpeg, - ) - .unwrap() - .to_rgba8(); - let image_dimensions = image.dimensions(); - let image = - glium::texture::RawImage2d::from_raw_rgba_reversed(&image.into_raw(), image_dimensions); - let texture = glium::texture::SrgbTexture2d::new(&display, image).unwrap(); + let textures: [SrgbTexture2d; BIOMES_NUMBER] = BIOMES.map(|biome| { + println!("{}", biome); + let image = image::load( + Cursor::new(&load_bytes!( + &format!("../Extensions/LemnosLife/Assets/Pictures/Map/Ground/{}.jpg", biome) + )), + image::ImageFormat::Jpeg, + ) + .unwrap() + .to_rgba8(); + let image_dimensions = image.dimensions(); + let image = + glium::texture::RawImage2d::from_raw_rgba_reversed(&image.into_raw(), image_dimensions); + glium::texture::SrgbTexture2d::new(&display, image).unwrap() + }); // the program let program = program!(&display, @@ -38,15 +50,19 @@ fn main() { uniform mat4 persp_matrix; uniform mat4 view_matrix; + // can't skip directly to fragment shader an unmodified variable? in vec3 normal; in uint index; in float altitude; + in uint biome; out vec3 v_normal; out vec2 v_tex_coords; + out uint v_biome; void main() { v_normal = normal; + v_biome = biome; uint index_mod = index % 6u; uint index_div = index / 6u; uint z = index_div / 250u; @@ -79,7 +95,9 @@ fn main() { in vec3 v_normal; in vec2 v_tex_coords; out vec4 f_color; + in uint v_biome; + // TODO: not hardcode uniform sampler2D tex; const vec3 LIGHT = vec3(0.0, -1.0, 0.0); @@ -103,7 +121,7 @@ fn main() { let uniforms = uniform! { persp_matrix: camera.get_perspective(), view_matrix: camera.get_view(), - tex: &texture, + tex: &textures[0] // could inline otherwise }; // draw parameters diff --git a/src/support/mod.rs b/src/support/mod.rs index cef0c64..eeaa588 100644 --- a/src/support/mod.rs +++ b/src/support/mod.rs @@ -55,6 +55,15 @@ where }) } +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 + } +} + /// Returns a vertex buffer that should be rendered as `TrianglesList`. pub fn load_ground(display: &Display) -> VertexBufferAny { #[derive(Copy, Clone)] @@ -62,30 +71,44 @@ pub fn load_ground(display: &Display) -> VertexBufferAny { altitude: f32, normal: [f32; 3], index: u32, + biome: u32, } implement_vertex!(Vertex, altitude, normal, index); let mut vertex_data: Vec = Vec::new(); - let contents = fs::read_to_string("Extensions/LemnosLife/Map/Altis/Ground/13 13.height").expect("Unable to load ground file!"); + // TODO: load "all" ground/biomes files + // TODO: use triangle strip + let height_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(); + let biomes_contents = fs::read_to_string("Extensions/LemnosLife/Map/Altis/Biomes/13 13.biomes") + .expect("Unable to load biomes file!"); + + let height_lines: Vec<&str> = height_contents.split('\n').collect(); + + let biomes_lines: Vec<&str> = biomes_contents.split('\n').collect(); let mut index: u32 = 0; - 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::().unwrap(); - let column_right = columns[columns_index + 1].parse::().unwrap(); - let column_below = next_columns[columns_index].parse::().unwrap(); - let column_below_right = next_columns[columns_index + 1].parse::().unwrap(); + 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(); - // TODO: normals if necessary. + let biomes_line = biomes_lines[lines_index / 2]; + + for columns_index in 0..height_columns.len() - 1 { + let column = height_columns[columns_index].parse::().unwrap(); + let column_right = height_columns[columns_index + 1].parse::().unwrap(); + let column_below = height_next_columns[columns_index].parse::().unwrap(); + let column_below_right = height_next_columns[columns_index + 1].parse::().unwrap(); + + let biome = get_biome(biomes_line, columns_index / 2); + + // TODO: compute normals if necessary. // First triangle. @@ -93,6 +116,7 @@ pub fn load_ground(display: &Display) -> VertexBufferAny { altitude: column, normal: [0.0, 0.0, 1.0], index, + biome, }); index += 1; @@ -100,6 +124,7 @@ pub fn load_ground(display: &Display) -> VertexBufferAny { altitude: column_right, normal: [0.0, 0.0, 1.0], index, + biome }); index += 1; @@ -107,6 +132,7 @@ pub fn load_ground(display: &Display) -> VertexBufferAny { altitude: column_below, normal: [0.0, 0.0, 1.0], index, + biome }); index += 1; @@ -116,6 +142,7 @@ pub fn load_ground(display: &Display) -> VertexBufferAny { altitude: column_below, normal: [0.0, 0.0, 1.0], index, + biome }); index += 1; @@ -123,6 +150,7 @@ pub fn load_ground(display: &Display) -> VertexBufferAny { altitude: column_right, normal: [0.0, 0.0, 1.0], index, + biome }); index += 1; @@ -130,6 +158,7 @@ pub fn load_ground(display: &Display) -> VertexBufferAny { altitude: column_below_right, normal: [0.0, 0.0, 1.0], index, + biome }); index += 1; }