dynamic cache texture size!!
This commit is contained in:
141
src/game/mod.rs
141
src/game/mod.rs
@@ -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);
|
self.texture_index_counter += 1;
|
||||||
uploaded_texture = t;
|
}, Self::convert_vertices) {
|
||||||
texture_size = Some(s);
|
Ok(BrushAction::Draw(quads)) => {
|
||||||
self.texture_index_counter += 1;
|
uploaded_mesh = update_text_quads(quads, self.texture_index_counter - 1, None, renderer);
|
||||||
}, Self::convert_vertices),
|
},
|
||||||
self.texture_index_counter - 1,
|
Ok(BrushAction::ReDraw) => {},
|
||||||
uploaded_texture.as_mut(),
|
Err(BrushError::TextureTooSmall { suggested }) => {
|
||||||
None,
|
glyph_brush.resize_texture(suggested.0, suggested.1);
|
||||||
None,
|
},
|
||||||
renderer);
|
};
|
||||||
|
|
||||||
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,91 +237,76 @@ 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 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> {
|
pub fn update_text_quads(quads: Vec<Vec<TextVertex>>, texture_index: usize, mesh_index: Option<usize>, renderer: &mut VulkanRenderer) -> Option<MeshHandle> {
|
||||||
match result {
|
let mut final_vertices = vec![];
|
||||||
Ok(BrushAction::Draw(quads)) => {
|
let mut final_indices: Vec<u32> = vec![];
|
||||||
let mut final_vertices = vec![];
|
let mut index_offset = 0;
|
||||||
let mut final_indices: Vec<u32> = vec![];
|
|
||||||
let mut index_offset = 0;
|
|
||||||
|
|
||||||
for quad in quads {
|
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_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());
|
final_indices.append(&mut [0, 2, 3, 0, 3, 1].iter().map(|x| *x + index_offset).collect());
|
||||||
index_offset += quad.len() as u32;
|
index_offset += quad.len() as u32;
|
||||||
}
|
}
|
||||||
if let Some(idx) = mesh_index {
|
if let Some(idx) = mesh_index {
|
||||||
renderer.update_mesh(idx, final_vertices, final_indices);
|
renderer.update_mesh(idx, final_vertices, final_indices);
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let mesh = CPUMesh {
|
let mesh = CPUMesh {
|
||||||
vertices: final_vertices,
|
vertices: final_vertices,
|
||||||
indices: final_indices,
|
indices: final_indices,
|
||||||
local_texture_index: Some(texture_index),
|
local_texture_index: Some(texture_index),
|
||||||
local_normal_map_index: None,
|
local_normal_map_index: None,
|
||||||
name: Some("font_texture".to_string()),
|
name: Some("font_texture".to_string()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mesh_index = renderer.upload_mesh(mesh, None);
|
let mesh_index = renderer.upload_mesh(mesh, None);
|
||||||
Some(MeshHandle {
|
Some(MeshHandle {
|
||||||
index: mesh_index,
|
index: mesh_index,
|
||||||
diffuse_handle: texture_index,
|
diffuse_handle: texture_index,
|
||||||
normal_handle: None,
|
normal_handle: None,
|
||||||
original_path: None,
|
original_path: None,
|
||||||
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);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user