diff options
| author | HampusM <hampus@hampusmat.com> | 2026-07-17 03:06:04 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-07-17 03:06:04 +0200 |
| commit | 65e24308babb2ed4f33fb6f1d7b531df676bd70d (patch) | |
| tree | df9477d4b805cc6866a086833d6118505804dd3a /engine/src | |
| parent | 649d4d4ab2f54ca12f75d2cba50e1adef2350dbe (diff) | |
refactor(engine): change Color struct into a enum
Diffstat (limited to 'engine/src')
| -rw-r--r-- | engine/src/data_types/color.rs | 143 | ||||
| -rw-r--r-- | engine/src/data_types/vector.rs | 13 | ||||
| -rw-r--r-- | engine/src/file_format/wavefront/mtl.rs | 10 | ||||
| -rw-r--r-- | engine/src/image.rs | 70 | ||||
| -rw-r--r-- | engine/src/lighting.rs | 6 | ||||
| -rw-r--r-- | engine/src/material.rs | 12 | ||||
| -rw-r--r-- | engine/src/rendering/backend/opengl.rs | 49 | ||||
| -rw-r--r-- | engine/src/rendering/shader/cursor.rs | 10 | ||||
| -rw-r--r-- | engine/src/rendering/shader/default.rs | 28 | ||||
| -rw-r--r-- | engine/src/texture.rs | 8 |
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(), }, ); |
