use crate::buffer::{GpuArrayBuffer, GpuDeviceExt};
use twmap::{Quad, QuadsLayer};
use vek::az::UnwrappedAs;
use vek::Vec2;
use wgpu::{BufferUsages, Device};
use super::super::{GpuEnvelopesData, QuadCorner};
const LABEL: Option<&str> = Some("Quads Data");
pub struct GpuQuadsData {
pub vertex_buffer: GpuArrayBuffer<QuadCorner>,
pub index_buffer: GpuArrayBuffer<u32>,
}
impl QuadCorner {
fn split_quad(quad: &Quad, envelopes: &GpuEnvelopesData) -> [Self; 4] {
[0, 1, 2, 3].map(|i| {
let position: Vec2<f32> = quad.corners[i].az();
let center: Vec2<f32> = quad.position.az();
Self {
center,
offset: position - center,
tex_coords: quad.texture_coords[i].az(),
color: quad.colors[i].az::<f32>() / u8::MAX as f32,
color_env: envelopes.quad_color_env_index(quad),
position_env: envelopes.quad_position_env_index(quad),
}
})
}
}
impl GpuQuadsData {
pub fn upload(layer: &QuadsLayer, envelopes: &GpuEnvelopesData, device: &Device) -> Self {
let mut vertices = Vec::new();
let mut indices: Vec<u32> = Vec::new();
for (n, quad) in layer.quads.iter().enumerate() {
vertices.extend(QuadCorner::split_quad(quad, envelopes));
let offset = n.unwrapped_as::<u32>().checked_mul(4).unwrap();
indices.extend([0, 1, 3, 0, 2, 3].map(|i| i + offset));
}
let vertex_buffer = device.array_buffer(&vertices, LABEL, BufferUsages::VERTEX);
let index_buffer = device.array_buffer(&indices, LABEL, BufferUsages::INDEX);
Self {
vertex_buffer,
index_buffer,
}
}
}