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 VertexDefinition 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::>(); // 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::(), 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>> for RuntimeVertexDef { fn decode(&self, bufs: Vec>) -> (Vec>, 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 ) } }