use glam::f32::{vec2, Mat4, Vec2};
use vulkano::{buffer::BufferContents, pipeline::graphics::vertex_input::Vertex as VTX};
#[repr(C)]
#[derive(BufferContents, VTX, Debug, Clone, Copy, PartialEq)]
pub struct Vertex {
#[format(R32G32_SFLOAT)]
pub position: Vec2,
#[format(R32G32_SFLOAT)]
pub tex_position: Vec2,
}
#[inline]
pub const fn vert(x: f32, y: f32) -> Vertex {
Vertex {
position: vec2(x, y),
tex_position: vec2(x, y),
}
}
#[inline]
pub const fn tvert(x: f32, y: f32, tx: f32, ty: f32) -> Vertex {
Vertex {
position: vec2(x, y),
tex_position: vec2(tx, ty),
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, BufferContents)]
pub(crate) struct ModelViewProj {
pub model: Mat4,
pub view: Mat4,
pub proj: Mat4,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, BufferContents)]
pub(crate) struct ObjectFrag {
pub color: [f32; 4],
pub texture_id: u32,
}
impl Default for ObjectFrag {
fn default() -> Self {
Self {
color: [0.0, 0.0, 0.0, 0.0],
texture_id: 0,
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, BufferContents)]
pub(crate) struct PushConstant {
pub resolution: [f32; 2],
}
#[derive(Debug, Clone, PartialEq)]
pub struct Data {
pub vertices: Vec<Vertex>,
pub indices: Vec<u32>,
}
impl Data {
pub const fn new(vertices: Vec<Vertex>, indices: Vec<u32>) -> Self {
Self { vertices, indices }
}
pub const fn empty() -> Self {
Data {
vertices: vec![],
indices: vec![],
}
}
pub fn square() -> Self {
Data {
vertices: SQUARE.into(),
indices: SQUARE_ID.into(),
}
}
pub fn triangle() -> Self {
Data {
vertices: TRIANGLE.into(),
indices: TRIANGLE_ID.into(),
}
}
}
#[allow(dead_code)]
pub const TRIANGLE: [Vertex; 3] = [vert(0.0, -1.0), vert(-1.0, 1.0), vert(1.0, 1.0)];
#[allow(dead_code)]
pub const TRIANGLE_ID: [u32; 3] = [0, 1, 2];
#[allow(dead_code)]
pub const SQUARE: [Vertex; 4] = [
vert(-1.0, -1.0),
vert(1.0, -1.0),
vert(-1.0, 1.0),
vert(1.0, 1.0),
];
#[allow(dead_code)]
pub const SQUARE_ID: [u32; 6] = [0, 1, 2, 1, 2, 3];
#[macro_export]
macro_rules! make_circle {
($corners:expr) => {{ use let_engine::{vec2, Vertex};
let corners = $corners;
let mut vertices: Vec<Vertex> = vec![];
let mut indices: Vec<u32> = vec![];
use core::f64::consts::TAU;
vertices.push(Vertex {
position: vec2(0.0, 0.0),
tex_position: vec2(0.0, 0.0),
});
for i in 0..corners {
vertices.push(vert(
(TAU * ((i as f64) / corners as f64)).cos() as f32,
(TAU * ((i as f64) / corners as f64)).sin() as f32,
));
}
for i in 0..corners - 1 { indices.extend([0, i + 1, i + 2]);
}
indices.extend([0, corners, 1]);
Data { vertices, indices }
}};
($corners:expr, $percent:expr) => {{ use core::f64::consts::TAU;
use let_engine::{vec2, Vertex};
let corners = $corners;
let percent = $percent as f64;
let percent: f64 = percent.clamp(0.0, 1.0);
let mut vertices: Vec<Vertex> = vec![];
let mut indices: Vec<u32> = vec![];
let count = TAU * percent;
vertices.push(vert(0.0, 0.0));
for i in 0..corners + 1 {
vertices.push(vert(
(count * ((i as f64) / corners as f64)).cos() as f32,
(count * ((i as f64) / corners as f64)).sin() as f32,
));
}
for i in 0..corners {
indices.extend([0, i + 1, i + 2]);
}
Data { vertices, indices }
}};
}