Skip to content

Commit 67dae33

Browse files
authored
Merge pull request #8 from jonathandturner/crossterm-port
Crossterm port
2 parents ee85258 + 7b5d3ad commit 67dae33

File tree

5 files changed

+248
-83
lines changed

5 files changed

+248
-83
lines changed

Cargo.lock

Lines changed: 107 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ edition = "2018"
66

77
[dependencies]
88
nalgebra = "0.17"
9-
termion = "1"
9+
crossterm = "0.9.3"
1010
tobj = "0.1.6"
1111
clap = "2.32"
1212
stl_io = "0.4.2"

src/base/context.rs

Lines changed: 73 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
use nalgebra::Matrix4;
21
use crate::base::SimpleMesh;
3-
use std::{f32};
2+
use crossterm::{cursor, terminal, Attribute, Color, Colored};
3+
use nalgebra::Matrix4;
4+
use std::error::Error;
5+
use std::f32;
46

57
pub struct Context {
68
pub utransform: Matrix4<f32>,
79
pub width: usize,
810
pub height: usize,
9-
pub frame_buffer: Vec<String>,
11+
pub frame_buffer: Vec<(char, (u8, u8, u8))>,
1012
pub z_buffer: Vec<f32>,
1113
}
1214

@@ -15,39 +17,73 @@ impl Context {
1517
//TODO: Make this a constant struct
1618
Context {
1719
utransform: Matrix4::new(
18-
1.0, 0.0, 0.0, 0.0,
19-
0.0, 1.0, 0.0, 0.0,
20-
0.0, 0.0, 1.0, 0.0,
21-
0.0, 0.0, 0.0, 1.0,
20+
1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
2221
),
2322
width: 0,
2423
height: 0,
2524
frame_buffer: vec![],
26-
z_buffer: vec![]
25+
z_buffer: vec![],
2726
}
2827
}
2928
pub fn clear(&mut self) {
30-
self.frame_buffer = vec![" ".to_string(); self.width * self.height as usize];
29+
self.frame_buffer = vec![(' ', (0, 0, 0)); self.width * self.height as usize];
3130
self.z_buffer = vec![f32::MAX; self.width * self.height as usize]; //f32::MAX is written to the z-buffer as an infinite back-wall to render with
3231
}
3332
pub fn camera(&mut self, proj: Matrix4<f32>, view: Matrix4<f32>) -> &Matrix4<f32> {
3433
self.utransform = proj * view;
3534
&self.utransform
3635
}
37-
pub fn flush(&self) {
38-
let mut x: String = "".to_string();
36+
pub fn flush(&self) -> Result<(), Box<Error>> {
37+
let cursor = cursor();
38+
cursor.goto(0, 0)?;
39+
40+
let mut prev_color = None;
41+
3942
for pixel in &self.frame_buffer {
40-
x.push_str(pixel);
43+
match prev_color {
44+
Some(c) if c == pixel.1 => {
45+
print!("{}", pixel.0);
46+
}
47+
_ => {
48+
prev_color = Some(pixel.1);
49+
print!(
50+
"{}{}{}",
51+
Colored::Fg(Color::Rgb {
52+
r: (pixel.1).0,
53+
g: (pixel.1).1,
54+
b: (pixel.1).2
55+
}),
56+
Colored::Bg(Color::Rgb {
57+
r: 25,
58+
g: 25,
59+
b: 25
60+
}),
61+
pixel.0
62+
)
63+
}
64+
}
4165
}
42-
println!("{}{}{}", termion::clear::All, termion::cursor::Goto(1, 1), x);
66+
67+
println!("{}", Attribute::Reset);
68+
69+
Ok(())
4370
}
44-
pub fn update(&mut self, mut old_size: (u16, u16),
71+
pub fn update(
72+
&mut self,
73+
mut old_size: (u16, u16),
4574
meshes: &[SimpleMesh],
46-
) {
47-
let terminal_size = termion::terminal_size().unwrap(); // Temporary size
75+
) -> Result<(), Box<Error>> {
76+
let terminal = terminal();
77+
let terminal_size = terminal.terminal_size();
78+
4879
if old_size != terminal_size {
4980
// Check if the size changed
81+
let cursor = cursor();
82+
83+
//re-hide the cursor
84+
cursor.hide()?;
5085
old_size = terminal_size; // It changed! Set new size
86+
old_size.0 += 1;
5187
let mut scale: f32 = 0.0; // The scene's scale
5288
for mesh in meshes {
5389
// This calculates the maximum axis value (x y or z) in all meshes
@@ -57,14 +93,29 @@ impl Context {
5793
.max(mesh.bounding_box.max.z);
5894
}
5995
scale = f32::from(old_size.1).min(f32::from(old_size.0) / 2.0) / scale / 2.0; // Constrain to width and height, whichever is smaller
60-
let t = Matrix4::new(scale, 0.0, 0.0, f32::from(old_size.0) / 4.0, // X translation is divided by 4 because there's a 1 char space between charxels
61-
0.0, -scale, 0.0, f32::from(old_size.1) / 2.0, // Y translation is divided by 2 to center
62-
0.0, 0.0, scale, 0.0,
63-
0.0, 0.0, 0.0, 1.0,
96+
let t = Matrix4::new(
97+
scale,
98+
0.0,
99+
0.0,
100+
f32::from(old_size.0) / 4.0, // X translation is divided by 4 because there's a 1 char space between charxels
101+
0.0,
102+
-scale,
103+
0.0,
104+
f32::from(old_size.1) / 2.0, // Y translation is divided by 2 to center
105+
0.0,
106+
0.0,
107+
scale,
108+
0.0,
109+
0.0,
110+
0.0,
111+
0.0,
112+
1.0,
64113
);
65114
self.utransform = t;
66-
self.width = (old_size.0) as usize;
67-
self.height = (old_size.1 - 1) as usize;
115+
self.width = old_size.0 as usize;
116+
self.height = (old_size.1) as usize;
68117
}
118+
119+
Ok(())
69120
}
70121
}

0 commit comments

Comments
 (0)