215 lines
4.7 KiB
Rust
215 lines
4.7 KiB
Rust
#[allow(unused_imports)]
|
|
use log::{debug, error, info, trace, warn};
|
|
|
|
use winit;
|
|
|
|
use cgmath::{Vector3, Vector2};
|
|
|
|
//--Position struct---------------------------------------------------------------------------------
|
|
#[derive(Copy, Clone, Debug)]
|
|
pub struct Position {
|
|
pub x: i32,
|
|
pub y: i32,
|
|
}
|
|
|
|
impl Position {
|
|
|
|
pub fn origin() -> Self {
|
|
Position {
|
|
x: 0,
|
|
y: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<Position> for Vector3<f32> {
|
|
|
|
fn from(pos: Position) -> Self {
|
|
Self::new(pos.x as f32, pos.y as f32, 0.0)
|
|
}
|
|
}
|
|
|
|
impl From<Position> for Vector2<f32> {
|
|
|
|
fn from(pos: Position) -> Self {
|
|
Self::new(pos.x as f32, pos.y as f32)
|
|
}
|
|
}
|
|
|
|
impl std::ops::Add for Position {
|
|
type Output = Self;
|
|
|
|
fn add(self, rhs: Self) -> Self::Output {
|
|
Position {
|
|
x: self.x + rhs.x,
|
|
y: self.y + rhs.y,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::ops::Mul<f32> for Position {
|
|
type Output = Self;
|
|
|
|
fn mul(self, rhs: f32) -> Self::Output {
|
|
Position {
|
|
x: ((self.x as f32) * rhs) as i32,
|
|
y: ((self.y as f32) * rhs) as i32,
|
|
}
|
|
}
|
|
}
|
|
|
|
//--Size struct-------------------------------------------------------------------------------------
|
|
#[derive(Copy, Clone)]
|
|
pub struct Size {
|
|
pub w: u32,
|
|
pub h: u32,
|
|
}
|
|
|
|
impl From<Size> for winit::dpi::Size {
|
|
|
|
fn from(size: Size) -> Self {
|
|
winit::dpi::Size::Physical (
|
|
winit::dpi::PhysicalSize {
|
|
width: size.w,
|
|
height: size.h,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl From<Size> for wgpu::Extent3d {
|
|
|
|
fn from(size: Size) -> Self {
|
|
wgpu::Extent3d {
|
|
width: size.w,
|
|
height: size.h,
|
|
depth_or_array_layers: 1,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<winit::dpi::PhysicalSize<u32>> for Size {
|
|
|
|
fn from(size: winit::dpi::PhysicalSize<u32>) -> Self {
|
|
Self {
|
|
w: size.width,
|
|
h: size.height,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<Size> for Vector2<f32> {
|
|
|
|
fn from(size: Size) -> Self {
|
|
Self::new(size.w as f32, size.h as f32)
|
|
}
|
|
}
|
|
|
|
//--Pixel struct------------------------------------------------------------------------------------
|
|
#[repr(packed, C)]
|
|
#[derive(Copy, Clone, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
|
|
pub struct Pixel {
|
|
pub r: u8,
|
|
pub g: u8,
|
|
pub b: u8,
|
|
pub a: u8,
|
|
}
|
|
|
|
impl From<Color> for Pixel {
|
|
|
|
fn from(value: Color) -> Self {
|
|
value.into_pixel()
|
|
}
|
|
}
|
|
|
|
impl Pixel {
|
|
|
|
pub const fn from_hex(hex: u32) -> Self {
|
|
let bytes = hex.to_be_bytes();
|
|
Self { r: bytes[0], g: bytes[1], b: bytes[2], a: bytes[3] }
|
|
}
|
|
|
|
}
|
|
|
|
//--Color values------------------------------------------------------------------------------------
|
|
#[non_exhaustive]
|
|
#[derive(Copy, Clone, PartialEq)]
|
|
pub struct Color {
|
|
r: f32,
|
|
g: f32,
|
|
b: f32,
|
|
a: f32,
|
|
}
|
|
|
|
impl From<Pixel> for Color {
|
|
|
|
fn from(value: Pixel) -> Self {
|
|
Self {
|
|
r: f32::from(value.r) / 255.0,
|
|
g: f32::from(value.g) / 255.0,
|
|
b: f32::from(value.b) / 255.0,
|
|
a: f32::from(value.a) / 255.0,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Color {
|
|
|
|
pub fn set_alpha(&mut self, a: u8) {
|
|
self.a = f32::from(a) / 255.0;
|
|
}
|
|
|
|
pub fn from_rgb(r: u8, g: u8, b: u8) -> Self {
|
|
Pixel { r, g, b, a: 255 }.into()
|
|
}
|
|
|
|
pub fn from_rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
|
|
Pixel { r, g, b, a }.into()
|
|
}
|
|
|
|
pub fn from_hex(hex: u32) -> Self {
|
|
Pixel::from_hex(hex).into()
|
|
}
|
|
|
|
pub fn into_pixel(self) -> Pixel {
|
|
//unsafe block is used here for "to_int_unchecked" since the struct's invariant garentees
|
|
//that the values are within [0.0, 1.0], meaning we won't ever overflow an u8
|
|
unsafe {
|
|
Pixel {
|
|
r: self.r.to_int_unchecked::<u8>() * 255,
|
|
g: self.g.to_int_unchecked::<u8>() * 255,
|
|
b: self.b.to_int_unchecked::<u8>() * 255,
|
|
a: self.a.to_int_unchecked::<u8>() * 255,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn into_wgpu_color(self) -> wgpu::Color {
|
|
wgpu::Color {
|
|
r: f64::from(self.r),
|
|
g: f64::from(self.g),
|
|
b: f64::from(self.b),
|
|
a: f64::from(self.a),
|
|
}
|
|
}
|
|
|
|
pub fn alpha_blend(&self, other: &Self) -> Self {
|
|
//apply alpha compisting's "over" operator, see
|
|
//[https://en.wikipedia.org/wiki/Alpha_compositing] for more detail
|
|
let a = self.a + other.a * (1.0 - self.a);
|
|
Self {
|
|
r: (self.r * self.a + other.r * other.a * (1.0 - self.a)) / a,
|
|
g: (self.g * self.a + other.g * other.a * (1.0 - self.a)) / a,
|
|
b: (self.b * self.a + other.b * other.a * (1.0 - self.a)) / a,
|
|
a,
|
|
}
|
|
}
|
|
|
|
pub const NONE: Self = Self {r: 0.0, g: 0.0, b: 0.0, a: 0.0};
|
|
pub const WHITE: Self = Self {r: 1.0, g: 1.0, b: 1.0, a: 1.0};
|
|
pub const BLACK: Self = Self {r: 0.0, g: 0.0, b: 0.0, a: 1.0};
|
|
pub const RED: Self = Self {r: 1.0, g: 0.0, b: 0.0, a: 1.0};
|
|
pub const GREEN: Self = Self {r: 0.0, g: 1.0, b: 0.0, a: 1.0};
|
|
pub const BLUE: Self = Self {r: 0.0, g: 0.0, b: 1.0, a: 1.0};
|
|
}
|
|
|