wip texture loading

This commit is contained in:
griffi-gh 2023-07-14 03:37:22 +02:00
parent f792e331a9
commit 35683d2b7c
11 changed files with 117 additions and 93 deletions

View file

@ -1,17 +0,0 @@
#version 300 es
precision highp float;
in vec2 v_uv;
out vec4 out_color;
uniform float progress;
uniform vec4 color;
uniform vec4 bg_color;
void main() {
if (v_uv.x <= progress) {
out_color = color;
} else {
out_color = bg_color;
}
}

View file

@ -1,12 +0,0 @@
#version 300 es
in vec2 position;
out vec2 v_uv;
uniform mat4 ui_view;
uniform mat3 transform;
void main() {
v_uv = position;
vec2 transformed = (transform * vec3(position, 1.)).xy;
gl_Position = ui_view * vec4(transformed, 0., 1.);
}

View file

@ -5,7 +5,7 @@ use crate::rendering::Renderer;
mod texture;
mod shaders;
use texture::load_texture2darray_prefab;
use texture::load_asset_texture_array;
use shaders::include_shader_prefab;
pub trait AssetPaths {
@ -57,11 +57,7 @@ pub fn load_prefabs(
) {
log::info!("Loading textures...");
storages.add_unique_non_send_sync(BlockTexturesPrefab(
load_texture2darray_prefab::<BlockTexture, _>(
"blocks".into(),
&renderer.display,
MipmapsOption::AutoGeneratedMipmaps
)
load_asset_texture_array::<BlockTexture>("blocks".into(), &renderer)
));
log::info!("Compiling shaders...");
@ -81,13 +77,5 @@ pub fn load_prefabs(
&renderer.display
)
));
storages.add_unique_non_send_sync(ProgressbarShaderPrefab(
include_shader_prefab!(
"gui/progressbar",
"../shaders/gui/progressbar.vert",
"../shaders/gui/progressbar.frag",
&renderer.display
)
));
renderer.display.release_shader_compiler();
}

109
kubi/src/assets/texture.rs Normal file
View file

@ -0,0 +1,109 @@
use glam::UVec2;
use strum::IntoEnumIterator;
use rayon::prelude::*;
use std::{path::PathBuf, io::BufReader, sync::Mutex, num::NonZeroU32};
use crate::{filesystem::open_asset, rendering::Renderer};
use super::AssetPaths;
pub fn load_asset_texture_array<
T: AssetPaths + IntoEnumIterator,
>(
directory: PathBuf,
renderer: &Renderer,
) -> wgpu::Texture {
log::info!("started loading texture array from: \"{}\"", directory.as_os_str().to_str().unwrap());
//Load raw images
let (texture_data, texture_dimensions): (Vec<Vec<u8>>, UVec2) = {
//Image dimensions
//Mutex is required to ensure exact size, without extra temporary allocations
let img_dim: Mutex<Option<(NonZeroU32, NonZeroU32)>> = Mutex::new(None);
//Get image file names into a Vec (because par_iter can't be called directly on IntoEnumIterator::iter())
let file_names: Vec<&'static str> = T::iter().map(|x| x.file_name()).collect();
//Load data in parallel
let raw_images: Vec<Vec<u8>> = file_names.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(open_asset(&path).expect("Failed to open texture file"))
};
//Load and parse image data
let image = image::load(
reader,
image::ImageFormat::Png
).unwrap().to_rgba8();
//Get image dimensions
let dimensions = image.dimensions();
let dim_nonzero = (
NonZeroU32::new(dimensions.0).expect("image dimensions must be non-zero"),
NonZeroU32::new(dimensions.1).expect("image dimensions must be non-zero")
);
//Ensure same size (skip if poisoned)
if !img_dim.is_poisoned() {
let img_dim = img_dim.lock().unwrap();
if let Some(current_size) = img_dim.replace(dim_nonzero) {
assert!(dim_nonzero == current_size, "image dimensions do not match");
}
}
image.into_raw()
}).collect();
//Lock for the final time and retrieve the dimensions
let img_dim = img_dim.lock().unwrap().expect("No images were loaded").clone();
let img_dim_vec = UVec2::new(img_dim.0.get(), img_dim.1.get());
(raw_images, img_dim_vec)
};
//Flatten the texture data
let texture_data_flat = texture_data.concat();
log::info!("done loading texture files, uploading to the gpu");
let texture_extent = wgpu::Extent3d {
width: texture_dimensions.x,
height: texture_dimensions.y,
depth_or_array_layers: texture_data.len() as u32,
};
//Create a wgpu texture
let texture_handle = renderer.device.create_texture(
&wgpu::TextureDescriptor {
size: texture_extent,
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2, ///XXX: is this supposed to be D2 for array tex.?
format: wgpu::TextureFormat::Rgba8UnormSrgb,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
label: Some("diffuse_texture"),
view_formats: &[],
}
);
//Upload texture data
renderer.queue.write_texture(
wgpu::ImageCopyTexture {
texture: &texture_handle,
mip_level: 0,
origin: wgpu::Origin3d::ZERO,
aspect: wgpu::TextureAspect::All,
},
&texture_data_flat,
wgpu::ImageDataLayout {
offset: 0,
bytes_per_row: Some(4 * texture_dimensions.x),
rows_per_image: Some(texture_dimensions.y),
},
texture_extent,
);
texture_handle
}

View file

@ -1,6 +1,6 @@
use shipyard::{UniqueView, UniqueViewMut, NonSendSync, View, Component, IntoIter, IntoWithId, Get, track};
use crate::{
prefabs::ProgressbarShaderPrefab,
assets::ProgressbarShaderPrefab,
rendering::{
RenderTarget,
primitives::rect::RectPrimitive

View file

@ -18,7 +18,7 @@ pub use kubi_shared::transform;
pub(crate) mod rendering;
pub(crate) mod world;
pub(crate) mod player;
pub(crate) mod prefabs;
pub(crate) mod assets;
pub(crate) mod settings;
pub(crate) mod camera;
pub(crate) mod events;
@ -48,7 +48,7 @@ use world::{
tasks::ChunkTaskManager,
};
use player::{spawn_player, MainPlayer};
use prefabs::load_prefabs;
use assets::load_prefabs;
use settings::{load_settings, GameSettings};
use camera::compute_cameras;
use events::{

View file

@ -1,44 +0,0 @@
use strum::IntoEnumIterator;
use rayon::prelude::*;
use std::{path::PathBuf, io::BufReader};
use crate::filesystem::open_asset;
use super::AssetPaths;
pub fn load_texture2darray_prefab<
T: AssetPaths + IntoEnumIterator,
E: Facade
>(
directory: PathBuf,
facade: &E,
mipmaps: MipmapsOption,
) -> SrgbTexture2dArray {
log::info!("started loading {}", 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(open_asset(&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::with_mipmaps(facade, raw_images, mipmaps)
.expect("Failed to upload texture array to GPU")
}

View file

@ -1,7 +1,7 @@
use shipyard::{NonSendSync, UniqueViewMut, UniqueView, View, IntoIter, IntoWithId};
use kubi_shared::{entity::Entity, transform::Transform};
use crate::{
prefabs::ColoredShaderPrefab,
assets::ColoredShaderPrefab,
camera::Camera,
settings::GameSettings
};

View file

@ -10,7 +10,7 @@ use glium::{
use crate::{
world::raycast::LookingAtBlock,
camera::Camera,
prefabs::ColoredShaderPrefab
assets::ColoredShaderPrefab
};
use super::{
RenderTarget,

View file

@ -4,7 +4,7 @@ use crate::{
camera::Camera,
player::MainPlayer,
transform::Transform,
prefabs::{
assets::{
ChunkShaderPrefab,
BlockTexturesPrefab,
ColoredShaderPrefab,