From 86392d4c05c2a5929f531ede2623240e2904efc3 Mon Sep 17 00:00:00 2001 From: lisk77 Date: Sun, 2 Nov 2025 02:11:17 +0100 Subject: [PATCH] feat(graphics_resource_manager): added font atlas and a way to load a shader directly from a source string (wgsl only right now) --- .../src/graphic_resource_manager.rs | 159 +++++------------- 1 file changed, 41 insertions(+), 118 deletions(-) diff --git a/crates/comet_resources/src/graphic_resource_manager.rs b/crates/comet_resources/src/graphic_resource_manager.rs index 9198b34..f092e0c 100644 --- a/crates/comet_resources/src/graphic_resource_manager.rs +++ b/crates/comet_resources/src/graphic_resource_manager.rs @@ -1,14 +1,19 @@ use std::{collections::HashMap, path::Path}; -use crate::font::Font; -use crate::texture_atlas::{TextureAtlas, TextureRegion}; -use crate::{font, texture, Texture}; +use crate::{ + font::Font, + texture_atlas::{TextureAtlas, TextureRegion}, + Texture, +}; use comet_log::info; -use wgpu::naga::ShaderStage; -use wgpu::{naga, Device, FilterMode, Queue, ShaderModule, TextureFormat, TextureUsages}; +use wgpu::{ + naga::{self, ShaderStage}, + Device, Queue, ShaderModule, +}; pub struct GraphicResourceManager { texture_atlas: TextureAtlas, + font_atlas: TextureAtlas, fonts: Vec, data_files: HashMap, shaders: HashMap, @@ -18,6 +23,7 @@ impl GraphicResourceManager { pub fn new() -> Self { Self { texture_atlas: TextureAtlas::empty(), + font_atlas: TextureAtlas::empty(), fonts: Vec::new(), data_files: HashMap::new(), shaders: HashMap::new(), @@ -28,6 +34,14 @@ impl GraphicResourceManager { &self.texture_atlas } + pub fn font_atlas(&self) -> &TextureAtlas { + &self.font_atlas + } + + pub fn set_font_atlas(&mut self, font_atlas: TextureAtlas) { + self.font_atlas = font_atlas + } + pub fn texture_locations(&self) -> &HashMap { &self.texture_atlas.textures() } @@ -40,6 +54,10 @@ impl GraphicResourceManager { &self.fonts } + pub fn fonts_mut(&mut self) -> &mut Vec { + &mut self.fonts + } + pub fn get_glyph(&self, font: &str, ch: char) -> Option<&TextureRegion> { self.fonts .iter() @@ -49,10 +67,6 @@ impl GraphicResourceManager { pub fn set_texture_atlas(&mut self, texture_atlas: TextureAtlas) { self.texture_atlas = texture_atlas; - - // This is just for testing purposes - //self.texture_locations.insert("normal_comet.png".to_string(), ([0,0], [15,15])); - //self.texture_locations.insert("green_comet.png".to_string(), ([0,15], [15,31])); } pub fn create_texture_atlas(&mut self, paths: Vec) { @@ -95,9 +109,9 @@ impl GraphicResourceManager { /// `shader_stage` is only needed if it is a GLSL shader, so default to None if it isn't GLSL pub fn load_shader( &mut self, + device: &Device, shader_stage: Option, file_name: &str, - device: &Device, ) -> anyhow::Result<()> { let shader_source = self.load_string(file_name)?; @@ -127,6 +141,23 @@ impl GraphicResourceManager { Ok(()) } + /// Loads the shader from a source code string + /// Right now only works with wgsl + pub fn load_shader_from_string( + &mut self, + device: &Device, + shader_name: &str, + shader_src: &str, + ) -> anyhow::Result<()> { + let module = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some(shader_name), + source: wgpu::ShaderSource::Wgsl(shader_src.into()), + }); + + self.shaders.insert(shader_name.to_string(), module); + Ok(()) + } + pub fn get_shader(&self, shader: &str) -> Option<&ShaderModule> { self.shaders.get(shader) } @@ -137,112 +168,4 @@ impl GraphicResourceManager { info!("Font {} loaded!", font.name()); self.fonts.push(font); } - - /*pub async fn load_model( - &self, - file_name: &str, - device: &wgpu::Device, - queue: &wgpu::Queue, - layout: &wgpu::BindGroupLayout, - ) -> anyhow::Result { - let obj_text = self.load_string(file_name).await?; - let obj_cursor = Cursor::new(obj_text); - let mut obj_reader = BufReader::new(obj_cursor); - - let (models, obj_materials) = tobj::load_obj_buf_async( - &mut obj_reader, - &tobj::LoadOptions { - triangulate: true, - single_index: true, - ..Default::default() - }, - |p| async move { - let mat_text = self.load_string(&p).await.unwrap(); - tobj::load_mtl_buf(&mut BufReader::new(Cursor::new(mat_text))) - }, - ) - .await?; - - let mut materials = Vec::new(); - for m in obj_materials? { - let diffuse_texture = self.load_texture(&m.diffuse_texture, false, device, queue).await?; - let normal_texture = self.load_texture(&m.normal_texture, true, device, queue).await?; - let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::TextureView(&diffuse_texture.view), - }, - wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler), - }, - ], - label: None, - }); - - materials.push(model::Material { - name: m.name, - diffuse_texture, - bind_group, - }); - } - - let meshes = models - .into_iter() - .map(|m| { - let vertices = (0..m.mesh.positions.len() / 3) - .map(|i| { - if m.mesh.normals.is_empty() { - model::ModelVertex { - position: [ - m.mesh.positions[i * 3], - m.mesh.positions[i * 3 + 1], - m.mesh.positions[i * 3 + 2], - ], - tex_coords: [m.mesh.texcoords[i * 2], 1.0 - m.mesh.texcoords[i * 2 + 1]], - normal: [0.0, 0.0, 0.0], - } - } else { - model::ModelVertex { - position: [ - m.mesh.positions[i * 3], - m.mesh.positions[i * 3 + 1], - m.mesh.positions[i * 3 + 2], - ], - tex_coords: [m.mesh.texcoords[i * 2], 1.0 - m.mesh.texcoords[i * 2 + 1]], - normal: [ - m.mesh.normals[i * 3], - m.mesh.normals[i * 3 + 1], - m.mesh.normals[i * 3 + 2], - ], - } - } - }) - .collect::>(); - - let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some(&format!("{:?} Vertex Buffer", file_name)), - contents: bytemuck::cast_slice(&vertices), - usage: wgpu::BufferUsages::VERTEX, - }); - let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some(&format!("{:?} Index Buffer", file_name)), - contents: bytemuck::cast_slice(&m.mesh.indices), - usage: wgpu::BufferUsages::INDEX, - }); - - model::Mesh { - name: file_name.to_string(), - vertex_buffer, - index_buffer, - num_elements: m.mesh.indices.len() as u32, - material: m.mesh.material_id.unwrap_or(0), - } - }) - .collect::>(); - - Ok(model::Model { meshes, materials }) - }*/ }