From 250cb67defcdfc789bfc0b4fa26fce194e3f67cd Mon Sep 17 00:00:00 2001 From: HampusM Date: Sat, 18 Apr 2026 16:17:03 +0200 Subject: feat(engine): add blending to renderer draw properties --- engine/src/renderer.rs | 12 ++++-- engine/src/renderer/blending.rs | 89 +++++++++++++++++++++++++++++++++++++++++ engine/src/renderer/opengl.rs | 66 ++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 engine/src/renderer/blending.rs (limited to 'engine') diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 066f3fc..1a77f9e 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -17,6 +17,7 @@ use crate::builder; use crate::draw_flags::{DrawFlags, NoDraw, PolygonModeConfig}; use crate::mesh::Mesh; use crate::model::{MaterialSearchResult, Model}; +use crate::renderer::blending::Config as BlendingConfig; use crate::renderer::object::{Id as ObjectId, Store as ObjectStore}; use crate::shader::cursor::{ BindingLocation as ShaderBindingLocation, @@ -33,6 +34,7 @@ use crate::shader::{ use crate::texture::{Texture, WHITE_1X1_ASSET_LABEL as TEXTURE_WHITE_1X1_ASSET_LABEL}; use crate::windowing::window::Window; +pub mod blending; pub mod object; pub mod opengl; @@ -218,6 +220,8 @@ pub enum MeshUsage pub struct DrawProperties { pub polygon_mode_config: PolygonModeConfig, + pub blending_enabled: bool, + pub blending_config: BlendingConfig, } bitflags! { @@ -225,6 +229,8 @@ bitflags! { pub struct DrawPropertiesUpdateFlags: usize { const POLYGON_MODE_CONFIG = 1 << 0; + const BLENDING_CONFIG = 1 << 1; + const BLENDING_ENABLED = 1 << 2; } } @@ -340,9 +346,7 @@ pub fn add_main_render_passes( renderer_ctx_ent_id, surface_id: surface_spec.id, commands: Vec::with_capacity(30), - draw_properties: DrawProperties { - polygon_mode_config: PolygonModeConfig::default(), - }, + draw_properties: DrawProperties::default(), }); let render_pass = render_passes.passes.front_mut().expect("Not possible"); @@ -468,6 +472,7 @@ pub fn add_main_render_passes( render_pass.commands.push(Command::UpdateDrawProperties( DrawProperties { polygon_mode_config: draw_flags.polygon_mode_config.clone(), + ..Default::default() }, DrawPropertiesUpdateFlags::POLYGON_MODE_CONFIG, )); @@ -491,6 +496,7 @@ pub fn add_main_render_passes( render_pass.commands.push(Command::UpdateDrawProperties( DrawProperties { polygon_mode_config: PolygonModeConfig::default(), + ..Default::default() }, DrawPropertiesUpdateFlags::POLYGON_MODE_CONFIG, )); diff --git a/engine/src/renderer/blending.rs b/engine/src/renderer/blending.rs new file mode 100644 index 0000000..9ae2f82 --- /dev/null +++ b/engine/src/renderer/blending.rs @@ -0,0 +1,89 @@ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Config +{ + pub source_factor: Factor, + pub destination_factor: Factor, + pub equation: Equation, +} + +impl Default for Config +{ + fn default() -> Self + { + Self { + source_factor: Factor::One, + destination_factor: Factor::Zero, + equation: Equation::default(), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[non_exhaustive] +pub enum Factor +{ + /// Factor will be the RGBA color `(0,0,0,0)` + Zero, + + /// Factor will be the RGBA color `(1,1,1,1)` + One, + + /// Factor will be the source color + SrcColor, + + /// Factor will be the RGBA color `(1,1,1,1) - source color` + OneMinusSrcColor, + + /// Factor will be the destination color + DstColor, + + /// Factor will be the RGBA color `(1,1,1,1) - destination color` + OneMinusDstColor, + + /// Factor will be the alpha component of the source color. + SrcAlpha, + + /// Factor will be the RGBA color `(1,1,1,1) - source color alpha` + OneMinusSrcAlpha, + + /// Factor will be the alpha component of the destination color. + DstAlpha, + + /// Factor will be the RGBA color `(1,1,1,1) - destination color alpha` + OneMinusDstAlpha, + + /// Factor will be the constant color + ConstantColor, + + /// Factor will be the RGBA color `(1,1,1,1) - constant color` + OneMinusConstantColor, + + /// Factor will be the alpha component of the constant color. + ConstantAlpha, + + /// Factor will be the RGBA color `(1,1,1,1) - constant color alpha` + OneMinusConstantAlpha, +} + +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +pub enum Equation +{ + /// The destination color and source color is added to each other in the blend + /// function + #[default] + Add, + + /// The destination color is subtracted from the source color in the blend function + Subtract, + + /// The source color is subtracted from the destination color in the blend function + ReverseSubtract, + + /// The blend function will take the component-wise minimum of the destination color + /// and the source color + Min, + + /// The blend function will take the component-wise maximum of the destination color + /// and the source color + Max, +} diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs index f80237a..c4d335c 100644 --- a/engine/src/renderer/opengl.rs +++ b/engine/src/renderer/opengl.rs @@ -20,6 +20,12 @@ use glutin::surface::{ Surface as GlutinSurface, WindowSurface as GlutinWindowSurface, }; +use opengl_bindings::blending::{ + Configuration as GlBlendingConfig, + Equation as GlBlendingEquation, + Factor as GlBlendingFactor, + configure as gl_blending_configure, +}; use opengl_bindings::debug::{ MessageIdsAction, MessageSeverity, @@ -66,6 +72,7 @@ use crate::data_types::dimens::Dimens; use crate::image::{ColorType as ImageColorType, Image}; use crate::matrix::Matrix; use crate::model::Model; +use crate::renderer::blending::{Equation as BlendingEquation, Factor as BlendingFactor}; use crate::renderer::object::{ Id as RendererObjectId, Kind as RendererObjectKind, @@ -1158,6 +1165,34 @@ fn handle_commands( draw_props.polygon_mode_config.mode, ); } + + if draw_props_update_flags + .contains(DrawPropertiesUpdateFlags::BLENDING_ENABLED) + { + set_enabled( + curr_gl_ctx, + Capability::Blend, + draw_props.blending_enabled, + ); + } + + if draw_props_update_flags + .contains(DrawPropertiesUpdateFlags::BLENDING_CONFIG) + { + gl_blending_configure( + curr_gl_ctx, + GlBlendingConfig::default() + .with_source_factor(blending_factor_to_gl( + draw_props.blending_config.source_factor, + )) + .with_destination_factor(blending_factor_to_gl( + draw_props.blending_config.destination_factor, + )) + .with_equation(blending_equation_to_gl( + draw_props.blending_config.equation, + )), + ); + } } } } @@ -1554,3 +1589,34 @@ impl From> for CF32Vec3 Self { x: src.x, y: src.y, z: src.z } } } + +fn blending_factor_to_gl(blending_factor: BlendingFactor) -> GlBlendingFactor +{ + match blending_factor { + BlendingFactor::Zero => GlBlendingFactor::Zero, + BlendingFactor::One => GlBlendingFactor::One, + BlendingFactor::SrcColor => GlBlendingFactor::SrcColor, + BlendingFactor::OneMinusSrcColor => GlBlendingFactor::OneMinusSrcColor, + BlendingFactor::DstColor => GlBlendingFactor::DstColor, + BlendingFactor::OneMinusDstColor => GlBlendingFactor::OneMinusDstColor, + BlendingFactor::SrcAlpha => GlBlendingFactor::SrcAlpha, + BlendingFactor::OneMinusSrcAlpha => GlBlendingFactor::OneMinusSrcAlpha, + BlendingFactor::DstAlpha => GlBlendingFactor::DstAlpha, + BlendingFactor::OneMinusDstAlpha => GlBlendingFactor::OneMinusDstAlpha, + BlendingFactor::ConstantColor => GlBlendingFactor::ConstantColor, + BlendingFactor::OneMinusConstantColor => GlBlendingFactor::OneMinusConstantColor, + BlendingFactor::ConstantAlpha => GlBlendingFactor::ConstantAlpha, + BlendingFactor::OneMinusConstantAlpha => GlBlendingFactor::OneMinusConstantAlpha, + } +} + +fn blending_equation_to_gl(blending_equation: BlendingEquation) -> GlBlendingEquation +{ + match blending_equation { + BlendingEquation::Add => GlBlendingEquation::Add, + BlendingEquation::Subtract => GlBlendingEquation::Subtract, + BlendingEquation::ReverseSubtract => GlBlendingEquation::ReverseSubtract, + BlendingEquation::Min => GlBlendingEquation::Min, + BlendingEquation::Max => GlBlendingEquation::Max, + } +} -- cgit v1.2.3-18-g5258