dynamic cache texture size!!

This commit is contained in:
2021-10-14 06:25:58 +02:00
parent ba172ea332
commit 366e3896da
3 changed files with 77 additions and 89 deletions

View File

@@ -12,7 +12,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, MeshHandle, TextVertex, Texture, TextureHandle, 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;
@@ -83,7 +83,7 @@ impl Game for TestGame {
if self.input.button_just_pressed("test") { if self.input.button_just_pressed("test") {
// self.paused = !self.paused; // self.paused = !self.paused;
self.text_objects[0].update_text(":)", 200.0, renderer, &mut self.game_objects); self.text_objects[0].update_text("holy shit look at this", 200.0, renderer, &mut self.game_objects);
} }
// Custom game object stuff // Custom game object stuff
@@ -197,8 +197,8 @@ 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 uploaded_texture = None; let mut uploaded_texture = None;
let mut uploaded_mesh = None;
let mut glyph_brush = GlyphBrushBuilder::using_font(self.font.clone()).build(); let mut glyph_brush = GlyphBrushBuilder::using_font(self.font.clone()).build();
@@ -206,24 +206,22 @@ 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))
); );
let mesh_option = process_text_brush_data( match glyph_brush.process_queued(|rect, text_data| {
glyph_brush.process_queued(|rect, text_data| { uploaded_texture = update_text_texture(None, renderer, 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.texture_index_counter += 1;
}, Self::convert_vertices), }, Self::convert_vertices) {
self.texture_index_counter - 1, Ok(BrushAction::Draw(quads)) => {
uploaded_texture.as_mut(), uploaded_mesh = update_text_quads(quads, self.texture_index_counter - 1, None, renderer);
None, },
None, Ok(BrushAction::ReDraw) => {},
renderer); Err(BrushError::TextureTooSmall { suggested }) => {
glyph_brush.resize_texture(suggested.0, suggested.1);
},
};
TextObject { TextObject {
brush: glyph_brush, brush: glyph_brush,
texture: uploaded_texture.unwrap(), game_object: self.add_game_object(renderer, uploaded_mesh.unwrap()),
game_object: self.add_game_object(renderer, mesh_option.unwrap()),
current_texture_size: texture_size.unwrap(),
} }
} }
@@ -239,24 +237,20 @@ 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(old_texture: Option<&mut Texture>, renderer: &mut VulkanRenderer, rect: Rectangle<u32>, text_data: &[u8]) -> (Option<Texture>, u32) { 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()); let size = u32::max(rect.width(), rect.height());
let mut final_texture = None;
if let Some(old_tex) = old_texture { if let Some(tex_handle) = old_texture {
renderer.update_texture(old_tex, text_data, [rect.width(), rect.height(), 1], [rect.min[0], rect.min[1], 0], renderer.device.clone()); renderer.update_texture(tex_handle, text_data, [rect.width(), rect.height(), 1], [rect.min[0], rect.min[1], 0], renderer.device.clone());
None
} else { } else {
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());
final_texture = Some(tex); Some(renderer.game_data.textures.len() - 1)
}
} }
(final_texture, size) pub fn update_text_quads(quads: Vec<Vec<TextVertex>>, texture_index: usize, mesh_index: Option<usize>, renderer: &mut VulkanRenderer) -> Option<MeshHandle> {
}
pub fn process_text_brush_data(result: Result<BrushAction<Vec<TextVertex>>, BrushError>, texture_index: usize, texture: Option<&mut Texture>, mesh_index: Option<usize>, game_object: Option<&mut GameObject>, renderer: &mut VulkanRenderer) -> Option<MeshHandle> {
match result {
Ok(BrushAction::Draw(quads)) => {
let mut final_vertices = vec![]; let mut final_vertices = vec![];
let mut final_indices: Vec<u32> = vec![]; let mut final_indices: Vec<u32> = vec![];
let mut index_offset = 0; let mut index_offset = 0;
@@ -287,43 +281,32 @@ pub fn process_text_brush_data(result: Result<BrushAction<Vec<TextVertex>>, Brus
pipeline_index: 1 pipeline_index: 1
}) })
} }
},
Ok(BrushAction::ReDraw) => None,
Err(BrushError::TextureTooSmall { suggested }) => {
let size = Dimensions::Dim2d { width: suggested.0, height: suggested.1 };
renderer.resize_texture(game_object.unwrap(), texture.unwrap(), size, renderer.device.clone());
None
},
}
} }
pub struct TextObject { pub struct TextObject {
pub brush: GlyphBrush<Vec<TextVertex>>, pub brush: GlyphBrush<Vec<TextVertex>>,
pub texture: Texture,
pub game_object: GameObjectHandle, pub game_object: GameObjectHandle,
pub current_texture_size: u32,
} }
impl TextObject { impl TextObject {
pub fn update_text(&mut self, new_text: &str, new_size: f32, renderer: &mut VulkanRenderer, game_objects: &mut Vec<GameObject>) { 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))); self.brush.queue(Section::default().add_text(Text::new(new_text).with_scale(new_size)));
let mut old_texture = self.texture.clone();
let mut new_texture = None;
let mut new_size = None;
let go = &mut game_objects[self.game_object]; let go = &mut game_objects[self.game_object];
let mesh_index = go.mesh_index; let mesh_index = go.mesh_index;
process_text_brush_data(self.brush.process_queued(|rect, text_data| { match self.brush.process_queued(|rect, text_data| {
let (t, s) = update_text_texture(Some(&mut old_texture), renderer, rect, text_data); update_text_texture(Some(go.textures.texture_index), renderer, rect, text_data);
new_texture = t; }, TestGame::convert_vertices) {
new_size = Some(s); Ok(BrushAction::Draw(quads)) => {
}, TestGame::convert_vertices), 420, Some(&mut self.texture), Some(mesh_index), Some(go), renderer); update_text_quads(quads, 420, Some(mesh_index), renderer);
if let Some(tex) = new_texture { },
self.texture = tex; Ok(BrushAction::ReDraw) => {},
} Err(BrushError::TextureTooSmall { suggested }) => {
if let Some(size) = new_size { let size = Dimensions::Dim2d { width: suggested.0, height: suggested.1 };
self.current_texture_size = size; renderer.resize_texture(go, go.textures.texture_index, size);
self.brush.resize_texture(suggested.0, suggested.1);
},
} }
} }
} }

View File

@@ -568,7 +568,9 @@ impl VulkanRenderer {
Texture { image: image_view, sampler } Texture { image: image_view, sampler }
} }
pub fn update_texture(&mut self, texture: &mut Texture, new_data: &[u8], new_data_dimensions: [u32; 3], new_data_offset: [u32; 3], device: Arc<Device>) { pub fn update_texture(&mut self, tex_handle: TextureHandle, new_data: &[u8], new_data_dimensions: [u32; 3], new_data_offset: [u32; 3], device: Arc<Device>) {
let texture = &mut self.game_data.textures[tex_handle];
let old_sub_image = SubImage::new( let old_sub_image = SubImage::new(
texture.image.clone(), texture.image.clone(),
0, 0,
@@ -604,7 +606,9 @@ impl VulkanRenderer {
future.flush().unwrap(); future.flush().unwrap();
} }
pub fn resize_texture(&mut self, game_object: &mut GameObject, old_texture: &mut Texture, new_size: Dimensions, device: Arc<Device>) { pub fn resize_texture(&mut self, game_object: &mut GameObject, texture_handle: TextureHandle, new_size: Dimensions) {
let mut texture = &mut self.game_data.textures[texture_handle];
let new_image_usage = ImageUsage { let new_image_usage = ImageUsage {
transfer_destination: true, transfer_destination: true,
transfer_source: true, transfer_source: true,
@@ -613,17 +617,17 @@ impl VulkanRenderer {
}; };
let (new_image_view, new_image_initializer) = ImmutableImage::uninitialized( let (new_image_view, new_image_initializer) = ImmutableImage::uninitialized(
device.clone(), self.device.clone(),
new_size, new_size,
old_texture.image.format(), texture.image.format(),
old_texture.image.mipmap_levels(), texture.image.mipmap_levels(),
new_image_usage, new_image_usage,
ImageLayout::ShaderReadOnlyOptimal, ImageLayout::ShaderReadOnlyOptimal,
device.active_queue_families(), self.device.active_queue_families(),
).unwrap(); ).unwrap();
let old_sub_image = SubImage::new( let old_sub_image = SubImage::new(
old_texture.image.clone(), texture.image.clone(),
0, 0,
1, 1,
0, 0,
@@ -640,7 +644,7 @@ impl VulkanRenderer {
ImageLayout::ShaderReadOnlyOptimal, ImageLayout::ShaderReadOnlyOptimal,
); );
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), self.queue.family()).unwrap(); let mut cbb = AutoCommandBufferBuilder::new(self.device.clone(), self.queue.family()).unwrap();
cbb.copy_image( cbb.copy_image(
old_sub_image.clone(), old_sub_image.clone(),
@@ -648,7 +652,7 @@ impl VulkanRenderer {
0, 0,
0, 0,
new_sub_image.clone(), new_sub_image.clone(),
[0, 0, 0], [10, 0, 0],
0, 0,
0, 0,
old_sub_image.dimensions().width_height_depth(), old_sub_image.dimensions().width_height_depth(),
@@ -659,7 +663,7 @@ impl VulkanRenderer {
let future = cb.execute(self.queue.clone()).unwrap(); let future = cb.execute(self.queue.clone()).unwrap();
future.flush().unwrap(); future.flush().unwrap();
old_texture.image = new_image_view; texture.image = new_image_view;
game_object.init_descriptor_sets(self); game_object.init_descriptor_sets(self);
} }

View File

@@ -350,6 +350,7 @@ impl Drawcall for TextShader {
let builder = PersistentDescriptorSet::start(descriptor_set_layout.clone()); let builder = PersistentDescriptorSet::start(descriptor_set_layout.clone());
let diffuse = &renderer.game_data.textures[textures.texture_index]; let diffuse = &renderer.game_data.textures[textures.texture_index];
println!("Using diffuse image with size {:?}", diffuse.image.dimensions());
descriptor_set = Arc::new(builder descriptor_set = Arc::new(builder
.add_buffer(uniform_buffer.clone()).unwrap() .add_buffer(uniform_buffer.clone()).unwrap()