use super::TexturePosition;
use crate::{quicksilver_compat::graphics::Color, Vector};
use web_sys::WebGlTexture;
#[derive(Clone, Debug)]
pub struct GpuVertex {
pub pos: Vector,
pub image: Option<TexturePosition>,
pub col: Color,
pub z: f32,
pub extra: Option<Vec<f32>>,
}
#[derive(Debug, Clone)]
pub struct VertexDescriptor {
attributes: Vec<VertexAttributeDescriptor>,
size: u32,
}
#[derive(Debug, Clone)]
pub struct VertexAttributeDescriptor {
pub name: &'static str,
pub size: i32,
pub(crate) source: VertexSource,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum VertexSource {
Pos,
Texture,
Color,
HasTexture,
ExtraVertexAttribute(usize),
}
impl GpuVertex {
pub fn new(
pos: Vector,
image: Option<TexturePosition>,
col: Color,
z: f32,
extra: Option<Vec<f32>>,
) -> Self {
Self {
pos,
image,
col,
z,
extra,
}
}
pub fn has_texture(&self) -> bool {
self.image.is_some()
}
pub fn tex_coordinate(&self) -> Option<Vector> {
self.image.as_ref().map(|img| img.st)
}
pub fn tex(&self) -> Option<&WebGlTexture> {
self.image.as_ref().map(|img| &img.tex)
}
}
impl VertexDescriptor {
pub fn new() -> Self {
Self {
attributes: Vec::new(),
size: 0,
}
}
pub fn with_pos(mut self) -> Self {
self.attributes.push(VertexAttributeDescriptor::new(
"position",
3,
VertexSource::Pos,
));
self.size += 3;
self
}
pub fn with_optional_tex(mut self) -> Self {
self.attributes.push(VertexAttributeDescriptor::new(
"tex_coord",
2,
VertexSource::Texture,
));
self.attributes.push(VertexAttributeDescriptor::new(
"uses_texture",
1,
VertexSource::HasTexture,
));
self.size += 3;
self
}
pub fn with_tex(mut self) -> Self {
self.attributes.push(VertexAttributeDescriptor::new(
"tex_coord",
2,
VertexSource::Texture,
));
self.size += 2;
self
}
pub fn with_col(mut self) -> Self {
self.attributes.push(VertexAttributeDescriptor::new(
"color",
4,
VertexSource::Color,
));
self.size += 4;
self
}
pub fn with(mut self, attribute: &'static str, size: usize) -> Self {
self.attributes.push(VertexAttributeDescriptor::new(
attribute,
size as i32,
VertexSource::ExtraVertexAttribute(self.attributes.len()),
));
self.size += size as u32;
self
}
pub fn vertex_size_in_sizeof_f32(&self) -> usize {
self.size as usize
}
pub fn attributes(&self) -> &[VertexAttributeDescriptor] {
&self.attributes
}
}
impl Default for VertexDescriptor {
fn default() -> Self {
Self {
attributes: vec![
VertexAttributeDescriptor::new("position", 3, VertexSource::Pos),
VertexAttributeDescriptor::new("tex_coord", 2, VertexSource::Texture),
VertexAttributeDescriptor::new("color", 4, VertexSource::Color),
VertexAttributeDescriptor::new("uses_texture", 1, VertexSource::HasTexture),
],
size: 10,
}
}
}
impl VertexAttributeDescriptor {
pub fn new(name: &'static str, size: i32, source: VertexSource) -> Self {
Self { name, size, source }
}
}