This commit is contained in:
griffi-gh 2023-01-20 16:28:34 +01:00
parent 2c01480a93
commit a39ad3b2dd
10 changed files with 150 additions and 38 deletions

1
crabs.txt Normal file
View file

@ -0,0 +1 @@
sorry no crabs here

15
shaders/world.frag Normal file
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.);
}

25
shaders/world.vert Normal file
View file

@ -0,0 +1,25 @@
#version 150 core
//TODO pack this data:
// uint position_normal_uv
// XXYYZZNU
// wehere Normal and Uv are enums
// maybe somehow pack in tex index too
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 vec2 position_offset;
uniform mat4 perspective;
uniform mat4 view;
void main() {
v_normal = normal;
v_tex_index = tex_index;
v_uv = uv;
gl_Position = perspective * view * (vec4(position, 1.0) + vec4(position_offset.x, 0., position_offset.y, 0.));
}

View file

@ -62,6 +62,9 @@ fn main() {
*control_flow = ControlFlow::Poll;
match event {
Event::WindowEvent { event, .. } => match event {
WindowEvent::Resized(size) => {
// todo ...
}
WindowEvent::CloseRequested => {
log::info!("exit requested");
*control_flow = ControlFlow::Exit;

View file

@ -1,11 +1,15 @@
use shipyard::{World, NonSendSync, UniqueView, Unique};
use strum::{EnumIter, IntoEnumIterator};
use rayon::prelude::*;
use glium::{texture::{SrgbTexture2dArray, RawImage2d}, backend::Facade};
use std::{fs::File, path::PathBuf, io::BufReader};
use glium::{texture::{SrgbTexture2dArray, RawImage2d}, backend::Facade, Program};
use crate::rendering::Rederer;
trait AssetPaths {
mod texture;
mod shaders;
use texture::load_texture2darray_prefab;
use shaders::include_shader_prefab;
pub trait AssetPaths {
fn file_name(self) -> &'static str;
}
@ -46,43 +50,27 @@ impl AssetPaths for BlockTextures {
}
}
fn load_texture2darray_prefab<T: AssetPaths + IntoEnumIterator, E: Facade>(directory: PathBuf, facade: &E) -> SrgbTexture2dArray {
//Load raw images
let tex_files: Vec<&'static str> = T::iter().map(|x| x.file_name()).collect();
let raw_images: Vec<RawImage2d<u8>> = tex_files.par_iter().map(|&file_name| {
log::info!("loading texture {}", file_name);
//Get path to the image and open the file
let reader = {
let path = directory.join(file_name);
BufReader::new(File::open(path).expect("Failed to open texture file"))
};
//Parse image data
let (image_data, dimensions) = {
let image =image::load(
reader,
image::ImageFormat::Png
).unwrap().to_rgba8();
let dimensions = image.dimensions();
(image.into_raw(), dimensions)
};
//Create a glium RawImage
RawImage2d::from_raw_rgba_reversed(
&image_data,
dimensions
)
}).collect();
log::info!("done loading texture files, uploading to the gpu");
//Upload images to the GPU
SrgbTexture2dArray::new(facade, raw_images)
.expect("Failed to upload texture array to GPU")
}
#[derive(Unique)]
pub struct BlockTexturesPrefab(SrgbTexture2dArray);
#[derive(Unique)]
pub struct ChunkShaderPrefab(Program);
pub fn load_prefabs(world: &World) {
let renderer = world.borrow::<NonSendSync<UniqueView<Rederer>>>().unwrap();
world.add_unique_non_send_sync(BlockTexturesPrefab(
load_texture2darray_prefab::<BlockTextures, _>("./assets/blocks/".into(), &renderer.display)
load_texture2darray_prefab::<BlockTextures, _>(
"./assets/blocks/".into(),
&renderer.display
)
));
world.add_unique_non_send_sync(ChunkShaderPrefab(
include_shader_prefab!(
"../shaders/world.vert",
"../shaders/world.frag",
&renderer.display
)
));
}

29
src/prefabs/shaders.rs Normal file
View file

@ -0,0 +1,29 @@
use glium::{Program, backend::Facade};
macro_rules! include_shader_prefab {
($vert: literal, $frag: literal, $geom: literal, $facade: expr) => {
{
log::info!("↓↓↓ compiling shader prefab ↓↓↓");
log::info!("{} {} {}", $vert, $frag, $geom);
Program::from_source(
&*$facade,
include_str!($vert),
include_str!($frag),
Some(include_str!($geom)),
).expect("Failed to compile gpu program")
}
};
($vert: literal, $frag: literal, $facade: expr) => {
{
log::info!("↓↓↓ compiling shader prefab ↓↓↓");
log::info!("{} {}", $vert, $frag);
Program::from_source(
&*$facade,
include_str!($vert),
include_str!($frag),
None,
).expect("Failed to compile gpu program")
}
};
}
pub(crate) use include_shader_prefab;

40
src/prefabs/texture.rs Normal file
View file

@ -0,0 +1,40 @@
use strum::IntoEnumIterator;
use rayon::prelude::*;
use std::{fs::File, path::PathBuf, io::BufReader};
use glium::{texture::{SrgbTexture2dArray, RawImage2d}, backend::Facade};
use super::AssetPaths;
pub fn load_texture2darray_prefab<T: AssetPaths + IntoEnumIterator, E: Facade>(
directory: PathBuf,
facade: &E
) -> SrgbTexture2dArray {
log::info!("↓↓↓ loading textures {} ↓↓↓", directory.as_os_str().to_str().unwrap());
//Load raw images
let tex_files: Vec<&'static str> = T::iter().map(|x| x.file_name()).collect();
let raw_images: Vec<RawImage2d<u8>> = tex_files.par_iter().map(|&file_name| {
log::info!("loading texture {}", file_name);
//Get path to the image and open the file
let reader = {
let path = directory.join(file_name);
BufReader::new(File::open(path).expect("Failed to open texture file"))
};
//Parse image data
let (image_data, dimensions) = {
let image =image::load(
reader,
image::ImageFormat::Png
).unwrap().to_rgba8();
let dimensions = image.dimensions();
(image.into_raw(), dimensions)
};
//Create a glium RawImage
RawImage2d::from_raw_rgba_reversed(
&image_data,
dimensions
)
}).collect();
log::info!("done loading texture files, uploading to the gpu");
//Upload images to the GPU
SrgbTexture2dArray::new(facade, raw_images)
.expect("Failed to upload texture array to GPU")
}

View file

@ -3,6 +3,7 @@ use hashbrown::HashMap;
pub mod chunk;
pub mod block;
pub mod render;
use chunk::Chunk;

View file

@ -1,6 +1,6 @@
use glam::IVec3;
use glium::{VertexBuffer, IndexBuffer};
use super::block::Block;
use super::{block::Block, render::ChunkVertex};
pub const CHUNK_SIZE: usize = 32;
@ -26,9 +26,9 @@ pub struct ChunkMesh {
pub enum ChunkState {
ToUnload, //desired only
Nothing,
Loading, //current only
Loading, //current only
Loaded,
Meshing, //current only
Meshing, //current only
Rendered
}

10
src/world/render.rs Normal file
View file

@ -0,0 +1,10 @@
use glium::implement_vertex;
#[derive(Clone, Copy)]
pub struct ChunkVertex {
pub position: [f32; 3],
pub normal: [f32; 3],
pub uv: [f32; 2],
pub tex_index: u8,
}
implement_vertex!(ChunkVertex, position, normal, uv, tex_index);