summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-07-17 03:06:04 +0200
committerHampusM <hampus@hampusmat.com>2026-07-17 03:06:04 +0200
commit65e24308babb2ed4f33fb6f1d7b531df676bd70d (patch)
treedf9477d4b805cc6866a086833d6118505804dd3a /engine
parent649d4d4ab2f54ca12f75d2cba50e1adef2350dbe (diff)
refactor(engine): change Color struct into a enum
Diffstat (limited to 'engine')
-rw-r--r--engine/src/data_types/color.rs143
-rw-r--r--engine/src/data_types/vector.rs13
-rw-r--r--engine/src/file_format/wavefront/mtl.rs10
-rw-r--r--engine/src/image.rs70
-rw-r--r--engine/src/lighting.rs6
-rw-r--r--engine/src/material.rs12
-rw-r--r--engine/src/rendering/backend/opengl.rs49
-rw-r--r--engine/src/rendering/shader/cursor.rs10
-rw-r--r--engine/src/rendering/shader/default.rs28
-rw-r--r--engine/src/texture.rs8
10 files changed, 182 insertions, 167 deletions
diff --git a/engine/src/data_types/color.rs b/engine/src/data_types/color.rs
index 06df450..18d5334 100644
--- a/engine/src/data_types/color.rs
+++ b/engine/src/data_types/color.rs
@@ -1,4 +1,4 @@
-use std::ops::{Add, Div, Mul, Neg, Sub};
+use std::ops::{Add, Div, Mul, Sub};
pub trait Pixel: sealed::Sealed
{
@@ -7,12 +7,32 @@ pub trait Pixel: sealed::Sealed
macro_rules! gen_color {
($ident: ident, components=($($component: ident),+)) => {
- #[derive(Debug, Clone)]
+ #[derive(Debug, Clone, Default)]
pub struct $ident<Component>
{
$(pub $component: Component),+
}
+ impl $ident<u8>
+ {
+ pub fn white() -> Self
+ {
+ Self {
+ $($component: 255),*
+ }
+ }
+ }
+
+ impl $ident<f32>
+ {
+ pub fn white() -> Self
+ {
+ Self {
+ $($component: 1.0),*
+ }
+ }
+ }
+
impl<Component> Pixel for $ident<Component>
{
type Component = Component;
@@ -27,59 +47,74 @@ gen_color!(Rgba, components = (r, g, b, a));
gen_color!(Luma, components = (l));
gen_color!(LumaA, components = (l, a));
-#[derive(Debug, Clone, Default)]
-pub struct Color<Value>
-{
- pub red: Value,
- pub green: Value,
- pub blue: Value,
-}
-
-impl Color<f32>
-{
- pub const WHITE_F32: Self = Self { red: 1.0, green: 1.0, blue: 1.0 };
-}
-
-impl Color<u8>
+#[derive(Debug, Clone)]
+pub enum Color<Component>
{
- pub const WHITE_U8: Self = Self { red: 255, green: 255, blue: 255 };
+ Rgb(Rgb<Component>),
+ Rgba(Rgba<Component>),
+ Luma(Luma<Component>),
+ LumaA(LumaA<Component>),
}
-impl<Value: Clone> From<Value> for Color<Value>
+impl<Component: Default> Default for Color<Component>
{
- fn from(value: Value) -> Self
+ fn default() -> Self
{
- Self {
- red: value.clone(),
- green: value.clone(),
- blue: value,
- }
+ Self::Rgb(Rgb::default())
}
}
-macro_rules! impl_math_op {
- ($math_op_trait: ident, $function: ident) => {
- impl<Value> $math_op_trait for Color<Value>
+macro_rules! gen_scalar_math_op_impl {
+ (
+ $ident: ident,
+ $math_op_trait: ident,
+ $function: ident,
+ components=($($component: ident),+)
+ ) => {
+ impl<Value> $math_op_trait<Value> for $ident<Value>
where
- Value: $math_op_trait<Output = Value>,
+ Value: $math_op_trait<Output = Value> + Clone,
{
type Output = Self;
- fn $function(self, rhs: Self) -> Self::Output
+ fn $function(self, rhs: Value) -> Self::Output
{
Self {
- red: self.red.$function(rhs.red),
- green: self.green.$function(rhs.green),
- blue: self.blue.$function(rhs.blue),
+ $($component: self.$component.$function(rhs.clone())),+
}
}
}
};
}
-macro_rules! impl_scalar_math_op {
- ($math_op_trait: ident, $function: ident) => {
- impl<Value> $math_op_trait<Value> for Color<Value>
+gen_scalar_math_op_impl!(Rgb, Add, add, components = (r, g, b));
+gen_scalar_math_op_impl!(Rgb, Sub, sub, components = (r, g, b));
+gen_scalar_math_op_impl!(Rgb, Mul, mul, components = (r, g, b));
+gen_scalar_math_op_impl!(Rgb, Div, div, components = (r, g, b));
+
+gen_scalar_math_op_impl!(Rgba, Add, add, components = (r, g, b, a));
+gen_scalar_math_op_impl!(Rgba, Sub, sub, components = (r, g, b, a));
+gen_scalar_math_op_impl!(Rgba, Mul, mul, components = (r, g, b, a));
+gen_scalar_math_op_impl!(Rgba, Div, div, components = (r, g, b, a));
+
+gen_scalar_math_op_impl!(Luma, Add, add, components = (l));
+gen_scalar_math_op_impl!(Luma, Sub, sub, components = (l));
+gen_scalar_math_op_impl!(Luma, Mul, mul, components = (l));
+gen_scalar_math_op_impl!(Luma, Div, div, components = (l));
+
+gen_scalar_math_op_impl!(LumaA, Add, add, components = (l, a));
+gen_scalar_math_op_impl!(LumaA, Sub, sub, components = (l, a));
+gen_scalar_math_op_impl!(LumaA, Mul, mul, components = (l, a));
+gen_scalar_math_op_impl!(LumaA, Div, div, components = (l, a));
+
+macro_rules! gen_enum_scalar_math_op_impl {
+ (
+ $ident: ident,
+ $math_op_trait: ident,
+ $function: ident,
+ variants=($($variant: ident),+)
+ ) => {
+ impl<Value> $math_op_trait<Value> for $ident<Value>
where
Value: $math_op_trait<Output = Value> + Clone,
{
@@ -87,41 +122,21 @@ macro_rules! impl_scalar_math_op {
fn $function(self, rhs: Value) -> Self::Output
{
- Self {
- red: self.red.$function(rhs.clone()),
- green: self.green.$function(rhs.clone()),
- blue: self.blue.$function(rhs),
+ match self {
+ $(
+ Self::$variant(inner) =>
+ Self::$variant(inner.$function(rhs.clone()))
+ ),+
}
}
}
};
}
-impl_math_op!(Add, add);
-impl_math_op!(Sub, sub);
-impl_math_op!(Mul, mul);
-impl_math_op!(Div, div);
-
-impl_scalar_math_op!(Add, add);
-impl_scalar_math_op!(Sub, sub);
-impl_scalar_math_op!(Mul, mul);
-impl_scalar_math_op!(Div, div);
-
-impl<Value> Neg for Color<Value>
-where
- Value: Neg<Output = Value>,
-{
- type Output = Self;
-
- fn neg(self) -> Self::Output
- {
- Self {
- red: -self.red,
- green: -self.green,
- blue: -self.blue,
- }
- }
-}
+gen_enum_scalar_math_op_impl!(Color, Add, add, variants = (Rgb, Rgba, Luma, LumaA));
+gen_enum_scalar_math_op_impl!(Color, Sub, sub, variants = (Rgb, Rgba, Luma, LumaA));
+gen_enum_scalar_math_op_impl!(Color, Mul, mul, variants = (Rgb, Rgba, Luma, LumaA));
+gen_enum_scalar_math_op_impl!(Color, Div, div, variants = (Rgb, Rgba, Luma, LumaA));
mod sealed
{
diff --git a/engine/src/data_types/vector.rs b/engine/src/data_types/vector.rs
index dd9e386..8644dd2 100644
--- a/engine/src/data_types/vector.rs
+++ b/engine/src/data_types/vector.rs
@@ -1,6 +1,5 @@
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
-use crate::color::Color;
use crate::reflection::Reflection;
macro_rules! impl_math_op_traits {
@@ -226,18 +225,6 @@ impl From<f32> for Vec3<f32>
}
}
-impl<Value> From<Color<Value>> for Vec3<Value>
-{
- fn from(color: Color<Value>) -> Self
- {
- Self {
- x: color.red,
- y: color.green,
- z: color.blue,
- }
- }
-}
-
impl<Value> From<[Value; 3]> for Vec3<Value>
{
fn from([x, y, z]: [Value; 3]) -> Self
diff --git a/engine/src/file_format/wavefront/mtl.rs b/engine/src/file_format/wavefront/mtl.rs
index f3c7a64..24387b9 100644
--- a/engine/src/file_format/wavefront/mtl.rs
+++ b/engine/src/file_format/wavefront/mtl.rs
@@ -4,7 +4,7 @@
use std::path::{Path, PathBuf};
-use crate::color::Color;
+use crate::color::{Color, Rgb};
use crate::file_format::wavefront::common::{
keyword,
parse_statement_line,
@@ -67,9 +67,9 @@ impl Default for NamedMaterial
{
Self {
name: String::new(),
- ambient: Color::WHITE_F32,
- diffuse: Color::WHITE_F32,
- specular: Color::WHITE_F32,
+ ambient: Color::Rgb(Rgb::<f32>::white()),
+ diffuse: Color::Rgb(Rgb::<f32>::white()),
+ specular: Color::Rgb(Rgb::<f32>::white()),
ambient_map: None,
diffuse_map: None,
specular_map: None,
@@ -276,7 +276,7 @@ fn get_color_from_statement(
let green = statement.get_float_arg(1, line_no)?;
let blue = statement.get_float_arg(2, line_no)?;
- Ok(Color { red, green, blue })
+ Ok(Color::Rgb(Rgb { r: red, g: green, b: blue }))
}
keyword! {
diff --git a/engine/src/image.rs b/engine/src/image.rs
index 68eac65..18d3015 100644
--- a/engine/src/image.rs
+++ b/engine/src/image.rs
@@ -6,7 +6,7 @@ use std::path::Path;
use image_rs::GenericImageView as _;
-use crate::color::{Color, Luma, LumaA, Pixel as ColorPixel, Rgb, Rgba};
+use crate::color::{Luma, LumaA, Pixel as ColorPixel, Rgb, Rgba};
use crate::data_types::dimens::Dimens;
use crate::vector::Vec2;
@@ -60,41 +60,11 @@ impl Image
Self::try_from(pixels)
}
- pub fn from_color(dimens: impl Into<Dimens<u32>>, color: impl Into<Color<u8>>)
- -> Self
- {
- let dimens: Dimens<u32> = dimens.into();
-
- let color: Color<u8> = color.into();
-
- Self {
- inner: image_rs::RgbImage::from_pixel(
- dimens.width,
- dimens.height,
- image_rs::Rgb([color.red, color.green, color.blue]),
- )
- .into(),
- }
- }
-
- pub fn from_color_and_alpha(
- dimens: impl Into<Dimens<u32>>,
- color: impl Into<Color<u8>>,
- alpha: u8,
- ) -> Self
+ pub fn from_color<PixelT: ColorPixel>(color: PixelT, size: Dimens<u32>) -> Self
+ where
+ Self: From<(PixelT, Dimens<u32>)>,
{
- let dimens: Dimens<u32> = dimens.into();
-
- let color: Color<u8> = color.into();
-
- Self {
- inner: image_rs::RgbaImage::from_pixel(
- dimens.width,
- dimens.height,
- image_rs::Rgba([color.red, color.green, color.blue, alpha]),
- )
- .into(),
- }
+ Self::from((color, size))
}
pub fn dimensions(&self) -> Dimens<u32>
@@ -153,6 +123,36 @@ impl Image
}
}
+impl From<(Rgb<u8>, Dimens<u32>)> for Image
+{
+ fn from((color, size): (Rgb<u8>, Dimens<u32>)) -> Self
+ {
+ Self {
+ inner: image_rs::RgbImage::from_pixel(
+ size.width,
+ size.height,
+ image_rs::Rgb([color.r, color.g, color.b]),
+ )
+ .into(),
+ }
+ }
+}
+
+impl From<(Rgba<u8>, Dimens<u32>)> for Image
+{
+ fn from((color, size): (Rgba<u8>, Dimens<u32>)) -> Self
+ {
+ Self {
+ inner: image_rs::RgbaImage::from_pixel(
+ size.width,
+ size.height,
+ image_rs::Rgba([color.r, color.g, color.b, color.a]),
+ )
+ .into(),
+ }
+ }
+}
+
macro_rules! gen_try_from_pixel_buffer_impl {
($pixel: ident<$component: ty>) => {
impl<Buf> TryFrom<PixelBuffer<$pixel<$component>, Buf>> for Image
diff --git a/engine/src/lighting.rs b/engine/src/lighting.rs
index f085b17..abe3d56 100644
--- a/engine/src/lighting.rs
+++ b/engine/src/lighting.rs
@@ -1,5 +1,5 @@
use crate::builder;
-use crate::color::Color;
+use crate::color::{Color, Rgb};
use crate::data_types::vector::Vec3;
use crate::ecs::{Component, Sole};
use crate::reflection::Reflection;
@@ -33,8 +33,8 @@ impl Default for PointLight
{
Self {
local_position: Vec3::default(),
- diffuse: Color { red: 0.5, green: 0.5, blue: 0.5 },
- specular: Color { red: 1.0, green: 1.0, blue: 1.0 },
+ diffuse: Color::Rgb(Rgb { r: 0.5, g: 0.5, b: 0.5 }),
+ specular: Color::Rgb(Rgb::<f32>::white()),
attenuation_params: AttenuationParams::default(),
}
}
diff --git a/engine/src/material.rs b/engine/src/material.rs
index 42a9884..dd5a460 100644
--- a/engine/src/material.rs
+++ b/engine/src/material.rs
@@ -1,6 +1,6 @@
use crate::asset::Handle as AssetHandle;
use crate::builder;
-use crate::color::Color;
+use crate::color::{Color, Rgb};
use crate::ecs::Component;
use crate::reflection::Reflection;
use crate::texture::Texture;
@@ -22,7 +22,7 @@ pub struct Material
impl Material
{
- pub const fn builder() -> Builder
+ pub fn builder() -> Builder
{
Builder::new()
}
@@ -52,12 +52,12 @@ pub struct Builder
impl Builder
{
#[must_use]
- pub const fn new() -> Self
+ pub fn new() -> Self
{
Self {
- ambient: Color::WHITE_F32,
- diffuse: Color::WHITE_F32,
- specular: Color::WHITE_F32,
+ ambient: Color::Rgb(Rgb::<f32>::white()),
+ diffuse: Color::Rgb(Rgb::<f32>::white()),
+ specular: Color::Rgb(Rgb::<f32>::white()),
ambient_map: None,
diffuse_map: None,
specular_map: None,
diff --git a/engine/src/rendering/backend/opengl.rs b/engine/src/rendering/backend/opengl.rs
index 95aef27..bab916a 100644
--- a/engine/src/rendering/backend/opengl.rs
+++ b/engine/src/rendering/backend/opengl.rs
@@ -66,9 +66,10 @@ use opengl_bindings::{
};
use raw_window_handle::WindowHandle;
use safer_ffi::layout::ReprC;
-use zerocopy::{Immutable, IntoBytes};
+use zerocopy::IntoBytes;
use crate::asset::Assets;
+use crate::data_types::color::Color;
use crate::data_types::dimens::Dimens;
use crate::ecs::actions::Actions;
use crate::ecs::query::term::Without;
@@ -676,6 +677,7 @@ fn handle_commands(
);
let fvec3_value;
+ let mut color_value = [0.0; 4];
uniform_buffer
.store_at_byte_offset(
@@ -686,10 +688,34 @@ fn handle_commands(
ShaderBindingValue::Int(ref value) => value.as_bytes(),
ShaderBindingValue::Float(ref value) => value.as_bytes(),
ShaderBindingValue::FVec3(value) => {
- fvec3_value = CF32Vec3::from(value);
-
+ fvec3_value = [value.x, value.y, value.z];
fvec3_value.as_bytes()
}
+ ShaderBindingValue::Color(value) => match value {
+ Color::Rgb(value) => {
+ color_value[..3]
+ .copy_from_slice(&[value.r, value.g, value.b]);
+
+ color_value[..3].as_bytes()
+ }
+ Color::Rgba(value) => {
+ color_value[..4].copy_from_slice(&[
+ value.r, value.g, value.b, value.a,
+ ]);
+
+ color_value[..4].as_bytes()
+ }
+ Color::Luma(ref value) => {
+ color_value[0] = value.l;
+
+ color_value[0].as_bytes()
+ }
+ Color::LumaA(value) => {
+ color_value[..2].copy_from_slice(&[value.l, value.a]);
+
+ color_value[..2].as_bytes()
+ }
+ },
ShaderBindingValue::FMat4x4(ref value) => {
value.items().as_bytes()
}
@@ -1503,23 +1529,6 @@ impl From<crate::draw_flags::PolygonModeFace> for opengl_bindings::misc::Polygon
}
}
-#[derive(Debug, IntoBytes, Immutable)]
-#[repr(C)]
-pub struct CF32Vec3
-{
- x: f32,
- y: f32,
- z: f32,
-}
-
-impl From<Vec3<f32>> for CF32Vec3
-{
- fn from(src: Vec3<f32>) -> Self
- {
- Self { x: src.x, y: src.y, z: src.z }
- }
-}
-
fn blending_factor_to_gl(blending_factor: BlendingFactor) -> GlBlendingFactor
{
match blending_factor {
diff --git a/engine/src/rendering/shader/cursor.rs b/engine/src/rendering/shader/cursor.rs
index 17f5748..8aab4f2 100644
--- a/engine/src/rendering/shader/cursor.rs
+++ b/engine/src/rendering/shader/cursor.rs
@@ -1,3 +1,4 @@
+use crate::color::Color;
use crate::data_types::matrix::Matrix;
use crate::data_types::vector::Vec3;
use crate::rendering::object::Id as RenderingObjectId;
@@ -114,6 +115,7 @@ pub enum BindingValue
Int(i32),
Float(f32),
FVec3(Vec3<f32>),
+ Color(Color<f32>),
FMat4x4(Matrix<f32, 4, 4>),
Texture(RenderingObjectId),
}
@@ -150,6 +152,14 @@ impl From<Vec3<f32>> for BindingValue
}
}
+impl From<Color<f32>> for BindingValue
+{
+ fn from(color: Color<f32>) -> Self
+ {
+ BindingValue::Color(color)
+ }
+}
+
impl From<Matrix<f32, 4, 4>> for BindingValue
{
fn from(matrix: Matrix<f32, 4, 4>) -> Self
diff --git a/engine/src/rendering/shader/default.rs b/engine/src/rendering/shader/default.rs
index 3194706..bb5c366 100644
--- a/engine/src/rendering/shader/default.rs
+++ b/engine/src/rendering/shader/default.rs
@@ -142,7 +142,7 @@ pub fn enqueue_set_shader_bindings(
MaterialSearchResult::NotFound => {
continue;
}
- MaterialSearchResult::NoMaterials => &const { Material::builder().build() },
+ MaterialSearchResult::NoMaterials => &Material::builder().build(),
};
if [
@@ -181,23 +181,21 @@ pub fn enqueue_set_shader_bindings(
),
(
material_shader_cursor.field("ambient"),
- Vec3::from(
- if material_flags.use_ambient_color {
- &model_material.ambient
- } else {
- &global_light.ambient
- }
- .clone(),
- )
+ (if material_flags.use_ambient_color {
+ &model_material.ambient
+ } else {
+ &global_light.ambient
+ }
+ .clone())
.into(),
),
(
material_shader_cursor.field("diffuse"),
- Vec3::from(model_material.diffuse.clone()).into(),
+ model_material.diffuse.clone().into(),
),
(
material_shader_cursor.field("specular"),
- Vec3::from(model_material.specular.clone()).into(),
+ model_material.specular.clone().into(),
),
(
material_shader_cursor.field("shininess"),
@@ -243,11 +241,11 @@ pub fn enqueue_set_shader_bindings(
[
(
phong_shader_cursor.field("diffuse"),
- Vec3::from(point_light.diffuse.clone()).into(),
+ point_light.diffuse.clone().into(),
),
(
phong_shader_cursor.field("specular"),
- Vec3::from(point_light.specular.clone()).into(),
+ point_light.specular.clone().into(),
),
(
point_light_shader_cursor.field("position"),
@@ -281,11 +279,11 @@ pub fn enqueue_set_shader_bindings(
[
(
phong_shader_cursor.field("diffuse"),
- Vec3::from(directional_light.diffuse.clone()).into(),
+ directional_light.diffuse.clone().into(),
),
(
phong_shader_cursor.field("specular"),
- Vec3::from(directional_light.specular.clone()).into(),
+ directional_light.specular.clone().into(),
),
(
directional_light_shader_cursor.field("direction"),
diff --git a/engine/src/texture.rs b/engine/src/texture.rs
index b069228..af56e97 100644
--- a/engine/src/texture.rs
+++ b/engine/src/texture.rs
@@ -3,7 +3,7 @@ use std::sync::LazyLock;
use crate::asset::{Assets, Label as AssetLabel, Submitter as AssetSubmitter};
use crate::builder;
-use crate::color::Color;
+use crate::color::Rgba;
use crate::data_types::dimens::Dimens;
use crate::image::{Error as ImageError, Image};
@@ -111,11 +111,7 @@ pub(crate) fn initialize(assets: &mut Assets)
assets.store_with_label(
WHITE_1X1_ASSET_LABEL.clone(),
Texture {
- image: Image::from_color_and_alpha(
- Dimens { width: 1, height: 1 },
- Color::WHITE_U8,
- 1,
- ),
+ image: Image::from_color(Rgba::<u8>::white(), Dimens { width: 1, height: 1 }),
properties: Properties::default(),
},
);