use crate::render::program::Program;
use crate::render::texture::Texture;
use crate::render::buffer::Buffer;
pub trait Target {
fn append(&mut self, data: &[f32], pattern: &[u32], vertex_size: u32, program: Option<&Program>, texture: Option<&Texture>, buffer: Option<&Buffer>);
}
pub struct VertexData {
pub(crate) vertices: Vec<f32>,
pub(crate) indices: Vec<u32>,
pub(crate) vertex_size: u32,
}
impl VertexData {
pub fn new() -> Self {
Self{ vertices: vec![], indices: vec![], vertex_size: 8 }
}
pub fn no_texture() -> Self {
Self{ vertices: vec![], indices: vec![], vertex_size: 6 }
}
pub fn custom(vertex_size: u32) -> Self {
Self{ vertices: vec![], indices: vec![], vertex_size }
}
fn error_check(&self, vertex_size: u32) {
if self.vertex_size != vertex_size {
panic!("incorrect vertex size, this vertex data accepts only vertex size {}, but \
you inputted vertex data with vertex size {}", self.vertex_size, vertex_size);
}
}
pub fn draw<T: Target>(&self, target: &mut T) {
target.append(&self.vertices, &self.indices, self.vertex_size, None, None, None);
}
pub fn clear(&mut self) {
self.indices.clear();
self.vertices.clear();
}
}
impl Target for VertexData {
#[inline]
fn append(&mut self, data: &[f32], pattern: &[u32], vertex_size: u32, _: Option<&Program>, _: Option<&Texture>, _: Option<&Buffer>) {
self.error_check(vertex_size);
let offset = self.vertices.len() as u32/ vertex_size;
self.vertices.extend(data);
for i in pattern {
self.indices.push(*i + offset);
}
}
}
pub struct Batch {
pub data: VertexData,
pub(crate) texture: Texture,
pub(crate) program: Program,
pub(crate) buffer: Option<Buffer>,
}
impl Batch {
pub fn no_texture() -> Batch {
Self::customized(Texture::NONE, Program::no_texture(), Some(Buffer::no_texture()))
}
pub fn new(texture: Texture) -> Batch {
Self::customized(texture, Program::default(), None)
}
pub fn customized(texture: Texture, program: Program, buffer: Option<Buffer>) -> Batch {
program.set_texture_size(texture.size());
let data = match &buffer {
Some(b) => {
VertexData::custom(b.data_size as u32)
}
None => VertexData::new()
};
Batch{texture, program, data, buffer}
}
pub fn draw<T: Target>(&self, target: &mut T) {
let buffer = match &self.buffer {
Some(b) => Some(b),
None => None,
};
target.append(&self.data.vertices, &self.data.indices, self.data.vertex_size, Some(&self.program), Some(&self.texture), buffer)
}
#[inline]
pub fn clear(&mut self) {
self.data.clear();
}
}
impl Target for Batch {
#[inline]
fn append(&mut self, data: &[f32], pattern: &[u32], vertex_size: u32, _: Option<&Program>, _: Option<&Texture>, _: Option<&Buffer>) {
self.data.append(data, pattern, vertex_size, None, None, None);
}
}