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 | 156 | fn edge(self, b :&Self) -> Vec<Self> { |
| 157 | 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 | 165 | impl<T> Display for Coordinate<T> { | ... | ... |
| ... | ... | @@ -155,9 +155,10 @@ where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> { |
| 155 | 155 | |
| 156 | 156 | pub struct Camera<T> |
| 157 | 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 | 164 | pub struct DirectLight<T> |
| ... | ... | @@ -181,15 +182,20 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
| 181 | 182 | let wh = width / 2.into(); |
| 182 | 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 | 189 | ( fov, 0.into(), wh, 0.into()) |
| 188 | 190 | , (0.into(), fov, hh, 0.into()) |
| 189 | 191 | , (0.into(), 0.into(), d, 1.into()) |
| 190 | 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 | 199 | pub fn get_projection(&self) -> TMatrix<T> { |
| 194 | 200 | self.project |
| 195 | 201 | } |
| ... | ... | @@ -253,11 +259,6 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
| 253 | 259 | let zc :T = T::sqrt(f3).unwrap() / f3 * a; |
| 254 | 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 | 262 | let ps = vec!( Point::new( f0, yc, f0) |
| 262 | 263 | , Point::new(-ah, -yi, -zi) |
| 263 | 264 | , Point::new( ah, -yi, -zi) |
| ... | ... | @@ -285,8 +286,6 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
| 285 | 286 | |
| 286 | 287 | let fs = vec!(Face::new(vec!(0, 1, 2), &ps)); |
| 287 | 288 | |
| 288 | - println!("== {:?}", fs); | |
| 289 | - | |
| 290 | 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 | 346 | // matrix we do not need to do it here. |
| 348 | 347 | let to_coord = |p :&usize| { |
| 349 | 348 | let Point(v, _) = camera.project(self.points[*p]); |
| 350 | - // println!("== {:?} / {:?}", self.points[*p], (v.z() - 1.into()).recip()); | |
| 351 | 349 | Coordinate(T::round(&v.x()), T::round(&v.y()), v.z() - 1.into()) |
| 352 | 350 | }; |
| 353 | 351 | let to_poly = |f :&Face<T>| { |
| ... | ... | @@ -378,7 +376,7 @@ where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> |
| 378 | 376 | }}; |
| 379 | 377 | |
| 380 | 378 | let mut ps :Vec<(Polygon<T>, u32)> = self.faces.iter() |
| 381 | - . filter_map(to_poly).collect(); | |
| 379 | + . filter_map(to_poly).collect(); | |
| 382 | 380 | // this sorts by the color value which is no longer neccessary as soon |
| 383 | 381 | // as the z-buffer is complete. |
| 384 | 382 | ps.sort_by(|a, b| a.1.cmp(&b.1)); | ... | ... |
| ... | ... | @@ -35,8 +35,7 @@ use fractional::fractional::{Fractional, from_vector}; |
| 35 | 35 | use fractional::trigonometry::Trig; |
| 36 | 36 | use fractional::vector::Vector; |
| 37 | 37 | use fractional::transform::{TMatrix, Transformable}; |
| 38 | - | |
| 39 | -use fractional::xcb::{XcbEasel, XcbCanvas}; | |
| 38 | +use fractional::xcb::XcbEasel; | |
| 40 | 39 | |
| 41 | 40 | use fractional::geometry::{Camera,DirectLight,Polyeder,Primitives}; |
| 42 | 41 | |
| ... | ... | @@ -322,8 +321,8 @@ fn _democanvas<T>( xcb :&XcbEasel |
| 322 | 321 | // was 50. |
| 323 | 322 | |
| 324 | 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 | 327 | thread::spawn(move || { |
| 329 | 328 | let start = Instant::now(); |
| ... | ... | @@ -348,7 +347,7 @@ fn _democanvas<T>( xcb :&XcbEasel |
| 348 | 347 | //let objects = vec!( (tetrahedron.transform(&rot1), 0xFFFF00) ); |
| 349 | 348 | //let objects = vec!( (triangle.transform(&rot1), 0xFFFF00) ); |
| 350 | 349 | |
| 351 | - <XcbCanvas as Canvas<T>>::clear(&mut canvas); | |
| 350 | + canvas.clear(); | |
| 352 | 351 | |
| 353 | 352 | for (o, color) in objects { |
| 354 | 353 | for (pg, c) in o.project(&camera, &light, color) { |
| ... | ... | @@ -367,11 +366,10 @@ fn _democanvas<T>( xcb :&XcbEasel |
| 367 | 366 | } |
| 368 | 367 | |
| 369 | 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 | 373 | thread::sleep(last - Instant::now()); |
| 376 | 374 | } |
| 377 | 375 | }); | ... | ... |
| ... | ... | @@ -24,19 +24,21 @@ use std::sync::Arc; |
| 24 | 24 | use std::ptr; //::{null, null_mut}; |
| 25 | 25 | use std::thread; |
| 26 | 26 | use std::sync::mpsc; |
| 27 | +use std::ops::{Add, Sub, Div}; | |
| 27 | 28 | |
| 28 | 29 | use crate::easel::{Easel, Canvas, Drawable, Coordinate, Coordinates}; |
| 29 | 30 | |
| 30 | 31 | #[derive(Clone)] |
| 31 | 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 | 43 | impl XcbEasel { |
| 42 | 44 | pub fn new() -> Result<XcbEasel, xcb::ConnError> { |
| ... | ... | @@ -55,7 +57,10 @@ impl XcbEasel { |
| 55 | 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 | 64 | let Self(conn, _) = self; |
| 60 | 65 | let conn = conn.clone(); |
| 61 | 66 | let screen = match self.screen() { |
| ... | ... | @@ -80,6 +85,7 @@ impl XcbEasel { |
| 80 | 85 | , &[ (xcb::GC_FOREGROUND, screen.white_pixel()) |
| 81 | 86 | , (xcb::GC_GRAPHICS_EXPOSURES, 0) ] ); |
| 82 | 87 | |
| 88 | + let zbuf :Vec<T> = vec!(0.into(); (width * height) as usize); | |
| 83 | 89 | let (shmid, shm) = getshm((width * height) as usize); |
| 84 | 90 | xcb::shm::attach(&conn, shmseg, shmid as u32, false); |
| 85 | 91 | unsafe { libc::shmctl(shmid, libc::IPC_RMID, ptr::null_mut()); } |
| ... | ... | @@ -96,11 +102,12 @@ impl XcbEasel { |
| 96 | 102 | , window: window |
| 97 | 103 | , pixmap: pixmap |
| 98 | 104 | , gc: gc |
| 105 | + , zbuf: zbuf | |
| 99 | 106 | , shm: Box::new(shm) } ) |
| 100 | 107 | } |
| 101 | 108 | } |
| 102 | 109 | |
| 103 | -impl<'a> XcbCanvas<'a> { | |
| 110 | +impl<'a, T> XcbCanvas<'a, T> { | |
| 104 | 111 | pub fn set_title(&self, title :&str) { |
| 105 | 112 | let c = xcb::change_property_checked( &self.conn |
| 106 | 113 | , xcb::PROP_MODE_REPLACE as u8 |
| ... | ... | @@ -129,7 +136,9 @@ fn getshm<'a>(size :usize) -> (i32, &'a mut [u32]) { |
| 129 | 136 | |
| 130 | 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 | 142 | fn init_events(&self) { |
| 134 | 143 | let mask = [( xcb::CW_EVENT_MASK, xcb::EVENT_MASK_EXPOSURE |
| 135 | 144 | | xcb::EVENT_MASK_KEY_PRESS |
| ... | ... | @@ -216,6 +225,7 @@ impl<'a,T> Canvas<T> for XcbCanvas<'a> { |
| 216 | 225 | } |
| 217 | 226 | |
| 218 | 227 | fn clear(&mut self) { |
| 228 | + self.zbuf = vec!(0.into(); self.zbuf.len()); | |
| 219 | 229 | unsafe { |
| 220 | 230 | let ptr = self.shm.as_mut_ptr(); |
| 221 | 231 | ptr::write_bytes( ptr, 0 |
| ... | ... | @@ -227,9 +237,12 @@ impl<'a,T> Canvas<T> for XcbCanvas<'a> { |
| 227 | 237 | let Coordinates(c) = d.plot(); |
| 228 | 238 | let Coordinate(xofs, yofs, _) = ofs; |
| 229 | 239 | |
| 230 | - for Coordinate(x, y, _) in c { | |
| 240 | + for Coordinate(x, y, zr) in c { | |
| 231 | 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 | 254 | } |
| 242 | 255 | |
| 243 | 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 | 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 | 266 | fn show(&self) { | ... | ... |
Please
register
or
login
to post a comment