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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
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


        num_vertices = 3;


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

        // The number of actually bound inputs
        let buffers = vec![
            (0, mem::size_of::<i32>(), InputRate::Vertex),
            (1, mem::size_of::<i32>(), InputRate::Vertex),
            (2, mem::size_of::<i32>(), InputRate::Vertex),
            (3, mem::size_of::<i32>(), InputRate::Vertex),
            (4, mem::size_of::<i32>(), InputRate::Vertex),
            (5, mem::size_of::<i32>(), InputRate::Vertex),
            (6, mem::size_of::<i32>(), InputRate::Vertex),
        ].into_iter();

        Ok((buffers, 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
        )
    }
}