1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
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; /// 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 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. // Binding is 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 })); } // let buffers = vec![ // (0, mem::size_of::<T>(), InputRate::Vertex), // (1, mem::size_of::<U>(), InputRate::Instance), // ].into_iter(); Ok((buffers_iter, attribs_iter.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 ) } }