update text texture and mesh!!

This commit is contained in:
2021-10-14 04:03:46 +02:00
parent 78917d96d1
commit ea9490ad3a
2 changed files with 105 additions and 71 deletions

View File

@@ -11,7 +11,7 @@ use player::Player;
use crate::{config::LogConfig, vulkan}; use crate::{config::LogConfig, vulkan};
use crate::input::InputState; 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::gameobject::{GameObject, GameObjectHandle, Updatable};
use crate::vulkan::mesh::{self, CPUMesh, CPUVertex}; use crate::vulkan::mesh::{self, CPUMesh, CPUVertex};
use crate::vulkan::pipelines::vs::ty::ObjectUniformData; use crate::vulkan::pipelines::vs::ty::ObjectUniformData;
@@ -124,7 +124,7 @@ impl TestGame {
load_level("levels/test.lvl", self, renderer).unwrap(); load_level("levels/test.lvl", self, renderer).unwrap();
println!("Game loaded!"); 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); 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 { pub fn create_text_object(&mut self, renderer: &mut VulkanRenderer, text: &str, size: f32) -> TextObject {
let mut texture_size = None; let mut texture_size = None;
let mut uploaded_texture = None; let mut uploaded_texture = None;
let mut uploaded_game_object = None;
let mut glyph_brush = GlyphBrushBuilder::using_font(self.font.clone()).build(); 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)) .add_text(Text::new(text).with_scale(size))
.with_bounds((renderer.game_data.dimensions[0] as f32, renderer.game_data.dimensions[1] as f32)) .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 mesh_option = process_text_brush_data(
let (t, s) = update_text_texture(None, renderer, rect, text_data); glyph_brush.process_queued(|rect, text_data| {
uploaded_texture = Some(t); let (t, s) = update_text_texture(None, renderer, rect, text_data);
texture_size = Some(s); uploaded_texture = t;
self.texture_index_counter += 1; texture_size = Some(s);
}, Self::convert_vertices) { self.texture_index_counter += 1;
Ok(BrushAction::Draw(quads)) => { }, Self::convert_vertices),
let mut final_vertices = vec![]; self.texture_index_counter - 1,
let mut final_indices: Vec<u32> = vec![]; None,
let mut index_offset = 0; renderer);
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); },
}
TextObject { TextObject {
brush: glyph_brush, brush: glyph_brush,
texture: uploaded_texture.unwrap(), 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(), current_texture_size: texture_size.unwrap(),
} }
} }
@@ -257,19 +231,65 @@ pub fn print_quat_as_euler(quat: Quaternion<f32>) {
print!("({:?},{:?},{:?})", Deg::from(euler.x), Deg::from(euler.y), Deg::from(euler.z)); 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<u32>, text_data: &[u8]) -> (Texture, u32) { pub fn update_text_texture(old_texture: Option<&mut Texture>, renderer: &mut VulkanRenderer, rect: Rectangle<u32>, text_data: &[u8]) -> (Option<Texture>, u32) {
if let Some(text) = text_obj { let size = u32::max(rect.width(), rect.height());
println!("Init size: {:?}", rect); let final_texture;
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()); if let Some(old_tex) = old_texture {
renderer.game_data.textures.push(tex.clone()); println!("rect: {:?}", rect);
(tex, size) 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 { } else {
println!("Init size: {:?}", rect); 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()); 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()); renderer.game_data.textures.push(tex.clone());
(tex, size) final_texture = Some(tex)
}
(final_texture, size)
}
pub fn process_text_brush_data(result: Result<BrushAction<Vec<TextVertex>>, BrushError>, texture_index: usize, mesh_index: Option<usize>, renderer: &mut VulkanRenderer) -> Option<MeshHandle> {
match result {
Ok(BrushAction::Draw(quads)) => {
let mut final_vertices = vec![];
let mut final_indices: Vec<u32> = 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 { impl TextObject {
pub fn update_text(&mut self, new_text: &str, new_size: f32, renderer: &mut VulkanRenderer) { 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))); 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 old_texture = self.texture.clone();
let mut new_texture = None; let mut new_texture = None;
match self.brush.process_queued(|rect, text_data| { let mut new_size = None;
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()); let mesh_index = self.game_object.get_game_object_mut(renderer).unwrap().mesh_index;
if let Some(tex) = tex_option.clone() {
println!("Updating texture"); process_text_brush_data(self.brush.process_queued(|rect, text_data| {
renderer.game_data.textures.push(tex.clone()); let (t, s) = update_text_texture(Some(&mut old_texture), renderer, rect, text_data);
go_handle.get_game_object_mut(renderer).unwrap().textures.texture_index = renderer.game_data.textures.len() - 1; new_texture = t;
renderer.update_descriptor_set(&mut go_handle); new_size = Some(s);
} }, TestGame::convert_vertices), 420, Some(mesh_index), renderer);
new_texture = tex_option;
}, TestGame::convert_vertices) {
Ok(_) => {},
Err(e) => println!("Error! {:?}", e),
}
if let Some(tex) = new_texture { if let Some(tex) = new_texture {
self.texture = tex; self.texture = tex;
} }
if let Some(size) = new_size {
self.current_texture_size = size;
}
} }
} }

View File

@@ -432,14 +432,6 @@ impl VulkanRenderer {
} }
pub fn upload_mesh(self: &mut Self, mesh: CPUMesh, original_path: Option<String>) -> usize { pub fn upload_mesh(self: &mut Self, mesh: CPUMesh, original_path: Option<String>) -> 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(); let index_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::index_buffer(), false, mesh.indices.into_iter()).unwrap();
match mesh.vertices.get(0).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<CPUVertex>, indices: Vec<u32>) {
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<Vertex> = 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<TextVertex> = 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<Device>) -> Texture { pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, filter: Filter, wrap: SamplerAddressMode, device: Arc<Device>) -> Texture {
let dimensions = Dimensions::Dim2d { width, height }; let dimensions = Dimensions::Dim2d { width, height };