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