render blender

This commit is contained in:
sfja 2026-04-04 23:56:17 +02:00
parent d191fda839
commit 97368f8710
8 changed files with 431 additions and 56 deletions

View File

@ -0,0 +1,12 @@
# Blender 5.1.0 MTL File: 'None'
# www.blender.org
newmtl Material
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2

View File

@ -0,0 +1,333 @@
# Blender 5.1.0
# www.blender.org
mtllib cube_and_sphere.mtl
o Cube
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
v 0.264812 2.047067 -0.748627
v 0.264812 1.937980 -1.279160
v 0.264812 1.232835 -1.809693
v 0.264812 0.527690 -1.279160
v 0.264812 0.418604 -0.748627
v 0.630177 1.937980 -1.177837
v 0.897643 1.639951 -1.492041
v 0.995542 1.232835 -1.607047
v 0.897643 0.825719 -1.492041
v 0.630177 0.527690 -1.177837
v 0.855985 1.937980 -0.912571
v 1.288754 1.639951 -1.032586
v 1.447159 1.232835 -1.076515
v 1.288754 0.825719 -1.032586
v 0.855985 0.527690 -0.912571
v 0.855985 1.937980 -0.584684
v 1.288754 1.639951 -0.464669
v 1.447159 1.232835 -0.420740
v 1.288754 0.825719 -0.464669
v 0.855985 0.527690 -0.584684
v 0.630177 1.937980 -0.319417
v 0.897643 1.639951 -0.005214
v 0.995543 1.232835 0.109793
v 0.897643 0.825719 -0.005214
v 0.630177 0.527690 -0.319417
v 0.264812 1.937980 -0.218095
v 0.264812 1.639951 0.170282
v 0.264812 1.232835 0.312438
v 0.264812 0.825719 0.170282
v 0.264812 0.527690 -0.218095
v -0.100553 1.937980 -0.319417
v -0.368019 1.639951 -0.005214
v -0.465918 1.232835 0.109793
v -0.368019 0.825719 -0.005214
v -0.100553 0.527690 -0.319417
v -0.326361 1.937980 -0.584684
v -0.759130 1.639951 -0.464669
v -0.917534 1.232835 -0.420740
v -0.759130 0.825719 -0.464669
v -0.326361 0.527690 -0.584684
v -0.326361 1.937980 -0.912571
v -0.759130 1.639951 -1.032586
v -0.917534 1.232835 -1.076515
v -0.759130 0.825719 -1.032586
v -0.326361 0.527690 -0.912571
v -0.100553 1.937980 -1.177837
v -0.368019 1.639951 -1.492041
v -0.465918 1.232835 -1.607048
v -0.368019 0.825719 -1.492041
v -0.100553 0.527690 -1.177837
v 0.264812 1.639951 -1.667537
v 0.264812 0.825719 -1.667537
vn -0.0000 1.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 0.0558 -0.9780 -0.2011
vn 0.2533 -0.3189 -0.9133
vn 0.1665 0.7823 -0.6003
vn 0.1665 -0.7823 -0.6003
vn 0.2533 0.3189 -0.9133
vn 0.0558 0.9780 -0.2011
vn 0.4496 0.8070 -0.3828
vn 0.4496 -0.8070 -0.3828
vn 0.7150 0.3439 -0.6087
vn 0.1465 0.9813 -0.1247
vn 0.1465 -0.9813 -0.1247
vn 0.7150 -0.3439 -0.6087
vn 0.5672 -0.8236 -0.0000
vn 0.9319 0.3626 -0.0000
vn 0.1815 0.9834 -0.0000
vn 0.1815 -0.9834 -0.0000
vn 0.9319 -0.3626 -0.0000
vn 0.5672 0.8236 -0.0000
vn 0.4496 -0.8070 0.3828
vn 0.7150 0.3439 0.6087
vn 0.1465 0.9813 0.1247
vn 0.1465 -0.9813 0.1247
vn 0.7150 -0.3439 0.6087
vn 0.4496 0.8070 0.3828
vn 0.1665 -0.7823 0.6003
vn 0.2533 0.3189 0.9133
vn 0.0558 0.9780 0.2011
vn 0.0558 -0.9780 0.2011
vn 0.2533 -0.3189 0.9133
vn 0.1665 0.7823 0.6003
vn -0.1665 -0.7823 0.6003
vn -0.2533 0.3189 0.9133
vn -0.0558 0.9780 0.2011
vn -0.0558 -0.9780 0.2011
vn -0.2533 -0.3189 0.9133
vn -0.1665 0.7823 0.6003
vn -0.7150 0.3439 0.6087
vn -0.1465 0.9813 0.1247
vn -0.1465 -0.9813 0.1247
vn -0.7150 -0.3439 0.6087
vn -0.4496 0.8070 0.3828
vn -0.4496 -0.8070 0.3828
vn -0.1815 0.9834 -0.0000
vn -0.1815 -0.9834 -0.0000
vn -0.9319 -0.3626 -0.0000
vn -0.5672 0.8236 -0.0000
vn -0.5672 -0.8236 -0.0000
vn -0.9319 0.3626 -0.0000
vn -0.1465 -0.9813 -0.1247
vn -0.7150 -0.3439 -0.6087
vn -0.4496 0.8070 -0.3828
vn -0.4496 -0.8070 -0.3828
vn -0.7150 0.3439 -0.6087
vn -0.1465 0.9813 -0.1247
vn -0.0558 -0.9780 -0.2011
vn -0.2533 -0.3189 -0.9133
vn -0.1665 0.7823 -0.6003
vn -0.1665 -0.7823 -0.6003
vn -0.2533 0.3189 -0.9133
vn -0.0558 0.9780 -0.2011
vt 0.875000 0.500000
vt 0.625000 0.750000
vt 0.625000 0.500000
vt 0.375000 1.000000
vt 0.375000 0.750000
vt 0.625000 0.000000
vt 0.375000 0.250000
vt 0.375000 0.000000
vt 0.375000 0.500000
vt 0.125000 0.750000
vt 0.125000 0.500000
vt 0.625000 0.250000
vt 0.650000 0.000000
vt 0.700000 0.166667
vt 0.600000 0.166667
vt 0.700000 0.500000
vt 0.600000 0.333333
vt 0.700000 0.333333
vt 0.700000 0.666667
vt 0.600000 0.833333
vt 0.600000 0.666667
vt 0.600000 0.500000
vt 0.700000 0.833333
vt 0.650000 1.000000
vt 0.500000 0.833333
vt 0.500000 0.666667
vt 0.500000 0.166667
vt 0.500000 0.500000
vt 0.550000 1.000000
vt 0.550000 0.000000
vt 0.500000 0.333333
vt 0.400000 0.166667
vt 0.400000 0.500000
vt 0.450000 1.000000
vt 0.400000 0.833333
vt 0.450000 0.000000
vt 0.400000 0.333333
vt 0.400000 0.666667
vt 0.300000 0.333333
vt 0.300000 0.166667
vt 0.300000 0.500000
vt 0.350000 1.000000
vt 0.300000 0.833333
vt 0.350000 0.000000
vt 0.300000 0.666667
vt 0.200000 0.333333
vt 0.200000 0.166667
vt 0.200000 0.500000
vt 0.250000 1.000000
vt 0.200000 0.833333
vt 0.250000 0.000000
vt 0.200000 0.666667
vt 0.100000 0.166667
vt 0.100000 0.666667
vt 0.100000 0.500000
vt 0.150000 1.000000
vt 0.100000 0.833333
vt 0.150000 0.000000
vt 0.100000 0.333333
vt 0.000000 0.666667
vt 0.000000 0.500000
vt 0.050000 1.000000
vt 0.000000 0.833333
vt 0.050000 0.000000
vt 0.000000 0.166667
vt 0.000000 0.333333
vt 1.000000 0.833333
vt 0.950000 1.000000
vt 0.900000 0.833333
vt 0.950000 0.000000
vt 1.000000 0.166667
vt 0.900000 0.166667
vt 1.000000 0.500000
vt 0.900000 0.333333
vt 1.000000 0.333333
vt 0.900000 0.666667
vt 1.000000 0.666667
vt 0.900000 0.500000
vt 0.850000 0.000000
vt 0.800000 0.166667
vt 0.800000 0.500000
vt 0.800000 0.333333
vt 0.800000 0.666667
vt 0.850000 1.000000
vt 0.800000 0.833333
vt 0.750000 0.000000
vt 0.750000 1.000000
vt 0.875000 0.750000
vt 0.625000 1.000000
s 0
usemtl Material
f 5/1/1 3/2/1 1/3/1
f 3/2/2 8/4/2 4/5/2
f 7/6/3 6/7/3 8/8/3
f 2/9/4 8/10/4 6/11/4
f 1/3/5 4/5/5 2/9/5
f 5/12/6 2/9/6 6/7/6
f 13/13/7 12/14/7 18/15/7
f 11/16/8 17/17/8 60/18/8
f 59/19/9 14/20/9 15/21/9
f 60/18/10 18/15/10 12/14/10
f 11/16/11 15/21/11 16/22/11
f 10/23/12 9/24/12 14/20/12
f 15/21/13 19/25/13 20/26/13
f 17/17/14 23/27/14 18/15/14
f 16/22/15 20/26/15 21/28/15
f 14/20/16 9/29/16 19/25/16
f 13/30/17 18/15/17 23/27/17
f 16/22/18 22/31/18 17/17/18
f 22/31/19 28/32/19 23/27/19
f 20/26/20 26/33/20 21/28/20
f 19/25/21 9/34/21 24/35/21
f 13/36/22 23/27/22 28/32/22
f 21/28/23 27/37/23 22/31/23
f 19/25/24 25/38/24 20/26/24
f 28/32/25 32/39/25 33/40/25
f 25/38/26 31/41/26 26/33/26
f 24/35/27 9/42/27 29/43/27
f 13/44/28 28/32/28 33/40/28
f 27/37/29 31/41/29 32/39/29
f 24/35/30 30/45/30 25/38/30
f 33/40/31 37/46/31 38/47/31
f 30/45/32 36/48/32 31/41/32
f 29/43/33 9/49/33 34/50/33
f 13/51/34 33/40/34 38/47/34
f 32/39/35 36/48/35 37/46/35
f 29/43/36 35/52/36 30/45/36
f 37/46/37 43/53/37 38/47/37
f 36/48/38 40/54/38 41/55/38
f 34/50/39 9/56/39 39/57/39
f 13/58/40 38/47/40 43/53/40
f 36/48/41 42/59/41 37/46/41
f 35/52/42 39/57/42 40/54/42
f 41/55/43 45/60/43 46/61/43
f 39/57/44 9/62/44 44/63/44
f 13/64/45 43/53/45 48/65/45
f 41/55/46 47/66/46 42/59/46
f 40/54/47 44/63/47 45/60/47
f 42/59/48 48/65/48 43/53/48
f 44/67/49 9/68/49 49/69/49
f 13/70/50 48/71/50 53/72/50
f 46/73/51 52/74/51 47/75/51
f 44/67/52 50/76/52 45/77/52
f 48/71/53 52/74/53 53/72/53
f 45/77/54 51/78/54 46/73/54
f 13/79/55 53/72/55 58/80/55
f 52/74/56 56/81/56 57/82/56
f 49/69/57 55/83/57 50/76/57
f 53/72/58 57/82/58 58/80/58
f 50/76/59 56/81/59 51/78/59
f 49/69/60 9/84/60 54/85/60
f 13/86/61 58/80/61 12/14/61
f 57/82/62 11/16/62 60/18/62
f 54/85/63 59/19/63 55/83/63
f 58/80/64 60/18/64 12/14/64
f 55/83/65 11/16/65 56/81/65
f 54/85/66 9/87/66 10/23/66
f 11/16/8 16/22/8 17/17/8
f 59/19/9 10/23/9 14/20/9
f 60/18/10 17/17/10 18/15/10
f 11/16/11 59/19/11 15/21/11
f 15/21/13 14/20/13 19/25/13
f 17/17/14 22/31/14 23/27/14
f 16/22/15 15/21/15 20/26/15
f 16/22/18 21/28/18 22/31/18
f 22/31/19 27/37/19 28/32/19
f 20/26/20 25/38/20 26/33/20
f 21/28/23 26/33/23 27/37/23
f 19/25/24 24/35/24 25/38/24
f 28/32/25 27/37/25 32/39/25
f 25/38/26 30/45/26 31/41/26
f 27/37/29 26/33/29 31/41/29
f 24/35/30 29/43/30 30/45/30
f 33/40/31 32/39/31 37/46/31
f 30/45/32 35/52/32 36/48/32
f 32/39/35 31/41/35 36/48/35
f 29/43/36 34/50/36 35/52/36
f 37/46/37 42/59/37 43/53/37
f 36/48/38 35/52/38 40/54/38
f 36/48/41 41/55/41 42/59/41
f 35/52/42 34/50/42 39/57/42
f 41/55/43 40/54/43 45/60/43
f 41/55/46 46/61/46 47/66/46
f 40/54/47 39/57/47 44/63/47
f 42/59/48 47/66/48 48/65/48
f 46/73/51 51/78/51 52/74/51
f 44/67/52 49/69/52 50/76/52
f 48/71/53 47/75/53 52/74/53
f 45/77/54 50/76/54 51/78/54
f 52/74/56 51/78/56 56/81/56
f 49/69/57 54/85/57 55/83/57
f 53/72/58 52/74/58 57/82/58
f 50/76/59 55/83/59 56/81/59
f 57/82/62 56/81/62 11/16/62
f 54/85/63 10/23/63 59/19/63
f 58/80/64 57/82/64 60/18/64
f 55/83/65 59/19/65 11/16/65
f 5/1/1 7/88/1 3/2/1
f 3/2/2 7/89/2 8/4/2
f 7/6/3 5/12/3 6/7/3
f 2/9/4 4/5/4 8/10/4
f 1/3/5 3/2/5 4/5/5
f 5/12/6 1/3/6 2/9/6

View File

@ -67,22 +67,23 @@ impl<R: Renderer> window::App<R> for App {
fn update(&mut self, delta_time: std::time::Duration) { fn update(&mut self, delta_time: std::time::Duration) {
self.rot.0 += PI * 2.0 * delta_time.as_secs_f64() * 0.1; self.rot.0 += PI * 2.0 * delta_time.as_secs_f64() * 0.1;
self.rot.1 += PI * 2.0 * delta_time.as_secs_f64() * 0.1; self.rot.1 += PI * 2.0 * delta_time.as_secs_f64() * 0.1;
self.rot.2 += PI * 2.0 * delta_time.as_secs_f64() * 0.1;
} }
fn render(&self, r: &mut R) { fn render(&self, r: &mut R) {
let mut scene = Scene::new(); let mut scene = Scene::new();
// let mut model1 = Model::new(); let mut model1 = Model::new();
// model1 model1
// .add_tri( .add_tri(
// Tri3(V3(0.0, 0.0, 0.0), V3(0.3, 0.3, 0.0), V3(0.3, 0.0, 0.0)), Tri3(V3(0.0, 0.0, 0.0), V3(0.3, 0.3, 0.0), V3(0.3, 0.0, 0.0)),
// Color::RGB(200, 200, 200), Color::RGB(125, 165, 165),
// ) )
// .rotate_by_m3x3(M3x3::from_v3_rot(self.rot)) .rotate_by_m3x3(M3x3::from_v3_rot(self.rot))
// .translate(V3(1.0, 0.0, 2.0)) .translate(V3(1.0, 0.0, 1.0))
// .scale(V3(1.0, 1.0, 1.0)); .scale(V3(1.0, 1.0, 1.0));
//
// scene.draw_model(model1); scene.draw_model(model1);
let mut model2 = Model::new(); let mut model2 = Model::new();
@ -91,7 +92,7 @@ impl<R: Renderer> window::App<R> for App {
.add_obj(&cube_obj, Color::RGB(165, 125, 165)) .add_obj(&cube_obj, Color::RGB(165, 125, 165))
.rotate_by_m3x3(M3x3::from_v3_rot(self.rot)) .rotate_by_m3x3(M3x3::from_v3_rot(self.rot))
.scale(V3(0.2, 0.2, 0.2)) .scale(V3(0.2, 0.2, 0.2))
.translate(V3(0.0, 0.0, 1.0)); .translate(V3(0.0, -0.2, 1.0));
scene.draw_model(model2); scene.draw_model(model2);
@ -99,9 +100,9 @@ impl<R: Renderer> window::App<R> for App {
scene.render( scene.render(
r, r,
V3(0.0, 0.0, 0.0), V3(0.0, 0.0, -1.0),
M3x3::from_v3_rot(V3(0.0, 0.0, 0.0)), M3x3::from_v3_rot(V3(0.0, 0.0, 0.0)),
V3(0.0, 0.0, 1.0), V3(0.0, 0.0, 0.0),
); );
// r.draw_line(V2(0.0, 0.0), V2(0.6, 0.2), Color::RED); // r.draw_line(V2(0.0, 0.0), V2(0.6, 0.2), Color::RED);

View File

@ -29,10 +29,8 @@ impl Scene {
.iter() .iter()
.enumerate() .enumerate()
.map(|(i, (tri, ..))| { .map(|(i, (tri, ..))| {
let mut point_scores = tri.points().map(|p| (camera_pos - p).len()); let mut score = (camera_pos - tri.middle()).len();
point_scores.sort_by(|a, b| a.total_cmp(b)); (i, score)
(i, point_scores[0])
}) })
.rev() .rev()
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -46,16 +44,28 @@ impl Scene {
// continue; // continue;
// } // }
// if normal.dot(camera_pos - tri3.0) < 0.0 { if normal.dot(camera_pos - tri3.0) < 0.0 {
// continue; continue;
// } }
let tri2 = tri3.project_2d(camera_pos, camera_rot, screen_rel_pos); let tri2 = tri3.project_2d(camera_pos, camera_rot, screen_rel_pos);
let n0 = tri3
.middle()
.project_2d(camera_pos, camera_rot, screen_rel_pos);
let n1 = (tri3.middle() + normal.unit() * 0.2).project_2d(
camera_pos,
camera_rot,
screen_rel_pos,
);
r.draw_triangles(&[tri2], *color); r.draw_triangles(&[tri2], *color);
r.draw_line(tri2.0, tri2.1, Color::BLACK); r.draw_line(tri2.0, tri2.1, Color::BLACK);
r.draw_line(tri2.1, tri2.2, Color::BLACK); r.draw_line(tri2.1, tri2.2, Color::BLACK);
r.draw_line(tri2.2, tri2.0, Color::BLACK); r.draw_line(tri2.2, tri2.0, Color::BLACK);
// r.draw_line(n0, n1, Color::RED);
} }
} }
@ -91,6 +101,7 @@ impl Model {
pub fn rotate_by_m3x3(&mut self, rot: M3x3) -> &mut Self { pub fn rotate_by_m3x3(&mut self, rot: M3x3) -> &mut Self {
for tri in &mut self.tris { for tri in &mut self.tris {
tri.0 = tri.0.rotate_by_m3x3(rot); tri.0 = tri.0.rotate_by_m3x3(rot);
tri.1 = tri.1.rotate_by_m3x3(rot);
} }
self self
} }
@ -108,33 +119,42 @@ impl Model {
} }
pub fn add_obj(&mut self, obj: &Obj, color: Color) -> &mut Self { pub fn add_obj(&mut self, obj: &Obj, color: Color) -> &mut Self {
// if our triangle definition convention is [0, 1, 2]
// obj's is [2, 1, 0].
//
// likewise, if our coordinate system is [x, y, z],
// obj's is [x, z, y].
let count = obj.indices.len() / 3; let count = obj.indices.len() / 3;
for i in 0..count { for i in 0..count {
let v0 = obj.vertices[obj.indices[i * 3] as usize]; let v2 = obj.vertices[obj.indices[i * 3] as usize];
let v1 = obj.vertices[obj.indices[i * 3 + 1] as usize]; let v1 = obj.vertices[obj.indices[i * 3 + 1] as usize];
let v2 = obj.vertices[obj.indices[i * 3 + 2] as usize]; let v0 = obj.vertices[obj.indices[i * 3 + 2] as usize];
self.tris.push(( let tri = Tri3(
Tri3( V3(
V3( v0.position[0] as _,
v0.position[0] as _, v0.position[2] as _,
v0.position[1] as _, v0.position[1] as _,
v0.position[2] as _,
),
V3(
v1.position[0] as _,
v1.position[1] as _,
v1.position[2] as _,
),
V3(
v2.position[0] as _,
v2.position[1] as _,
v2.position[2] as _,
),
), ),
V3(v0.normal[0] as _, v0.normal[1] as _, v0.normal[2] as _), V3(
color, v1.position[0] as _,
)); v1.position[2] as _,
v1.position[1] as _,
),
V3(
v2.position[0] as _,
v2.position[2] as _,
v2.position[1] as _,
),
);
let normal = tri.normal();
// let normal = V3(v0.normal[0] as _, v0.normal[2] as _, v0.normal[1] as _)
// + V3(v1.normal[0] as _, v1.normal[2] as _, v1.normal[1] as _)
// + V3(v2.normal[0] as _, v2.normal[2] as _, v2.normal[1] as _);
self.tris.push((tri, normal, color));
} }
self self
} }

View File

@ -50,4 +50,8 @@ impl Tri3 {
pub fn normal(&self) -> V3 { pub fn normal(&self) -> V3 {
(self.1 - self.0).cross(self.2 - self.1) (self.1 - self.0).cross(self.2 - self.1)
} }
pub fn middle(&self) -> V3 {
(self.0 + self.1 + self.2).map(|v| v / 3.0)
}
} }

View File

@ -16,6 +16,10 @@ impl V2 {
Self(func(self.0, rhs.0), func(self.1, rhs.1)) Self(func(self.0, rhs.0), func(self.1, rhs.1))
} }
pub fn iter(&self) -> impl Iterator<Item = f64> {
[self.0, self.1].into_iter()
}
pub fn reduce<F: Fn(f64, f64) -> f64>(&self, initial: f64, func: F) -> f64 { pub fn reduce<F: Fn(f64, f64) -> f64>(&self, initial: f64, func: F) -> f64 {
let acc = initial; let acc = initial;
let acc = func(acc, self.0); let acc = func(acc, self.0);

View File

@ -22,11 +22,16 @@ impl V3 {
) )
} }
pub fn iter(&self) -> impl Iterator<Item = f64> {
[self.0, self.1, self.2].into_iter()
}
pub fn reduce<F: Fn(f64, f64) -> f64>(&self, initial: f64, func: F) -> f64 { pub fn reduce<F: Fn(f64, f64) -> f64>(&self, initial: f64, func: F) -> f64 {
let acc = initial; let mut acc = initial;
let acc = func(acc, self.0); for v in self.iter() {
let acc = func(acc, self.1); acc = func(acc, v);
func(acc, self.0) }
acc
} }
pub fn cross(&self, rhs: V3) -> Self { pub fn cross(&self, rhs: V3) -> Self {
@ -67,7 +72,7 @@ impl V3 {
} }
pub fn len(&self) -> f64 { pub fn len(&self) -> f64 {
self.map(|v| v.powi(2)).reduce(0.0, |acc, v| acc + v) self.map(|v| v.powi(2)).reduce(0.0, |acc, v| acc + v).sqrt()
} }
pub fn unit(&self) -> V3 { pub fn unit(&self) -> V3 {

View File

@ -129,14 +129,10 @@ impl Renderer for Window {
.unwrap(); .unwrap();
} }
fn draw_line(&mut self, from: V2, to: V2, color: Color) { fn draw_line(&mut self, from: V2, to: V2, color: Color) {
let n = (to - from).normal().unit() * 0.0005; self.canvas.set_draw_color(color);
self.canvas
let p0 = from - n; .draw_line(self.point_w2s(from), self.point_w2s(to))
let p1 = to - n; .unwrap();
let p2 = from + n;
let p3 = to + n;
self.draw_triangles(&[Tri2(p0, p1, p2), Tri2(p3, p2, p1)], color);
} }
fn draw_triangles(&mut self, tris: &[Tri2], color: Color) { fn draw_triangles(&mut self, tris: &[Tri2], color: Color) {