From 832daefbda9d912eafbebfa2fffa157e7e8e2d6a Mon Sep 17 00:00:00 2001 From: gered Date: Fri, 31 Mar 2023 23:27:15 -0400 Subject: [PATCH] add initial triangle_2d_textured method --- ggdt/benches/triangles.rs | 16 ++++++++++++++++ ggdt/src/graphics/bitmap/triangles.rs | 25 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/ggdt/benches/triangles.rs b/ggdt/benches/triangles.rs index 60b0e86..ac06fce 100644 --- a/ggdt/benches/triangles.rs +++ b/ggdt/benches/triangles.rs @@ -7,6 +7,8 @@ pub fn criterion_benchmark(c: &mut Criterion) { let height = 240; let mut dest = IndexedBitmap::new(width, height).unwrap(); + let (texture, _palette) = + IndexedBitmap::load_gif_file(std::path::Path::new("./test-assets/gif/small.gif")).unwrap(); c.bench_function("indexedbitmap_triangle_2d_solid_color", |b| { b.iter(|| { @@ -18,6 +20,20 @@ pub fn criterion_benchmark(c: &mut Criterion) { ); }) }); + + c.bench_function("indexedbitmap_triangle_2d_textured", |b| { + b.iter(|| { + dest.triangle_2d_textured( + black_box(Vector2::new(47.0, 23.0)), + black_box(Vector2::new(0.0, 0.0)), + black_box(Vector2::new(60.0, 192.0)), + black_box(Vector2::new(1.0, 0.0)), + black_box(Vector2::new(280.0, 153.0)), + black_box(Vector2::new(1.0, 1.0)), + black_box(&texture), + ); + }) + }); } criterion_group!(benches, criterion_benchmark); diff --git a/ggdt/src/graphics/bitmap/triangles.rs b/ggdt/src/graphics/bitmap/triangles.rs index b0dfd89..f714eeb 100644 --- a/ggdt/src/graphics/bitmap/triangles.rs +++ b/ggdt/src/graphics/bitmap/triangles.rs @@ -19,6 +19,31 @@ impl Bitmap { ) } + pub fn triangle_2d_textured( + &mut self, + a: Vector2, + a_tex: Vector2, + b: Vector2, + b_tex: Vector2, + c: Vector2, + c_tex: Vector2, + texture: &Bitmap, + ) { + let texture_width = texture.width() as f32; + let texture_height = texture.height() as f32; + let inverse_area = 1.0 / cross(a, b, c); // inverting to avoid division + self.triangle_2d_custom( + a, // + b, + c, + |dest_pixels, w0, w1, w2| { + let u = (w0 * a_tex.x + w1 * b_tex.x + w2 * c_tex.x) * inverse_area * texture_width; + let v = (w0 * a_tex.y + w1 * b_tex.y + w2 * c_tex.y) * inverse_area * texture_height; + *dest_pixels = unsafe { texture.get_pixel_unchecked(u as i32, v as i32) }; + }, + ) + } + #[inline] pub fn triangle_2d_custom( &mut self,