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