From b1b081af8712d569dd2f6bca1412140949fd7c48 Mon Sep 17 00:00:00 2001 From: mitchellhansen Date: Tue, 8 Oct 2019 21:31:57 -0700 Subject: [PATCH] working through the pipeline I have going on for the text stuff --- src/canvas/canvas_buffer.rs | 15 +++++++ src/canvas/canvas_state.rs | 78 ++++++++++++++++--------------------- src/canvas/canvas_text.rs | 75 +++++++++++++++++++++++------------ src/util/vertex_3d.rs | 8 ++++ 4 files changed, 106 insertions(+), 70 deletions(-) diff --git a/src/canvas/canvas_buffer.rs b/src/canvas/canvas_buffer.rs index abb212af..1dd2b410 100644 --- a/src/canvas/canvas_buffer.rs +++ b/src/canvas/canvas_buffer.rs @@ -51,3 +51,18 @@ impl CanvasImage { } } +#[derive(Clone)] +pub struct CanvasText { +} + +impl CanvasText { + pub fn get_descriptor_set(pipeline: Arc) + -> Box { + let o: Box = Box::new( + PersistentDescriptorSet::start( + pipeline.clone(), 0, + ) + .build().unwrap()); + o + } +} diff --git a/src/canvas/canvas_state.rs b/src/canvas/canvas_state.rs index 1bee29ff..e240fdb3 100644 --- a/src/canvas/canvas_state.rs +++ b/src/canvas/canvas_state.rs @@ -20,9 +20,8 @@ use vulkano::pipeline::viewport::Viewport; use vulkano::descriptor::descriptor::DescriptorDescTy::TexelBuffer; use crate::canvas::canvas_frame::CanvasFrame; use std::hash::Hash; -use crate::canvas::canvas_text::{CanvasText, CanvasFontHandle}; - -use crate::canvas::canvas_buffer::{CanvasImage, CanvasTexture, CanvasTextCache}; +use crate::canvas::canvas_text::{CanvasFont, CanvasFontHandle}; +use crate::canvas::canvas_buffer::{CanvasImage, CanvasTexture, CanvasText}; use crate::util::vertex_3d::Vertex3D; use vulkano::pipeline::depth_stencil::{StencilFaceFlags, DynamicStencilValue}; use crate::canvas::shader::common::{CompiledGraphicsPipeline, CompiledGraphicsPipelineHandle}; @@ -30,6 +29,7 @@ use crate::canvas::shader::generic_shader::GenericShader; use vulkano::memory::pool::PotentialDedicatedAllocation::Generic; use rusttype::Glyph; use std::borrow::Borrow; +use crate::canvas::shader::text_shader::GlyphInstance; /// A drawable object can be passed into a CanvasFrame to be rendered /// Very generic implementation. (N % 2 == 0) vertices, ditto for texture coords, and rgba color @@ -82,21 +82,18 @@ pub struct CanvasState { texture_buffers: Vec>, shader_buffers: Vec>>, - // - text_buffers: Vec>, + // Individually hold onto the Fonts + font_buffers: Vec>, // Hold onto the vertices we get from the Compu and Canvas Frames // When the run comes around, push the vertices to the GPU - colored_vertex_buffer: Vec>, + colored_vertex_buffer: Vec>, - textured_vertex_buffer: HashMap, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>, + textured_vertex_buffer: HashMap, Arc<(dyn BufferAccess + Send + Sync)>>, - image_vertex_buffer: HashMap, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>, + image_vertex_buffer: HashMap, Arc<(dyn BufferAccess + Send + Sync)>>, - // So what exactly is this going to hold? - // Its going to be untextured. Colored. Lists of vertices. - text_instances: HashMap, Vec<(Vertex3D, )>>, - text_atlas_buffer: HashMap, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>, + text_instances: HashMap, Arc<(dyn BufferAccess + Send + Sync)>>, // Looks like we gotta hold onto the queue for managing textures queue: Arc, @@ -203,16 +200,12 @@ impl CanvasState { image_buffers: vec![], texture_buffers: vec![], shader_buffers: vec![], - text_buffers: vec![], + font_buffers: vec![], - colored_drawables: vec![], colored_vertex_buffer: vec![], - textured_drawables: HashMap::default(), textured_vertex_buffer: Default::default(), - image_drawables: Default::default(), image_vertex_buffer: Default::default(), text_instances: HashMap::default(), - text_atlas_buffer: Default::default(), queue: queue.clone(), device: device.clone(), @@ -222,7 +215,7 @@ impl CanvasState { /// Using the dimensions and suggested usage, load a CanvasImage and return it's handle pub fn create_text_buffers(&mut self, dimensions: (u32, u32)) -> Arc { - let handle = Arc::new(CanvasFontHandle { handle: self.text_buffers.len() as u32 }); + let handle = Arc::new(CanvasFontHandle { handle: self.font_buffers.len() as u32 }); // // let text = CanvasText { // handle: handle.clone(), @@ -403,10 +396,14 @@ impl CanvasState { /// Scrape all the values from the CanvasFrame and then allocate the vertex buffers pub fn draw(&mut self, canvas_frame: CanvasFrame) { - let textured_drawables = canvas_frame.textured_drawables; - let colored_drawables = canvas_frame.colored_drawables; - let image_drawables = canvas_frame.image_drawables; - let text_drawables = canvas_frame.text_drawables; + + // Consume the canvas frame + let mut textured_drawables = canvas_frame.textured_drawables; + let mut colored_drawables = canvas_frame.colored_drawables; + let mut image_drawables = canvas_frame.image_drawables; + let mut text_drawables = canvas_frame.text_drawables; + + // Walk through the consumed items and allocate them to GPU buffers self.colored_vertex_buffer.clear(); { @@ -423,7 +420,7 @@ impl CanvasState { self.textured_vertex_buffer.clear(); { let g = hprof::enter("Textured Vertex Buffer"); - for (k, v) in self.textured_drawables.drain() { + for (k, v) in textured_drawables.drain() { let vertex_buffer = v.clone().iter() .fold(Vec::new(), |mut a: Vec, b| { a.extend(b); @@ -444,7 +441,7 @@ impl CanvasState { self.image_vertex_buffer.clear(); { let g = hprof::enter("Image Vertex Buffer"); - for (k, v) in self.image_drawables.drain() { + for (k, v) in image_drawables.drain() { let vertex_buffer = v.clone().iter() .fold(Vec::new(), |mut a: Vec, b| { a.extend(b); @@ -465,18 +462,12 @@ impl CanvasState { self.text_instances.clear(); { let g = hprof::enter("Text Instance Vertex Buffer"); - for (k, v) in self.text_.drain() { - let vertex_buffer = v.clone().iter() - .fold(Vec::new(), |mut a: Vec, b| { - a.extend(b); - a - }); - - self.image_vertex_buffer.insert( + for (k, v) in text_drawables.drain() { + self.text_instances.insert( k.clone(), ImmutableBuffer::from_iter( - vertex_buffer.iter().cloned(), - BufferUsage::vertex_buffer(), + v.iter().cloned(), + BufferUsage::all(), self.queue.clone(), ).unwrap().0, ); @@ -580,27 +571,24 @@ impl CanvasState { } // Text - let mut shader = self.text_buffers.get( + let mut shader = self.shader_buffers.get( self.get_shader_handle(String::from("simple_text")) .unwrap().clone().handle as usize ).unwrap(); - // - - if !self.text_atlas_buffer.is_empty() { - for (text_handle, vertex_buffer) in self.text_atlas_buffer.clone() { - let handle = text_handle.clone().handle as usize; - let descriptor_set = self.text_buffers.get(handle).clone().unwrap().clone() - .get_descriptor_set(shader.get_pipeline(), self.sampler.clone()); - let instance_data = self.text_instances.get(text_handle.borrow()).unwrap(); + if !self.text_instances.is_empty() { + for (font_handle, instance_buffer) in self.text_instances.clone() { + let handle = font_handle.clone().handle as usize; + let font = self.font_buffers.get(handle).clone().unwrap().clone(); + let descriptor_set = CanvasText::get_descriptor_set(shader.get_pipeline()); command_buffer = command_buffer.draw( shader.get_pipeline().clone(), // Multiple vertex buffers must have their definition in the pipeline! &self.dynamic_state.clone(), - (vec![vertex_buffer],vec![]), - vec![descriptor_set], (), + vec![font.get_vertex_buffer().clone(), instance_buffer.clone()], + (), (), ).unwrap(); } } diff --git a/src/canvas/canvas_text.rs b/src/canvas/canvas_text.rs index 5c8fa65d..492f7b06 100644 --- a/src/canvas/canvas_text.rs +++ b/src/canvas/canvas_text.rs @@ -1,5 +1,5 @@ use vulkano::descriptor::descriptor_set::PersistentDescriptorSet; -use rusttype::{Font, PositionedGlyph, Scale, Rect, point}; +use rusttype::{Font, PositionedGlyph, Scale, Rect, point, GlyphId}; use rusttype::gpu_cache::Cache; use vulkano::buffer::{BufferAccess, BufferUsage, ImmutableBuffer, CpuAccessibleBuffer}; use vulkano::device::{Device, Queue}; @@ -8,6 +8,10 @@ use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState}; use vulkano::image::{ImmutableImage, ImageUsage, ImageLayout, Dimensions}; use vulkano::format::ClearValue; use vulkano::format::Format::R8Unorm; +use std::fs::File; +use std::io::Read; +use crate::canvas::shader::text_shader::GlyphInstance; +use crate::util::vertex_3d::{Vertex3D, TextVertex3D}; /* @@ -30,9 +34,7 @@ that can come when I look at caching the sprites */ -pub struct Glyph { - -} +pub struct Glyph {} /// Typed wrapper for a u32 shader handle (index id) #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] @@ -42,34 +44,58 @@ pub struct CanvasFontHandle { /// So currently, I'm using these as container classes which vkprocessor owns /// I then use a CanvasFrame which accumulates lists of handles and vertices. -pub struct CanvasText { - device: Arc, - queue: Arc, - font: Font<'static>, +pub struct CanvasFont { + font: Font<'static>, + font_name: String, + allocated_font_atlas: Arc<(dyn BufferAccess + Send + Sync)>, } -impl CanvasText { +impl CanvasFont { - /// Load the font - pub fn new(device: Arc, queue: Arc) -> CanvasText { + fn parse_to_vertex_buffer(font: Font) -> Vec { + + let mut current_x = 0; + let mut current_y = 0; + + let mut accumulator = Vec::new(); + + for i in (0..255) { + + let glyph = font.glyph(GlyphId{ 0: 40 }); - let font_data = include_bytes!("../../resources/fonts/sansation.ttf"); - let font = Font::from_bytes(font_data as &[u8]).unwrap(); + let glyph_data = glyph.get_data().unwrap(); - CanvasText { - device: device.clone(), - queue: queue.clone(), - font: font, + for vertex in glyph_data.clone().shape.clone().unwrap() { + accumulator.push(TextVertex3D { + position: [vertex.x as f32, vertex.y as f32, 0.0], + }); + } + } + + accumulator + } + /// Load the font + pub fn new(device: Arc, queue: Arc, font_name: String) -> CanvasFont { + + let font = Font::from_bytes({ + let mut f = File::open("resources/fonts/sansation.ttf").expect("Font file not found"); + let mut font_data = Vec::new(); + f.read_to_end(&mut font_data).expect("Dont know"); + font_data + }).unwrap(); + + CanvasFont { + font: font.clone(), + font_name: font_name, + allocated_font_atlas: ImmutableBuffer::from_iter( + CanvasFont::parse_to_vertex_buffer(font.clone()).iter().cloned(), + BufferUsage::vertex_buffer(), queue).unwrap().0, } } /// Generate a vertex buffer from the font - /* - So... These fonts are going to have unequal amounts of vertices. - - */ - pub fn get_vertex_buffer(&self) { - unimplemented!() + pub fn get_vertex_buffer(&self) -> Arc<(dyn BufferAccess + Send + Sync)> { + return self.allocated_font_atlas.clone(); } /// postpone this until caching @@ -89,7 +115,7 @@ impl CanvasText { pub fn draw_text(&mut self, command_buffer: AutoCommandBufferBuilder, - image_num: usize + image_num: usize, ) -> AutoCommandBufferBuilder { // let screen_width = 0; @@ -208,5 +234,4 @@ impl CanvasText { command_buffer//.end_render_pass().unwrap() } - } \ No newline at end of file diff --git a/src/util/vertex_3d.rs b/src/util/vertex_3d.rs index c84f8037..59e8fb66 100644 --- a/src/util/vertex_3d.rs +++ b/src/util/vertex_3d.rs @@ -9,3 +9,11 @@ pub struct Vertex3D { vulkano::impl_vertex!(Vertex3D, v_position, color, ti_position); +/// Text vertex 3d with vertex position +#[derive(Default, Debug, Clone, Copy)] +pub struct TextVertex3D { + pub position: [f32; 3], +} + +vulkano::impl_vertex!(TextVertex3D, position); +