diff --git a/ggdt/src/graphics/bitmap/rgb/triangles.rs b/ggdt/src/graphics/bitmap/rgb/triangles.rs index 6474149..b02ee48 100644 --- a/ggdt/src/graphics/bitmap/rgb/triangles.rs +++ b/ggdt/src/graphics/bitmap/rgb/triangles.rs @@ -1,6 +1,6 @@ use crate::graphics::bitmap::rgb::RgbaBitmap; use crate::graphics::bitmap::triangles::{edge_function, per_pixel_triangle_2d}; -use crate::graphics::color::{from_rgb32_normalized, to_rgb32_normalized, BlendFunction}; +use crate::graphics::color::{from_rgb32_normalized, multiply_argb32, tint_argb32, to_rgb32_normalized, BlendFunction}; use crate::math::vector2::Vector2; #[derive(Debug, Clone, PartialEq)] @@ -28,6 +28,38 @@ pub enum RgbaTriangle2d<'a> { texcoord: [Vector2; 3], bitmap: &'a RgbaBitmap, }, + SolidTexturedColored { + position: [Vector2; 3], // + texcoord: [Vector2; 3], + color: u32, + bitmap: &'a RgbaBitmap, + }, + SolidTexturedColoredBlended { + position: [Vector2; 3], // + texcoord: [Vector2; 3], + color: u32, + bitmap: &'a RgbaBitmap, + blend: BlendFunction, + }, + SolidTexturedMultiColored { + position: [Vector2; 3], // + texcoord: [Vector2; 3], + color: [u32; 3], + bitmap: &'a RgbaBitmap, + }, + SolidTexturedMultiColoredBlended { + position: [Vector2; 3], // + texcoord: [Vector2; 3], + color: [u32; 3], + bitmap: &'a RgbaBitmap, + blend: BlendFunction, + }, + SolidTexturedTinted { + position: [Vector2; 3], // + texcoord: [Vector2; 3], + bitmap: &'a RgbaBitmap, + tint: u32, + }, SolidTexturedBlended { position: [Vector2; 3], // texcoord: [Vector2; 3], @@ -108,6 +140,90 @@ impl RgbaBitmap { }, ) } + SolidTexturedColored { position, texcoord, color, bitmap } => { + 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 = multiply_argb32(bitmap.sample_at(u, v), *color) + }, + ) + } + SolidTexturedColoredBlended { position, texcoord, color, 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; + let src = multiply_argb32(bitmap.sample_at(u, v), *color); + *dest_pixels = blend.blend(src, *dest_pixels) + }, + ) + } + SolidTexturedMultiColored { position, texcoord, color, bitmap } => { + 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; + 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 = multiply_argb32(bitmap.sample_at(u, v), to_rgb32_normalized(r, g, b)) + }, + ) + } + SolidTexturedMultiColoredBlended { position, texcoord, color, bitmap, 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; + 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; + let src = multiply_argb32(bitmap.sample_at(u, v), to_rgb32_normalized(r, g, b)); + *dest_pixels = blend.blend(src, *dest_pixels) + }, + ) + } + SolidTexturedTinted { position, texcoord, bitmap, tint } => { + 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 = tint_argb32(bitmap.sample_at(u, v), *tint); + }, + ) + } SolidTexturedBlended { position, texcoord, bitmap, blend } => { let inverse_area = 1.0 / edge_function(position[0], position[1], position[2]); per_pixel_triangle_2d(