use core::{handle, buffer};
use core::{Primitive, Resources, VertexCount};
use core::command::InstanceParams;
use core::factory::Factory;
use core::memory::Bind;
use format::Format;
use pso;
#[derive(Clone, Debug, PartialEq)]
pub struct Slice<R: Resources> {
pub start: VertexCount,
pub end: VertexCount,
pub base_vertex: VertexCount,
pub instances: Option<InstanceParams>,
pub buffer: IndexBuffer<R>,
}
impl<R: Resources> Slice<R> {
pub fn new_match_vertex_buffer<V>(vbuf: &handle::Buffer<R, V>) -> Self
where V: pso::buffer::Structure<Format> {
Slice {
start: 0,
end: vbuf.len() as u32,
base_vertex: 0,
instances: None,
buffer: IndexBuffer::Auto,
}
}
pub fn get_prim_count(&self, prim: Primitive) -> u32 {
use core::Primitive as p;
let nv = (self.end - self.start) as u32;
match prim {
p::PointList => nv,
p::LineList => nv / 2,
p::LineStrip => (nv-1),
p::TriangleList => nv / 3,
p::TriangleStrip => (nv-2) / 3,
p::PatchList(num) => nv / (num as u32),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum IndexBuffer<R: Resources> {
Auto,
Index16(handle::Buffer<R, u16>),
Index32(handle::Buffer<R, u32>),
}
impl<R: Resources> Default for IndexBuffer<R> {
fn default() -> Self {
IndexBuffer::Auto
}
}
pub trait IntoIndexBuffer<R: Resources> {
fn into_index_buffer<F: Factory<R> + ?Sized>(self, factory: &mut F) -> IndexBuffer<R>;
}
impl<R: Resources> IntoIndexBuffer<R> for IndexBuffer<R> {
fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
self
}
}
impl<R: Resources> IntoIndexBuffer<R> for () {
fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
IndexBuffer::Auto
}
}
macro_rules! impl_index_buffer {
($prim_ty:ty, $buf_ty:ident) => (
impl<R: Resources> IntoIndexBuffer<R> for handle::Buffer<R, $prim_ty> {
fn into_index_buffer<F: Factory<R> + ?Sized>(self, _: &mut F) -> IndexBuffer<R> {
IndexBuffer::$buf_ty(self)
}
}
impl<'s, R: Resources> IntoIndexBuffer<R> for &'s [$prim_ty] {
fn into_index_buffer<F: Factory<R> + ?Sized>(self, factory: &mut F) -> IndexBuffer<R> {
factory.create_buffer_immutable(self, buffer::Role::Index, Bind::empty())
.unwrap()
.into_index_buffer(factory)
}
}
)
}
impl_index_buffer!(u16, Index16);
impl_index_buffer!(u32, Index32);