pub use gfx_hal::pso::Element as VertexElement;
use gfx_hal::pso::{
self,
AttributeDesc,
VertexBufferDesc,
};
use super::{
buffer::Buffer,
surface::ColorFormat,
};
#[derive(Debug, Clone)]
pub struct VertexAttribute {
pub location: u32,
pub offset: u32,
pub element: VertexElement<ColorFormat>,
}
pub struct PrimitiveAssemblerBuilder {
buffer_descriptions: Vec<VertexBufferDesc>,
attribute_descriptions: Vec<AttributeDesc>,
}
impl PrimitiveAssemblerBuilder {
pub fn new() -> Self {
return Self {
buffer_descriptions: Vec::new(),
attribute_descriptions: Vec::new(),
};
}
pub fn build<'shader, RenderBackend: gfx_hal::Backend>(
&'shader mut self,
vertex_shader: &'shader super::shader::ShaderModule<RenderBackend>,
buffers: Option<&Vec<&Buffer<RenderBackend>>>,
attributes: Option<&[VertexAttribute]>,
) -> PrimitiveAssembler<'shader, RenderBackend> {
let binding = self.buffer_descriptions.len() as u32;
match (buffers, attributes) {
(Some(buffers), Some(attributes)) => {
logging::debug!(
"Building primitive assembler with buffers and attributes"
);
self.buffer_descriptions = buffers
.iter()
.map(|buffer| VertexBufferDesc {
binding,
stride: buffer.stride() as u32,
rate: pso::VertexInputRate::Vertex,
})
.collect();
self.attribute_descriptions = attributes
.iter()
.map(|attribute| {
return AttributeDesc {
location: attribute.location,
binding,
element: attribute.element,
};
})
.collect();
}
_ => {}
}
let primitive_assembler = pso::PrimitiveAssemblerDesc::Vertex {
buffers: self.buffer_descriptions.as_slice(),
attributes: self.attribute_descriptions.as_slice(),
input_assembler: pso::InputAssemblerDesc::new(
pso::Primitive::TriangleList,
),
vertex: pso::EntryPoint {
entry: vertex_shader.entry(),
module: super::internal::module_for(vertex_shader),
specialization: vertex_shader.specializations().clone(),
},
tessellation: None,
geometry: None,
};
return PrimitiveAssembler::<'shader> {
primitive_assembler,
};
}
}
pub struct PrimitiveAssembler<'shader, RenderBackend: gfx_hal::Backend> {
primitive_assembler: pso::PrimitiveAssemblerDesc<'shader, RenderBackend>,
}
impl<'shader, RenderBackend: gfx_hal::Backend>
PrimitiveAssembler<'shader, RenderBackend>
{
pub(super) fn internal_primitive_assembler(
self,
) -> pso::PrimitiveAssemblerDesc<'shader, RenderBackend> {
return self.primitive_assembler;
}
}