Added template dynamic vertex.
This commit is contained in:
@@ -80,20 +80,20 @@ impl Pair<GlyphInstance> {
|
|||||||
pub struct GenericCanvasFrame<H, V, In> {
|
pub struct GenericCanvasFrame<H, V, In> {
|
||||||
frame_data: HashMap<H, Vec<(Vec<V>, Vec<In>)>>
|
frame_data: HashMap<H, Vec<(Vec<V>, Vec<In>)>>
|
||||||
}
|
}
|
||||||
|
//
|
||||||
impl<V, In> GenericCanvasFrame<Vertex3D, V, In> {
|
//impl<V, In> GenericCanvasFrame<Vertex3D, V, In> {
|
||||||
|
//
|
||||||
/// Creates a bare canvas frame with empty accumulators
|
// /// Creates a bare canvas frame with empty accumulators
|
||||||
pub fn new() -> GenericCanvasFrame<Vertex3D, V, In> {
|
// pub fn new() -> GenericCanvasFrame<Vertex3D, V, In> {
|
||||||
GenericCanvasFrame {
|
// GenericCanvasFrame {
|
||||||
frame_data: Default::default()
|
// frame_data: Default::default()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
pub fn draw(&mut self, drawable: &dyn DrawableTest<V, Vertex3D, In>) {
|
// pub fn draw(&mut self, drawable: &dyn DrawableTest<V, Vertex3D, In>) {
|
||||||
self.frame_data
|
// self.frame_data
|
||||||
.entry(drawable.get_handle().clone())
|
// .entry(drawable.get_handle().clone())
|
||||||
.or_insert(Vec::new())
|
// .or_insert(Vec::new())
|
||||||
.push((drawable.get_vertices(), drawable.get_instances()));
|
// .push((drawable.get_vertices(), drawable.get_instances()));
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
@@ -31,6 +31,7 @@ use crate::canvas::shader::text_shader::GlyphInstance;
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use rusttype::{Font, PositionedGlyph, Scale, Rect, point, GlyphId};
|
use rusttype::{Font, PositionedGlyph, Scale, Rect, point, GlyphId};
|
||||||
|
use vulkano::pipeline::vertex::VertexDefinition;
|
||||||
|
|
||||||
|
|
||||||
// I don't think this is going to work without getting into Box'ing
|
// I don't think this is going to work without getting into Box'ing
|
||||||
@@ -322,7 +323,7 @@ impl CanvasState {
|
|||||||
filename: String,
|
filename: String,
|
||||||
physical: PhysicalDevice,
|
physical: PhysicalDevice,
|
||||||
capabilities: Capabilities) -> Option<Arc<CompiledGraphicsPipelineHandle>>
|
capabilities: Capabilities) -> Option<Arc<CompiledGraphicsPipelineHandle>>
|
||||||
where T: CompiledGraphicsPipeline {
|
where T: CompiledGraphicsPipeline, V: VertexDefinition {
|
||||||
|
|
||||||
let handle = Arc::new(CompiledGraphicsPipelineHandle {
|
let handle = Arc::new(CompiledGraphicsPipelineHandle {
|
||||||
handle: self.shader_buffers.len() as u32
|
handle: self.shader_buffers.len() as u32
|
||||||
|
|||||||
109
src/canvas/shader/dynamic_vertex.rs
Normal file
109
src/canvas/shader/dynamic_vertex.rs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
pub struct RuntimeVertexDef {
|
||||||
|
buffers: Vec<(u32, usize, InputRate)>,
|
||||||
|
vertex_buffer_ids: Vec<(usize, usize)>,
|
||||||
|
attributes: Vec<(String, u32, AttributeInfo)>,
|
||||||
|
num_vertices: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RuntimeVertexDef {
|
||||||
|
pub fn from_primitive(primitive: gltf::Primitive) -> RuntimeVertexDef {
|
||||||
|
use gltf::mesh::Attribute;
|
||||||
|
use gltf::accessor::{DataType, Dimensions};
|
||||||
|
|
||||||
|
let mut buffers = Vec::new();
|
||||||
|
let mut vertex_buffer_ids = Vec::new();
|
||||||
|
let mut attributes = Vec::new();
|
||||||
|
|
||||||
|
let mut num_vertices = u32::max_value();
|
||||||
|
|
||||||
|
for (attribute_id, attribute) in primitive.attributes().enumerate() {
|
||||||
|
let (name, accessor) = match attribute.clone() {
|
||||||
|
Attribute::Positions(accessor) => ("i_position".to_owned(), accessor),
|
||||||
|
Attribute::Normals(accessor) => ("i_normal".to_owned(), accessor),
|
||||||
|
Attribute::Tangents(accessor) => ("i_tangent".to_owned(), accessor),
|
||||||
|
Attribute::Colors(0, accessor) => ("i_color_0".to_owned(), accessor),
|
||||||
|
Attribute::TexCoords(0, accessor) => ("i_texcoord_0".to_owned(), accessor),
|
||||||
|
Attribute::TexCoords(1, accessor) => ("i_texcoord_1".to_owned(), accessor),
|
||||||
|
Attribute::Joints(0, accessor) => ("i_joints_0".to_owned(), accessor),
|
||||||
|
Attribute::Weights(0, accessor) => ("i_weights_0".to_owned(), accessor),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (accessor.count() as u32) < num_vertices {
|
||||||
|
num_vertices = accessor.count() as u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
let infos = AttributeInfo {
|
||||||
|
offset: 0,
|
||||||
|
format: match (accessor.data_type(), accessor.dimensions()) {
|
||||||
|
(DataType::I8, Dimensions::Scalar) => Format::R8Snorm,
|
||||||
|
(DataType::U8, Dimensions::Scalar) => Format::R8Unorm,
|
||||||
|
(DataType::F32, Dimensions::Vec2) => Format::R32G32Sfloat,
|
||||||
|
(DataType::F32, Dimensions::Vec3) => Format::R32G32B32Sfloat,
|
||||||
|
(DataType::F32, Dimensions::Vec4) => Format::R32G32B32A32Sfloat,
|
||||||
|
_ => unimplemented!()
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let view = accessor.view();
|
||||||
|
buffers.push((attribute_id as u32, view.stride().unwrap_or(accessor.size()), InputRate::Vertex));
|
||||||
|
attributes.push((name, attribute_id as u32, infos));
|
||||||
|
vertex_buffer_ids.push((view.buffer().index(), view.offset() + accessor.offset()));
|
||||||
|
}
|
||||||
|
|
||||||
|
RuntimeVertexDef {
|
||||||
|
buffers: buffers,
|
||||||
|
vertex_buffer_ids: vertex_buffer_ids,
|
||||||
|
num_vertices: num_vertices,
|
||||||
|
attributes: attributes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the indices of the buffers to bind as vertex buffers and the byte offset, when
|
||||||
|
/// drawing the primitive.
|
||||||
|
pub fn vertex_buffer_ids(&self) -> &[(usize, usize)] {
|
||||||
|
&self.vertex_buffer_ids
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<I> VertexDefinition<I> for RuntimeVertexDef
|
||||||
|
where I: ShaderInterfaceDef
|
||||||
|
{
|
||||||
|
type BuffersIter = VecIntoIter<(u32, usize, InputRate)>;
|
||||||
|
type AttribsIter = VecIntoIter<(u32, u32, AttributeInfo)>;
|
||||||
|
|
||||||
|
fn definition(&self, interface: &I)
|
||||||
|
-> Result<(Self::BuffersIter, Self::AttribsIter), IncompatibleVertexDefinitionError>
|
||||||
|
{
|
||||||
|
let buffers_iter = self.buffers.clone().into_iter();
|
||||||
|
|
||||||
|
let mut attribs_iter = self.attributes.iter().map(|&(ref name, buffer_id, ref infos)| {
|
||||||
|
let attrib_loc = interface
|
||||||
|
.elements()
|
||||||
|
.find(|e| e.name.as_ref().map(|n| &n[..]) == Some(&name[..]))
|
||||||
|
.unwrap()
|
||||||
|
.location.start;
|
||||||
|
(attrib_loc as u32, buffer_id, AttributeInfo { offset: infos.offset, format: infos.format })
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
// Add dummy attributes.
|
||||||
|
for binding in interface.elements() {
|
||||||
|
if attribs_iter.iter().any(|a| a.0 == binding.location.start) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
attribs_iter.push((binding.location.start, 0,
|
||||||
|
AttributeInfo { offset: 0, format: binding.format }));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((buffers_iter, attribs_iter.into_iter()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl VertexSource<Vec<Arc<BufferAccess + Send + Sync>>> for RuntimeVertexDef {
|
||||||
|
fn decode(&self, bufs: Vec<Arc<BufferAccess + Send + Sync>>)
|
||||||
|
-> (Vec<Box<BufferAccess + Send + Sync>>, usize, usize)
|
||||||
|
{
|
||||||
|
(bufs.into_iter().map(|b| Box::new(b) as Box<_>).collect(), self.num_vertices as usize, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,17 +6,18 @@ use std::collections::{HashSet, HashMap};
|
|||||||
use vulkano::device::Device;
|
use vulkano::device::Device;
|
||||||
use vulkano::framebuffer::{RenderPassAbstract, Subpass};
|
use vulkano::framebuffer::{RenderPassAbstract, Subpass};
|
||||||
use vulkano::pipeline::GraphicsPipeline;
|
use vulkano::pipeline::GraphicsPipeline;
|
||||||
use vulkano::pipeline::shader::{GraphicsEntryPoint, ShaderModule, GraphicsShaderType, GeometryShaderExecutionMode};
|
use vulkano::pipeline::shader::{GraphicsEntryPoint, ShaderModule, GraphicsShaderType, GeometryShaderExecutionMode, ShaderInterfaceDef};
|
||||||
use crate::canvas::shader::ShaderSpecializationConstants;
|
use crate::canvas::shader::ShaderSpecializationConstants;
|
||||||
use shade_runner::{Input, Output, Layout, Entry};
|
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, VertexDefinition};
|
||||||
use crate::util::vertex_3d::Vertex3D;
|
use crate::util::vertex_3d::Vertex3D;
|
||||||
use shade_runner as sr;
|
use shade_runner as sr;
|
||||||
use crate::canvas::shader::common::CompiledGraphicsPipelineResources;
|
use crate::canvas::shader::common::CompiledGraphicsPipelineResources;
|
||||||
use vulkano::memory::pool::PotentialDedicatedAllocation::Generic;
|
use vulkano::memory::pool::PotentialDedicatedAllocation::Generic;
|
||||||
|
use vulkano::SafeDeref;
|
||||||
|
|
||||||
/// 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)]
|
||||||
@@ -39,7 +40,7 @@ impl CompiledGraphicsPipelineResources for GenericShader {}
|
|||||||
impl CompiledGraphicsPipeline for GenericShader {
|
impl CompiledGraphicsPipeline for GenericShader {
|
||||||
|
|
||||||
/// This will explode when the shader does not want to compile
|
/// This will explode when the shader does not want to compile
|
||||||
fn new<T>(filename: String,
|
fn new<T: VertexDefinition>(filename: String,
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: Arc<CompiledGraphicsPipelineHandle>,
|
handle: Arc<CompiledGraphicsPipelineHandle>,
|
||||||
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> GenericShader {
|
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> GenericShader {
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ use crate::canvas::shader::common::CompiledGraphicsPipeline;
|
|||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod generic_shader;
|
pub mod generic_shader;
|
||||||
pub mod text_shader;
|
pub mod text_shader;
|
||||||
|
use mod dynamic_vertex;
|
||||||
|
|
||||||
use crate::canvas::shader::common::*;
|
use crate::canvas::shader::common::*;
|
||||||
use crate::canvas::shader::generic_shader::*;
|
use crate::canvas::shader::generic_shader::*;
|
||||||
use crate::canvas::shader::text_shader::*;
|
use crate::canvas::shader::text_shader::*;
|
||||||
|
use crate::canvas::shader::dynamic_vertex::*;
|
||||||
|
|
||||||
|
|
||||||
use vulkano::pipeline::shader::{SpecializationConstants, SpecializationMapEntry};
|
use vulkano::pipeline::shader::{SpecializationConstants, SpecializationMapEntry};
|
||||||
|
|||||||
Reference in New Issue
Block a user