update text texture and mesh!!
This commit is contained in:
135
src/game/mod.rs
135
src/game/mod.rs
@@ -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(
|
||||||
|
glyph_brush.process_queued(|rect, text_data| {
|
||||||
let (t, s) = update_text_texture(None, renderer, rect, text_data);
|
let (t, s) = update_text_texture(None, renderer, rect, text_data);
|
||||||
uploaded_texture = Some(t);
|
uploaded_texture = t;
|
||||||
texture_size = Some(s);
|
texture_size = Some(s);
|
||||||
self.texture_index_counter += 1;
|
self.texture_index_counter += 1;
|
||||||
}, Self::convert_vertices) {
|
}, Self::convert_vertices),
|
||||||
Ok(BrushAction::Draw(quads)) => {
|
self.texture_index_counter - 1,
|
||||||
let mut final_vertices = vec![];
|
None,
|
||||||
let mut final_indices: Vec<u32> = vec![];
|
renderer);
|
||||||
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); },
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
println!("Init size: {:?}", rect);
|
|
||||||
let size = u32::max(rect.width(), rect.height());
|
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 final_texture;
|
||||||
renderer.game_data.textures.push(tex.clone());
|
|
||||||
(tex, size)
|
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 {
|
} 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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 };
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user