2019-05-04 14:28:21 +00:00
|
|
|
use super::{gfx_backend, mesh::Mesh, Pipeline, RenderError};
|
|
|
|
use gfx::{
|
|
|
|
buffer::Role,
|
|
|
|
memory::{Bind, Usage},
|
|
|
|
traits::FactoryExt,
|
|
|
|
Factory,
|
|
|
|
};
|
|
|
|
use std::ops::Range;
|
2019-01-07 21:10:31 +00:00
|
|
|
|
2019-01-11 23:18:34 +00:00
|
|
|
/// Represents a mesh that has been sent to the GPU.
|
2019-01-07 21:10:31 +00:00
|
|
|
pub struct Model<P: Pipeline> {
|
2019-01-11 20:14:37 +00:00
|
|
|
pub vbuf: gfx::handle::Buffer<gfx_backend::Resources, P::Vertex>,
|
|
|
|
pub slice: gfx::Slice<gfx_backend::Resources>,
|
2019-01-07 21:10:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<P: Pipeline> Model<P> {
|
2019-04-29 20:37:19 +00:00
|
|
|
pub fn new(factory: &mut gfx_backend::Factory, mesh: &Mesh<P>) -> Self {
|
2019-01-07 21:10:31 +00:00
|
|
|
Self {
|
2019-01-11 20:14:37 +00:00
|
|
|
vbuf: factory.create_vertex_buffer(mesh.vertices()),
|
|
|
|
slice: gfx::Slice {
|
|
|
|
start: 0,
|
|
|
|
end: mesh.vertices().len() as u32,
|
|
|
|
base_vertex: 0,
|
|
|
|
instances: None,
|
|
|
|
buffer: gfx::IndexBuffer::Auto,
|
|
|
|
},
|
2019-01-07 21:10:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-05-04 14:28:21 +00:00
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
/// Represents a mesh on the GPU which can be updated dynamically.
|
2019-05-04 14:28:21 +00:00
|
|
|
pub struct DynamicModel<P: Pipeline> {
|
|
|
|
pub vbuf: gfx::handle::Buffer<gfx_backend::Resources, P::Vertex>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<P: Pipeline> DynamicModel<P> {
|
|
|
|
pub fn new(factory: &mut gfx_backend::Factory, size: usize) -> Result<Self, RenderError> {
|
|
|
|
Ok(Self {
|
|
|
|
vbuf: factory
|
|
|
|
.create_buffer(size, Role::Vertex, Usage::Dynamic, Bind::empty())
|
|
|
|
.map_err(|err| RenderError::BufferCreationError(err))?,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-05-17 09:22:32 +00:00
|
|
|
/// Create a model with a slice of a portion of this model to send to the renderer.
|
2019-05-04 14:28:21 +00:00
|
|
|
pub fn submodel(&self, range: Range<usize>) -> Model<P> {
|
|
|
|
Model {
|
|
|
|
vbuf: self.vbuf.clone(),
|
|
|
|
slice: gfx::Slice {
|
|
|
|
start: range.start as u32,
|
|
|
|
end: range.end as u32,
|
|
|
|
base_vertex: 0,
|
|
|
|
instances: None,
|
|
|
|
buffer: gfx::IndexBuffer::Auto,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn update(
|
|
|
|
&self,
|
|
|
|
encoder: &mut gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
|
|
|
mesh: &Mesh<P>,
|
|
|
|
offset: usize,
|
|
|
|
) -> Result<(), RenderError> {
|
|
|
|
encoder
|
|
|
|
.update_buffer(&self.vbuf, mesh.vertices(), offset)
|
|
|
|
.map_err(|err| RenderError::UpdateError(err))
|
|
|
|
}
|
|
|
|
}
|