add optional color to points
This commit is contained in:
parent
10882983fe
commit
06596a0f76
4 changed files with 30 additions and 60 deletions
67
src/main.rs
67
src/main.rs
|
@ -40,27 +40,7 @@ fn main() {
|
||||||
let h = 800;
|
let h = 800;
|
||||||
let mut fb = TGAImage::new(w, h, TGAFormat::RGB);
|
let mut fb = TGAImage::new(w, h, TGAFormat::RGB);
|
||||||
|
|
||||||
_render_head(&mut fb);
|
render_head(&mut fb);
|
||||||
}
|
|
||||||
|
|
||||||
fn _fill_triangles(fb: &mut TGAImage) {
|
|
||||||
let t1a = Point2i::new(7, 45);
|
|
||||||
let t1b = Point2i::new(35, 100);
|
|
||||||
let t1c = Point2i::new(45, 60);
|
|
||||||
let t1 = Triangle::new(t1a, t1b, t1c);
|
|
||||||
t1.render_filled(RED, fb);
|
|
||||||
|
|
||||||
let t2a = Point2i::new(120, 35);
|
|
||||||
let t2b = Point2i::new(90, 5);
|
|
||||||
let t2c = Point2i::new(45, 110);
|
|
||||||
let t2 = Triangle::new(t2a, t2b, t2c);
|
|
||||||
t2.render_filled(WHITE, fb);
|
|
||||||
|
|
||||||
let a = Point2i::new(115, 83);
|
|
||||||
let b = Point2i::new(80, 90);
|
|
||||||
let c = Point2i::new(85, 120);
|
|
||||||
let t3 = Triangle::new(a, b, c);
|
|
||||||
t3.render_filled(GREEN, fb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _render_diablo(fb: &mut TGAImage) {
|
fn _render_diablo(fb: &mut TGAImage) {
|
||||||
|
@ -69,7 +49,7 @@ fn _render_diablo(fb: &mut TGAImage) {
|
||||||
fb.write_file("diablo.tga", true, true).unwrap();
|
fb.write_file("diablo.tga", true, true).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _render_head(fb: &mut TGAImage) {
|
fn render_head(fb: &mut TGAImage) {
|
||||||
let model = Model::from_obj("head.obj");
|
let model = Model::from_obj("head.obj");
|
||||||
model.render_triangles(fb);
|
model.render_triangles(fb);
|
||||||
fb.write_file("head.tga", true, true).unwrap();
|
fb.write_file("head.tga", true, true).unwrap();
|
||||||
|
@ -96,27 +76,6 @@ fn _baseline(framebuffer: &mut TGAImage) {
|
||||||
line(a, c, RED, framebuffer);
|
line(a, c, RED, framebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _bench(fb: &mut TGAImage) {
|
|
||||||
let mut rng = rand::rng();
|
|
||||||
|
|
||||||
for _ in 0..1 << 24 {
|
|
||||||
let ax = rng.random_range(0..fb.width);
|
|
||||||
let ay = rng.random_range(0..fb.height);
|
|
||||||
let a = Point2i::newu(ax, ay);
|
|
||||||
|
|
||||||
let bx = rng.random_range(0..fb.width);
|
|
||||||
let by = rng.random_range(0..fb.height);
|
|
||||||
let b = Point2i::newu(bx, by);
|
|
||||||
|
|
||||||
line(
|
|
||||||
a,
|
|
||||||
b,
|
|
||||||
[rng.random(), rng.random(), rng.random(), rng.random()].into(),
|
|
||||||
fb,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn line(mut a: Point2i, mut b: Point2i, color: TGAColor, mut 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();
|
let is_steep = (a.x - b.x).abs() < (a.y - b.y).abs();
|
||||||
if is_steep {
|
if is_steep {
|
||||||
|
@ -141,13 +100,13 @@ fn line(mut a: Point2i, mut b: Point2i, color: TGAColor, mut fb: &mut TGAImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
struct Triangle {
|
struct Triangle2i {
|
||||||
a: Point2i,
|
a: Point2i,
|
||||||
b: Point2i,
|
b: Point2i,
|
||||||
c: Point2i,
|
c: Point2i,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Triangle {
|
impl Triangle2i {
|
||||||
pub fn new(a: Point2i, b: Point2i, c: Point2i) -> Self {
|
pub fn new(a: Point2i, b: Point2i, c: Point2i) -> Self {
|
||||||
Self { a, b, c }
|
Self { a, b, c }
|
||||||
}
|
}
|
||||||
|
@ -177,21 +136,17 @@ impl Triangle {
|
||||||
if total_area < 1.0 {
|
if total_area < 1.0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let it = 1.0 / total_area;
|
||||||
(bb.ymin()..=bb.ymax()).into_par_iter().for_each(|y| {
|
(bb.ymin()..=bb.ymax()).into_par_iter().for_each(|y| {
|
||||||
(bb.xmin()..bb.xmax()).into_par_iter().for_each(|x| {
|
(bb.xmin()..bb.xmax()).into_par_iter().for_each(|x| {
|
||||||
let p = Point2i::new(x, y);
|
let p = Point2i::new(x, y);
|
||||||
let a = Triangle::new(p, self.a, self.b)
|
let a = Triangle2i::new(p, self.a, self.b).signed_area() * it;
|
||||||
.signed_area()
|
let b = Triangle2i::new(p, self.b, self.c).signed_area() * it;
|
||||||
.is_sign_positive();
|
let c = Triangle2i::new(p, self.c, self.a).signed_area() * it;
|
||||||
let b = Triangle::new(p, self.b, self.c)
|
|
||||||
.signed_area()
|
|
||||||
.is_sign_positive();
|
|
||||||
let c = Triangle::new(p, self.c, self.a)
|
|
||||||
.signed_area()
|
|
||||||
.is_sign_positive();
|
|
||||||
|
|
||||||
if a && b
|
if a.is_sign_positive()
|
||||||
&& c
|
&& b.is_sign_positive()
|
||||||
|
&& c.is_sign_positive()
|
||||||
&& let Ok(mut fb) = fb.lock()
|
&& let Ok(mut fb) = fb.lock()
|
||||||
{
|
{
|
||||||
fb.set(x as u32, y as u32, color);
|
fb.set(x as u32, y as u32, color);
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::ops::{Deref, DerefMut};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
RED, Triangle, line,
|
RED, Triangle2i, line,
|
||||||
point::{Point2i, Point3f},
|
point::{Point2i, Point3f},
|
||||||
tga::TGAImage,
|
tga::TGAImage,
|
||||||
};
|
};
|
||||||
|
@ -103,7 +103,7 @@ impl Model {
|
||||||
let a = world2view(self.verts[face[0]], width, height);
|
let a = world2view(self.verts[face[0]], width, height);
|
||||||
let b = world2view(self.verts[face[1]], width, height);
|
let b = world2view(self.verts[face[1]], width, height);
|
||||||
let c = world2view(self.verts[face[2]], width, height);
|
let c = world2view(self.verts[face[2]], width, height);
|
||||||
let triangle = Triangle::new(a, b, c);
|
let triangle = Triangle2i::new(a, b, c);
|
||||||
let color = [
|
let color = [
|
||||||
rng.random_range(0..=255u8),
|
rng.random_range(0..=255u8),
|
||||||
rng.random_range(0..=255u8),
|
rng.random_range(0..=255u8),
|
||||||
|
|
17
src/point.rs
17
src/point.rs
|
@ -1,20 +1,31 @@
|
||||||
use std::ops::{Add, Deref, DerefMut, Div, Mul, Sub};
|
use std::ops::{Add, Deref, DerefMut, Div, Mul, Sub};
|
||||||
|
|
||||||
|
use crate::tga::TGAColor;
|
||||||
|
|
||||||
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct Point2i {
|
pub struct Point2i {
|
||||||
pub x: i32,
|
pub x: i32,
|
||||||
pub y: i32,
|
pub y: i32,
|
||||||
|
pub c: Option<TGAColor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Point2i {
|
impl Point2i {
|
||||||
pub fn new(x: i32, y: i32) -> Self {
|
pub fn new(x: i32, y: i32) -> Self {
|
||||||
Self { x, y }
|
Self { x, y, c: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn newu(x: u32, y: u32) -> Self {
|
pub fn newu(x: u32, y: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: x as i32,
|
x: x as i32,
|
||||||
y: y as i32,
|
y: y as i32,
|
||||||
|
c: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_color(self, color: TGAColor) -> Self {
|
||||||
|
Self {
|
||||||
|
c: Some(color),
|
||||||
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +37,7 @@ impl Add for Point2i {
|
||||||
Self {
|
Self {
|
||||||
x: self.x + rhs.x,
|
x: self.x + rhs.x,
|
||||||
y: self.y + rhs.y,
|
y: self.y + rhs.y,
|
||||||
|
c: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +49,7 @@ impl Sub for Point2i {
|
||||||
Self {
|
Self {
|
||||||
x: self.x - rhs.x,
|
x: self.x - rhs.x,
|
||||||
y: self.y - rhs.y,
|
y: self.y - rhs.y,
|
||||||
|
c: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,6 +61,7 @@ impl Mul for Point2i {
|
||||||
Self {
|
Self {
|
||||||
x: self.x * rhs.x,
|
x: self.x * rhs.x,
|
||||||
y: self.y * rhs.y,
|
y: self.y * rhs.y,
|
||||||
|
c: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,6 +143,7 @@ impl From<Point3f> for Point2i {
|
||||||
Self {
|
Self {
|
||||||
x: p.x().round_ties_even() as i32,
|
x: p.x().round_ties_even() as i32,
|
||||||
y: p.y().round_ties_even() as i32,
|
y: p.y().round_ties_even() as i32,
|
||||||
|
c: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ impl TryFrom<u8> for TGAFormat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct TGAColor {
|
pub struct TGAColor {
|
||||||
pub bgra: ColorBuf,
|
pub bgra: ColorBuf,
|
||||||
|
|
Loading…
Reference in a new issue