Advertisement
Guest User

Untitled

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