Commit 7900e2ff6a80d636cdb07ef049f902fd643a1311

Authored by Georg Hopp
1 parent 56b9b96a

First working z-buffer.

@@ -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