add RgbaBitmap triangle blending options

This commit is contained in:
Gered 2023-04-01 21:37:00 -04:00
parent a41fca5640
commit 2c7d78f0d1

View file

@ -1,7 +1,7 @@
use crate::graphics::bitmap::rgb::RgbaBitmap; use crate::graphics::bitmap::rgb::RgbaBitmap;
use crate::graphics::bitmap::triangles::{edge_function, per_pixel_triangle_2d}; use crate::graphics::bitmap::triangles::{edge_function, per_pixel_triangle_2d};
use crate::graphics::color::{from_rgb32_normalized, to_rgb32_normalized, BlendFunction};
use crate::math::vector2::Vector2; use crate::math::vector2::Vector2;
use crate::prelude::{from_rgb32, from_rgb32_normalized, to_rgb32_normalized};
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum RgbaTriangle2d<'a> { pub enum RgbaTriangle2d<'a> {
@ -9,15 +9,31 @@ pub enum RgbaTriangle2d<'a> {
position: [Vector2; 3], // position: [Vector2; 3], //
color: u32, color: u32,
}, },
SolidBlended {
position: [Vector2; 3], //
color: u32,
blend: BlendFunction,
},
SolidMultiColor { SolidMultiColor {
position: [Vector2; 3], // position: [Vector2; 3], //
color: [u32; 3], color: [u32; 3],
}, },
SolidMultiColorBlended {
position: [Vector2; 3], //
color: [u32; 3],
blend: BlendFunction,
},
SolidTextured { SolidTextured {
position: [Vector2; 3], // position: [Vector2; 3], //
texcoord: [Vector2; 3], texcoord: [Vector2; 3],
bitmap: &'a RgbaBitmap, bitmap: &'a RgbaBitmap,
}, },
SolidTexturedBlended {
position: [Vector2; 3], //
texcoord: [Vector2; 3],
bitmap: &'a RgbaBitmap,
blend: BlendFunction,
},
} }
impl RgbaBitmap { impl RgbaBitmap {
@ -33,6 +49,15 @@ impl RgbaBitmap {
|dest_pixels, _w0, _w1, _w2| *dest_pixels = *color, |dest_pixels, _w0, _w1, _w2| *dest_pixels = *color,
) )
} }
SolidBlended { position, color, blend } => {
per_pixel_triangle_2d(
self, //
position[0],
position[1],
position[2],
|dest_pixels, _w0, _w1, _w2| *dest_pixels = blend.blend(*color, *dest_pixels),
)
}
SolidMultiColor { position, color } => { SolidMultiColor { position, color } => {
let inverse_area = 1.0 / edge_function(position[0], position[1], position[2]); let inverse_area = 1.0 / edge_function(position[0], position[1], position[2]);
let (r1, g1, b1) = from_rgb32_normalized(color[0]); let (r1, g1, b1) = from_rgb32_normalized(color[0]);
@ -51,6 +76,24 @@ impl RgbaBitmap {
}, },
) )
} }
SolidMultiColorBlended { position, color, blend } => {
let inverse_area = 1.0 / edge_function(position[0], position[1], position[2]);
let (r1, g1, b1) = from_rgb32_normalized(color[0]);
let (r2, g2, b2) = from_rgb32_normalized(color[1]);
let (r3, g3, b3) = from_rgb32_normalized(color[2]);
per_pixel_triangle_2d(
self, //
position[0],
position[1],
position[2],
|dest_pixels, w0, w1, w2| {
let r = (w0 * r1 + w1 * r2 + w2 * r3) * inverse_area;
let g = (w0 * g1 + w1 * g2 + w2 * g3) * inverse_area;
let b = (w0 * b1 + w1 * b2 + w2 * b3) * inverse_area;
*dest_pixels = blend.blend(to_rgb32_normalized(r, g, b), *dest_pixels)
},
)
}
SolidTextured { position, texcoord, bitmap } => { SolidTextured { position, texcoord, bitmap } => {
let inverse_area = 1.0 / edge_function(position[0], position[1], position[2]); let inverse_area = 1.0 / edge_function(position[0], position[1], position[2]);
per_pixel_triangle_2d( per_pixel_triangle_2d(
@ -65,6 +108,20 @@ impl RgbaBitmap {
}, },
) )
} }
SolidTexturedBlended { position, texcoord, bitmap, blend } => {
let inverse_area = 1.0 / edge_function(position[0], position[1], position[2]);
per_pixel_triangle_2d(
self, //
position[0],
position[1],
position[2],
|dest_pixels, w0, w1, w2| {
let u = (w0 * texcoord[0].x + w1 * texcoord[1].x + w2 * texcoord[2].x) * inverse_area;
let v = (w0 * texcoord[0].y + w1 * texcoord[1].y + w2 * texcoord[2].y) * inverse_area;
*dest_pixels = blend.blend(bitmap.sample_at(u, v), *dest_pixels);
},
)
}
} }
} }
} }