Added texture config file

master
Mark 2023-12-22 22:46:46 -08:00
parent 7cd4d77d15
commit cac65cbb73
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
1 changed files with 72 additions and 33 deletions

View File

@ -1,4 +1,5 @@
use anyhow::Result;
use serde::Deserialize;
use std::{collections::HashMap, fs::File, io::Read, num::NonZeroU32};
use wgpu::BindGroupLayout;
@ -7,50 +8,88 @@ use super::rawtexture::RawTexture;
pub struct TextureArray {
pub bind_group: wgpu::BindGroup,
pub bind_group_layout: BindGroupLayout,
texture_dims: Vec<(u32, u32)>,
texture_indices: HashMap<String, u32>,
textures: HashMap<String, Texture>,
error_texture: Texture,
}
const TEX: &[&str] = &["error", "small", "gypsum", "earth", "a0"];
#[derive(Debug, Clone, Copy)]
pub struct Texture {
pub index: u32, // Index in texture array
pub aspect: f32, // width / height
pub height: f32, // Height in game units
}
impl TextureArray {
pub fn get_texture(&self, name: &str) -> Texture {
let index = match self.texture_indices.get(name) {
Some(x) => *x,
None => 0, // Default texture
};
let dimensions = self.texture_dims[index as usize];
return Texture {
index,
height: 100.0,
aspect: dimensions.0 as f32 / dimensions.1 as f32,
};
#[derive(Deserialize)]
struct Textures {
texture: Vec<Tex>,
error: Tex,
}
pub fn new(device: &wgpu::Device, queue: &wgpu::Queue) -> Result<Self> {
let mut textures: Vec<RawTexture> = Vec::new();
let mut texture_indices: HashMap<String, u32> = HashMap::new();
#[derive(Deserialize)]
struct Tex {
name: String,
path: String,
height: f32,
}
let mut i = 0;
for t in TEX {
let p = format!("assets/{t}.png");
impl Tex {
pub fn read(&self, device: &wgpu::Device, queue: &wgpu::Queue) -> Result<RawTexture> {
let p = format!("{}/{}", TextureArray::INDEX_ROOT, self.path);
let mut f = File::open(&p)?;
let mut bytes = Vec::new();
f.read_to_end(&mut bytes)?;
textures.push(RawTexture::from_bytes(&device, &queue, &bytes, &p).unwrap());
texture_indices.insert(t.to_string(), i);
RawTexture::from_bytes(&device, &queue, &bytes, &self.name)
}
}
impl TextureArray {
const INDEX_PATH: &'static str = "assets/index.toml";
const INDEX_ROOT: &'static str = "assets";
pub fn get_texture(&self, name: &str) -> Texture {
match self.textures.get(name) {
Some(x) => *x,
None => self.error_texture,
}
}
pub fn new(device: &wgpu::Device, queue: &wgpu::Queue) -> Result<Self> {
// Load all textures
let (error_texture, textures, texture_data) = {
let mut texture_data: Vec<RawTexture> = Vec::new();
let mut textures: HashMap<String, Texture> = HashMap::new();
let mut texture_index_string = String::new();
let _ = File::open(Self::INDEX_PATH)?.read_to_string(&mut texture_index_string);
let texture_index: Textures = toml::from_str(&texture_index_string)?;
// First texture is always error
let raw = texture_index.error.read(device, queue)?;
let error_texture = Texture {
index: 0,
height: texture_index.error.height,
aspect: raw.dimensions.0 as f32 / raw.dimensions.1 as f32,
};
texture_data.push(raw);
// Load the rest
let mut i = 1;
for t in texture_index.texture {
let raw = t.read(device, queue)?;
let tx = Texture {
index: i,
height: t.height,
aspect: raw.dimensions.0 as f32 / raw.dimensions.1 as f32,
};
textures.insert(t.name.clone(), tx);
texture_data.push(raw);
i += 1;
}
// One of these overall
(error_texture, textures, texture_data)
};
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
@ -73,19 +112,19 @@ impl TextureArray {
view_dimension: wgpu::TextureViewDimension::D2,
sample_type: wgpu::TextureSampleType::Float { filterable: true },
},
count: NonZeroU32::new(textures.len() as u32),
count: NonZeroU32::new(texture_data.len() as u32),
},
// Texture sampler
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: NonZeroU32::new(textures.len() as u32),
count: NonZeroU32::new(texture_data.len() as u32),
},
],
});
let views: Vec<&wgpu::TextureView> = textures.iter().map(|x| &x.view).collect();
let views: Vec<&wgpu::TextureView> = texture_data.iter().map(|x| &x.view).collect();
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("texture_bind_group"),
layout: &bind_group_layout,
@ -105,8 +144,8 @@ impl TextureArray {
return Ok(Self {
bind_group,
bind_group_layout,
texture_dims: textures.iter().map(|x| x.dimensions).collect(),
texture_indices,
textures,
error_texture,
});
}
}