font i guess?

This commit is contained in:
2021-10-13 21:53:12 +02:00
parent 00d6d1c5f8
commit db9a455311
7 changed files with 228 additions and 94 deletions

View File

@@ -1,6 +1,6 @@
use std::time::SystemTime;
use cgmath::{Deg, Euler, Quaternion, vec3};
use glyph_brush::{BrushAction, BrushError, GlyphBrushBuilder, Section, Text};
use glyph_brush::{BrushAction, BrushError, GlyphBrush, GlyphBrushBuilder, GlyphVertex, Section, Text};
use glyph_brush::ab_glyph::FontArc;
use vulkano::format::Format;
use vulkano::sampler::{Filter, SamplerAddressMode};
@@ -11,7 +11,7 @@ use player::Player;
use crate::{config::LogConfig, vulkan};
use crate::input::InputState;
use crate::vulkan::{Game, MeshHandle, TextVertex, Vertex, VulkanRenderer};
use crate::vulkan::{Game, 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;
@@ -23,11 +23,13 @@ pub struct TestGame {
pub input: InputState,
pub player: Player,
pub game_objects: Vec<GameObjectHandle>,
pub text_objects: Vec<TextObject>,
pub log_config: LogConfig,
pub texture_index_counter: usize,
pub last_time: f32,
pub components: Vec<Box<dyn Updatable>>,
pub paused: bool,
pub font: FontArc
}
impl Game for TestGame {
@@ -73,7 +75,8 @@ impl Game for TestGame {
}
if self.input.button_just_pressed("test") {
self.paused = !self.paused;
// self.paused = !self.paused;
self.text_objects[0].update_text("yeet", 100.0, renderer);
}
// Custom game object stuff
@@ -107,11 +110,13 @@ impl TestGame {
input: InputState::new(toml_path, log_config),
player: Player::new(),
game_objects: vec![],
text_objects: vec![],
log_config,
texture_index_counter: 0,
last_time: 0.0,
components: vec![],
paused: false,
font: FontArc::try_from_slice(include_bytes!("../../models/FiraCode-Regular.ttf")).unwrap(),
}
}
@@ -119,60 +124,8 @@ impl TestGame {
load_level("levels/test.lvl", self, renderer).unwrap();
println!("Game loaded!");
let font = FontArc::try_from_slice(include_bytes!("../../models/OverpassRegular.ttf")).unwrap();
let mut glyph_brush = GlyphBrushBuilder::using_font(font).build();
let mut tex_min_size = None;
let mut tex_max_size = None;
glyph_brush.queue(Section::default().add_text(Text::new("penis lol").with_scale(100.)));
match glyph_brush.process_queued(|rect, text_data| {
renderer.upload_texture(text_data, rect.width(), rect.height(), Format::R8Unorm, Filter::Nearest, SamplerAddressMode::ClampToEdge, renderer.device.clone());
self.texture_index_counter += 1;
tex_max_size = Some(u32::max(rect.width(), rect.height()));
tex_min_size = Some(u32::min(rect.width(), rect.height()));
}, |vertex_data| {
println!("VD: {:?}", vertex_data);
let result = vec![
TextVertex { position: [vertex_data.pixel_coords.min.x, vertex_data.pixel_coords.min.y, 0.], uv: [vertex_data.tex_coords.min.x, vertex_data.tex_coords.min.y] },
TextVertex { position: [vertex_data.pixel_coords.min.x, vertex_data.pixel_coords.max.y, 0.], uv: [vertex_data.tex_coords.min.x, vertex_data.tex_coords.max.y] },
TextVertex { position: [vertex_data.pixel_coords.max.x, vertex_data.pixel_coords.min.y, 0.], uv: [vertex_data.tex_coords.max.x, vertex_data.tex_coords.min.y] },
TextVertex { position: [vertex_data.pixel_coords.max.x, vertex_data.pixel_coords.max.y, 0.], uv: [vertex_data.tex_coords.max.x, vertex_data.tex_coords.max.y] },
];
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] * (tex_max_size.unwrap() as f32) / (tex_min_size.unwrap() as f32) ] })).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
};
let mut game_object_handle = self.add_game_object(renderer, mesh_handle);
game_object_handle.get_game_object_mut(renderer).unwrap().scale = vec3(0.1, 0.1, 0.1);
self.game_objects.push(game_object_handle);
},
Ok(BrushAction::ReDraw) => {},
Err(BrushError::TextureTooSmall { suggested: _ }) => { println!("texture too small!"); },
}
let text_obj = self.create_text_object(renderer, "Nice font", 24.);
self.text_objects.push(text_obj);
}
pub fn offset_texture_id(&mut self, local_tex_id: Option<usize>) -> usize {
@@ -208,7 +161,8 @@ impl TestGame {
for doc_image in document.images() {
let texture_start_time = SystemTime::now();
vulkan::dds::upload_texture_from_file(&format!("models/textures/{}.dds", doc_image.name().unwrap()), renderer).unwrap();
let texture = vulkan::dds::upload_texture_from_file(&format!("models/textures/{}.dds", doc_image.name().unwrap()), renderer).unwrap();
renderer.game_data.textures.push(texture);
self.texture_index_counter += 1;
if self.log_config.mesh_load_info {
@@ -225,6 +179,74 @@ impl TestGame {
self.game_objects.last().unwrap().clone()
}
fn convert_vertices(vertex_data: GlyphVertex) -> Vec<TextVertex> {
// println!("VD: {:?}", vertex_data);
let result = vec![
TextVertex { position: [vertex_data.pixel_coords.min.x, vertex_data.pixel_coords.min.y, 0.], uv: [vertex_data.tex_coords.min.x, vertex_data.tex_coords.min.y] },
TextVertex { position: [vertex_data.pixel_coords.min.x, vertex_data.pixel_coords.max.y, 0.], uv: [vertex_data.tex_coords.min.x, vertex_data.tex_coords.max.y] },
TextVertex { position: [vertex_data.pixel_coords.max.x, vertex_data.pixel_coords.min.y, 0.], uv: [vertex_data.tex_coords.max.x, vertex_data.tex_coords.min.y] },
TextVertex { position: [vertex_data.pixel_coords.max.x, vertex_data.pixel_coords.max.y, 0.], uv: [vertex_data.tex_coords.max.x, vertex_data.tex_coords.max.y] },
];
result
}
pub fn create_text_object(&mut self, renderer: &mut VulkanRenderer, text: &str, size: f32) -> TextObject {
let mut tex_min_size = None;
let mut tex_max_size = None;
let mut uploaded_texture = None;
let mut uploaded_game_object = None;
let mut glyph_brush = GlyphBrushBuilder::using_font(self.font.clone()).build();
glyph_brush.queue(Section::default()
.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 tex = renderer.upload_texture(text_data, rect.width(), rect.height(), Format::R8Unorm, Filter::Nearest, SamplerAddressMode::ClampToEdge, renderer.device.clone());
renderer.game_data.textures.push(tex.clone());
uploaded_texture = Some(tex);
self.texture_index_counter += 1;
tex_max_size = Some(u32::max(rect.width(), rect.height()));
tex_min_size = Some(u32::min(rect.width(), rect.height()));
}, Self::convert_vertices) {
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] * (tex_max_size.unwrap() as f32) / (tex_min_size.unwrap() as f32) ] })).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 {
brush: glyph_brush,
texture: uploaded_texture.unwrap(),
game_object: uploaded_game_object.unwrap()
}
}
pub fn clear_level(&mut self, renderer: &mut VulkanRenderer) {
self.game_objects.clear();
self.texture_index_counter = 0;
@@ -235,4 +257,32 @@ impl TestGame {
pub fn print_quat_as_euler(quat: Quaternion<f32>) {
let euler = Euler::from(quat);
print!("({:?},{:?},{:?})", Deg::from(euler.x), Deg::from(euler.y), Deg::from(euler.z));
}
pub struct TextObject {
pub brush: GlyphBrush<Vec<TextVertex>>,
pub texture: Texture,
pub game_object: GameObjectHandle
}
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| {
let tex = renderer.blit_and_update_texture(&mut old_texture, text_data, [rect.width(), rect.height(), 1], renderer.device.clone());
renderer.game_data.textures.push(tex.clone());
new_texture = Some(tex);
go_handle.get_game_object_mut(renderer).unwrap().textures.texture_index = renderer.game_data.textures.len() - 1;
renderer.update_descriptor_set(&mut go_handle);
}, TestGame::convert_vertices) {
Ok(_) => {},
Err(e) => println!("Error! {:?}", e),
}
if let Some(tex) = new_texture {
self.texture = tex;
}
}
}