Files
Trac3r-rust/src/canvas/shader/dynamic_vertex.rs
2020-01-23 23:13:36 -08:00

175 lines
6.9 KiB
Rust

use vulkano::pipeline::vertex::{VertexDefinition, InputRate, AttributeInfo, IncompatibleVertexDefinitionError, VertexSource, VertexMemberInfo, VertexMemberTy};
use vulkano::pipeline::shader::ShaderInterfaceDef;
use vulkano::buffer::BufferAccess;
use std::sync::Arc;
use cgmath::num_traits::real::Real;
use std::vec::IntoIter as VecIntoIter;
use std::mem;
/// Runtime Vertex def is just a generic holder of "dynamic vertex definitions"
// This baby needs to be able to be copied....
#[derive(Default, Debug, Clone)]
pub struct RuntimeVertexDef {
buffers: Vec<(u32, usize, InputRate)>, // (attribute id, stride, Vertex or Instance data)
vertex_buffer_ids: Vec<(usize, usize)>,//
attributes: Vec<(String, u32, AttributeInfo)>,
num_vertices: u32,
}
impl RuntimeVertexDef {
/// primitive is an input value or struct which can then describe
/// these damn values that are required for inputting them into vulkan
pub fn from_primitive(primitive: u32) -> RuntimeVertexDef {
// Literally every value in this class
let mut buffers = Vec::new();
let mut vertex_buffer_ids = Vec::new();
let mut attributes = Vec::new();
let mut num_vertices = u32::max_value();
// https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/Box/glTF/Box.gltf
// https://github.com/tomaka/vulkano-examples/blob/gltf/gltf/gltf_system.rs
// 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
}
}
/// Implementing VertexDefinition
unsafe impl<I> VertexDefinition<I> for RuntimeVertexDef
where I: ShaderInterfaceDef
{
/// Iterator that returns the offset, the stride (in bytes) and input rate of each buffer.
type BuffersIter = VecIntoIter<(u32, usize, InputRate)>;
/// Iterator that returns the attribute location, buffer id, and infos.
type AttribsIter = VecIntoIter<(u32, u32, AttributeInfo)>;
/// Builds the vertex definition to use to link this definition to a vertex shader's input
/// interface.
///
/// At this point I need to have enough information from the implementing type to
/// describe its elements
///
/// Needs:
/// buffers
/// attributes
///
fn definition(&self, interface: &I)
-> Result<(Self::BuffersIter, Self::AttribsIter), IncompatibleVertexDefinitionError>
{
let buffers_iter = self.buffers.clone().into_iter();
let mut attributes = Vec::default();
for input in interface.elements() {
attributes.push((
input.location.start as u32,
input.location.start as u32,
AttributeInfo { offset: 0, format: input.format }
));
println!("{:?}", input.location);
println!("{:?}", input.format);
println!("{:?}", input.name);
}
// 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<_>>();
// This does nothing?
for binding in interface.elements() {
if attributes.iter().any(|a| a.0 == binding.location.start) {
continue;
}
attributes.push((binding.location.start, 0,
AttributeInfo { offset: 0, format: binding.format }));
}
let buffers = vec![
(0, mem::size_of::<i32>(), InputRate::Vertex),
].into_iter();
Ok((buffers_iter, attributes.into_iter()))
}
}
/// I don't know what the fuck is going on here... It just repackages the buffs
/// Needs the num vertices
unsafe impl VertexSource<Vec<Arc<dyn BufferAccess + Send + Sync>>> for RuntimeVertexDef {
fn decode(&self, bufs: Vec<Arc<dyn BufferAccess + Send + Sync>>)
-> (Vec<Box<dyn BufferAccess + Send + Sync>>, usize, usize)
{
(
bufs.into_iter().map(|b| Box::new(b) as Box<_>).collect(), // Box up the buffers
self.num_vertices as usize, // Number of vertices
1 // Number of instances
)
}
}