Advertisement
Guest User

Untitled

a guest
Sep 5th, 2019
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 5.22 KB | None | 0 0
  1. use std::cmp::{max, min};
  2. use std::mem::swap;
  3.  
  4. use super::Target;
  5. use super::FragmentShader;
  6. use super::Varying;
  7. use super::VertexShader;
  8.  
  9. pub struct Triangle;
  10.  
  11. impl Triangle {
  12.  
  13.     /// Rasterizes a triangle with the given parameters. Results are written to the given TTarget.
  14.     pub fn triangle<TVertexShader, TFragmentShader, TUniform, TVertex, TVarying, TTarget>(
  15.         vs:      &TVertexShader,
  16.         fs:      &TFragmentShader,
  17.         uniform: &TUniform,
  18.         vertex0: &TVertex,
  19.         vertex1: &TVertex,
  20.         vertex2: &TVertex,
  21.         target:  &TTarget,
  22.     ) where
  23.         TVertexShader:   VertexShader<Uniform = TUniform, Vertex = TVertex, Varying = TVarying>,
  24.         TFragmentShader: FragmentShader<Uniform = TUniform, Varying = TVarying>,
  25.         TVarying:        Varying,
  26.         TTarget:         Target,
  27.     {
  28.         // compute half width and height.
  29.         let width  = target.width()  as f32;
  30.         let height = target.height() as f32;
  31.         let half_width  = width  * 0.5;
  32.         let half_height = height * 0.5;
  33.  
  34.         // setup vrs for this primitive.
  35.         let mut vr0 = Varying::new();
  36.         let mut vr1 = Varying::new();
  37.         let mut vr2 = Varying::new();
  38.  
  39.         // execute vertex shader, store position for interpolation.
  40.         let t0 = vs.main(&uniform, &vertex0, &mut vr0);
  41.         let t1 = vs.main(&uniform, &vertex1, &mut vr1);
  42.         let t2 = vs.main(&uniform, &vertex2, &mut vr2);
  43.  
  44.         // calculate positions in clip space.
  45.         let cs0 = Vector2::new(
  46.             ((t0.x / t0.z) * width)  + half_width,
  47.             ((t0.y / t0.z) * height) + half_height,
  48.         );
  49.         let cs1 = Vector2::new(
  50.             ((t1.x / t1.z) * width)  + half_width,
  51.             ((t1.y / t1.z) * height) + half_height,
  52.         );
  53.         let cs2 = Vector2::new(
  54.             ((t2.x / t2.z) * width)  + half_width,
  55.             ((t2.y / t2.z) * height) + half_height,
  56.         );
  57.  
  58.         // run fragment processor
  59.         Self::run_fragment(
  60.             fs,
  61.             uniform,
  62.             &vr0,
  63.             &vr1,
  64.             &vr2,
  65.             &cs0,
  66.             &cs1,
  67.             &cs2,
  68.             target,
  69.         );
  70.     }
  71.  
  72.     /// Runs a fragment shader rasterization pass for this triangle.
  73.     fn run_fragment<TTarget, TFragmentShader, TVarying, TUniform>(
  74.         fs:      &TFragmentShader,
  75.         uniform: &TUniform,
  76.         vr0:     &TVarying,
  77.         vr1:     &TVarying,
  78.         vr2:     &TVarying,
  79.         cs0:     &Vector2,
  80.         cs1:     &Vector2,
  81.         cs2:     &Vector2,
  82.         target:  &TTarget,
  83.     ) where
  84.         TFragmentShader: FragmentShader<Uniform = TUniform, Varying = TVarying>,
  85.         TVarying: Varying,
  86.         TTarget:  Target,
  87.     {
  88.         let mut x0 = cs0.x;
  89.         let mut y0 = cs0.y;
  90.         let mut x1 = cs1.x;
  91.         let mut y1 = cs1.y;
  92.         let mut x2 = cs2.x;
  93.         let mut y2 = cs2.y;
  94.         let width  = target.width();
  95.         let height = target.height();
  96.        
  97.         // sort top to bottom
  98.         if y0 > y1 {
  99.             swap(&mut x0, &mut x1);
  100.             swap(&mut y0, &mut y1);
  101.         }
  102.         if y1 > y2 {
  103.             swap(&mut x1, &mut x2);
  104.             swap(&mut y1, &mut y2);
  105.         }
  106.         if y0 > y1 {
  107.             swap(&mut x0, &mut x1);
  108.             swap(&mut y0, &mut y1);
  109.         }
  110.         // full height
  111.         let h0 = y2 - y0;
  112.  
  113.         // top triangle
  114.         {
  115.             let h1 = y1 - y0;
  116.             if h1 > 0_f32 {
  117.                 let xmin = max(y0 as i32, 0);
  118.                 let ymax = min(y1 as i32, (height - 1) as i32);
  119.                 for y in xmin..ymax + 1 {
  120.                     let sx = (y as f32 - y0) / h0;
  121.                     let sy = (y as f32 - y0) / h1;
  122.                     let m0 = (x0 + (x2 - x0) * sx) as i32;
  123.                     let m1 = (x0 + (x1 - x0) * sy) as i32;
  124.                     let xmin = max(min(m0, m1), 0);
  125.                     let xmax = min(max(m0, m1), (width - 1) as i32);
  126.                     for x in xmin..xmax + 1 {
  127.                         // let c = p.pixel(&w, &h, &x, &y);
  128.                         // buf.set(x as usize, y as usize, c);
  129.                     }
  130.                 }
  131.             }
  132.         }
  133.  
  134.         // bottom triangle
  135.         {
  136.             let h1 = y2 - y1;
  137.             if h1 > 0_f32 {
  138.                 let xmin = max(y1 as i32, 0);
  139.                 let ymax = min(y2 as i32, (height - 1) as i32);
  140.                 for y in xmin..ymax + 1 {
  141.                     let sx = (y as f32 - y0) / h0;
  142.                     let sy = (y as f32 - y1) / h1;
  143.                     let m0 = (x0 + (x2 - x0) * sx) as i32;
  144.                     let m1 = (x1 + (x2 - x1) * sy) as i32;
  145.                     let xmin = max(min(m0, m1), 0);
  146.                     let xmax = min(max(m0, m1), (width - 1) as i32);
  147.                     for x in xmin..xmax + 1 {
  148.                         // let c = p.pixel(&w, &h, &x, &y);
  149.                         // buf.set(x as usize, y as usize, c);
  150.                     }
  151.                 }
  152.             }
  153.         }
  154.        
  155.     }
  156.  
  157.     fn visible(&self, v0: &Vector2, v1: &Vector2, v2: &Vector2) -> bool {
  158.         return ((v1.x - v0.x) * (v2.y - v0.y)) - ((v1.y - v0.y) * (v2.x - v0.x)) >= 0.0;
  159.     }
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement