fix(resources): load_string is no longer build.rs dependent

This commit is contained in:
lisk77 2025-10-31 01:10:31 +01:00
parent c2776e1bc4
commit fafc7d22a4
2 changed files with 480 additions and 495 deletions

View file

@ -1,19 +1,17 @@
use std::{ use std::{collections::HashMap, path::Path};
collections::HashMap, path::Path
};
use wgpu::{naga, Device, FilterMode, Queue, ShaderModule, TextureFormat, TextureUsages};
use wgpu::naga::ShaderStage;
use comet_log::info;
use crate::{font, texture, Texture};
use crate::font::Font; use crate::font::Font;
use crate::texture_atlas::{TextureAtlas, TextureRegion}; use crate::texture_atlas::{TextureAtlas, TextureRegion};
use crate::{font, texture, Texture};
use comet_log::info;
use wgpu::naga::ShaderStage;
use wgpu::{naga, Device, FilterMode, Queue, ShaderModule, TextureFormat, TextureUsages};
pub struct GraphicResourceManager { pub struct GraphicResourceManager {
texture_atlas: TextureAtlas, texture_atlas: TextureAtlas,
fonts: Vec<Font>, fonts: Vec<Font>,
data_files: HashMap<String, String>, data_files: HashMap<String, String>,
shaders: HashMap<String, ShaderModule> shaders: HashMap<String, ShaderModule>,
} }
impl GraphicResourceManager { impl GraphicResourceManager {
@ -22,7 +20,7 @@ impl GraphicResourceManager {
texture_atlas: TextureAtlas::empty(), texture_atlas: TextureAtlas::empty(),
fonts: Vec::new(), fonts: Vec::new(),
data_files: HashMap::new(), data_files: HashMap::new(),
shaders: HashMap::new() shaders: HashMap::new(),
} }
} }
@ -43,7 +41,10 @@ impl GraphicResourceManager {
} }
pub fn get_glyph(&self, font: &str, ch: char) -> Option<&TextureRegion> { pub fn get_glyph(&self, font: &str, ch: char) -> Option<&TextureRegion> {
self.fonts.iter().find(|f| f.name() == font).and_then(|f| f.get_glyph(ch)) self.fonts
.iter()
.find(|f| f.name() == font)
.and_then(|f| f.get_glyph(ch))
} }
pub fn set_texture_atlas(&mut self, texture_atlas: TextureAtlas) { pub fn set_texture_atlas(&mut self, texture_atlas: TextureAtlas) {
@ -59,10 +60,13 @@ impl GraphicResourceManager {
} }
pub fn load_string(&self, file_name: &str) -> anyhow::Result<String> { pub fn load_string(&self, file_name: &str) -> anyhow::Result<String> {
let path = Path::new(std::env::var("OUT_DIR")?.as_str()) let base_path = std::env::var("OUT_DIR")
.join("res") .map(|p| Path::new(&p).to_path_buf())
.join(file_name); .unwrap_or_else(|_| Path::new(".").to_path_buf());
let txt = std::fs::read_to_string(path)?;
let path = base_path.join(file_name);
let txt = std::fs::read_to_string(&path)
.map_err(|e| anyhow::anyhow!("Failed to load {}: {}", path.display(), e))?;
Ok(txt) Ok(txt)
} }
@ -93,32 +97,28 @@ impl GraphicResourceManager {
&mut self, &mut self,
shader_stage: Option<ShaderStage>, shader_stage: Option<ShaderStage>,
file_name: &str, file_name: &str,
device: &Device device: &Device,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let shader_source = self.load_string(file_name)?; let shader_source = self.load_string(file_name)?;
let module = match file_name.split('.').last() { let module = match file_name.split('.').last() {
Some ("wgsl") => { Some("wgsl") => device.create_shader_module(wgpu::ShaderModuleDescriptor {
device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some(file_name),
label: Some(file_name.clone()), source: wgpu::ShaderSource::Wgsl(shader_source.into()),
source: wgpu::ShaderSource::Wgsl(shader_source.into()) }),
})
},
Some("glsl") => { Some("glsl") => {
if let Some(stage) = shader_stage { if let Some(stage) = shader_stage {
device.create_shader_module(wgpu::ShaderModuleDescriptor { device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some(file_name.clone()), label: Some(file_name),
source: wgpu::ShaderSource::Glsl { source: wgpu::ShaderSource::Glsl {
shader: shader_source.into(), shader: shader_source.into(),
stage, stage,
defines: naga::FastHashMap::default() defines: naga::FastHashMap::default(),
} },
}) })
} else {
return Err(anyhow::anyhow!("GLSL shader needs a stage"));
} }
else {
return Err(anyhow::anyhow!("GLSL shader needs a stage"))
}
} }
_ => return Err(anyhow::anyhow!("Unsupported shader type")), _ => return Err(anyhow::anyhow!("Unsupported shader type")),
}; };

View file

@ -1,6 +1,5 @@
use anyhow::*; use anyhow::*;
use image::{DynamicImage, GenericImageView, RgbaImage}; use image::{DynamicImage, GenericImageView, RgbaImage};
use wgpu::{Device, Queue};
#[derive(Debug)] #[derive(Debug)]
pub struct Texture { pub struct Texture {
@ -53,7 +52,7 @@ impl Texture {
texture, texture,
view, view,
sampler, sampler,
size, // NEW! size,
} }
} }
@ -183,19 +182,12 @@ impl Texture {
} }
} }
pub fn to_image( pub fn to_image(&self, device: &wgpu::Device, queue: &wgpu::Queue) -> Result<DynamicImage> {
&self,
device: &wgpu::Device,
queue: &wgpu::Queue,
) -> Result<DynamicImage> {
// Size of the texture
let width = self.size.width; let width = self.size.width;
let height = self.size.height; let height = self.size.height;
// Calculate the size of the texture in bytes
let texture_size_bytes = (4 * width * height) as wgpu::BufferAddress; let texture_size_bytes = (4 * width * height) as wgpu::BufferAddress;
// Create a buffer for reading the texture data back from the GPU
let buffer = device.create_buffer(&wgpu::BufferDescriptor { let buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("Texture Readback Buffer"), label: Some("Texture Readback Buffer"),
size: texture_size_bytes, size: texture_size_bytes,
@ -203,12 +195,10 @@ impl Texture {
mapped_at_creation: false, mapped_at_creation: false,
}); });
// Create a command encoder to copy the texture data to the buffer
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Texture to Buffer Encoder"), label: Some("Texture to Buffer Encoder"),
}); });
// Define the copy operation from the texture to the buffer
encoder.copy_texture_to_buffer( encoder.copy_texture_to_buffer(
wgpu::ImageCopyTexture { wgpu::ImageCopyTexture {
texture: &self.texture, texture: &self.texture,
@ -227,10 +217,8 @@ impl Texture {
self.size, self.size,
); );
// Submit the command to the queue
queue.submit(Some(encoder.finish())); queue.submit(Some(encoder.finish()));
// Wait for the GPU to finish the operation
let buffer_slice = buffer.slice(..); let buffer_slice = buffer.slice(..);
buffer_slice.map_async(wgpu::MapMode::Read, |result| { buffer_slice.map_async(wgpu::MapMode::Read, |result| {
if let Err(e) = result { if let Err(e) = result {
@ -238,17 +226,13 @@ impl Texture {
} }
}); });
// Get the buffer data
let data = buffer_slice.get_mapped_range(); let data = buffer_slice.get_mapped_range();
// Convert the raw data into an image::RgbaImage
let image = RgbaImage::from_raw(width, height, data.to_vec()) let image = RgbaImage::from_raw(width, height, data.to_vec())
.ok_or_else(|| anyhow!("Failed to create image from raw texture data"))?; .ok_or_else(|| anyhow!("Failed to create image from raw texture data"))?;
// Unmap the buffer now that we're done with it
buffer.unmap(); buffer.unmap();
// Convert the RgbaImage into a DynamicImage
Ok(DynamicImage::ImageRgba8(image)) Ok(DynamicImage::ImageRgba8(image))
} }
} }
@ -323,3 +307,4 @@ impl CubeTexture {
&self.sampler &self.sampler
} }
} }