working through the pipeline I have going on for the text stuff

master
mitchellhansen 5 years ago
parent 86eb27f86d
commit b1b081af87

@ -51,3 +51,18 @@ impl CanvasImage {
} }
} }
#[derive(Clone)]
pub struct CanvasText {
}
impl CanvasText {
pub fn get_descriptor_set(pipeline: Arc<dyn GraphicsPipelineAbstract + Sync + Send>)
-> Box<dyn DescriptorSet + Send + Sync> {
let o: Box<dyn DescriptorSet + Send + Sync> = Box::new(
PersistentDescriptorSet::start(
pipeline.clone(), 0,
)
.build().unwrap());
o
}
}

@ -20,9 +20,8 @@ use vulkano::pipeline::viewport::Viewport;
use vulkano::descriptor::descriptor::DescriptorDescTy::TexelBuffer; use vulkano::descriptor::descriptor::DescriptorDescTy::TexelBuffer;
use crate::canvas::canvas_frame::CanvasFrame; use crate::canvas::canvas_frame::CanvasFrame;
use std::hash::Hash; use std::hash::Hash;
use crate::canvas::canvas_text::{CanvasText, CanvasFontHandle}; use crate::canvas::canvas_text::{CanvasFont, CanvasFontHandle};
use crate::canvas::canvas_buffer::{CanvasImage, CanvasTexture, CanvasText};
use crate::canvas::canvas_buffer::{CanvasImage, CanvasTexture, CanvasTextCache};
use crate::util::vertex_3d::Vertex3D; use crate::util::vertex_3d::Vertex3D;
use vulkano::pipeline::depth_stencil::{StencilFaceFlags, DynamicStencilValue}; use vulkano::pipeline::depth_stencil::{StencilFaceFlags, DynamicStencilValue};
use crate::canvas::shader::common::{CompiledGraphicsPipeline, CompiledGraphicsPipelineHandle}; 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 vulkano::memory::pool::PotentialDedicatedAllocation::Generic;
use rusttype::Glyph; use rusttype::Glyph;
use std::borrow::Borrow; use std::borrow::Borrow;
use crate::canvas::shader::text_shader::GlyphInstance;
/// A drawable object can be passed into a CanvasFrame to be rendered /// 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 /// Very generic implementation. (N % 2 == 0) vertices, ditto for texture coords, and rgba color
@ -82,21 +82,18 @@ pub struct CanvasState {
texture_buffers: Vec<Arc<CanvasTexture>>, texture_buffers: Vec<Arc<CanvasTexture>>,
shader_buffers: Vec<Arc<Box<dyn CompiledGraphicsPipeline>>>, shader_buffers: Vec<Arc<Box<dyn CompiledGraphicsPipeline>>>,
// // Individually hold onto the Fonts
text_buffers: Vec<Arc<CanvasText>>, font_buffers: Vec<Arc<CanvasFont>>,
// Hold onto the vertices we get from the Compu and Canvas Frames // Hold onto the vertices we get from the Compu and Canvas Frames
// When the run comes around, push the vertices to the GPU // When the run comes around, push the vertices to the GPU
colored_vertex_buffer: Vec<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>, colored_vertex_buffer: Vec<Arc<(dyn BufferAccess + Send + Sync)>>,
textured_vertex_buffer: HashMap<Arc<CanvasTextureHandle>, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>, textured_vertex_buffer: HashMap<Arc<CanvasTextureHandle>, Arc<(dyn BufferAccess + Send + Sync)>>,
image_vertex_buffer: HashMap<Arc<CanvasImageHandle>, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>, image_vertex_buffer: HashMap<Arc<CanvasImageHandle>, Arc<(dyn BufferAccess + Send + Sync)>>,
// So what exactly is this going to hold? text_instances: HashMap<Arc<CanvasFontHandle>, Arc<(dyn BufferAccess + Send + Sync)>>,
// Its going to be untextured. Colored. Lists of vertices.
text_instances: HashMap<Arc<CanvasFontHandle>, Vec<(Vertex3D, )>>,
text_atlas_buffer: HashMap<Arc<CanvasFontHandle>, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
// Looks like we gotta hold onto the queue for managing textures // Looks like we gotta hold onto the queue for managing textures
queue: Arc<Queue>, queue: Arc<Queue>,
@ -203,16 +200,12 @@ impl CanvasState {
image_buffers: vec![], image_buffers: vec![],
texture_buffers: vec![], texture_buffers: vec![],
shader_buffers: vec![], shader_buffers: vec![],
text_buffers: vec![], font_buffers: vec![],
colored_drawables: vec![],
colored_vertex_buffer: vec![], colored_vertex_buffer: vec![],
textured_drawables: HashMap::default(),
textured_vertex_buffer: Default::default(), textured_vertex_buffer: Default::default(),
image_drawables: Default::default(),
image_vertex_buffer: Default::default(), image_vertex_buffer: Default::default(),
text_instances: HashMap::default(), text_instances: HashMap::default(),
text_atlas_buffer: Default::default(),
queue: queue.clone(), queue: queue.clone(),
device: device.clone(), device: device.clone(),
@ -222,7 +215,7 @@ impl CanvasState {
/// Using the dimensions and suggested usage, load a CanvasImage and return it's handle /// 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<CanvasFontHandle> { pub fn create_text_buffers(&mut self, dimensions: (u32, u32)) -> Arc<CanvasFontHandle> {
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 { // let text = CanvasText {
// handle: handle.clone(), // handle: handle.clone(),
@ -403,10 +396,14 @@ impl CanvasState {
/// Scrape all the values from the CanvasFrame and then allocate the vertex buffers /// Scrape all the values from the CanvasFrame and then allocate the vertex buffers
pub fn draw(&mut self, canvas_frame: CanvasFrame) { pub fn draw(&mut self, canvas_frame: CanvasFrame) {
let textured_drawables = canvas_frame.textured_drawables;
let colored_drawables = canvas_frame.colored_drawables; // Consume the canvas frame
let image_drawables = canvas_frame.image_drawables; let mut textured_drawables = canvas_frame.textured_drawables;
let text_drawables = canvas_frame.text_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(); self.colored_vertex_buffer.clear();
{ {
@ -423,7 +420,7 @@ impl CanvasState {
self.textured_vertex_buffer.clear(); self.textured_vertex_buffer.clear();
{ {
let g = hprof::enter("Textured Vertex Buffer"); 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() let vertex_buffer = v.clone().iter()
.fold(Vec::new(), |mut a: Vec<Vertex3D>, b| { .fold(Vec::new(), |mut a: Vec<Vertex3D>, b| {
a.extend(b); a.extend(b);
@ -444,7 +441,7 @@ impl CanvasState {
self.image_vertex_buffer.clear(); self.image_vertex_buffer.clear();
{ {
let g = hprof::enter("Image Vertex Buffer"); 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() let vertex_buffer = v.clone().iter()
.fold(Vec::new(), |mut a: Vec<Vertex3D>, b| { .fold(Vec::new(), |mut a: Vec<Vertex3D>, b| {
a.extend(b); a.extend(b);
@ -465,18 +462,12 @@ impl CanvasState {
self.text_instances.clear(); self.text_instances.clear();
{ {
let g = hprof::enter("Text Instance Vertex Buffer"); let g = hprof::enter("Text Instance Vertex Buffer");
for (k, v) in self.text_.drain() { for (k, v) in text_drawables.drain() {
let vertex_buffer = v.clone().iter() self.text_instances.insert(
.fold(Vec::new(), |mut a: Vec<Vertex3D>, b| {
a.extend(b);
a
});
self.image_vertex_buffer.insert(
k.clone(), k.clone(),
ImmutableBuffer::from_iter( ImmutableBuffer::from_iter(
vertex_buffer.iter().cloned(), v.iter().cloned(),
BufferUsage::vertex_buffer(), BufferUsage::all(),
self.queue.clone(), self.queue.clone(),
).unwrap().0, ).unwrap().0,
); );
@ -580,27 +571,24 @@ impl CanvasState {
} }
// Text // Text
let mut shader = self.text_buffers.get( let mut shader = self.shader_buffers.get(
self.get_shader_handle(String::from("simple_text")) self.get_shader_handle(String::from("simple_text"))
.unwrap().clone().handle as usize .unwrap().clone().handle as usize
).unwrap(); ).unwrap();
// if !self.text_instances.is_empty() {
for (font_handle, instance_buffer) in self.text_instances.clone() {
if !self.text_atlas_buffer.is_empty() { let handle = font_handle.clone().handle as usize;
for (text_handle, vertex_buffer) in self.text_atlas_buffer.clone() { let font = self.font_buffers.get(handle).clone().unwrap().clone();
let handle = text_handle.clone().handle as usize; let descriptor_set = CanvasText::get_descriptor_set(shader.get_pipeline());
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();
command_buffer = command_buffer.draw( command_buffer = command_buffer.draw(
shader.get_pipeline().clone(), shader.get_pipeline().clone(),
// Multiple vertex buffers must have their definition in the pipeline! // Multiple vertex buffers must have their definition in the pipeline!
&self.dynamic_state.clone(), &self.dynamic_state.clone(),
(vec![vertex_buffer],vec![]), vec![font.get_vertex_buffer().clone(), instance_buffer.clone()],
vec![descriptor_set], (), (), (),
).unwrap(); ).unwrap();
} }
} }

@ -1,5 +1,5 @@
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet; 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 rusttype::gpu_cache::Cache;
use vulkano::buffer::{BufferAccess, BufferUsage, ImmutableBuffer, CpuAccessibleBuffer}; use vulkano::buffer::{BufferAccess, BufferUsage, ImmutableBuffer, CpuAccessibleBuffer};
use vulkano::device::{Device, Queue}; use vulkano::device::{Device, Queue};
@ -8,6 +8,10 @@ use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
use vulkano::image::{ImmutableImage, ImageUsage, ImageLayout, Dimensions}; use vulkano::image::{ImmutableImage, ImageUsage, ImageLayout, Dimensions};
use vulkano::format::ClearValue; use vulkano::format::ClearValue;
use vulkano::format::Format::R8Unorm; 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) /// Typed wrapper for a u32 shader handle (index id)
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[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 /// So currently, I'm using these as container classes which vkprocessor owns
/// I then use a CanvasFrame which accumulates lists of handles and vertices. /// I then use a CanvasFrame which accumulates lists of handles and vertices.
pub struct CanvasText { pub struct CanvasFont {
device: Arc<Device>, font: Font<'static>,
queue: Arc<Queue>, font_name: String,
font: Font<'static>, allocated_font_atlas: Arc<(dyn BufferAccess + Send + Sync)>,
} }
impl CanvasText { impl CanvasFont {
/// Load the font fn parse_to_vertex_buffer(font: Font) -> Vec<TextVertex3D> {
pub fn new(device: Arc<Device>, queue: Arc<Queue>) -> CanvasText {
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 glyph_data = glyph.get_data().unwrap();
let font = Font::from_bytes(font_data as &[u8]).unwrap();
CanvasText { for vertex in glyph_data.clone().shape.clone().unwrap() {
device: device.clone(), accumulator.push(TextVertex3D {
queue: queue.clone(), position: [vertex.x as f32, vertex.y as f32, 0.0],
font: font, });
}
}
accumulator
}
/// Load the font
pub fn new(device: Arc<Device>, queue: Arc<Queue>, 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 /// Generate a vertex buffer from the font
/* pub fn get_vertex_buffer(&self) -> Arc<(dyn BufferAccess + Send + Sync)> {
So... These fonts are going to have unequal amounts of vertices. return self.allocated_font_atlas.clone();
*/
pub fn get_vertex_buffer(&self) {
unimplemented!()
} }
/// postpone this until caching /// postpone this until caching
@ -89,7 +115,7 @@ impl CanvasText {
pub fn draw_text(&mut self, pub fn draw_text(&mut self,
command_buffer: AutoCommandBufferBuilder, command_buffer: AutoCommandBufferBuilder,
image_num: usize image_num: usize,
) -> AutoCommandBufferBuilder { ) -> AutoCommandBufferBuilder {
// let screen_width = 0; // let screen_width = 0;
@ -208,5 +234,4 @@ impl CanvasText {
command_buffer//.end_render_pass().unwrap() command_buffer//.end_render_pass().unwrap()
} }
} }

@ -9,3 +9,11 @@ pub struct Vertex3D {
vulkano::impl_vertex!(Vertex3D, v_position, color, ti_position); 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);

Loading…
Cancel
Save