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
        )
    }
}