use super::*;
#[derive(Clone, Debug, PartialEq)]
pub struct Paint<T> {
pub template: T,
}
impl<V: TVertex, U: TUniform> DrawBuilder<V, U> {
#[inline(never)]
pub fn fill_rect<T: ToVertex<V>>(&mut self, paint: &Paint<T>, rc: &Bounds2f) {
let vertices = [
paint.template.to_vertex(rc.bottom_left(), 0),
paint.template.to_vertex(rc.top_left(), 1),
paint.template.to_vertex(rc.top_right(), 2),
paint.template.to_vertex(rc.bottom_right(), 3),
];
let mut cv = self.begin(PrimType::Triangles, 4, 2);
cv.add_indices_quad();
cv.add_vertices(&vertices);
}
#[inline(never)]
pub fn fill_edge_rect<T: ToVertex<V>>(&mut self, paint: &Paint<T>, rc: &Bounds2f, thickness: f32) {
let vertices = [
paint.template.to_vertex(rc.top_left(), 1),
paint.template.to_vertex(rc.top_right(), 2),
paint.template.to_vertex(rc.bottom_right(), 3),
paint.template.to_vertex(rc.bottom_left(), 0),
paint.template.to_vertex(rc.top_left() + Vec2(thickness, thickness), 5),
paint.template.to_vertex(rc.top_right() + Vec2(-thickness, thickness), 6),
paint.template.to_vertex(rc.bottom_right() + Vec2(-thickness, -thickness), 7),
paint.template.to_vertex(rc.bottom_left() + Vec2(thickness, -thickness), 4)
];
let mut cv = self.begin(PrimType::Triangles, 8, 8);
cv.add_indices(&[
0, 5, 4, 0, 1, 5,
1, 6, 5, 1, 2, 6,
2, 7, 6, 2, 3, 7,
3, 4, 7, 3, 0, 4,
]);
cv.add_vertices(&vertices);
}
#[inline(never)]
pub fn fill_round_rect<T: ToVertex<V>>(&mut self, paint: &Paint<T>, rc: &Bounds2f, sx: f32, sy: f32, _segments: i32) {
let sx = if sx + sx > rc.width() { rc.width() * 0.5 } else { sx };
let sy = if sy + sy > rc.height() { rc.height() * 0.5 } else { sy };
if sx <= 0.0 || sy <= 0.0 {
return self.fill_rect(paint, rc);
}
unimplemented!()
}
#[inline(never)]
pub fn fill_convex<T: ToVertex<V>>(&mut self, paint: &Paint<T>, pts: &[Point2f]) {
if pts.len() < 3 {
return;
}
let n = pts.len() - 2;
let mut cv = self.begin(PrimType::Triangles, pts.len(), n);
for i in 0..n as u32 {
cv.add_index3(i, i + 1, n as u32 + 1);
}
for v in 0..pts.len() {
cv.add_vertex(paint.template.to_vertex(pts[v], v));
}
}
#[inline(never)]
pub fn fill_polygon<T: ToVertex<V>>(&mut self, paint: &Paint<T>, pts: &[Point2f], triangles: &[Index3]) {
let mut cv = self.begin(PrimType::Triangles, pts.len(), triangles.len());
for i in 0..triangles.len() {
let Index3 { p1, p2, p3 } = triangles[i];
let _ = pts[p1 as usize];
let _ = pts[p2 as usize];
let _ = pts[p3 as usize];
cv.add_index3(p1 as u32, p2 as u32, p3 as u32);
}
for v in 0..pts.len() {
cv.add_vertex(paint.template.to_vertex(pts[v], v));
}
}
#[inline(never)]
pub fn fill_polygon2(&mut self, vertices: &[V], triangles: &[Index3]) {
let mut cv = self.begin(PrimType::Triangles, vertices.len(), triangles.len());
for i in 0..triangles.len() {
let Index3 { p1, p2, p3 } = triangles[i];
let _ = vertices[p1 as usize];
let _ = vertices[p2 as usize];
let _ = vertices[p3 as usize];
cv.add_index3(p1 as u32, p2 as u32, p3 as u32);
}
cv.add_vertices(vertices);
}
#[inline(never)]
pub fn fill_quad<T: ToVertex<V>>(&mut self, paint: &Paint<T>, bottom_left: &Point2f, top_left: &Point2f, top_right: &Point2f, bottom_right: &Point2f) {
let vertices = [
paint.template.to_vertex(*bottom_left, 0),
paint.template.to_vertex(*top_left, 1),
paint.template.to_vertex(*top_right, 2),
paint.template.to_vertex(*bottom_right, 3),
];
let mut cv = self.begin(PrimType::Triangles, 4, 2);
cv.add_indices_quad();
cv.add_vertices(&vertices);
}
#[inline(never)]
pub fn fill_ellipse<T: ToVertex<V>>(&mut self, paint: &Paint<T>, rc: &Bounds2f, segments: i32) {
let n = cmp::max(3, segments) as usize;
let mut cv = self.begin(PrimType::Triangles, n + 1, n);
let (s, c) = (Angle::TURN / (n as i32 as f32)).sin_cos();
let radius = rc.size() * 0.5;
let center = rc.top_left() + radius;
let mut pt = Point2(1.0, 0.0);
for i in 1..n {
cv.add_index3(0, i as u32, i as u32 + 1);
}
cv.add_index3(0, n as u32 - 1, 1);
cv.add_vertex(paint.template.to_vertex(center, 0));
for i in 0..n {
let pos = pt * radius + center;
cv.add_vertex(paint.template.to_vertex(pos, i + 1));
let x = pt.x;
pt.x = c * x - s * pt.y;
pt.y = s * x + c * pt.y;
}
}
#[inline(never)]
pub fn fill_pie<T: ToVertex<V>>(&mut self, paint: &Paint<T>, rc: &Bounds2f, start: Angle<f32>, sweep: Angle<f32>, segments: i32) {
let n = cmp::max(2, segments) as usize;
let mut cv = self.begin(PrimType::Triangles, n + 2, n);
for i in 1..n + 1 {
cv.add_index3(0, i as u32, i as u32 + 1);
}
let (s, c) = (sweep / (n as i32 as f32)).sin_cos();
let radius = rc.size() * 0.5;
let center = rc.top_left() + radius;
let mut pt = {
let (y, x) = start.sin_cos();
Point2(x, y)
};
cv.add_vertex(paint.template.to_vertex(center, 0));
for i in 0..n + 1 {
let pos = pt * radius + center;
cv.add_vertex(paint.template.to_vertex(pos, i + 1));
let x = pt.x;
pt.x = c * x - s * pt.y;
pt.y = s * x + c * pt.y;
}
}
#[inline(never)]
pub fn fill_ring<T: ToVertex<V>>(&mut self, paint: &Paint<T>, rc: &Bounds2f, thickness: f32, segments: i32) {
let n = cmp::max(3, segments) as usize;
let mut cv = self.begin(PrimType::Triangles, n * 2, n * 2);
for i in 0..n - 1 {
let v = i * 2;
cv.add_index3(v as u32, (v + 1) as u32, (v + 2) as u32);
cv.add_index3((v + 1) as u32, (v + 2) as u32, (v + 3) as u32);
}
{
let v = (n - 1) * 2;
cv.add_index3(v as u32, (v + 1) as u32, 0);
cv.add_index3((v + 1) as u32, 0, 1);
}
let (s, c) = (Angle::TURN / (n as i32 as f32)).sin_cos();
let radius = rc.size() * 0.5;
let width = radius - Point2::dup(thickness);
let center = rc.top_left() + radius;
let mut pt = Point2(1.0, 0.0);
for i in 0..n {
let pos = pt * radius + center;
cv.add_vertex(paint.template.to_vertex(pos, i * 2));
let pos = pt * width + center;
cv.add_vertex(paint.template.to_vertex(pos, i * 2 + 1));
let x = pt.x;
pt.x = c * x - s * pt.y;
pt.y = s * x + c * pt.y;
}
}
pub fn fill_bezier2<T: ToVertex<V>>(&mut self, paint: &Paint<T>, pivot: &Point2f, pts: &[Point2f; 3], segments: i32) {
let n = cmp::max(2, segments) as usize;
let mut cv = self.begin(PrimType::Triangles, n + 2, n);
for i in 1..n + 1 {
cv.add_index3(0, i as u32, i as u32 + 1);
}
cv.add_vertex(paint.template.to_vertex(*pivot, 0));
for v in 1..n + 2 {
let pt = curve::bezier2(v as i32 as f32 / n as i32 as f32, pts[0], pts[1], pts[2]);
cv.add_vertex(paint.template.to_vertex(pt, v));
}
}
}