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"] }
hashbrown = "0.13"
simdnoise = "3.1"
rayon = "1.6"
[features]
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 glium::texture::{RawImage2d, SrgbTexture2d};
use std::{fs, io, path::PathBuf, sync::atomic::AtomicU16};
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 {
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()
}
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 block_atlas: SrgbTexture2d
pub blocks: SrgbTexture2dArray
}
impl Textures {
/// Load textures synchronously, one by one and upload them to the GPU
pub fn load_sync(display: &glium::Display) -> 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 normal: [f32; 3],
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 = r#"
#version 150 core
pub const VERTEX_SHADER: &str = include_str!("./glsl/chunk.vert");
pub const FRAGMENT_SHADER: &str = include_str!("./glsl/chunk.frag");
in vec3 position;
in vec3 normal;
in vec2 uv;
out vec3 v_normal;
out vec2 v_uv;
uniform mat4 perspective;
uniform mat4 view;
uniform mat4 model;
// pub const VERTEX_SHADER: &str = r#"
// #version 150 core
void main() {
mat4 modelview = view * model;
//v_normal = transpose(inverse(mat3(modelview))) * normal;
v_normal = normal;
v_uv = uv;
gl_Position = perspective * modelview * vec4(position, 1.0);
}
"#;
pub const FRAGMENT_SHADER: &str = r#"
#version 150 core
// in vec3 position;
// in vec3 normal;
// in vec2 uv;
// out vec3 v_normal;
// out vec2 v_uv;
// uniform mat4 perspective;
// uniform mat4 view;
// uniform mat4 model;
in vec2 v_uv;
in vec3 v_normal;
out vec4 color;
uniform sampler2D tex;
void main() {
// 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.);
}
"#;
// void main() {
// mat4 modelview = view * model;
// //v_normal = transpose(inverse(mat3(modelview))) * normal;
// v_normal = normal;
// v_uv = uv;
// gl_Position = perspective * modelview * vec4(position, 1.0);
// }
// "#;

View file

@ -6,22 +6,5 @@ pub struct Vertex {
}
implement_vertex!(Vertex, position);
pub const VERTEX_SHADER: &str = r#"
#version 150 core
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;
}
"#;
pub const VERTEX_SHADER: &str = include_str!("./glsl/colored2d.vert");
pub const FRAGMENT_SHADER: &str = include_str!("./glsl/colored2d.frag");

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,
perspective: perspective,
tex: Sampler(&assets.textures.block_atlas, sampler)
tex: Sampler(&assets.textures.blocks, sampler)
},
&draw_parameters
).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(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., 0., -1.],
[-1., 0., 0.],
@ -38,7 +38,14 @@ pub const CUBE_FACE_NORMALS: [[f32; 3]; 6] = [
[0., 0., 1.],
[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)]
struct MeshBuilder {
@ -51,7 +58,7 @@ impl MeshBuilder {
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 face_index = face as usize;
@ -63,7 +70,8 @@ impl MeshBuilder {
self.vertex_buffer.push(Vertex {
position: (coord + vert[i]).to_array(),
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 {
let texures = descriptor.render.unwrap().1;
let texture_id = match face {
let texture_index = match face {
CubeFace::Top => texures.top,
CubeFace::Front => texures.front,
CubeFace::Left => texures.left,
@ -120,22 +128,7 @@ pub fn generate_mesh(position: IVec2, chunk_data: ChunkData, neighbors: [ChunkDa
CubeFace::Back => texures.back,
CubeFace::Bottom => texures.bottom,
};
//TODO replace with a proper texture resolver (or calculate uvs in a shader!)
//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),
]);
builer.add_face(face, coord, texture_index);
}
}
}