Showing
4 changed files
with
55 additions
and
40 deletions
@@ -156,6 +156,10 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | @@ -156,6 +156,10 @@ where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
156 | fn edge(self, b :&Self) -> Vec<Self> { | 156 | fn edge(self, b :&Self) -> Vec<Self> { |
157 | self.edge_iter(b).collect() | 157 | self.edge_iter(b).collect() |
158 | } | 158 | } |
159 | + | ||
160 | + fn face(edges :&[Self]) -> Vec<Self> { | ||
161 | + edges.to_vec() | ||
162 | + } | ||
159 | } | 163 | } |
160 | 164 | ||
161 | impl<T> Display for Coordinate<T> { | 165 | impl<T> Display for Coordinate<T> { |
@@ -155,9 +155,10 @@ where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> { | @@ -155,9 +155,10 @@ where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> { | ||
155 | 155 | ||
156 | pub struct Camera<T> | 156 | pub struct Camera<T> |
157 | where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> { | 157 | where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> { |
158 | - width :T, | ||
159 | - height :T, | ||
160 | - project :TMatrix<T>, | 158 | + width :T, |
159 | + height :T, | ||
160 | + distance :T, | ||
161 | + project :TMatrix<T>, | ||
161 | } | 162 | } |
162 | 163 | ||
163 | pub struct DirectLight<T> | 164 | pub struct DirectLight<T> |
@@ -181,15 +182,20 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | @@ -181,15 +182,20 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
181 | let wh = width / 2.into(); | 182 | let wh = width / 2.into(); |
182 | let hh = height / 2.into(); | 183 | let hh = height / 2.into(); |
183 | 184 | ||
184 | - Camera { width: width | ||
185 | - , height: height | ||
186 | - , project: TMatrix::new( | 185 | + Camera { width: width |
186 | + , height: height | ||
187 | + , distance: d | ||
188 | + , project: TMatrix::new( | ||
187 | ( fov, 0.into(), wh, 0.into()) | 189 | ( fov, 0.into(), wh, 0.into()) |
188 | , (0.into(), fov, hh, 0.into()) | 190 | , (0.into(), fov, hh, 0.into()) |
189 | , (0.into(), 0.into(), d, 1.into()) | 191 | , (0.into(), 0.into(), d, 1.into()) |
190 | , (0.into(), 0.into(), 1.into(), 0.into()) ) } | 192 | , (0.into(), 0.into(), 1.into(), 0.into()) ) } |
191 | } | 193 | } |
192 | 194 | ||
195 | + pub fn get_distance(&self) -> T { | ||
196 | + self.distance | ||
197 | + } | ||
198 | + | ||
193 | pub fn get_projection(&self) -> TMatrix<T> { | 199 | pub fn get_projection(&self) -> TMatrix<T> { |
194 | self.project | 200 | self.project |
195 | } | 201 | } |
@@ -253,11 +259,6 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | @@ -253,11 +259,6 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
253 | let zc :T = T::sqrt(f3).unwrap() / f3 * a; | 259 | let zc :T = T::sqrt(f3).unwrap() / f3 * a; |
254 | let ah :T = a / 2.into(); | 260 | let ah :T = a / 2.into(); |
255 | 261 | ||
256 | - // half the height in y | ||
257 | - let _yh :T = a / f6 * T::sqrt(f6).unwrap(); | ||
258 | - // half the deeps in z | ||
259 | - let _zh :T = T::sqrt(f3).unwrap() / f4 * a; | ||
260 | - | ||
261 | let ps = vec!( Point::new( f0, yc, f0) | 262 | let ps = vec!( Point::new( f0, yc, f0) |
262 | , Point::new(-ah, -yi, -zi) | 263 | , Point::new(-ah, -yi, -zi) |
263 | , Point::new( ah, -yi, -zi) | 264 | , Point::new( ah, -yi, -zi) |
@@ -285,8 +286,6 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | @@ -285,8 +286,6 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
285 | 286 | ||
286 | let fs = vec!(Face::new(vec!(0, 1, 2), &ps)); | 287 | let fs = vec!(Face::new(vec!(0, 1, 2), &ps)); |
287 | 288 | ||
288 | - println!("== {:?}", fs); | ||
289 | - | ||
290 | Polyeder{ points: ps, faces: fs } | 289 | Polyeder{ points: ps, faces: fs } |
291 | } | 290 | } |
292 | 291 | ||
@@ -347,7 +346,6 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | @@ -347,7 +346,6 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
347 | // matrix we do not need to do it here. | 346 | // matrix we do not need to do it here. |
348 | let to_coord = |p :&usize| { | 347 | let to_coord = |p :&usize| { |
349 | let Point(v, _) = camera.project(self.points[*p]); | 348 | let Point(v, _) = camera.project(self.points[*p]); |
350 | - // println!("== {:?} / {:?}", self.points[*p], (v.z() - 1.into()).recip()); | ||
351 | Coordinate(T::round(&v.x()), T::round(&v.y()), v.z() - 1.into()) | 349 | Coordinate(T::round(&v.x()), T::round(&v.y()), v.z() - 1.into()) |
352 | }; | 350 | }; |
353 | let to_poly = |f :&Face<T>| { | 351 | let to_poly = |f :&Face<T>| { |
@@ -378,7 +376,7 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | @@ -378,7 +376,7 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
378 | }}; | 376 | }}; |
379 | 377 | ||
380 | let mut ps :Vec<(Polygon<T>, u32)> = self.faces.iter() | 378 | let mut ps :Vec<(Polygon<T>, u32)> = self.faces.iter() |
381 | - . filter_map(to_poly).collect(); | 379 | + . filter_map(to_poly).collect(); |
382 | // this sorts by the color value which is no longer neccessary as soon | 380 | // this sorts by the color value which is no longer neccessary as soon |
383 | // as the z-buffer is complete. | 381 | // as the z-buffer is complete. |
384 | ps.sort_by(|a, b| a.1.cmp(&b.1)); | 382 | ps.sort_by(|a, b| a.1.cmp(&b.1)); |
@@ -35,8 +35,7 @@ use fractional::fractional::{Fractional, from_vector}; | @@ -35,8 +35,7 @@ use fractional::fractional::{Fractional, from_vector}; | ||
35 | use fractional::trigonometry::Trig; | 35 | use fractional::trigonometry::Trig; |
36 | use fractional::vector::Vector; | 36 | use fractional::vector::Vector; |
37 | use fractional::transform::{TMatrix, Transformable}; | 37 | use fractional::transform::{TMatrix, Transformable}; |
38 | - | ||
39 | -use fractional::xcb::{XcbEasel, XcbCanvas}; | 38 | +use fractional::xcb::XcbEasel; |
40 | 39 | ||
41 | use fractional::geometry::{Camera,DirectLight,Polyeder,Primitives}; | 40 | use fractional::geometry::{Camera,DirectLight,Polyeder,Primitives}; |
42 | 41 | ||
@@ -322,8 +321,8 @@ fn _democanvas<T>( xcb :&XcbEasel | @@ -322,8 +321,8 @@ fn _democanvas<T>( xcb :&XcbEasel | ||
322 | // was 50. | 321 | // was 50. |
323 | 322 | ||
324 | canvas.set_title(title); | 323 | canvas.set_title(title); |
325 | - <XcbCanvas as Canvas<T>>::init_events(&canvas); | ||
326 | - <XcbCanvas as Canvas<T>>::start_events(&canvas, tx.clone()); | 324 | + canvas.init_events(); |
325 | + canvas.start_events(tx.clone()); | ||
327 | 326 | ||
328 | thread::spawn(move || { | 327 | thread::spawn(move || { |
329 | let start = Instant::now(); | 328 | let start = Instant::now(); |
@@ -348,7 +347,7 @@ fn _democanvas<T>( xcb :&XcbEasel | @@ -348,7 +347,7 @@ fn _democanvas<T>( xcb :&XcbEasel | ||
348 | //let objects = vec!( (tetrahedron.transform(&rot1), 0xFFFF00) ); | 347 | //let objects = vec!( (tetrahedron.transform(&rot1), 0xFFFF00) ); |
349 | //let objects = vec!( (triangle.transform(&rot1), 0xFFFF00) ); | 348 | //let objects = vec!( (triangle.transform(&rot1), 0xFFFF00) ); |
350 | 349 | ||
351 | - <XcbCanvas as Canvas<T>>::clear(&mut canvas); | 350 | + canvas.clear(); |
352 | 351 | ||
353 | for (o, color) in objects { | 352 | for (o, color) in objects { |
354 | for (pg, c) in o.project(&camera, &light, color) { | 353 | for (pg, c) in o.project(&camera, &light, color) { |
@@ -367,11 +366,10 @@ fn _democanvas<T>( xcb :&XcbEasel | @@ -367,11 +366,10 @@ fn _democanvas<T>( xcb :&XcbEasel | ||
367 | } | 366 | } |
368 | 367 | ||
369 | last = last + step*(f + 1); | 368 | last = last + step*(f + 1); |
370 | - <XcbCanvas as Canvas<T>>::put_text( &canvas | ||
371 | - , Coordinate(10, 15, 0.into()) | ||
372 | - , &format!( "sleep: {:?}" | ||
373 | - , last - Instant::now() )); | ||
374 | - <XcbCanvas as Canvas<T>>::show(&canvas); | 369 | + canvas.put_text( Coordinate(10, 15, 0.into()) |
370 | + , &format!( "sleep: {:?}" | ||
371 | + , last - Instant::now() )); | ||
372 | + canvas.show(); | ||
375 | thread::sleep(last - Instant::now()); | 373 | thread::sleep(last - Instant::now()); |
376 | } | 374 | } |
377 | }); | 375 | }); |
@@ -24,19 +24,21 @@ use std::sync::Arc; | @@ -24,19 +24,21 @@ use std::sync::Arc; | ||
24 | use std::ptr; //::{null, null_mut}; | 24 | use std::ptr; //::{null, null_mut}; |
25 | use std::thread; | 25 | use std::thread; |
26 | use std::sync::mpsc; | 26 | use std::sync::mpsc; |
27 | +use std::ops::{Add, Sub, Div}; | ||
27 | 28 | ||
28 | use crate::easel::{Easel, Canvas, Drawable, Coordinate, Coordinates}; | 29 | use crate::easel::{Easel, Canvas, Drawable, Coordinate, Coordinates}; |
29 | 30 | ||
30 | #[derive(Clone)] | 31 | #[derive(Clone)] |
31 | pub struct XcbEasel (Arc<xcb::Connection>, i32); | 32 | pub struct XcbEasel (Arc<xcb::Connection>, i32); |
32 | 33 | ||
33 | -pub struct XcbCanvas<'a> { conn :Arc<xcb::Connection> | ||
34 | - , width :u16 | ||
35 | - , height :u16 | ||
36 | - , window :u32 | ||
37 | - , pixmap :u32 | ||
38 | - , gc :u32 | ||
39 | - , shm :Box<&'a mut [u32]> } | 34 | +pub struct XcbCanvas<'a, T> { conn :Arc<xcb::Connection> |
35 | + , width :u16 | ||
36 | + , height :u16 | ||
37 | + , window :u32 | ||
38 | + , pixmap :u32 | ||
39 | + , gc :u32 | ||
40 | + , zbuf :Vec<T> | ||
41 | + , shm :Box<&'a mut [u32]> } | ||
40 | 42 | ||
41 | impl XcbEasel { | 43 | impl XcbEasel { |
42 | pub fn new() -> Result<XcbEasel, xcb::ConnError> { | 44 | pub fn new() -> Result<XcbEasel, xcb::ConnError> { |
@@ -55,7 +57,10 @@ impl XcbEasel { | @@ -55,7 +57,10 @@ impl XcbEasel { | ||
55 | self.setup().roots().nth(*num as usize) | 57 | self.setup().roots().nth(*num as usize) |
56 | } | 58 | } |
57 | 59 | ||
58 | - pub fn canvas<'a>(&self, width :u16, height :u16) -> Option<XcbCanvas<'a>> { | 60 | + pub fn canvas<'a, T>( &self |
61 | + , width :u16 | ||
62 | + , height :u16) -> Option<XcbCanvas<'a, T>> | ||
63 | + where T: Clone + From<i32> { | ||
59 | let Self(conn, _) = self; | 64 | let Self(conn, _) = self; |
60 | let conn = conn.clone(); | 65 | let conn = conn.clone(); |
61 | let screen = match self.screen() { | 66 | let screen = match self.screen() { |
@@ -80,6 +85,7 @@ impl XcbEasel { | @@ -80,6 +85,7 @@ impl XcbEasel { | ||
80 | , &[ (xcb::GC_FOREGROUND, screen.white_pixel()) | 85 | , &[ (xcb::GC_FOREGROUND, screen.white_pixel()) |
81 | , (xcb::GC_GRAPHICS_EXPOSURES, 0) ] ); | 86 | , (xcb::GC_GRAPHICS_EXPOSURES, 0) ] ); |
82 | 87 | ||
88 | + let zbuf :Vec<T> = vec!(0.into(); (width * height) as usize); | ||
83 | let (shmid, shm) = getshm((width * height) as usize); | 89 | let (shmid, shm) = getshm((width * height) as usize); |
84 | xcb::shm::attach(&conn, shmseg, shmid as u32, false); | 90 | xcb::shm::attach(&conn, shmseg, shmid as u32, false); |
85 | unsafe { libc::shmctl(shmid, libc::IPC_RMID, ptr::null_mut()); } | 91 | unsafe { libc::shmctl(shmid, libc::IPC_RMID, ptr::null_mut()); } |
@@ -96,11 +102,12 @@ impl XcbEasel { | @@ -96,11 +102,12 @@ impl XcbEasel { | ||
96 | , window: window | 102 | , window: window |
97 | , pixmap: pixmap | 103 | , pixmap: pixmap |
98 | , gc: gc | 104 | , gc: gc |
105 | + , zbuf: zbuf | ||
99 | , shm: Box::new(shm) } ) | 106 | , shm: Box::new(shm) } ) |
100 | } | 107 | } |
101 | } | 108 | } |
102 | 109 | ||
103 | -impl<'a> XcbCanvas<'a> { | 110 | +impl<'a, T> XcbCanvas<'a, T> { |
104 | pub fn set_title(&self, title :&str) { | 111 | pub fn set_title(&self, title :&str) { |
105 | let c = xcb::change_property_checked( &self.conn | 112 | let c = xcb::change_property_checked( &self.conn |
106 | , xcb::PROP_MODE_REPLACE as u8 | 113 | , xcb::PROP_MODE_REPLACE as u8 |
@@ -129,7 +136,9 @@ fn getshm<'a>(size :usize) -> (i32, &'a mut [u32]) { | @@ -129,7 +136,9 @@ fn getshm<'a>(size :usize) -> (i32, &'a mut [u32]) { | ||
129 | 136 | ||
130 | impl Easel for XcbEasel {} | 137 | impl Easel for XcbEasel {} |
131 | 138 | ||
132 | -impl<'a,T> Canvas<T> for XcbCanvas<'a> { | 139 | +impl<'a, T> Canvas<T> for XcbCanvas<'a, T> |
140 | +where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
141 | + + Copy + From<i32> + PartialOrd { | ||
133 | fn init_events(&self) { | 142 | fn init_events(&self) { |
134 | let mask = [( xcb::CW_EVENT_MASK, xcb::EVENT_MASK_EXPOSURE | 143 | let mask = [( xcb::CW_EVENT_MASK, xcb::EVENT_MASK_EXPOSURE |
135 | | xcb::EVENT_MASK_KEY_PRESS | 144 | | xcb::EVENT_MASK_KEY_PRESS |
@@ -216,6 +225,7 @@ impl<'a,T> Canvas<T> for XcbCanvas<'a> { | @@ -216,6 +225,7 @@ impl<'a,T> Canvas<T> for XcbCanvas<'a> { | ||
216 | } | 225 | } |
217 | 226 | ||
218 | fn clear(&mut self) { | 227 | fn clear(&mut self) { |
228 | + self.zbuf = vec!(0.into(); self.zbuf.len()); | ||
219 | unsafe { | 229 | unsafe { |
220 | let ptr = self.shm.as_mut_ptr(); | 230 | let ptr = self.shm.as_mut_ptr(); |
221 | ptr::write_bytes( ptr, 0 | 231 | ptr::write_bytes( ptr, 0 |
@@ -227,9 +237,12 @@ impl<'a,T> Canvas<T> for XcbCanvas<'a> { | @@ -227,9 +237,12 @@ impl<'a,T> Canvas<T> for XcbCanvas<'a> { | ||
227 | let Coordinates(c) = d.plot(); | 237 | let Coordinates(c) = d.plot(); |
228 | let Coordinate(xofs, yofs, _) = ofs; | 238 | let Coordinate(xofs, yofs, _) = ofs; |
229 | 239 | ||
230 | - for Coordinate(x, y, _) in c { | 240 | + for Coordinate(x, y, zr) in c { |
231 | let idx :usize = ((y+yofs)*(self.width as i32)+x+xofs) as usize; | 241 | let idx :usize = ((y+yofs)*(self.width as i32)+x+xofs) as usize; |
232 | - self.shm[idx] = color; | 242 | + if self.zbuf[idx] < zr { |
243 | + self.zbuf[idx] = zr; | ||
244 | + self.shm[idx] = color; | ||
245 | + } | ||
233 | } | 246 | } |
234 | } | 247 | } |
235 | 248 | ||
@@ -241,11 +254,13 @@ impl<'a,T> Canvas<T> for XcbCanvas<'a> { | @@ -241,11 +254,13 @@ impl<'a,T> Canvas<T> for XcbCanvas<'a> { | ||
241 | } | 254 | } |
242 | 255 | ||
243 | fn set_pixel(&mut self, c :Coordinate<T>, color :u32) { | 256 | fn set_pixel(&mut self, c :Coordinate<T>, color :u32) { |
244 | - let Coordinate(x, y, _) = c; | 257 | + let Coordinate(x, y, zr) = c; |
245 | let idx :usize = (y * (self.width as i32) + x) as usize; | 258 | let idx :usize = (y * (self.width as i32) + x) as usize; |
246 | 259 | ||
247 | - //print!("({}, {})", idx, color); | ||
248 | - self.shm[idx] = color; | 260 | + if self.zbuf[idx] < zr { |
261 | + self.zbuf[idx] = zr; | ||
262 | + self.shm[idx] = color; | ||
263 | + } | ||
249 | } | 264 | } |
250 | 265 | ||
251 | fn show(&self) { | 266 | fn show(&self) { |
Please
register
or
login
to post a comment