parallel lines, aabb for triangles
This commit is contained in:
parent
4c7337a694
commit
59d264a38f
3 changed files with 97 additions and 12 deletions
52
Cargo.lock
generated
52
Cargo.lock
generated
|
@ -8,6 +8,37 @@ version = "1.0.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.3"
|
||||
|
@ -99,6 +130,26 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
|
@ -147,6 +198,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"justerror",
|
||||
"rand",
|
||||
"rayon",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
|
|
@ -6,4 +6,5 @@ edition = "2024"
|
|||
[dependencies]
|
||||
justerror = "1.1.0"
|
||||
rand = "0.9.2"
|
||||
rayon = "1.11.0"
|
||||
thiserror = "2.0.16"
|
||||
|
|
56
src/main.rs
56
src/main.rs
|
@ -1,10 +1,12 @@
|
|||
#[macro_use]
|
||||
extern crate justerror;
|
||||
|
||||
mod tga;
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use rand::Rng;
|
||||
use rayon::prelude::*;
|
||||
|
||||
mod tga;
|
||||
use tga::*;
|
||||
|
||||
mod point;
|
||||
|
@ -112,7 +114,7 @@ fn _bench(fb: &mut TGAImage) {
|
|||
}
|
||||
}
|
||||
|
||||
fn line(mut a: Point2i, mut b: Point2i, color: TGAColor, fb: &mut TGAImage) {
|
||||
fn line(mut a: Point2i, mut b: Point2i, color: TGAColor, mut fb: &mut TGAImage) {
|
||||
let is_steep = (a.x - b.x).abs() < (a.y - b.y).abs();
|
||||
if is_steep {
|
||||
std::mem::swap(&mut a.x, &mut a.y);
|
||||
|
@ -122,17 +124,30 @@ fn line(mut a: Point2i, mut b: Point2i, color: TGAColor, fb: &mut TGAImage) {
|
|||
std::mem::swap(&mut a, &mut b);
|
||||
}
|
||||
|
||||
let fb = Arc::new(Mutex::new(fb));
|
||||
let y = Arc::new(Mutex::new(a.y as f32));
|
||||
|
||||
let step = (b.y - a.y) as f32 / (b.x - a.x) as f32;
|
||||
let mut y = a.y as f32;
|
||||
for x in (a.x)..b.x {
|
||||
let (px, py) = if is_steep {
|
||||
(y.round_ties_even() as i32, x)
|
||||
} else {
|
||||
(x, y.round_ties_even() as i32)
|
||||
(a.x..b.x).into_par_iter().for_each(|x| {
|
||||
let ny = {
|
||||
if let Ok(y) = y.lock() {
|
||||
*y
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
};
|
||||
fb.set(px as u32, py as u32, color);
|
||||
y += step;
|
||||
}
|
||||
let (px, py) = if is_steep {
|
||||
(ny.round_ties_even() as i32, x)
|
||||
} else {
|
||||
(x, ny.round_ties_even() as i32)
|
||||
};
|
||||
if let Ok(mut fb) = fb.lock() {
|
||||
fb.set(px as u32, py as u32, color);
|
||||
}
|
||||
if let Ok(mut y) = y.lock() {
|
||||
*y += step;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn triangle_lines(a: Point2i, b: Point2i, c: Point2i, color: TGAColor, fb: &mut TGAImage) {
|
||||
|
@ -148,6 +163,13 @@ fn triangle_filled(a: Point2i, b: Point2i, c: Point2i, color: TGAColor, fb: &mut
|
|||
|
||||
let total_height = c.y - a.y;
|
||||
|
||||
let (lower_left, upper_right) = triangle_bb(a, b, c);
|
||||
for y in lower_left.y..=upper_right.y {
|
||||
let a = Point2i::new(lower_left.x, y);
|
||||
let b = Point2i::new(upper_right.x, y);
|
||||
line(a, b, color, fb);
|
||||
}
|
||||
|
||||
let segment_height = b.y - a.y;
|
||||
for y in a.y..=b.y {
|
||||
let dy = y - a.y;
|
||||
|
@ -163,3 +185,13 @@ fn triangle_filled(a: Point2i, b: Point2i, c: Point2i, color: TGAColor, fb: &mut
|
|||
line(Point2i::new(x1, y), Point2i::new(x2, y), color, fb);
|
||||
}
|
||||
}
|
||||
|
||||
fn triangle_bb(a: Point2i, b: Point2i, c: Point2i) -> (Point2i, Point2i) {
|
||||
let xmax = a.x.max(b.x.max(c.x));
|
||||
let xmin = a.x.min(b.x.min(c.x));
|
||||
|
||||
let ymax = a.y.max(b.y.max(c.y));
|
||||
let ymin = a.y.min(b.y.min(c.y));
|
||||
|
||||
(Point2i::new(xmin, ymin), Point2i::new(xmax, ymax))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue