fps counter
This commit is contained in:
14
src/game/components.rs
Normal file
14
src/game/components.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
use crate::{input::InputState, text::update_text, vulkan::{VulkanRenderer, gameobject::{GameObject, GameObjectHandle, Updatable}}};
|
||||||
|
|
||||||
|
use super::GameState;
|
||||||
|
|
||||||
|
pub struct FpsCounter {
|
||||||
|
pub game_object: GameObjectHandle
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Updatable for FpsCounter {
|
||||||
|
fn update(&mut self, delta_time: f32, _input: &InputState, game_state: &mut GameState, game_objects: &mut Vec<GameObject>, renderer: &mut VulkanRenderer) {
|
||||||
|
let text = format!("{}ms\n{}fps", delta_time * 1000., 1. / delta_time);
|
||||||
|
update_text(self.game_object, &text, 30., renderer, &mut game_state.brush, game_objects)
|
||||||
|
}
|
||||||
|
}
|
||||||
166
src/game/mod.rs
166
src/game/mod.rs
@@ -1,36 +1,38 @@
|
|||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use cgmath::{Deg, Euler, Quaternion, vec3};
|
use cgmath::{Deg, Euler, Quaternion, vec3};
|
||||||
use glyph_brush::{BrushAction, BrushError, GlyphBrush, GlyphBrushBuilder, GlyphVertex, Rectangle, Section, Text};
|
use glyph_brush::GlyphBrush;
|
||||||
use glyph_brush::ab_glyph::FontArc;
|
|
||||||
use vulkano::format::Format;
|
|
||||||
use vulkano::image::Dimensions;
|
|
||||||
use vulkano::sampler::{Filter, SamplerAddressMode};
|
|
||||||
use winit::event::Event;
|
use winit::event::Event;
|
||||||
|
|
||||||
use level::{load_level, save_level};
|
use level::{load_level, save_level};
|
||||||
use player::Player;
|
use player::Player;
|
||||||
|
|
||||||
|
use crate::game::components::FpsCounter;
|
||||||
|
use crate::text::{create_brush, create_text_object};
|
||||||
use crate::{config::LogConfig, vulkan};
|
use crate::{config::LogConfig, vulkan};
|
||||||
use crate::input::InputState;
|
use crate::input::InputState;
|
||||||
use crate::vulkan::{Game, MeshHandle, TextVertex, TextureHandle, Vertex, VulkanRenderer};
|
use crate::vulkan::{Game, MeshHandle, TextVertex, Vertex, VulkanRenderer};
|
||||||
use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable};
|
use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable};
|
||||||
use crate::vulkan::mesh::{self, CPUMesh, CPUVertexList};
|
use crate::vulkan::mesh::{self};
|
||||||
use crate::vulkan::pipelines::vs::ty::ObjectUniformData;
|
use crate::vulkan::pipelines::vs::ty::ObjectUniformData;
|
||||||
|
|
||||||
pub mod player;
|
pub mod player;
|
||||||
mod level;
|
mod level;
|
||||||
|
mod components;
|
||||||
|
|
||||||
pub struct TestGame {
|
pub struct TestGame {
|
||||||
pub input: InputState,
|
pub input: InputState,
|
||||||
pub player: Player,
|
pub player: Player,
|
||||||
pub game_objects: Vec<GameObject>,
|
pub game_objects: Vec<GameObject>,
|
||||||
pub text_objects: Vec<TextObject>,
|
|
||||||
pub log_config: LogConfig,
|
pub log_config: LogConfig,
|
||||||
pub texture_index_counter: usize,
|
pub texture_index_counter: usize,
|
||||||
pub last_time: f32,
|
pub last_time: f32,
|
||||||
pub components: Vec<Box<dyn Updatable>>,
|
pub components: Vec<Box<dyn Updatable>>,
|
||||||
|
pub game_state: GameState,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GameState {
|
||||||
pub paused: bool,
|
pub paused: bool,
|
||||||
pub font: FontArc,
|
pub brush: GlyphBrush<Vec<TextVertex>>,
|
||||||
pub test_str: String,
|
pub test_str: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,11 +55,14 @@ impl Game for TestGame {
|
|||||||
let input = &self.input;
|
let input = &self.input;
|
||||||
let objs = &mut self.game_objects;
|
let objs = &mut self.game_objects;
|
||||||
let components = &mut self.components;
|
let components = &mut self.components;
|
||||||
|
let paused = self.game_state.paused;
|
||||||
|
let state = &mut self.game_state;
|
||||||
|
|
||||||
if !self.paused {
|
if !paused {
|
||||||
components.iter_mut().for_each(|component| {
|
components.iter_mut().for_each(|component| {
|
||||||
component.update(frame_time, &input, renderer, objs);
|
component.update(frame_time, &input, state, objs, renderer);
|
||||||
});
|
});
|
||||||
|
self.player.update(frame_time, &input, state, objs, renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// User interaction
|
// User interaction
|
||||||
@@ -85,22 +90,18 @@ impl Game for TestGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.input.button_just_pressed("test") {
|
if self.input.button_just_pressed("test") {
|
||||||
self.paused = !self.paused;
|
self.game_state.paused = !self.game_state.paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
for char in self.input.typed_characters.iter() {
|
for char in self.input.typed_characters.iter() {
|
||||||
match char {
|
match char {
|
||||||
'\u{8}' => { self.test_str.pop(); },
|
'\u{8}' => { self.game_state.test_str.pop(); },
|
||||||
c => { self.test_str.push(*c); },
|
c => { self.game_state.test_str.push(*c); },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.text_objects[0].update_text(&self.test_str, 30., renderer, &mut self.game_objects);
|
|
||||||
|
|
||||||
// Custom game object stuff
|
// Custom game object stuff
|
||||||
let light_pos = vec3(2.0, 0.5, 2.0);
|
let light_pos = vec3(2.0, 0.5, 2.0);
|
||||||
if !self.paused {
|
|
||||||
self.player.update(frame_time, &self.input, renderer, &mut self.game_objects);
|
|
||||||
}
|
|
||||||
|
|
||||||
// End frame
|
// End frame
|
||||||
self.last_time = time;
|
self.last_time = time;
|
||||||
@@ -127,14 +128,15 @@ impl TestGame {
|
|||||||
input: InputState::new(toml_path, log_config),
|
input: InputState::new(toml_path, log_config),
|
||||||
player: Player::new(3., 30.),
|
player: Player::new(3., 30.),
|
||||||
game_objects: vec![],
|
game_objects: vec![],
|
||||||
text_objects: vec![],
|
|
||||||
log_config,
|
log_config,
|
||||||
texture_index_counter: 0,
|
texture_index_counter: 0,
|
||||||
last_time: 0.0,
|
last_time: 0.0,
|
||||||
components: vec![],
|
components: vec![],
|
||||||
paused: false,
|
game_state: GameState {
|
||||||
font: FontArc::try_from_slice(include_bytes!("../../models/FiraCode-Regular.ttf")).unwrap(),
|
brush: create_brush(),
|
||||||
test_str: String::new()
|
paused: false,
|
||||||
|
test_str: "".to_string(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,8 +144,9 @@ 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, "aaxx", 128.);
|
let text_mesh = create_text_object(&mut self.game_state.brush, renderer, "aaxx", 30.);
|
||||||
self.text_objects.push(text_obj);
|
let fps = Box::new(FpsCounter { game_object: self.add_game_object(renderer, text_mesh) });
|
||||||
|
self.components.push(fps);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn offset_texture_id(&mut self, local_tex_id: Option<usize>) -> usize {
|
pub fn offset_texture_id(&mut self, local_tex_id: Option<usize>) -> usize {
|
||||||
@@ -197,45 +200,6 @@ impl TestGame {
|
|||||||
self.game_objects.len() - 1
|
self.game_objects.len() - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_vertices(vertex_data: GlyphVertex) -> Vec<TextVertex> {
|
|
||||||
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 uploaded_texture = None;
|
|
||||||
let mut uploaded_mesh = 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| {
|
|
||||||
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,
|
|
||||||
game_object: self.add_game_object(renderer, uploaded_mesh.unwrap()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clear_level(&mut self, renderer: &mut VulkanRenderer) {
|
pub fn clear_level(&mut self, renderer: &mut VulkanRenderer) {
|
||||||
self.game_objects.clear();
|
self.game_objects.clear();
|
||||||
self.texture_index_counter = 0;
|
self.texture_index_counter = 0;
|
||||||
@@ -247,79 +211,3 @@ pub fn print_quat_as_euler(quat: Quaternion<f32>) {
|
|||||||
let euler = Euler::from(quat);
|
let euler = Euler::from(quat);
|
||||||
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(old_texture: Option<TextureHandle>, renderer: &mut VulkanRenderer, rect: Rectangle<u32>, text_data: &[u8]) -> Option<TextureHandle> {
|
|
||||||
let size = u32::max(rect.width(), rect.height());
|
|
||||||
|
|
||||||
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());
|
|
||||||
Some(renderer.game_data.textures.len() - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_text_quads(quads: Vec<Vec<TextVertex>>, texture_index: usize, mesh_index: Option<usize>, renderer: &mut VulkanRenderer) -> Option<MeshHandle> {
|
|
||||||
let mut final_vertices = vec![];
|
|
||||||
let mut final_indices: Vec<u32> = vec![];
|
|
||||||
let mut index_offset = 0;
|
|
||||||
|
|
||||||
for mut quad in quads {
|
|
||||||
let len = quad.len();
|
|
||||||
final_vertices.append(&mut quad);
|
|
||||||
final_indices.append(&mut [0, 2, 3, 0, 3, 1].iter().map(|x| *x + index_offset).collect());
|
|
||||||
index_offset += len as u32;
|
|
||||||
}
|
|
||||||
if let Some(idx) = mesh_index {
|
|
||||||
renderer.update_mesh(idx, CPUVertexList::VertexText(final_vertices), final_indices);
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let mesh = CPUMesh {
|
|
||||||
vertices: CPUVertexList::VertexText(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<Vec<TextVertex>>,
|
|
||||||
pub game_object: GameObjectHandle,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TextObject {
|
|
||||||
pub fn update_text(&mut self, new_text: &str, new_size: f32, renderer: &mut VulkanRenderer, game_objects: &mut Vec<GameObject>) {
|
|
||||||
self.brush.queue(Section::default().add_text(Text::new(new_text).with_scale(new_size)));
|
|
||||||
|
|
||||||
let go = &mut game_objects[self.game_object];
|
|
||||||
let mesh_index = go.mesh_index;
|
|
||||||
|
|
||||||
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);
|
|
||||||
self.update_text(new_text, new_size, renderer, game_objects);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,6 +11,8 @@ use crate::vulkan::{
|
|||||||
VulkanRenderer
|
VulkanRenderer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::GameState;
|
||||||
|
|
||||||
pub struct Camera {
|
pub struct Camera {
|
||||||
pub fov_y: f32,
|
pub fov_y: f32,
|
||||||
pub position: Vector3<f32>,
|
pub position: Vector3<f32>,
|
||||||
@@ -178,7 +180,7 @@ pub fn intersect_triangle(ray_origin: Vector3<f32>, ray_direction: Vector3<f32>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Updatable for Player {
|
impl Updatable for Player {
|
||||||
fn update(&mut self, delta_time: f32, input: &InputState, renderer: &mut VulkanRenderer, game_objects: &mut Vec<GameObject>) {
|
fn update(&mut self, delta_time: f32, input: &InputState, game_state: &mut GameState, game_objects: &mut Vec<GameObject>, renderer: &mut VulkanRenderer) {
|
||||||
// Edit mode
|
// Edit mode
|
||||||
if input.button_just_pressed("toggle_edit") {
|
if input.button_just_pressed("toggle_edit") {
|
||||||
if self.movement_mode == FirstPerson {
|
if self.movement_mode == FirstPerson {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ mod input;
|
|||||||
mod config;
|
mod config;
|
||||||
mod game;
|
mod game;
|
||||||
mod tests;
|
mod tests;
|
||||||
|
mod text;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let log_config = LogConfig::from_file("config/log.toml");
|
let log_config = LogConfig::from_file("config/log.toml");
|
||||||
|
|||||||
113
src/text.rs
Normal file
113
src/text.rs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
use glyph_brush::{BrushAction, BrushError, GlyphBrush, GlyphBrushBuilder, GlyphVertex, Rectangle, Section, Text, ab_glyph::FontArc};
|
||||||
|
use vulkano::{format::Format, image::Dimensions, sampler::{Filter, SamplerAddressMode}};
|
||||||
|
|
||||||
|
use crate::vulkan::{MeshHandle, TextVertex, TextureHandle, VulkanRenderer, gameobject::{GameObject, GameObjectHandle}, mesh::{CPUMesh, CPUVertexList}};
|
||||||
|
|
||||||
|
pub fn update_text(game_object_handle: GameObjectHandle, new_text: &str, new_size: f32, renderer: &mut VulkanRenderer, brush: &mut GlyphBrush<Vec<TextVertex>>, game_objects: &mut Vec<GameObject>) {
|
||||||
|
brush.queue(Section::default()
|
||||||
|
.add_text(Text::new(new_text).with_scale(new_size))
|
||||||
|
.with_bounds((renderer.game_data.dimensions[0] as f32, renderer.game_data.dimensions[1] as f32)));
|
||||||
|
|
||||||
|
let go = &mut game_objects[game_object_handle];
|
||||||
|
let mesh_index = go.mesh_index;
|
||||||
|
|
||||||
|
match brush.process_queued(|rect, text_data| {
|
||||||
|
update_text_texture(Some(go.textures.texture_index), renderer, rect, text_data);
|
||||||
|
}, 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);
|
||||||
|
brush.resize_texture(suggested.0, suggested.1);
|
||||||
|
update_text(game_object_handle, new_text, new_size, renderer, brush, game_objects);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_brush<T>() -> GlyphBrush<T> {
|
||||||
|
let font = FontArc::try_from_slice(include_bytes!("../models/FiraCode-Regular.ttf")).unwrap();
|
||||||
|
GlyphBrushBuilder::using_font(font).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_text_object(brush: &mut GlyphBrush<Vec<TextVertex>>, renderer: &mut VulkanRenderer, text: &str, size: f32) -> MeshHandle {
|
||||||
|
let mut uploaded_texture = None;
|
||||||
|
let mut uploaded_mesh = None;
|
||||||
|
|
||||||
|
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 brush.process_queued(|rect, text_data| {
|
||||||
|
uploaded_texture = update_text_texture(None, renderer, rect, text_data);
|
||||||
|
}, convert_vertices) {
|
||||||
|
Ok(BrushAction::Draw(quads)) => {
|
||||||
|
uploaded_mesh = update_text_quads(quads, uploaded_texture.unwrap(), None, renderer);
|
||||||
|
},
|
||||||
|
Ok(BrushAction::ReDraw) => {},
|
||||||
|
Err(BrushError::TextureTooSmall { suggested }) => {
|
||||||
|
brush.resize_texture(suggested.0, suggested.1);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
uploaded_mesh.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_text_texture(old_texture: Option<TextureHandle>, renderer: &mut VulkanRenderer, rect: Rectangle<u32>, text_data: &[u8]) -> Option<TextureHandle> {
|
||||||
|
let size = u32::max(rect.width(), rect.height());
|
||||||
|
|
||||||
|
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());
|
||||||
|
Some(renderer.game_data.textures.len() - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_text_quads(quads: Vec<Vec<TextVertex>>, texture_index: usize, mesh_index: Option<usize>, renderer: &mut VulkanRenderer) -> Option<MeshHandle> {
|
||||||
|
let mut final_vertices = vec![];
|
||||||
|
let mut final_indices: Vec<u32> = vec![];
|
||||||
|
let mut index_offset = 0;
|
||||||
|
|
||||||
|
for mut quad in quads {
|
||||||
|
let len = quad.len();
|
||||||
|
final_vertices.append(&mut quad);
|
||||||
|
final_indices.append(&mut [0, 2, 3, 0, 3, 1].iter().map(|x| *x + index_offset).collect());
|
||||||
|
index_offset += len as u32;
|
||||||
|
}
|
||||||
|
if let Some(idx) = mesh_index {
|
||||||
|
renderer.update_mesh(idx, CPUVertexList::VertexText(final_vertices), final_indices);
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let mesh = CPUMesh {
|
||||||
|
vertices: CPUVertexList::VertexText(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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_vertices(vertex_data: GlyphVertex) -> Vec<TextVertex> {
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use cgmath::{Deg, Euler, Matrix4, Quaternion, Vector3};
|
use cgmath::{Deg, Euler, Matrix4, Quaternion, Vector3};
|
||||||
|
|
||||||
|
use crate::game::GameState;
|
||||||
use crate::input::InputState;
|
use crate::input::InputState;
|
||||||
use crate::vulkan::{RendererDescriptorSets, TextureHandle};
|
use crate::vulkan::{RendererDescriptorSets, TextureHandle};
|
||||||
use crate::vulkan::{MeshHandle, VulkanRenderer};
|
use crate::vulkan::{MeshHandle, VulkanRenderer};
|
||||||
@@ -87,5 +88,5 @@ impl GameObject {
|
|||||||
pub type GameObjectHandle = usize;
|
pub type GameObjectHandle = usize;
|
||||||
|
|
||||||
pub trait Updatable {
|
pub trait Updatable {
|
||||||
fn update(&mut self, delta_time: f32, input: &InputState, renderer: &mut VulkanRenderer, game_objects: &mut Vec<GameObject>);
|
fn update(&mut self, delta_time: f32, input: &InputState, game_state: &mut GameState, game_objects: &mut Vec<GameObject>, renderer: &mut VulkanRenderer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -319,7 +319,6 @@ impl TextShader {
|
|||||||
.build(device.clone())
|
.build(device.clone())
|
||||||
.unwrap());
|
.unwrap());
|
||||||
|
|
||||||
println!("layout: {:?}", vulkano::descriptor::PipelineLayoutAbstract::descriptor_set_layout(&gp, 0).unwrap().descriptors_count());
|
|
||||||
gp
|
gp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user