From ea9490ad3ab68f65e453ecab33123065fab2b62a Mon Sep 17 00:00:00 2001 From: Asuro Date: Thu, 14 Oct 2021 04:03:46 +0200 Subject: [PATCH] update text texture and mesh!! --- src/game/mod.rs | 143 ++++++++++++++++++++++++++-------------------- src/vulkan/mod.rs | 33 ++++++++--- 2 files changed, 105 insertions(+), 71 deletions(-) diff --git a/src/game/mod.rs b/src/game/mod.rs index b179ad9..1c8bf63 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -11,7 +11,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, Mesh, MeshHandle, TextVertex, Texture, Vertex, VulkanRenderer}; use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable}; use crate::vulkan::mesh::{self, CPUMesh, CPUVertex}; use crate::vulkan::pipelines::vs::ty::ObjectUniformData; @@ -124,7 +124,7 @@ impl TestGame { load_level("levels/test.lvl", self, renderer).unwrap(); println!("Game loaded!"); - let text_obj = self.create_text_object(renderer, "Nice font", 128.); + let text_obj = self.create_text_object(renderer, "aaxx", 128.); self.text_objects.push(text_obj); } @@ -193,7 +193,6 @@ 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_game_object = None; let mut glyph_brush = GlyphBrushBuilder::using_font(self.font.clone()).build(); @@ -201,46 +200,21 @@ 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)) ); - match glyph_brush.process_queued(|rect, text_data| { - let (t, s) = update_text_texture(None, renderer, rect, text_data); - uploaded_texture = Some(t); - texture_size = Some(s); - self.texture_index_counter += 1; - }, Self::convert_vertices) { - Ok(BrushAction::Draw(quads)) => { - 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; - } - let mesh = CPUMesh { - vertices: final_vertices, - indices: final_indices, - local_texture_index: Some(self.texture_index_counter - 1), - local_normal_map_index: None, - name: Some("font_texture".to_string()), - }; - let mesh_index = renderer.upload_mesh(mesh, None); - let mesh_handle = MeshHandle { - index: mesh_index, - diffuse_handle: self.texture_index_counter - 1, - normal_handle: None, - original_path: None, - pipeline_index: 1 - }; - uploaded_game_object = Some(self.add_game_object(renderer, mesh_handle)); - }, - Ok(BrushAction::ReDraw) => {}, - Err(BrushError::TextureTooSmall { suggested }) => { println!("texture too small, suggested: {:?}!", suggested); }, - } + 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, + None, + renderer); TextObject { brush: glyph_brush, texture: uploaded_texture.unwrap(), - game_object: uploaded_game_object.unwrap(), + game_object: self.add_game_object(renderer, mesh_option.unwrap()), current_texture_size: texture_size.unwrap(), } } @@ -257,19 +231,65 @@ 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(text_obj: Option<&mut TextObject>, renderer: &mut VulkanRenderer, rect: Rectangle, text_data: &[u8]) -> (Texture, u32) { - if let Some(text) = text_obj { - println!("Init size: {:?}", rect); - let size = u32::max(rect.width(), rect.height()); - 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()); - (tex, size) +pub fn update_text_texture(old_texture: Option<&mut Texture>, renderer: &mut VulkanRenderer, rect: Rectangle, text_data: &[u8]) -> (Option, u32) { + let size = u32::max(rect.width(), rect.height()); + let final_texture; + + if let Some(old_tex) = old_texture { + println!("rect: {:?}", rect); + final_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) = final_texture.clone() { + println!("Updating texture size. TODO!"); + // renderer.game_data.textures.push(tex.clone()); + // go_handle.get_game_object_mut(renderer).unwrap().textures.texture_index = renderer.game_data.textures.len() - 1; + // renderer.update_descriptor_set(&mut go_handle); + } } else { println!("Init size: {:?}", rect); - let size = u32::max(rect.width(), rect.height()); 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()); - (tex, size) + final_texture = Some(tex) + } + + (final_texture, size) +} + +pub fn process_text_brush_data(result: Result>, BrushError>, texture_index: usize, mesh_index: Option, 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; + + 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 }) => { println!("texture too small, suggested: {:?}!", suggested); None }, } } @@ -283,25 +303,22 @@ pub struct TextObject { impl TextObject { pub fn update_text(&mut self, new_text: &str, new_size: f32, renderer: &mut VulkanRenderer) { self.brush.queue(Section::default().add_text(Text::new(new_text).with_scale(new_size))); - let mut go_handle = self.game_object; let mut old_texture = self.texture.clone(); let mut new_texture = None; - match self.brush.process_queued(|rect, text_data| { - println!("rect: {:?}", rect); - let tex_option = renderer.update_texture(&mut old_texture, text_data, [rect.width(), rect.height(), 1], [rect.min[0], rect.min[1], 0], renderer.device.clone()); - if let Some(tex) = tex_option.clone() { - println!("Updating texture"); - renderer.game_data.textures.push(tex.clone()); - go_handle.get_game_object_mut(renderer).unwrap().textures.texture_index = renderer.game_data.textures.len() - 1; - renderer.update_descriptor_set(&mut go_handle); - } - new_texture = tex_option; - }, TestGame::convert_vertices) { - Ok(_) => {}, - Err(e) => println!("Error! {:?}", e), - } + let mut new_size = None; + + let mesh_index = self.game_object.get_game_object_mut(renderer).unwrap().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(mesh_index), renderer); if let Some(tex) = new_texture { self.texture = tex; } + if let Some(size) = new_size { + self.current_texture_size = size; + } } } \ No newline at end of file diff --git a/src/vulkan/mod.rs b/src/vulkan/mod.rs index 2e0fce4..0b95e1c 100644 --- a/src/vulkan/mod.rs +++ b/src/vulkan/mod.rs @@ -432,14 +432,6 @@ impl VulkanRenderer { } pub fn upload_mesh(self: &mut Self, mesh: CPUMesh, original_path: Option) -> usize { - // let mut collision_mesh = mgf::Mesh::new(); - // mesh.vertices.iter().for_each(|v| { - // collision_mesh.push_vert(v.position.into()); - // }); // TODO: convert vert pos to world space - // for i in (0..mesh.indices.len()).step_by(3) { - // collision_mesh.push_face((mesh.indices[i] as usize, mesh.indices[i + 1] as usize, mesh.indices[i + 2] as usize)); - // } - let index_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::index_buffer(), false, mesh.indices.into_iter()).unwrap(); match mesh.vertices.get(0).unwrap() { @@ -465,6 +457,31 @@ impl VulkanRenderer { } } + pub fn update_mesh(self: &mut Self, mesh_index: usize, vertices: Vec, indices: Vec) { + let index_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::index_buffer(), false, indices.into_iter()).unwrap(); + + match vertices.get(0).unwrap() { + CPUVertex::Vertex3D(_) => { + let verts: Vec = vertices.into_iter().filter_map(|v| match v { + CPUVertex::Vertex3D(vert) => Some(vert), + CPUVertex::VertexText(_) => None + }).collect(); + let mesh = &mut self.game_data.meshes[mesh_index]; + mesh.vertex_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::vertex_buffer(), false, verts.into_iter()).unwrap(); + mesh.index_buffer = index_buffer; + }, + CPUVertex::VertexText(_) => { + let verts: Vec = vertices.into_iter().filter_map(|v| match v { + CPUVertex::Vertex3D(_) => None, + CPUVertex::VertexText(vert) => Some(vert) + }).collect(); + let mesh = &mut self.game_data.meshes_text[mesh_index]; + mesh.vertex_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::vertex_buffer(), false, verts.into_iter()).unwrap(); + mesh.index_buffer = index_buffer; + } + } + } + pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, filter: Filter, wrap: SamplerAddressMode, device: Arc) -> Texture { let dimensions = Dimensions::Dim2d { width, height };