parent
554e8d551e
commit
c4b20bcd79
@ -0,0 +1,109 @@
|
||||
pub struct RuntimeVertexDef {
|
||||
buffers: Vec<(u32, usize, InputRate)>,
|
||||
vertex_buffer_ids: Vec<(usize, usize)>,
|
||||
attributes: Vec<(String, u32, AttributeInfo)>,
|
||||
num_vertices: u32,
|
||||
}
|
||||
|
||||
impl RuntimeVertexDef {
|
||||
pub fn from_primitive(primitive: gltf::Primitive) -> RuntimeVertexDef {
|
||||
use gltf::mesh::Attribute;
|
||||
use gltf::accessor::{DataType, Dimensions};
|
||||
|
||||
let mut buffers = Vec::new();
|
||||
let mut vertex_buffer_ids = Vec::new();
|
||||
let mut attributes = Vec::new();
|
||||
|
||||
let mut num_vertices = u32::max_value();
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<I> VertexDefinition<I> for RuntimeVertexDef
|
||||
where I: ShaderInterfaceDef
|
||||
{
|
||||
type BuffersIter = VecIntoIter<(u32, usize, InputRate)>;
|
||||
type AttribsIter = VecIntoIter<(u32, u32, AttributeInfo)>;
|
||||
|
||||
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.
|
||||
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 }));
|
||||
}
|
||||
|
||||
Ok((buffers_iter, attribs_iter.into_iter()))
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl VertexSource<Vec<Arc<BufferAccess + Send + Sync>>> for RuntimeVertexDef {
|
||||
fn decode(&self, bufs: Vec<Arc<BufferAccess + Send + Sync>>)
|
||||
-> (Vec<Box<BufferAccess + Send + Sync>>, usize, usize)
|
||||
{
|
||||
(bufs.into_iter().map(|b| Box::new(b) as Box<_>).collect(), self.num_vertices as usize, 1)
|
||||
}
|
||||
}
|
Loading…
Reference in new issue