getting the canvasframe set up for text
This commit is contained in:
@@ -7,6 +7,11 @@ layout(location = 0) in vec3 v_position;
|
|||||||
layout(location = 1) in vec4 color;
|
layout(location = 1) in vec4 color;
|
||||||
layout(location = 2) in vec2 ti_position;
|
layout(location = 2) in vec2 ti_position;
|
||||||
|
|
||||||
|
layout(location = 3) in vec2 screen_position;
|
||||||
|
layout(location = 4) in vec2 atlas_position;
|
||||||
|
layout(location = 5) in vec2 atlas_size;
|
||||||
|
layout(location = 6 in float scale;
|
||||||
|
|
||||||
// These are made up in the shader themselves
|
// These are made up in the shader themselves
|
||||||
layout(location = 0) out vec2 tex_coords;
|
layout(location = 0) out vec2 tex_coords;
|
||||||
|
|
||||||
|
|||||||
@@ -51,45 +51,3 @@ impl CanvasImage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct CanvasTextCache {
|
|
||||||
//pub(crate) handle: Arc<CanvasTextCacheHandle>,
|
|
||||||
pub(crate) buffer: Arc<CpuAccessibleBuffer<u8>>,
|
|
||||||
pub(crate) size: (u32, u32),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CanvasTextCache {
|
|
||||||
pub fn get_descriptor_set(&self,
|
|
||||||
pipeline: Arc<dyn GraphicsPipelineAbstract + Sync + Send>,
|
|
||||||
sampler: Arc<Sampler>) -> Box<dyn DescriptorSet + Send + Sync> {
|
|
||||||
let o: Box<dyn DescriptorSet + Send + Sync> = Box::new(
|
|
||||||
PersistentDescriptorSet::start(
|
|
||||||
pipeline.clone(), 0,
|
|
||||||
)
|
|
||||||
.add_buffer(self.buffer.clone()).unwrap()
|
|
||||||
.build().unwrap());
|
|
||||||
o
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct CanvasText {
|
|
||||||
pub(crate) handle: Arc<CanvasFontHandle>,
|
|
||||||
pub(crate) buffer: Arc<ImmutableImage<R8Unorm>>,
|
|
||||||
pub(crate) size: (u32, u32),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CanvasText {
|
|
||||||
pub fn get_descriptor_set(&self,
|
|
||||||
pipeline: Arc<dyn GraphicsPipelineAbstract + Sync + Send>,
|
|
||||||
sampler: Arc<Sampler>) -> Box<dyn DescriptorSet + Send + Sync> {
|
|
||||||
let o: Box<dyn DescriptorSet + Send + Sync> = Box::new(
|
|
||||||
PersistentDescriptorSet::start(
|
|
||||||
pipeline.clone(), 0,
|
|
||||||
)
|
|
||||||
.add_sampled_image(self.buffer.clone(), sampler.clone()).unwrap()
|
|
||||||
.build().unwrap());
|
|
||||||
o
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,12 +2,15 @@ use crate::util::vertex_3d::{Vertex3D};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use crate::canvas::canvas_state::{Drawable, CanvasTextureHandle, CanvasImageHandle};
|
use crate::canvas::canvas_state::{Drawable, CanvasTextureHandle, CanvasImageHandle};
|
||||||
|
use crate::canvas::canvas_text::CanvasFontHandle;
|
||||||
|
use crate::canvas::shader::text_shader::GlyphInstance;
|
||||||
|
|
||||||
///
|
///
|
||||||
pub struct CanvasFrame {
|
pub struct CanvasFrame {
|
||||||
pub colored_drawables: Vec<Vertex3D>,
|
pub colored_drawables: Vec<Vertex3D>,
|
||||||
pub textured_drawables: HashMap<Arc<CanvasTextureHandle>, Vec<Vec<Vertex3D>>>,
|
pub textured_drawables: HashMap<Arc<CanvasTextureHandle>, Vec<Vec<Vertex3D>>>,
|
||||||
pub image_drawables: HashMap<Arc<CanvasImageHandle>, Vec<Vec<Vertex3D>>>,
|
pub image_drawables: HashMap<Arc<CanvasImageHandle>, Vec<Vec<Vertex3D>>>,
|
||||||
|
pub text_drawables: HashMap<Arc<CanvasFontHandle>, Vec<GlyphInstance>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CanvasFrame {
|
impl CanvasFrame {
|
||||||
@@ -18,9 +21,12 @@ impl CanvasFrame {
|
|||||||
colored_drawables: vec![],
|
colored_drawables: vec![],
|
||||||
textured_drawables: Default::default(),
|
textured_drawables: Default::default(),
|
||||||
image_drawables: Default::default(),
|
image_drawables: Default::default(),
|
||||||
|
text_drawables: Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Fix this for text and fonts
|
||||||
/// Accumulates the drawables collected Vertex2D's
|
/// Accumulates the drawables collected Vertex2D's
|
||||||
pub fn draw(&mut self, drawable: &dyn Drawable) {
|
pub fn draw(&mut self, drawable: &dyn Drawable) {
|
||||||
match drawable.get_texture_handle() {
|
match drawable.get_texture_handle() {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ use crate::canvas::shader::common::{CompiledGraphicsPipeline, CompiledGraphicsPi
|
|||||||
use crate::canvas::shader::generic_shader::GenericShader;
|
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;
|
||||||
|
|
||||||
/// 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
|
||||||
@@ -80,23 +81,22 @@ pub struct CanvasState {
|
|||||||
image_buffers: Vec<Arc<CanvasImage>>,
|
image_buffers: Vec<Arc<CanvasImage>>,
|
||||||
texture_buffers: Vec<Arc<CanvasTexture>>,
|
texture_buffers: Vec<Arc<CanvasTexture>>,
|
||||||
shader_buffers: Vec<Arc<Box<dyn CompiledGraphicsPipeline>>>,
|
shader_buffers: Vec<Arc<Box<dyn CompiledGraphicsPipeline>>>,
|
||||||
text_buffers: Vec<Arc<(CanvasText, CanvasTextCache)>>,
|
|
||||||
|
//
|
||||||
|
text_buffers: Vec<Arc<CanvasText>>,
|
||||||
|
|
||||||
// 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_drawables: Vec<Vertex3D>,
|
|
||||||
colored_vertex_buffer: Vec<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
|
colored_vertex_buffer: Vec<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
|
||||||
|
|
||||||
textured_drawables: HashMap<Arc<CanvasTextureHandle>, Vec<Vec<Vertex3D>>>,
|
|
||||||
textured_vertex_buffer: HashMap<Arc<CanvasTextureHandle>, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
|
textured_vertex_buffer: HashMap<Arc<CanvasTextureHandle>, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
|
||||||
|
|
||||||
image_drawables: HashMap<Arc<CanvasImageHandle>, Vec<Vec<Vertex3D>>>,
|
|
||||||
image_vertex_buffer: HashMap<Arc<CanvasImageHandle>, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
|
image_vertex_buffer: HashMap<Arc<CanvasImageHandle>, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
|
||||||
|
|
||||||
// So what exactly is this going to hold?
|
// So what exactly is this going to hold?
|
||||||
// Its going to be untextured. Colored. Lists of vertices.
|
// Its going to be untextured. Colored. Lists of vertices.
|
||||||
text_drawables: HashMap<Arc<CanvasFontHandle>, Vec<(Vertex3D)>>,
|
text_instances: HashMap<Arc<CanvasFontHandle>, Vec<(Vertex3D, )>>,
|
||||||
text_vertex_buffer: HashMap<Arc<CanvasFontHandle>, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
|
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>,
|
||||||
@@ -211,8 +211,8 @@ impl CanvasState {
|
|||||||
textured_vertex_buffer: Default::default(),
|
textured_vertex_buffer: Default::default(),
|
||||||
image_drawables: Default::default(),
|
image_drawables: Default::default(),
|
||||||
image_vertex_buffer: Default::default(),
|
image_vertex_buffer: Default::default(),
|
||||||
text_drawables: HashMap::default(),
|
text_instances: HashMap::default(),
|
||||||
text_vertex_buffer: Default::default(),
|
text_atlas_buffer: Default::default(),
|
||||||
|
|
||||||
queue: queue.clone(),
|
queue: queue.clone(),
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
@@ -257,7 +257,6 @@ impl CanvasState {
|
|||||||
handle
|
handle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// 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_image(&mut self, dimensions: (u32, u32), usage: ImageUsage) -> Arc<CanvasImageHandle> {
|
pub fn create_image(&mut self, dimensions: (u32, u32), usage: ImageUsage) -> Arc<CanvasImageHandle> {
|
||||||
let handle = Arc::new(CanvasImageHandle { handle: self.image_buffers.len() as u32 });
|
let handle = Arc::new(CanvasImageHandle { handle: self.image_buffers.len() as u32 });
|
||||||
@@ -404,22 +403,17 @@ 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) {
|
||||||
self.textured_drawables = canvas_frame.textured_drawables;
|
let textured_drawables = canvas_frame.textured_drawables;
|
||||||
self.colored_drawables = canvas_frame.colored_drawables;
|
let colored_drawables = canvas_frame.colored_drawables;
|
||||||
self.image_drawables = canvas_frame.image_drawables;
|
let image_drawables = canvas_frame.image_drawables;
|
||||||
|
let text_drawables = canvas_frame.text_drawables;
|
||||||
|
|
||||||
self.allocate_vertex_buffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// draw(canvas_fame) stored all the intermediate information, this function
|
|
||||||
/// allocates the vertex buffers using that information
|
|
||||||
fn allocate_vertex_buffers(&mut self) {
|
|
||||||
self.colored_vertex_buffer.clear();
|
self.colored_vertex_buffer.clear();
|
||||||
{
|
{
|
||||||
let g = hprof::enter("Colored Vertex Buffer");
|
let g = hprof::enter("Colored Vertex Buffer");
|
||||||
self.colored_vertex_buffer.push(
|
self.colored_vertex_buffer.push(
|
||||||
ImmutableBuffer::from_iter(
|
ImmutableBuffer::from_iter(
|
||||||
self.colored_drawables.iter().cloned(),
|
colored_drawables.iter().cloned(),
|
||||||
BufferUsage::vertex_buffer(),
|
BufferUsage::vertex_buffer(),
|
||||||
self.queue.clone(),
|
self.queue.clone(),
|
||||||
).unwrap().0
|
).unwrap().0
|
||||||
@@ -467,6 +461,27 @@ 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<Vertex3D>, b| {
|
||||||
|
a.extend(b);
|
||||||
|
a
|
||||||
|
});
|
||||||
|
|
||||||
|
self.image_vertex_buffer.insert(
|
||||||
|
k.clone(),
|
||||||
|
ImmutableBuffer::from_iter(
|
||||||
|
vertex_buffer.iter().cloned(),
|
||||||
|
BufferUsage::vertex_buffer(),
|
||||||
|
self.queue.clone(),
|
||||||
|
).unwrap().0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the descriptor set for solid colors using the input kernel (needs to support solid colors)
|
/// Builds the descriptor set for solid colors using the input kernel (needs to support solid colors)
|
||||||
@@ -565,25 +580,30 @@ impl CanvasState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
// let mut shader = self.text_buffers.get(
|
let mut shader = self.text_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_vertex_buffer.is_empty() {
|
|
||||||
// for (text_handle, vertex_buffer) in self.text_vertex_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());
|
|
||||||
//
|
//
|
||||||
// command_buffer = command_buffer.draw(
|
|
||||||
// shader.get_pipeline().clone(),
|
if !self.text_atlas_buffer.is_empty() {
|
||||||
// // Multiple vertex buffers must have their definition in the pipeline!
|
for (text_handle, vertex_buffer) in self.text_atlas_buffer.clone() {
|
||||||
// &self.dynamic_state.clone(), vec![vertex_buffer],
|
let handle = text_handle.clone().handle as usize;
|
||||||
// vec![descriptor_set], (),
|
let descriptor_set = self.text_buffers.get(handle).clone().unwrap().clone()
|
||||||
// ).unwrap();
|
.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(
|
||||||
|
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], (),
|
||||||
|
).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
command_buffer
|
command_buffer
|
||||||
.end_render_pass()
|
.end_render_pass()
|
||||||
|
|||||||
@@ -11,11 +11,20 @@ use shade_runner::{Input, Output, Layout, Entry};
|
|||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use vulkano::pipeline::depth_stencil::{DepthStencil, Compare, DepthBounds, Stencil, StencilOp};
|
use vulkano::pipeline::depth_stencil::{DepthStencil, Compare, DepthBounds, Stencil, StencilOp};
|
||||||
use vulkano::pipeline::vertex::SingleBufferDefinition;
|
use vulkano::pipeline::vertex::{SingleBufferDefinition, OneVertexOneInstanceDefinition};
|
||||||
use crate::util::vertex_3d::Vertex3D;
|
use crate::util::vertex_3d::Vertex3D;
|
||||||
use crate::canvas::shader::generic_shader::GenericShader;
|
use crate::canvas::shader::generic_shader::GenericShader;
|
||||||
use shade_runner as sr;
|
use shade_runner as sr;
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, Copy)]
|
||||||
|
pub struct GlyphInstance {
|
||||||
|
screen_position: (f32, f32),
|
||||||
|
atlas_position: (f32, f32),
|
||||||
|
atlas_size: (f32, f32),
|
||||||
|
scale: f32,
|
||||||
|
}
|
||||||
|
vulkano::impl_vertex!(GlyphInstance, screen_position, atlas_position, atlas_size, scale);
|
||||||
|
|
||||||
/// CanvasShader holds the pipeline and render pass for the input shader source
|
/// CanvasShader holds the pipeline and render pass for the input shader source
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TextShader {
|
pub struct TextShader {
|
||||||
@@ -99,7 +108,7 @@ impl CompiledGraphicsPipeline for TextShader {
|
|||||||
graphics_pipeline:
|
graphics_pipeline:
|
||||||
Some(Arc::new(GraphicsPipeline::start()
|
Some(Arc::new(GraphicsPipeline::start()
|
||||||
|
|
||||||
.vertex_input(SingleBufferDefinition::<Vertex3D>::new())
|
.vertex_input(OneVertexOneInstanceDefinition::<Vertex3D, GlyphInstance>::new())
|
||||||
|
|
||||||
.vertex_shader(vertex_entry_point.clone(), ShaderSpecializationConstants {
|
.vertex_shader(vertex_entry_point.clone(), ShaderSpecializationConstants {
|
||||||
first_constant: 0,
|
first_constant: 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user