diff --git a/src/game/mod.rs b/src/game/mod.rs index d0a7b81..fa55917 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -12,7 +12,7 @@ use player::Player; use crate::{config::LogConfig, vulkan}; use crate::input::InputState; -use crate::vulkan::{Game, MeshHandle, TextVertex, Texture, Vertex, VulkanRenderer}; +use crate::vulkan::{Game, MeshHandle, TextVertex, Texture, TextureHandle, Vertex, VulkanRenderer}; use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable}; use crate::vulkan::mesh::{self, CPUMesh, CPUVertex}; use crate::vulkan::pipelines::vs::ty::ObjectUniformData; @@ -83,7 +83,7 @@ impl Game for TestGame { if self.input.button_just_pressed("test") { // self.paused = !self.paused; - self.text_objects[0].update_text(":)", 200.0, renderer, &mut self.game_objects); + self.text_objects[0].update_text("holy shit look at this", 200.0, renderer, &mut self.game_objects); } // Custom game object stuff @@ -197,8 +197,8 @@ impl TestGame { } pub fn create_text_object(&mut self, renderer: &mut VulkanRenderer, text: &str, size: f32) -> TextObject { - let mut texture_size = None; let mut uploaded_texture = None; + let mut uploaded_mesh = None; let mut glyph_brush = GlyphBrushBuilder::using_font(self.font.clone()).build(); @@ -206,24 +206,22 @@ impl TestGame { .add_text(Text::new(text).with_scale(size)) .with_bounds((renderer.game_data.dimensions[0] as f32, renderer.game_data.dimensions[1] as f32)) ); - let mesh_option = process_text_brush_data( - glyph_brush.process_queued(|rect, text_data| { - let (t, s) = update_text_texture(None, renderer, rect, text_data); - uploaded_texture = t; - texture_size = Some(s); - self.texture_index_counter += 1; - }, Self::convert_vertices), - self.texture_index_counter - 1, - uploaded_texture.as_mut(), - None, - None, - renderer); + match glyph_brush.process_queued(|rect, text_data| { + uploaded_texture = update_text_texture(None, renderer, rect, text_data); + self.texture_index_counter += 1; + }, Self::convert_vertices) { + Ok(BrushAction::Draw(quads)) => { + uploaded_mesh = update_text_quads(quads, self.texture_index_counter - 1, None, renderer); + }, + Ok(BrushAction::ReDraw) => {}, + Err(BrushError::TextureTooSmall { suggested }) => { + glyph_brush.resize_texture(suggested.0, suggested.1); + }, + }; TextObject { brush: glyph_brush, - texture: uploaded_texture.unwrap(), - game_object: self.add_game_object(renderer, mesh_option.unwrap()), - current_texture_size: texture_size.unwrap(), + game_object: self.add_game_object(renderer, uploaded_mesh.unwrap()), } } @@ -239,91 +237,76 @@ pub fn print_quat_as_euler(quat: Quaternion) { print!("({:?},{:?},{:?})", Deg::from(euler.x), Deg::from(euler.y), Deg::from(euler.z)); } -pub fn update_text_texture(old_texture: Option<&mut Texture>, renderer: &mut VulkanRenderer, rect: Rectangle, text_data: &[u8]) -> (Option, u32) { +pub fn update_text_texture(old_texture: Option, renderer: &mut VulkanRenderer, rect: Rectangle, text_data: &[u8]) -> Option { let size = u32::max(rect.width(), rect.height()); - let mut final_texture = None; - if let Some(old_tex) = old_texture { - renderer.update_texture(old_tex, text_data, [rect.width(), rect.height(), 1], [rect.min[0], rect.min[1], 0], renderer.device.clone()); + if let Some(tex_handle) = old_texture { + renderer.update_texture(tex_handle, text_data, [rect.width(), rect.height(), 1], [rect.min[0], rect.min[1], 0], renderer.device.clone()); + None } else { let tex = renderer.upload_texture(text_data, size, size, Format::R8Unorm, Filter::Nearest, SamplerAddressMode::ClampToEdge, renderer.device.clone()); renderer.game_data.textures.push(tex.clone()); - final_texture = Some(tex); + Some(renderer.game_data.textures.len() - 1) } - - (final_texture, size) } -pub fn process_text_brush_data(result: Result>, BrushError>, texture_index: usize, texture: Option<&mut Texture>, mesh_index: Option, game_object: Option<&mut GameObject>, renderer: &mut VulkanRenderer) -> Option { - match result { - Ok(BrushAction::Draw(quads)) => { - let mut final_vertices = vec![]; - let mut final_indices: Vec = vec![]; - let mut index_offset = 0; +pub fn update_text_quads(quads: Vec>, texture_index: usize, mesh_index: Option, renderer: &mut VulkanRenderer) -> Option { + let mut final_vertices = vec![]; + let mut final_indices: Vec = vec![]; + let mut index_offset = 0; - for quad in quads { - final_vertices.append(&mut quad.iter().map(|v| CPUVertex::VertexText(TextVertex { position: v.position, uv: [v.uv[0], v.uv[1]] })).collect()); - final_indices.append(&mut [0, 2, 3, 0, 3, 1].iter().map(|x| *x + index_offset).collect()); - index_offset += quad.len() as u32; - } - if let Some(idx) = mesh_index { - renderer.update_mesh(idx, final_vertices, final_indices); - None - } else { - let mesh = CPUMesh { - vertices: final_vertices, - indices: final_indices, - local_texture_index: Some(texture_index), - local_normal_map_index: None, - name: Some("font_texture".to_string()), - }; - - let mesh_index = renderer.upload_mesh(mesh, None); - Some(MeshHandle { - index: mesh_index, - diffuse_handle: texture_index, - normal_handle: None, - original_path: None, - pipeline_index: 1 - }) - } - }, - Ok(BrushAction::ReDraw) => None, - Err(BrushError::TextureTooSmall { suggested }) => { - let size = Dimensions::Dim2d { width: suggested.0, height: suggested.1 }; - renderer.resize_texture(game_object.unwrap(), texture.unwrap(), size, renderer.device.clone()); - None - }, + for quad in quads { + final_vertices.append(&mut quad.iter().map(|v| CPUVertex::VertexText(TextVertex { position: v.position, uv: [v.uv[0], v.uv[1]] })).collect()); + final_indices.append(&mut [0, 2, 3, 0, 3, 1].iter().map(|x| *x + index_offset).collect()); + index_offset += quad.len() as u32; + } + if let Some(idx) = mesh_index { + renderer.update_mesh(idx, final_vertices, final_indices); + None + } else { + let mesh = CPUMesh { + vertices: final_vertices, + indices: final_indices, + local_texture_index: Some(texture_index), + local_normal_map_index: None, + name: Some("font_texture".to_string()), + }; + + let mesh_index = renderer.upload_mesh(mesh, None); + Some(MeshHandle { + index: mesh_index, + diffuse_handle: texture_index, + normal_handle: None, + original_path: None, + pipeline_index: 1 + }) } } pub struct TextObject { pub brush: GlyphBrush>, - pub texture: Texture, pub game_object: GameObjectHandle, - pub current_texture_size: u32, } impl TextObject { pub fn update_text(&mut self, new_text: &str, new_size: f32, renderer: &mut VulkanRenderer, game_objects: &mut Vec) { self.brush.queue(Section::default().add_text(Text::new(new_text).with_scale(new_size))); - let mut old_texture = self.texture.clone(); - let mut new_texture = None; - let mut new_size = None; let go = &mut game_objects[self.game_object]; let mesh_index = go.mesh_index; - process_text_brush_data(self.brush.process_queued(|rect, text_data| { - let (t, s) = update_text_texture(Some(&mut old_texture), renderer, rect, text_data); - new_texture = t; - new_size = Some(s); - }, TestGame::convert_vertices), 420, Some(&mut self.texture), Some(mesh_index), Some(go), renderer); - if let Some(tex) = new_texture { - self.texture = tex; - } - if let Some(size) = new_size { - self.current_texture_size = size; + match self.brush.process_queued(|rect, text_data| { + update_text_texture(Some(go.textures.texture_index), renderer, rect, text_data); + }, TestGame::convert_vertices) { + Ok(BrushAction::Draw(quads)) => { + update_text_quads(quads, 420, Some(mesh_index), renderer); + }, + Ok(BrushAction::ReDraw) => {}, + Err(BrushError::TextureTooSmall { suggested }) => { + let size = Dimensions::Dim2d { width: suggested.0, height: suggested.1 }; + renderer.resize_texture(go, go.textures.texture_index, size); + self.brush.resize_texture(suggested.0, suggested.1); + }, } } } \ No newline at end of file diff --git a/src/vulkan/mod.rs b/src/vulkan/mod.rs index 4f48436..d6bdeed 100644 --- a/src/vulkan/mod.rs +++ b/src/vulkan/mod.rs @@ -568,7 +568,9 @@ impl VulkanRenderer { Texture { image: image_view, sampler } } - pub fn update_texture(&mut self, texture: &mut Texture, new_data: &[u8], new_data_dimensions: [u32; 3], new_data_offset: [u32; 3], device: Arc) { + pub fn update_texture(&mut self, tex_handle: TextureHandle, new_data: &[u8], new_data_dimensions: [u32; 3], new_data_offset: [u32; 3], device: Arc) { + let texture = &mut self.game_data.textures[tex_handle]; + let old_sub_image = SubImage::new( texture.image.clone(), 0, @@ -604,7 +606,9 @@ impl VulkanRenderer { future.flush().unwrap(); } - pub fn resize_texture(&mut self, game_object: &mut GameObject, old_texture: &mut Texture, new_size: Dimensions, device: Arc) { + pub fn resize_texture(&mut self, game_object: &mut GameObject, texture_handle: TextureHandle, new_size: Dimensions) { + let mut texture = &mut self.game_data.textures[texture_handle]; + let new_image_usage = ImageUsage { transfer_destination: true, transfer_source: true, @@ -613,17 +617,17 @@ impl VulkanRenderer { }; let (new_image_view, new_image_initializer) = ImmutableImage::uninitialized( - device.clone(), + self.device.clone(), new_size, - old_texture.image.format(), - old_texture.image.mipmap_levels(), + texture.image.format(), + texture.image.mipmap_levels(), new_image_usage, ImageLayout::ShaderReadOnlyOptimal, - device.active_queue_families(), + self.device.active_queue_families(), ).unwrap(); let old_sub_image = SubImage::new( - old_texture.image.clone(), + texture.image.clone(), 0, 1, 0, @@ -640,7 +644,7 @@ impl VulkanRenderer { ImageLayout::ShaderReadOnlyOptimal, ); - let mut cbb = AutoCommandBufferBuilder::new(device.clone(), self.queue.family()).unwrap(); + let mut cbb = AutoCommandBufferBuilder::new(self.device.clone(), self.queue.family()).unwrap(); cbb.copy_image( old_sub_image.clone(), @@ -648,7 +652,7 @@ impl VulkanRenderer { 0, 0, new_sub_image.clone(), - [0, 0, 0], + [10, 0, 0], 0, 0, old_sub_image.dimensions().width_height_depth(), @@ -659,7 +663,7 @@ impl VulkanRenderer { let future = cb.execute(self.queue.clone()).unwrap(); future.flush().unwrap(); - old_texture.image = new_image_view; + texture.image = new_image_view; game_object.init_descriptor_sets(self); } diff --git a/src/vulkan/pipelines.rs b/src/vulkan/pipelines.rs index ecbd237..bd09c7d 100644 --- a/src/vulkan/pipelines.rs +++ b/src/vulkan/pipelines.rs @@ -350,6 +350,7 @@ impl Drawcall for TextShader { let builder = PersistentDescriptorSet::start(descriptor_set_layout.clone()); let diffuse = &renderer.game_data.textures[textures.texture_index]; + println!("Using diffuse image with size {:?}", diffuse.image.dimensions()); descriptor_set = Arc::new(builder .add_buffer(uniform_buffer.clone()).unwrap()