Work-in-progress refactor

This commit is contained in:
griffi-gh 2023-01-18 01:12:13 +01:00
parent a439dc9dcf
commit 365ab73643
22 changed files with 134 additions and 80 deletions

View file

@ -12,6 +12,7 @@ strum = { version = "0.24", features = ["derive"] }
glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] } glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] }
hashbrown = "0.13" hashbrown = "0.13"
simdnoise = "3.1" simdnoise = "3.1"
rayon = "1.6"
[features] [features]
default = [] default = []

BIN
assets/blocks/bedrock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

BIN
assets/blocks/dirt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

BIN
assets/blocks/grass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

BIN
assets/blocks/leaf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

BIN
assets/blocks/sand.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

BIN
assets/blocks/stone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

BIN
assets/blocks/torch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

BIN
assets/blocks/tree.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

BIN
assets/blocks/tree_top.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

View file

@ -1,5 +1,8 @@
use std::{fs, io}; use std::{fs, io, path::PathBuf, sync::atomic::AtomicU16};
use glium::texture::{RawImage2d, SrgbTexture2d}; use rayon::prelude::*;
use glium::texture::{RawImage2d, SrgbTexture2d, SrgbTexture2dArray};
//This code is terrible and has a alot of duplication
fn load_png(file_path: &str, display: &glium::Display) -> SrgbTexture2d { fn load_png(file_path: &str, display: &glium::Display) -> SrgbTexture2d {
log::info!("loading texture {}", file_path); log::info!("loading texture {}", file_path);
@ -25,14 +28,53 @@ fn load_png(file_path: &str, display: &glium::Display) -> SrgbTexture2d {
SrgbTexture2d::new(display, raw_image).unwrap() SrgbTexture2d::new(display, raw_image).unwrap()
} }
fn load_png_array(file_paths: &[PathBuf], display: &glium::Display) -> SrgbTexture2dArray {
let counter = AtomicU16::new(0);
let raw_images: Vec<RawImage2d<u8>> = file_paths.par_iter().enumerate().map(|(_, file_path)| {
let counter = counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
log::info!("loading texture {}/{}: {}", counter, file_paths.len(), file_path.to_str().unwrap());
//Load file
let data = fs::read(file_path).expect("Failed to load texture");
//decode image data
let image_data = image::load(
io::Cursor::new(&data),
image::ImageFormat::Png
).unwrap().to_rgba8();
//Create raw glium image
let image_dimensions = image_data.dimensions();
let raw_image = RawImage2d::from_raw_rgba_reversed(
&image_data.into_raw(),
image_dimensions
);
raw_image
}).collect();
SrgbTexture2dArray::new(display, raw_images).unwrap()
}
pub struct Textures { pub struct Textures {
pub block_atlas: SrgbTexture2d pub blocks: SrgbTexture2dArray
} }
impl Textures { impl Textures {
/// Load textures synchronously, one by one and upload them to the GPU /// Load textures synchronously, one by one and upload them to the GPU
pub fn load_sync(display: &glium::Display) -> Self { pub fn load_sync(display: &glium::Display) -> Self {
Self { Self {
block_atlas: load_png("assets/spritesheet.png", display) blocks: load_png_array(&[
"./assets/blocks/stone.png".into(),
"./assets/blocks/dirt.png".into(),
"./assets/blocks/grass.png".into(),
"./assets/blocks/grass_side.png".into(),
"./assets/blocks/sand.png".into(),
"./assets/blocks/bedrock.png".into(),
"./assets/blocks/tree.png".into(),
"./assets/blocks/tree_top.png".into(),
"./assets/blocks/leaf.png".into(),
"./assets/blocks/torch.png".into(),
"./assets/blocks/tall_grass.png".into(),
], display)
} }
} }
} }

View file

@ -5,43 +5,30 @@ pub struct Vertex {
pub position: [f32; 3], pub position: [f32; 3],
pub normal: [f32; 3], pub normal: [f32; 3],
pub uv: [f32; 2], pub uv: [f32; 2],
pub tex_index: u8,
} }
implement_vertex!(Vertex, position, normal, uv); implement_vertex!(Vertex, position, normal, uv, tex_index);
//TODO store vertex data in a more compact way pub const VERTEX_SHADER: &str = include_str!("./glsl/chunk.vert");
pub const VERTEX_SHADER: &str = r#" pub const FRAGMENT_SHADER: &str = include_str!("./glsl/chunk.frag");
#version 150 core
in vec3 position; // pub const VERTEX_SHADER: &str = r#"
in vec3 normal; // #version 150 core
in vec2 uv;
out vec3 v_normal;
out vec2 v_uv;
uniform mat4 perspective;
uniform mat4 view;
uniform mat4 model;
void main() { // in vec3 position;
mat4 modelview = view * model; // in vec3 normal;
//v_normal = transpose(inverse(mat3(modelview))) * normal; // in vec2 uv;
v_normal = normal; // out vec3 v_normal;
v_uv = uv; // out vec2 v_uv;
gl_Position = perspective * modelview * vec4(position, 1.0); // uniform mat4 perspective;
} // uniform mat4 view;
"#; // uniform mat4 model;
pub const FRAGMENT_SHADER: &str = r#"
#version 150 core
in vec2 v_uv; // void main() {
in vec3 v_normal; // mat4 modelview = view * model;
out vec4 color; // //v_normal = transpose(inverse(mat3(modelview))) * normal;
uniform sampler2D tex; // v_normal = normal;
// v_uv = uv;
void main() { // gl_Position = perspective * modelview * vec4(position, 1.0);
// base color from texture // }
color = texture(tex, v_uv); // "#;
//basic lighting
color *= vec4(vec3(abs(v_normal.x) + .8 * abs(v_normal.y) + .6 * abs(v_normal.z)), 1.);
}
"#;

View file

@ -6,22 +6,5 @@ pub struct Vertex {
} }
implement_vertex!(Vertex, position); implement_vertex!(Vertex, position);
pub const VERTEX_SHADER: &str = r#" pub const VERTEX_SHADER: &str = include_str!("./glsl/colored2d.vert");
#version 150 core pub const FRAGMENT_SHADER: &str = include_str!("./glsl/colored2d.frag");
in vec2 position;
void main() {
gl_Position = vec4(position, 0., 1.);
}
"#;
pub const FRAGMENT_SHADER: &str = r#"
#version 150 core
out vec4 color;
uniform vec4 u_color;
void main() {
color = u_color;
}
"#;

View file

@ -0,0 +1,15 @@
#version 150 core
in vec3 v_normal;
in vec2 v_uv;
flat in uint v_tex_index;
out vec4 color;
uniform sampler2DArray tex;
void main() {
// base color from texture
color = texture(tex, vec3(v_uv, v_tex_index));
//basic "lighting"
float light = abs(v_normal.x) + .8 * abs(v_normal.y) + .6 * abs(v_normal.z);
color *= vec4(vec3(light), 1.);
}

View file

@ -0,0 +1,18 @@
#version 150 core
in vec3 position;
in vec3 normal;
in vec2 uv;
in uint tex_index;
out vec2 v_uv;
out vec3 v_normal;
flat out uint v_tex_index;
uniform vec3 position_offset;
uniform mat4 perspective;
uniform mat4 view;
void main() {
v_normal = normal;
v_tex_index = tex_index;
gl_Position = perspective * view * vec4(position, 1.0) * vec4(position_offset, 1.0);
}

View file

@ -0,0 +1,8 @@
#version 150 core
out vec4 color;
uniform vec4 u_color;
void main() {
color = u_color;
}

View file

@ -0,0 +1,7 @@
#version 150 core
in vec2 position;
void main() {
gl_Position = vec4(position, 0., 1.);
}

View file

@ -95,7 +95,7 @@ impl World {
], ],
view: view, view: view,
perspective: perspective, perspective: perspective,
tex: Sampler(&assets.textures.block_atlas, sampler) tex: Sampler(&assets.textures.blocks, sampler)
}, },
&draw_parameters &draw_parameters
).unwrap(); ).unwrap();

View file

@ -30,7 +30,7 @@ const CUBE_FACE_VERTICES: [[Vec3A; 4]; 6] = [
[vec3a(1., 0., 1.), vec3a(1., 1., 1.), vec3a(0., 0., 1.), vec3a(0., 1., 1.)], [vec3a(1., 0., 1.), vec3a(1., 1., 1.), vec3a(0., 0., 1.), vec3a(0., 1., 1.)],
[vec3a(0., 0., 1.), vec3a(0., 0., 0.), vec3a(1., 0., 1.), vec3a(1., 0., 0.)], [vec3a(0., 0., 1.), vec3a(0., 0., 0.), vec3a(1., 0., 1.), vec3a(1., 0., 0.)],
]; ];
pub const CUBE_FACE_NORMALS: [[f32; 3]; 6] = [ const CUBE_FACE_NORMALS: [[f32; 3]; 6] = [
[0., 1., 0.], [0., 1., 0.],
[0., 0., -1.], [0., 0., -1.],
[-1., 0., 0.], [-1., 0., 0.],
@ -38,7 +38,14 @@ pub const CUBE_FACE_NORMALS: [[f32; 3]; 6] = [
[0., 0., 1.], [0., 0., 1.],
[0., -1., 0.] [0., -1., 0.]
]; ];
pub const CUBE_FACE_INDICES: [u32; 6] = [0, 1, 2, 2, 1, 3]; const CUBE_FACE_INDICES: [u32; 6] = [0, 1, 2, 2, 1, 3];
const UV_COORDS: [[f32; 2]; 4] = [
[0., 0.],
[0., 1.],
[1., 0.],
[1., 1.],
];
#[derive(Default)] #[derive(Default)]
struct MeshBuilder { struct MeshBuilder {
@ -51,7 +58,7 @@ impl MeshBuilder {
Self::default() Self::default()
} }
pub fn add_face(&mut self, face: CubeFace, coord: IVec3, uvs: [Vec2; 4]) { pub fn add_face(&mut self, face: CubeFace, coord: IVec3, texture: u8) {
let coord = coord.as_vec3a(); let coord = coord.as_vec3a();
let face_index = face as usize; let face_index = face as usize;
@ -63,7 +70,8 @@ impl MeshBuilder {
self.vertex_buffer.push(Vertex { self.vertex_buffer.push(Vertex {
position: (coord + vert[i]).to_array(), position: (coord + vert[i]).to_array(),
normal: norm, normal: norm,
uv: uvs[i].to_array() uv: UV_COORDS[i],
tex_index: texture
}); });
} }
@ -112,7 +120,7 @@ pub fn generate_mesh(position: IVec2, chunk_data: ChunkData, neighbors: [ChunkDa
}; };
if show { if show {
let texures = descriptor.render.unwrap().1; let texures = descriptor.render.unwrap().1;
let texture_id = match face { let texture_index = match face {
CubeFace::Top => texures.top, CubeFace::Top => texures.top,
CubeFace::Front => texures.front, CubeFace::Front => texures.front,
CubeFace::Left => texures.left, CubeFace::Left => texures.left,
@ -120,22 +128,7 @@ pub fn generate_mesh(position: IVec2, chunk_data: ChunkData, neighbors: [ChunkDa
CubeFace::Back => texures.back, CubeFace::Back => texures.back,
CubeFace::Bottom => texures.bottom, CubeFace::Bottom => texures.bottom,
}; };
//TODO replace with a proper texture resolver (or calculate uvs in a shader!) builer.add_face(face, coord, texture_index);
//this is temporary!
//also this can only resolve textures on the first row.
const TEX_WIDTH: f32 = 16. / 640.;
const TEX_HEIGHT: f32 = 16. / 404.;
let x1 = TEX_WIDTH * texture_id as f32;
let x2 = x1 + TEX_WIDTH as f32;
let y1 = 1. - TEX_HEIGHT;
let y2 = 1.;
builer.add_face(face, coord, [
vec2(x1, y1),
vec2(x1, y2),
vec2(x2, y1),
vec2(x2, y2),
]);
} }
} }
} }